]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/ide/legacy/ide-cs.c
[PATCH] pcmcia: add another ide-cs CF card id
[linux-2.6.git] / drivers / ide / legacy / ide-cs.c
1 /*======================================================================
2
3     A driver for PCMCIA IDE/ATA disk cards
4
5     ide-cs.c 1.3 2002/10/26 05:45:31
6
7     The contents of this file are subject to the Mozilla Public
8     License Version 1.1 (the "License"); you may not use this file
9     except in compliance with the License. You may obtain a copy of
10     the License at http://www.mozilla.org/MPL/
11
12     Software distributed under the License is distributed on an "AS
13     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14     implied. See the License for the specific language governing
15     rights and limitations under the License.
16
17     The initial developer of the original code is David A. Hinds
18     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
19     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
20
21     Alternatively, the contents of this file may be used under the
22     terms of the GNU General Public License version 2 (the "GPL"), in
23     which case the provisions of the GPL are applicable instead of the
24     above.  If you wish to allow the use of your version of this file
25     only under the terms of the GPL and not to allow others to use
26     your version of this file under the MPL, indicate your decision
27     by deleting the provisions above and replace them with the notice
28     and other provisions required by the GPL.  If you do not delete
29     the provisions above, a recipient may use your version of this
30     file under either the MPL or the GPL.
31     
32 ======================================================================*/
33
34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/init.h>
37 #include <linux/sched.h>
38 #include <linux/ptrace.h>
39 #include <linux/slab.h>
40 #include <linux/string.h>
41 #include <linux/timer.h>
42 #include <linux/ioport.h>
43 #include <linux/ide.h>
44 #include <linux/hdreg.h>
45 #include <linux/major.h>
46 #include <linux/delay.h>
47 #include <asm/io.h>
48 #include <asm/system.h>
49
50 #include <pcmcia/cs_types.h>
51 #include <pcmcia/cs.h>
52 #include <pcmcia/cistpl.h>
53 #include <pcmcia/ds.h>
54 #include <pcmcia/cisreg.h>
55 #include <pcmcia/ciscode.h>
56
57 /*====================================================================*/
58
59 /* Module parameters */
60
61 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
62 MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
63 MODULE_LICENSE("Dual MPL/GPL");
64
65 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
66
67 #ifdef PCMCIA_DEBUG
68 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
69 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
70 static char *version =
71 "ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)";
72 #else
73 #define DEBUG(n, args...)
74 #endif
75
76 /*====================================================================*/
77
78 static const char ide_major[] = {
79     IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
80     IDE4_MAJOR, IDE5_MAJOR
81 };
82
83 typedef struct ide_info_t {
84     dev_link_t  link;
85     int         ndev;
86     dev_node_t  node;
87     int         hd;
88 } ide_info_t;
89
90 static void ide_release(dev_link_t *);
91 static void ide_config(dev_link_t *);
92
93 static void ide_detach(struct pcmcia_device *p_dev);
94
95
96
97
98 /*======================================================================
99
100     ide_attach() creates an "instance" of the driver, allocating
101     local data structures for one device.  The device is registered
102     with Card Services.
103
104 ======================================================================*/
105
106 static int ide_attach(struct pcmcia_device *p_dev)
107 {
108     ide_info_t *info;
109     dev_link_t *link;
110
111     DEBUG(0, "ide_attach()\n");
112
113     /* Create new ide device */
114     info = kzalloc(sizeof(*info), GFP_KERNEL);
115     if (!info)
116         return -ENOMEM;
117     link = &info->link; link->priv = info;
118
119     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
120     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
121     link->io.IOAddrLines = 3;
122     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
123     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
124     link->conf.Attributes = CONF_ENABLE_IRQ;
125     link->conf.Vcc = 50;
126     link->conf.IntType = INT_MEMORY_AND_IO;
127
128     link->handle = p_dev;
129     p_dev->instance = link;
130
131     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
132     ide_config(link);
133
134     return 0;
135 } /* ide_attach */
136
137 /*======================================================================
138
139     This deletes a driver "instance".  The device is de-registered
140     with Card Services.  If it has been released, all local data
141     structures are freed.  Otherwise, the structures will be freed
142     when the device is released.
143
144 ======================================================================*/
145
146 static void ide_detach(struct pcmcia_device *p_dev)
147 {
148     dev_link_t *link = dev_to_instance(p_dev);
149
150     DEBUG(0, "ide_detach(0x%p)\n", link);
151
152     if (link->state & DEV_CONFIG)
153         ide_release(link);
154
155     kfree(link->priv);
156 } /* ide_detach */
157
158 static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
159 {
160     hw_regs_t hw;
161     memset(&hw, 0, sizeof(hw));
162     ide_init_hwif_ports(&hw, io, ctl, NULL);
163     hw.irq = irq;
164     hw.chipset = ide_pci;
165     hw.dev = &handle->dev;
166     return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
167 }
168
169 /*======================================================================
170
171     ide_config() is scheduled to run after a CARD_INSERTION event
172     is received, to configure the PCMCIA socket, and to make the
173     ide device available to the system.
174
175 ======================================================================*/
176
177 #define CS_CHECK(fn, ret) \
178 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
179
180 static void ide_config(dev_link_t *link)
181 {
182     client_handle_t handle = link->handle;
183     ide_info_t *info = link->priv;
184     tuple_t tuple;
185     struct {
186         u_short         buf[128];
187         cisparse_t      parse;
188         config_info_t   conf;
189         cistpl_cftable_entry_t dflt;
190     } *stk = NULL;
191     cistpl_cftable_entry_t *cfg;
192     int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0;
193     unsigned long io_base, ctl_base;
194
195     DEBUG(0, "ide_config(0x%p)\n", link);
196
197     stk = kzalloc(sizeof(*stk), GFP_KERNEL);
198     if (!stk) goto err_mem;
199     cfg = &stk->parse.cftable_entry;
200
201     tuple.TupleData = (cisdata_t *)&stk->buf;
202     tuple.TupleOffset = 0;
203     tuple.TupleDataMax = 255;
204     tuple.Attributes = 0;
205     tuple.DesiredTuple = CISTPL_CONFIG;
206     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
207     CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
208     CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse));
209     link->conf.ConfigBase = stk->parse.config.base;
210     link->conf.Present = stk->parse.config.rmask[0];
211
212     tuple.DesiredTuple = CISTPL_MANFID;
213     if (!pcmcia_get_first_tuple(handle, &tuple) &&
214         !pcmcia_get_tuple_data(handle, &tuple) &&
215         !pcmcia_parse_tuple(handle, &tuple, &stk->parse))
216         is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
217                   ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
218                    (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
219
220     /* Configure card */
221     link->state |= DEV_CONFIG;
222
223     /* Not sure if this is right... look up the current Vcc */
224     CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf));
225     link->conf.Vcc = stk->conf.Vcc;
226
227     pass = io_base = ctl_base = 0;
228     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
229     tuple.Attributes = 0;
230     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
231     while (1) {
232         if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry;
233         if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) goto next_entry;
234
235         /* Check for matching Vcc, unless we're desperate */
236         if (!pass) {
237             if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
238                 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
239                     goto next_entry;
240             } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
241                 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
242                     goto next_entry;
243             }
244         }
245
246         if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
247             link->conf.Vpp1 = link->conf.Vpp2 =
248                 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
249         else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
250             link->conf.Vpp1 = link->conf.Vpp2 =
251                 stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
252
253         if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
254             cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
255             link->conf.ConfigIndex = cfg->index;
256             link->io.BasePort1 = io->win[0].base;
257             link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
258             if (!(io->flags & CISTPL_IO_16BIT))
259                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
260             if (io->nwin == 2) {
261                 link->io.NumPorts1 = 8;
262                 link->io.BasePort2 = io->win[1].base;
263                 link->io.NumPorts2 = (is_kme) ? 2 : 1;
264                 if (pcmcia_request_io(link->handle, &link->io) != 0)
265                         goto next_entry;
266                 io_base = link->io.BasePort1;
267                 ctl_base = link->io.BasePort2;
268             } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
269                 link->io.NumPorts1 = io->win[0].len;
270                 link->io.NumPorts2 = 0;
271                 if (pcmcia_request_io(link->handle, &link->io) != 0)
272                         goto next_entry;
273                 io_base = link->io.BasePort1;
274                 ctl_base = link->io.BasePort1 + 0x0e;
275             } else goto next_entry;
276             /* If we've got this far, we're done */
277             break;
278         }
279
280     next_entry:
281         if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
282             memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
283         if (pass) {
284             CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
285         } else if (pcmcia_get_next_tuple(handle, &tuple) != 0) {
286             CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
287             memset(&stk->dflt, 0, sizeof(stk->dflt));
288             pass++;
289         }
290     }
291
292     CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
293     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
294
295     /* disable drive interrupts during IDE probe */
296     outb(0x02, ctl_base);
297
298     /* special setup for KXLC005 card */
299     if (is_kme)
300         outb(0x81, ctl_base+1);
301
302     /* retry registration in case device is still spinning up */
303     for (hd = -1, i = 0; i < 10; i++) {
304         hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle);
305         if (hd >= 0) break;
306         if (link->io.NumPorts1 == 0x20) {
307             outb(0x02, ctl_base + 0x10);
308             hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
309                                 link->irq.AssignedIRQ, handle);
310             if (hd >= 0) {
311                 io_base += 0x10;
312                 ctl_base += 0x10;
313                 break;
314             }
315         }
316         msleep(100);
317     }
318
319     if (hd < 0) {
320         printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx"
321                ", irq %u failed\n", io_base, ctl_base,
322                link->irq.AssignedIRQ);
323         goto failed;
324     }
325
326     info->ndev = 1;
327     sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
328     info->node.major = ide_major[hd];
329     info->node.minor = 0;
330     info->hd = hd;
331     link->dev = &info->node;
332     printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
333            info->node.dev_name, link->conf.Vcc / 10, link->conf.Vcc % 10,
334            link->conf.Vpp1 / 10, link->conf.Vpp1 % 10);
335
336     link->state &= ~DEV_CONFIG_PENDING;
337     kfree(stk);
338     return;
339
340 err_mem:
341     printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
342     goto failed;
343
344 cs_failed:
345     cs_error(link->handle, last_fn, last_ret);
346 failed:
347     kfree(stk);
348     ide_release(link);
349     link->state &= ~DEV_CONFIG_PENDING;
350 } /* ide_config */
351
352 /*======================================================================
353
354     After a card is removed, ide_release() will unregister the net
355     device, and release the PCMCIA configuration.  If the device is
356     still open, this will be postponed until it is closed.
357     
358 ======================================================================*/
359
360 void ide_release(dev_link_t *link)
361 {
362     ide_info_t *info = link->priv;
363     
364     DEBUG(0, "ide_release(0x%p)\n", link);
365
366     if (info->ndev) {
367         /* FIXME: if this fails we need to queue the cleanup somehow
368            -- need to investigate the required PCMCIA magic */
369         ide_unregister(info->hd);
370     }
371     info->ndev = 0;
372     link->dev = NULL;
373     
374     pcmcia_release_configuration(link->handle);
375     pcmcia_release_io(link->handle, &link->io);
376     pcmcia_release_irq(link->handle, &link->irq);
377     
378     link->state &= ~DEV_CONFIG;
379
380 } /* ide_release */
381
382 static int ide_suspend(struct pcmcia_device *dev)
383 {
384         dev_link_t *link = dev_to_instance(dev);
385
386         link->state |= DEV_SUSPEND;
387         if (link->state & DEV_CONFIG)
388                 pcmcia_release_configuration(link->handle);
389
390         return 0;
391 }
392
393 static int ide_resume(struct pcmcia_device *dev)
394 {
395         dev_link_t *link = dev_to_instance(dev);
396
397         link->state &= ~DEV_SUSPEND;
398         if (DEV_OK(link))
399                 pcmcia_request_configuration(link->handle, &link->conf);
400
401         return 0;
402 }
403
404 /*======================================================================
405
406     The card status event handler.  Mostly, this schedules other
407     stuff to run after an event is received.  A CARD_REMOVAL event
408     also sets some flags to discourage the ide drivers from
409     talking to the ports.
410     
411 ======================================================================*/
412
413 static struct pcmcia_device_id ide_ids[] = {
414         PCMCIA_DEVICE_FUNC_ID(4),
415         PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),        /* Hitachi */
416         PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
417         PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
418         PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
419         PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
420         PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
421         PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),        /* Hitachi */
422         PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
423         PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),        /* Lexar */
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("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
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_ID2("NinjaATA-", 0xebe0bd79),
444         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
445         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
446         PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
447         PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
448         PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
449         PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
450         PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
451         PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
452         PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
453         PCMCIA_DEVICE_NULL,
454 };
455 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
456
457 static struct pcmcia_driver ide_cs_driver = {
458         .owner          = THIS_MODULE,
459         .drv            = {
460                 .name   = "ide-cs",
461         },
462         .probe          = ide_attach,
463         .remove         = ide_detach,
464         .id_table       = ide_ids,
465         .suspend        = ide_suspend,
466         .resume         = ide_resume,
467 };
468
469 static int __init init_ide_cs(void)
470 {
471         return pcmcia_register_driver(&ide_cs_driver);
472 }
473
474 static void __exit exit_ide_cs(void)
475 {
476         pcmcia_unregister_driver(&ide_cs_driver);
477 }
478
479 late_initcall(init_ide_cs);
480 module_exit(exit_ide_cs);