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