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