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