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