[PATCH] pcmcia: add return value to _config() functions
[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 int 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_probe(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     return ide_config(link);
130 } /* ide_attach */
131
132 /*======================================================================
133
134     This deletes a driver "instance".  The device is de-registered
135     with Card Services.  If it has been released, all local data
136     structures are freed.  Otherwise, the structures will be freed
137     when the device is released.
138
139 ======================================================================*/
140
141 static void ide_detach(struct pcmcia_device *link)
142 {
143     DEBUG(0, "ide_detach(0x%p)\n", link);
144
145     if (link->state & DEV_CONFIG)
146         ide_release(link);
147
148     kfree(link->priv);
149 } /* ide_detach */
150
151 static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
152 {
153     hw_regs_t hw;
154     memset(&hw, 0, sizeof(hw));
155     ide_init_hwif_ports(&hw, io, ctl, NULL);
156     hw.irq = irq;
157     hw.chipset = ide_pci;
158     hw.dev = &handle->dev;
159     return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
160 }
161
162 /*======================================================================
163
164     ide_config() is scheduled to run after a CARD_INSERTION event
165     is received, to configure the PCMCIA socket, and to make the
166     ide device available to the system.
167
168 ======================================================================*/
169
170 #define CS_CHECK(fn, ret) \
171 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
172
173 static int ide_config(struct pcmcia_device *link)
174 {
175     ide_info_t *info = link->priv;
176     tuple_t tuple;
177     struct {
178         u_short         buf[128];
179         cisparse_t      parse;
180         config_info_t   conf;
181         cistpl_cftable_entry_t dflt;
182     } *stk = NULL;
183     cistpl_cftable_entry_t *cfg;
184     int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0;
185     unsigned long io_base, ctl_base;
186
187     DEBUG(0, "ide_config(0x%p)\n", link);
188
189     stk = kzalloc(sizeof(*stk), GFP_KERNEL);
190     if (!stk) goto err_mem;
191     cfg = &stk->parse.cftable_entry;
192
193     tuple.TupleData = (cisdata_t *)&stk->buf;
194     tuple.TupleOffset = 0;
195     tuple.TupleDataMax = 255;
196     tuple.Attributes = 0;
197     tuple.DesiredTuple = CISTPL_CONFIG;
198     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
199     CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
200     CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse));
201     link->conf.ConfigBase = stk->parse.config.base;
202     link->conf.Present = stk->parse.config.rmask[0];
203
204     tuple.DesiredTuple = CISTPL_MANFID;
205     if (!pcmcia_get_first_tuple(link, &tuple) &&
206         !pcmcia_get_tuple_data(link, &tuple) &&
207         !pcmcia_parse_tuple(link, &tuple, &stk->parse))
208         is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
209                   ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
210                    (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
211
212     /* Configure card */
213     link->state |= DEV_CONFIG;
214
215     /* Not sure if this is right... look up the current Vcc */
216     CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
217
218     pass = io_base = ctl_base = 0;
219     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
220     tuple.Attributes = 0;
221     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
222     while (1) {
223         if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
224         if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
225
226         /* Check for matching Vcc, unless we're desperate */
227         if (!pass) {
228             if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
229                 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
230                     goto next_entry;
231             } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
232                 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
233                     goto next_entry;
234             }
235         }
236
237         if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
238             link->conf.Vpp =
239                 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
240         else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
241             link->conf.Vpp =
242                 stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
243
244         if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
245             cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
246             link->conf.ConfigIndex = cfg->index;
247             link->io.BasePort1 = io->win[0].base;
248             link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
249             if (!(io->flags & CISTPL_IO_16BIT))
250                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
251             if (io->nwin == 2) {
252                 link->io.NumPorts1 = 8;
253                 link->io.BasePort2 = io->win[1].base;
254                 link->io.NumPorts2 = (is_kme) ? 2 : 1;
255                 if (pcmcia_request_io(link, &link->io) != 0)
256                         goto next_entry;
257                 io_base = link->io.BasePort1;
258                 ctl_base = link->io.BasePort2;
259             } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
260                 link->io.NumPorts1 = io->win[0].len;
261                 link->io.NumPorts2 = 0;
262                 if (pcmcia_request_io(link, &link->io) != 0)
263                         goto next_entry;
264                 io_base = link->io.BasePort1;
265                 ctl_base = link->io.BasePort1 + 0x0e;
266             } else goto next_entry;
267             /* If we've got this far, we're done */
268             break;
269         }
270
271     next_entry:
272         if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
273             memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
274         if (pass) {
275             CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
276         } else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
277             CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
278             memset(&stk->dflt, 0, sizeof(stk->dflt));
279             pass++;
280         }
281     }
282
283     CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
284     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
285
286     /* disable drive interrupts during IDE probe */
287     outb(0x02, ctl_base);
288
289     /* special setup for KXLC005 card */
290     if (is_kme)
291         outb(0x81, ctl_base+1);
292
293     /* retry registration in case device is still spinning up */
294     for (hd = -1, i = 0; i < 10; i++) {
295         hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
296         if (hd >= 0) break;
297         if (link->io.NumPorts1 == 0x20) {
298             outb(0x02, ctl_base + 0x10);
299             hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
300                                 link->irq.AssignedIRQ, link);
301             if (hd >= 0) {
302                 io_base += 0x10;
303                 ctl_base += 0x10;
304                 break;
305             }
306         }
307         msleep(100);
308     }
309
310     if (hd < 0) {
311         printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx"
312                ", irq %u failed\n", io_base, ctl_base,
313                link->irq.AssignedIRQ);
314         goto failed;
315     }
316
317     info->ndev = 1;
318     sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
319     info->node.major = ide_major[hd];
320     info->node.minor = 0;
321     info->hd = hd;
322     link->dev_node = &info->node;
323     printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
324            info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
325
326     link->state &= ~DEV_CONFIG_PENDING;
327     kfree(stk);
328     return 0;
329
330 err_mem:
331     printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
332     goto failed;
333
334 cs_failed:
335     cs_error(link, last_fn, last_ret);
336 failed:
337     kfree(stk);
338     ide_release(link);
339     link->state &= ~DEV_CONFIG_PENDING;
340     return -ENODEV;
341 } /* ide_config */
342
343 /*======================================================================
344
345     After a card is removed, ide_release() will unregister the net
346     device, and release the PCMCIA configuration.  If the device is
347     still open, this will be postponed until it is closed.
348     
349 ======================================================================*/
350
351 void ide_release(struct pcmcia_device *link)
352 {
353     ide_info_t *info = link->priv;
354     
355     DEBUG(0, "ide_release(0x%p)\n", link);
356
357     if (info->ndev) {
358         /* FIXME: if this fails we need to queue the cleanup somehow
359            -- need to investigate the required PCMCIA magic */
360         ide_unregister(info->hd);
361     }
362     info->ndev = 0;
363
364     pcmcia_disable_device(link);
365 } /* ide_release */
366
367
368 /*======================================================================
369
370     The card status event handler.  Mostly, this schedules other
371     stuff to run after an event is received.  A CARD_REMOVAL event
372     also sets some flags to discourage the ide drivers from
373     talking to the ports.
374     
375 ======================================================================*/
376
377 static struct pcmcia_device_id ide_ids[] = {
378         PCMCIA_DEVICE_FUNC_ID(4),
379         PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),        /* Hitachi */
380         PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
381         PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
382         PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
383         PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
384         PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
385         PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),        /* Hitachi */
386         PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
387         PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),        /* Lexar */
388         PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
389         PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
390         PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
391         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
392         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
393         PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
394         PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
395         PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
396         PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
397         PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
398         PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
399         PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
400         PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
401         PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
402         PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
403         PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
404         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
405         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
406         PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
407         PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
408         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
409         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
410         PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
411         PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
412         PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
413         PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
414         PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
415         PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
416         PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
417         PCMCIA_DEVICE_NULL,
418 };
419 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
420
421 static struct pcmcia_driver ide_cs_driver = {
422         .owner          = THIS_MODULE,
423         .drv            = {
424                 .name   = "ide-cs",
425         },
426         .probe          = ide_probe,
427         .remove         = ide_detach,
428         .id_table       = ide_ids,
429 };
430
431 static int __init init_ide_cs(void)
432 {
433         return pcmcia_register_driver(&ide_cs_driver);
434 }
435
436 static void __exit exit_ide_cs(void)
437 {
438         pcmcia_unregister_driver(&ide_cs_driver);
439 }
440
441 late_initcall(init_ide_cs);
442 module_exit(exit_ide_cs);