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