ide: add struct ide_host (take 3)
[linux-2.6-block.git] / drivers / ide / legacy / ide-cs.c
1 /*======================================================================
2
3     A driver for PCMCIA IDE/ATA disk cards
4
5     The contents of this file are subject to the Mozilla Public
6     License Version 1.1 (the "License"); you may not use this file
7     except in compliance with the License. You may obtain a copy of
8     the License at http://www.mozilla.org/MPL/
9
10     Software distributed under the License is distributed on an "AS
11     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12     implied. See the License for the specific language governing
13     rights and limitations under the License.
14
15     The initial developer of the original code is David A. Hinds
16     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
17     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
18
19     Alternatively, the contents of this file may be used under the
20     terms of the GNU General Public License version 2 (the "GPL"), in
21     which case the provisions of the GPL are applicable instead of the
22     above.  If you wish to allow the use of your version of this file
23     only under the terms of the GPL and not to allow others to use
24     your version of this file under the MPL, indicate your decision
25     by deleting the provisions above and replace them with the notice
26     and other provisions required by the GPL.  If you do not delete
27     the provisions above, a recipient may use your version of this
28     file under either the MPL or the GPL.
29
30 ======================================================================*/
31
32 #include <linux/module.h>
33 #include <linux/kernel.h>
34 #include <linux/init.h>
35 #include <linux/ptrace.h>
36 #include <linux/slab.h>
37 #include <linux/string.h>
38 #include <linux/timer.h>
39 #include <linux/ioport.h>
40 #include <linux/ide.h>
41 #include <linux/hdreg.h>
42 #include <linux/major.h>
43 #include <linux/delay.h>
44 #include <asm/io.h>
45 #include <asm/system.h>
46
47 #include <pcmcia/cs_types.h>
48 #include <pcmcia/cs.h>
49 #include <pcmcia/cistpl.h>
50 #include <pcmcia/ds.h>
51 #include <pcmcia/cisreg.h>
52 #include <pcmcia/ciscode.h>
53
54 #define DRV_NAME "ide-cs"
55
56 /*====================================================================*/
57
58 /* Module parameters */
59
60 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
61 MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
62 MODULE_LICENSE("Dual MPL/GPL");
63
64 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
65
66 #ifdef CONFIG_PCMCIA_DEBUG
67 INT_MODULE_PARM(pc_debug, 0);
68 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
69 #else
70 #define DEBUG(n, args...)
71 #endif
72
73 /*====================================================================*/
74
75 typedef struct ide_info_t {
76         struct pcmcia_device    *p_dev;
77         struct ide_host         *host;
78     int         ndev;
79     dev_node_t  node;
80 } ide_info_t;
81
82 static void ide_release(struct pcmcia_device *);
83 static int ide_config(struct pcmcia_device *);
84
85 static void ide_detach(struct pcmcia_device *p_dev);
86
87
88
89
90 /*======================================================================
91
92     ide_attach() creates an "instance" of the driver, allocating
93     local data structures for one device.  The device is registered
94     with Card Services.
95
96 ======================================================================*/
97
98 static int ide_probe(struct pcmcia_device *link)
99 {
100     ide_info_t *info;
101
102     DEBUG(0, "ide_attach()\n");
103
104     /* Create new ide device */
105     info = kzalloc(sizeof(*info), GFP_KERNEL);
106     if (!info)
107         return -ENOMEM;
108
109     info->p_dev = link;
110     link->priv = info;
111
112     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
113     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
114     link->io.IOAddrLines = 3;
115     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
116     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
117     link->conf.Attributes = CONF_ENABLE_IRQ;
118     link->conf.IntType = INT_MEMORY_AND_IO;
119
120     return ide_config(link);
121 } /* ide_attach */
122
123 /*======================================================================
124
125     This deletes a driver "instance".  The device is de-registered
126     with Card Services.  If it has been released, all local data
127     structures are freed.  Otherwise, the structures will be freed
128     when the device is released.
129
130 ======================================================================*/
131
132 static void ide_detach(struct pcmcia_device *link)
133 {
134     ide_info_t *info = link->priv;
135     ide_hwif_t *hwif = info->host->ports[0];
136     unsigned long data_addr, ctl_addr;
137
138     DEBUG(0, "ide_detach(0x%p)\n", link);
139
140     data_addr = hwif->io_ports.data_addr;
141     ctl_addr  = hwif->io_ports.ctl_addr;
142
143     ide_release(link);
144
145     release_region(ctl_addr, 1);
146     release_region(data_addr, 8);
147
148     kfree(info);
149 } /* ide_detach */
150
151 static const struct ide_port_ops idecs_port_ops = {
152         .quirkproc              = ide_undecoded_slave,
153 };
154
155 static const struct ide_port_info idecs_port_info = {
156         .port_ops               = &idecs_port_ops,
157         .host_flags             = IDE_HFLAG_NO_DMA,
158 };
159
160 static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
161                                 unsigned long irq, struct pcmcia_device *handle)
162 {
163     struct ide_host *host;
164     ide_hwif_t *hwif;
165     int i;
166     hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
167
168     if (!request_region(io, 8, DRV_NAME)) {
169         printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
170                         DRV_NAME, io, io + 7);
171         return NULL;
172     }
173
174     if (!request_region(ctl, 1, DRV_NAME)) {
175         printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
176                         DRV_NAME, ctl);
177         release_region(io, 8);
178         return NULL;
179     }
180
181     memset(&hw, 0, sizeof(hw));
182     ide_std_init_ports(&hw, io, ctl);
183     hw.irq = irq;
184     hw.chipset = ide_pci;
185     hw.dev = &handle->dev;
186
187     host = ide_host_alloc(&idecs_port_info, hws);
188     if (host == NULL)
189         goto out_release;
190
191     ide_host_register(host, &idecs_port_info, hws);
192
193     hwif = host->ports[0];
194
195     if (hwif->present)
196         return host;
197
198     /* retry registration in case device is still spinning up */
199     for (i = 0; i < 10; i++) {
200         msleep(100);
201         ide_port_scan(hwif);
202         if (hwif->present)
203             return host;
204     }
205
206     return host;
207
208 out_release:
209     release_region(ctl, 1);
210     release_region(io, 8);
211     return NULL;
212 }
213
214 /*======================================================================
215
216     ide_config() is scheduled to run after a CARD_INSERTION event
217     is received, to configure the PCMCIA socket, and to make the
218     ide device available to the system.
219
220 ======================================================================*/
221
222 #define CS_CHECK(fn, ret) \
223 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
224
225 static int ide_config(struct pcmcia_device *link)
226 {
227     ide_info_t *info = link->priv;
228     tuple_t tuple;
229     struct {
230         u_short         buf[128];
231         cisparse_t      parse;
232         config_info_t   conf;
233         cistpl_cftable_entry_t dflt;
234     } *stk = NULL;
235     cistpl_cftable_entry_t *cfg;
236     int pass, last_ret = 0, last_fn = 0, is_kme = 0;
237     unsigned long io_base, ctl_base;
238     struct ide_host *host;
239
240     DEBUG(0, "ide_config(0x%p)\n", link);
241
242     stk = kzalloc(sizeof(*stk), GFP_KERNEL);
243     if (!stk) goto err_mem;
244     cfg = &stk->parse.cftable_entry;
245
246     tuple.TupleData = (cisdata_t *)&stk->buf;
247     tuple.TupleOffset = 0;
248     tuple.TupleDataMax = 255;
249     tuple.Attributes = 0;
250
251     is_kme = ((link->manf_id == MANFID_KME) &&
252               ((link->card_id == PRODID_KME_KXLC005_A) ||
253                (link->card_id == PRODID_KME_KXLC005_B)));
254
255     /* Not sure if this is right... look up the current Vcc */
256     CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
257
258     pass = io_base = ctl_base = 0;
259     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
260     tuple.Attributes = 0;
261     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
262     while (1) {
263         if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
264         if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
265
266         /* Check for matching Vcc, unless we're desperate */
267         if (!pass) {
268             if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
269                 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
270                     goto next_entry;
271             } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
272                 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
273                     goto next_entry;
274             }
275         }
276
277         if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
278             link->conf.Vpp =
279                 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
280         else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
281             link->conf.Vpp =
282                 stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
283
284         if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
285             cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
286             link->conf.ConfigIndex = cfg->index;
287             link->io.BasePort1 = io->win[0].base;
288             link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
289             if (!(io->flags & CISTPL_IO_16BIT))
290                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
291             if (io->nwin == 2) {
292                 link->io.NumPorts1 = 8;
293                 link->io.BasePort2 = io->win[1].base;
294                 link->io.NumPorts2 = (is_kme) ? 2 : 1;
295                 if (pcmcia_request_io(link, &link->io) != 0)
296                         goto next_entry;
297                 io_base = link->io.BasePort1;
298                 ctl_base = link->io.BasePort2;
299             } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
300                 link->io.NumPorts1 = io->win[0].len;
301                 link->io.NumPorts2 = 0;
302                 if (pcmcia_request_io(link, &link->io) != 0)
303                         goto next_entry;
304                 io_base = link->io.BasePort1;
305                 ctl_base = link->io.BasePort1 + 0x0e;
306             } else goto next_entry;
307             /* If we've got this far, we're done */
308             break;
309         }
310
311     next_entry:
312         if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
313             memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
314         if (pass) {
315             CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
316         } else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
317             CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
318             memset(&stk->dflt, 0, sizeof(stk->dflt));
319             pass++;
320         }
321     }
322
323     CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
324     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
325
326     /* disable drive interrupts during IDE probe */
327     outb(0x02, ctl_base);
328
329     /* special setup for KXLC005 card */
330     if (is_kme)
331         outb(0x81, ctl_base+1);
332
333      host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
334      if (host == NULL && link->io.NumPorts1 == 0x20) {
335             outb(0x02, ctl_base + 0x10);
336             host = idecs_register(io_base + 0x10, ctl_base + 0x10,
337                                   link->irq.AssignedIRQ, link);
338     }
339
340     if (host == NULL)
341         goto failed;
342
343     info->ndev = 1;
344     sprintf(info->node.dev_name, "hd%c", 'a' + host->ports[0]->index * 2);
345     info->node.major = host->ports[0]->major;
346     info->node.minor = 0;
347     info->host = host;
348     link->dev_node = &info->node;
349     printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
350            info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
351
352     kfree(stk);
353     return 0;
354
355 err_mem:
356     printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
357     goto failed;
358
359 cs_failed:
360     cs_error(link, last_fn, last_ret);
361 failed:
362     kfree(stk);
363     ide_release(link);
364     return -ENODEV;
365 } /* ide_config */
366
367 /*======================================================================
368
369     After a card is removed, ide_release() will unregister the net
370     device, and release the PCMCIA configuration.  If the device is
371     still open, this will be postponed until it is closed.
372
373 ======================================================================*/
374
375 static void ide_release(struct pcmcia_device *link)
376 {
377     ide_info_t *info = link->priv;
378     struct ide_host *host = info->host;
379
380     DEBUG(0, "ide_release(0x%p)\n", link);
381
382     if (info->ndev)
383         /* FIXME: if this fails we need to queue the cleanup somehow
384            -- need to investigate the required PCMCIA magic */
385         ide_host_remove(host);
386
387     info->ndev = 0;
388
389     pcmcia_disable_device(link);
390 } /* ide_release */
391
392
393 /*======================================================================
394
395     The card status event handler.  Mostly, this schedules other
396     stuff to run after an event is received.  A CARD_REMOVAL event
397     also sets some flags to discourage the ide drivers from
398     talking to the ports.
399
400 ======================================================================*/
401
402 static struct pcmcia_device_id ide_ids[] = {
403         PCMCIA_DEVICE_FUNC_ID(4),
404         PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000),        /* Corsair */
405         PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),        /* Hitachi */
406         PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000),        /* I-O Data CFA */
407         PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001),        /* Mitsubishi CFA */
408         PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
409         PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),        /* SanDisk CFA */
410         PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000),        /* Kingston */
411         PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
412         PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
413         PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
414         PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),        /* Hitachi */
415         PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
416         PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100),        /* Viking CFA */
417         PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),        /* Lexar, Viking CFA */
418         PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
419         PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
420         PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
421         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
422         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
423         PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
424         PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
425         PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
426         PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
427         PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
428         PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
429         PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
430         PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
431         PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
432         PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
433         PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
434         PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
435         PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
436         PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
437         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
438         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
439         PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
440         PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
441         PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
442         PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
443         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
444         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
445         PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
446         PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
447         PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
448         PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
449         PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
450         PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
451         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
452         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
453         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
454         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
455         PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
456         PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
457         PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
458         PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
459         PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
460         PCMCIA_DEVICE_NULL,
461 };
462 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
463
464 static struct pcmcia_driver ide_cs_driver = {
465         .owner          = THIS_MODULE,
466         .drv            = {
467                 .name   = "ide-cs",
468         },
469         .probe          = ide_probe,
470         .remove         = ide_detach,
471         .id_table       = ide_ids,
472 };
473
474 static int __init init_ide_cs(void)
475 {
476         return pcmcia_register_driver(&ide_cs_driver);
477 }
478
479 static void __exit exit_ide_cs(void)
480 {
481         pcmcia_unregister_driver(&ide_cs_driver);
482 }
483
484 late_initcall(init_ide_cs);
485 module_exit(exit_ide_cs);