1fb8976496d9d2152e90e8f019b488947f3aef89
[cascardo/linux.git] / 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     dev_link_t  link;
85     int         ndev;
86     dev_node_t  node;
87     int         hd;
88 } ide_info_t;
89
90 static void ide_release(dev_link_t *);
91 static int ide_event(event_t event, int priority,
92                      event_callback_args_t *args);
93
94 static dev_info_t dev_info = "ide-cs";
95
96 static dev_link_t *ide_attach(void);
97 static void ide_detach(struct pcmcia_device *p_dev);
98
99 static dev_link_t *dev_list = NULL;
100
101 /*======================================================================
102
103     ide_attach() creates an "instance" of the driver, allocating
104     local data structures for one device.  The device is registered
105     with Card Services.
106
107 ======================================================================*/
108
109 static dev_link_t *ide_attach(void)
110 {
111     ide_info_t *info;
112     dev_link_t *link;
113     client_reg_t client_reg;
114     int ret;
115     
116     DEBUG(0, "ide_attach()\n");
117
118     /* Create new ide device */
119     info = kzalloc(sizeof(*info), GFP_KERNEL);
120     if (!info) return NULL;
121     link = &info->link; link->priv = info;
122
123     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
124     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
125     link->io.IOAddrLines = 3;
126     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
127     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
128     link->conf.Attributes = CONF_ENABLE_IRQ;
129     link->conf.Vcc = 50;
130     link->conf.IntType = INT_MEMORY_AND_IO;
131     
132     /* Register with Card Services */
133     link->next = dev_list;
134     dev_list = link;
135     client_reg.dev_info = &dev_info;
136     client_reg.Version = 0x0210;
137     client_reg.event_callback_args.client_data = link;
138     ret = pcmcia_register_client(&link->handle, &client_reg);
139     if (ret != CS_SUCCESS) {
140         cs_error(link->handle, RegisterClient, ret);
141         ide_detach(link->handle);
142         return NULL;
143     }
144     
145     return link;
146 } /* ide_attach */
147
148 /*======================================================================
149
150     This deletes a driver "instance".  The device is de-registered
151     with Card Services.  If it has been released, all local data
152     structures are freed.  Otherwise, the structures will be freed
153     when the device is released.
154
155 ======================================================================*/
156
157 static void ide_detach(struct pcmcia_device *p_dev)
158 {
159     dev_link_t *link = dev_to_instance(p_dev);
160     dev_link_t **linkp;
161
162     DEBUG(0, "ide_detach(0x%p)\n", link);
163     
164     /* Locate device structure */
165     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
166         if (*linkp == link) break;
167     if (*linkp == NULL)
168         return;
169
170     if (link->state & DEV_CONFIG)
171         ide_release(link);
172     
173     /* Unlink, free device structure */
174     *linkp = link->next;
175     kfree(link->priv);
176     
177 } /* ide_detach */
178
179 static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
180 {
181     hw_regs_t hw;
182     memset(&hw, 0, sizeof(hw));
183     ide_init_hwif_ports(&hw, io, ctl, NULL);
184     hw.irq = irq;
185     hw.chipset = ide_pci;
186     hw.dev = &handle->dev;
187     return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
188 }
189
190 /*======================================================================
191
192     ide_config() is scheduled to run after a CARD_INSERTION event
193     is received, to configure the PCMCIA socket, and to make the
194     ide device available to the system.
195
196 ======================================================================*/
197
198 #define CS_CHECK(fn, ret) \
199 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
200
201 static void ide_config(dev_link_t *link)
202 {
203     client_handle_t handle = link->handle;
204     ide_info_t *info = link->priv;
205     tuple_t tuple;
206     struct {
207         u_short         buf[128];
208         cisparse_t      parse;
209         config_info_t   conf;
210         cistpl_cftable_entry_t dflt;
211     } *stk = NULL;
212     cistpl_cftable_entry_t *cfg;
213     int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0;
214     unsigned long io_base, ctl_base;
215
216     DEBUG(0, "ide_config(0x%p)\n", link);
217
218     stk = kzalloc(sizeof(*stk), GFP_KERNEL);
219     if (!stk) goto err_mem;
220     cfg = &stk->parse.cftable_entry;
221
222     tuple.TupleData = (cisdata_t *)&stk->buf;
223     tuple.TupleOffset = 0;
224     tuple.TupleDataMax = 255;
225     tuple.Attributes = 0;
226     tuple.DesiredTuple = CISTPL_CONFIG;
227     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
228     CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
229     CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse));
230     link->conf.ConfigBase = stk->parse.config.base;
231     link->conf.Present = stk->parse.config.rmask[0];
232
233     tuple.DesiredTuple = CISTPL_MANFID;
234     if (!pcmcia_get_first_tuple(handle, &tuple) &&
235         !pcmcia_get_tuple_data(handle, &tuple) &&
236         !pcmcia_parse_tuple(handle, &tuple, &stk->parse))
237         is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
238                   ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
239                    (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
240
241     /* Configure card */
242     link->state |= DEV_CONFIG;
243
244     /* Not sure if this is right... look up the current Vcc */
245     CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf));
246     link->conf.Vcc = stk->conf.Vcc;
247
248     pass = io_base = ctl_base = 0;
249     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
250     tuple.Attributes = 0;
251     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
252     while (1) {
253         if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry;
254         if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) goto next_entry;
255
256         /* Check for matching Vcc, unless we're desperate */
257         if (!pass) {
258             if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
259                 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
260                     goto next_entry;
261             } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
262                 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
263                     goto next_entry;
264             }
265         }
266
267         if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
268             link->conf.Vpp1 = link->conf.Vpp2 =
269                 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
270         else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
271             link->conf.Vpp1 = link->conf.Vpp2 =
272                 stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
273
274         if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
275             cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
276             link->conf.ConfigIndex = cfg->index;
277             link->io.BasePort1 = io->win[0].base;
278             link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
279             if (!(io->flags & CISTPL_IO_16BIT))
280                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
281             if (io->nwin == 2) {
282                 link->io.NumPorts1 = 8;
283                 link->io.BasePort2 = io->win[1].base;
284                 link->io.NumPorts2 = (is_kme) ? 2 : 1;
285                 if (pcmcia_request_io(link->handle, &link->io) != 0)
286                         goto next_entry;
287                 io_base = link->io.BasePort1;
288                 ctl_base = link->io.BasePort2;
289             } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
290                 link->io.NumPorts1 = io->win[0].len;
291                 link->io.NumPorts2 = 0;
292                 if (pcmcia_request_io(link->handle, &link->io) != 0)
293                         goto next_entry;
294                 io_base = link->io.BasePort1;
295                 ctl_base = link->io.BasePort1 + 0x0e;
296             } else goto next_entry;
297             /* If we've got this far, we're done */
298             break;
299         }
300
301     next_entry:
302         if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
303             memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
304         if (pass) {
305             CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
306         } else if (pcmcia_get_next_tuple(handle, &tuple) != 0) {
307             CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
308             memset(&stk->dflt, 0, sizeof(stk->dflt));
309             pass++;
310         }
311     }
312
313     CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
314     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
315
316     /* disable drive interrupts during IDE probe */
317     outb(0x02, ctl_base);
318
319     /* special setup for KXLC005 card */
320     if (is_kme)
321         outb(0x81, ctl_base+1);
322
323     /* retry registration in case device is still spinning up */
324     for (hd = -1, i = 0; i < 10; i++) {
325         hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle);
326         if (hd >= 0) break;
327         if (link->io.NumPorts1 == 0x20) {
328             outb(0x02, ctl_base + 0x10);
329             hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
330                                 link->irq.AssignedIRQ, handle);
331             if (hd >= 0) {
332                 io_base += 0x10;
333                 ctl_base += 0x10;
334                 break;
335             }
336         }
337         msleep(100);
338     }
339
340     if (hd < 0) {
341         printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx"
342                ", irq %u failed\n", io_base, ctl_base,
343                link->irq.AssignedIRQ);
344         goto failed;
345     }
346
347     info->ndev = 1;
348     sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
349     info->node.major = ide_major[hd];
350     info->node.minor = 0;
351     info->hd = hd;
352     link->dev = &info->node;
353     printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
354            info->node.dev_name, link->conf.Vcc / 10, link->conf.Vcc % 10,
355            link->conf.Vpp1 / 10, link->conf.Vpp1 % 10);
356
357     link->state &= ~DEV_CONFIG_PENDING;
358     kfree(stk);
359     return;
360
361 err_mem:
362     printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
363     goto failed;
364
365 cs_failed:
366     cs_error(link->handle, last_fn, last_ret);
367 failed:
368     kfree(stk);
369     ide_release(link);
370     link->state &= ~DEV_CONFIG_PENDING;
371 } /* ide_config */
372
373 /*======================================================================
374
375     After a card is removed, ide_release() will unregister the net
376     device, and release the PCMCIA configuration.  If the device is
377     still open, this will be postponed until it is closed.
378     
379 ======================================================================*/
380
381 void ide_release(dev_link_t *link)
382 {
383     ide_info_t *info = link->priv;
384     
385     DEBUG(0, "ide_release(0x%p)\n", link);
386
387     if (info->ndev) {
388         /* FIXME: if this fails we need to queue the cleanup somehow
389            -- need to investigate the required PCMCIA magic */
390         ide_unregister(info->hd);
391     }
392     info->ndev = 0;
393     link->dev = NULL;
394     
395     pcmcia_release_configuration(link->handle);
396     pcmcia_release_io(link->handle, &link->io);
397     pcmcia_release_irq(link->handle, &link->irq);
398     
399     link->state &= ~DEV_CONFIG;
400
401 } /* ide_release */
402
403 static int ide_suspend(struct pcmcia_device *dev)
404 {
405         dev_link_t *link = dev_to_instance(dev);
406
407         link->state |= DEV_SUSPEND;
408         if (link->state & DEV_CONFIG)
409                 pcmcia_release_configuration(link->handle);
410
411         return 0;
412 }
413
414 static int ide_resume(struct pcmcia_device *dev)
415 {
416         dev_link_t *link = dev_to_instance(dev);
417
418         link->state &= ~DEV_SUSPEND;
419         if (DEV_OK(link))
420                 pcmcia_request_configuration(link->handle, &link->conf);
421
422         return 0;
423 }
424
425 /*======================================================================
426
427     The card status event handler.  Mostly, this schedules other
428     stuff to run after an event is received.  A CARD_REMOVAL event
429     also sets some flags to discourage the ide drivers from
430     talking to the ports.
431     
432 ======================================================================*/
433
434 int ide_event(event_t event, int priority,
435               event_callback_args_t *args)
436 {
437     dev_link_t *link = args->client_data;
438
439     DEBUG(1, "ide_event(0x%06x)\n", event);
440     
441     switch (event) {
442     case CS_EVENT_CARD_INSERTION:
443         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
444         ide_config(link);
445         break;
446     }
447     return 0;
448 } /* ide_event */
449
450 static struct pcmcia_device_id ide_ids[] = {
451         PCMCIA_DEVICE_FUNC_ID(4),
452         PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
453         PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
454         PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
455         PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
456         PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
457         PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
458         PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),        /* Lexar */
459         PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
460         PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
461         PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
462         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
463         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
464         PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
465         PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
466         PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
467         PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
468         PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
469         PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
470         PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
471         PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
472         PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
473         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
474         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
475         PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
476         PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
477         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
478         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
479         PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
480         PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
481         PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
482         PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
483         PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
484         PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
485         PCMCIA_DEVICE_NULL,
486 };
487 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
488
489 static struct pcmcia_driver ide_cs_driver = {
490         .owner          = THIS_MODULE,
491         .drv            = {
492                 .name   = "ide-cs",
493         },
494         .attach         = ide_attach,
495         .event          = ide_event,
496         .remove         = ide_detach,
497         .id_table       = ide_ids,
498         .suspend        = ide_suspend,
499         .resume         = ide_resume,
500 };
501
502 static int __init init_ide_cs(void)
503 {
504         return pcmcia_register_driver(&ide_cs_driver);
505 }
506
507 static void __exit exit_ide_cs(void)
508 {
509         pcmcia_unregister_driver(&ide_cs_driver);
510         BUG_ON(dev_list != NULL);
511 }
512
513 late_initcall(init_ide_cs);
514 module_exit(exit_ide_cs);