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