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