1 /*======================================================================
3 A driver for PCMCIA IDE/ATA disk cards
5 ide-cs.c 1.3 2002/10/26 05:45:31
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/
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.
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.
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.
32 ======================================================================*/
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>
48 #include <asm/system.h>
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>
57 /*====================================================================*/
59 /* Module parameters */
61 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
62 MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
63 MODULE_LICENSE("Dual MPL/GPL");
65 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
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)";
73 #define DEBUG(n, args...)
76 /*====================================================================*/
78 static const char ide_major[] = {
79 IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
80 IDE4_MAJOR, IDE5_MAJOR
83 typedef struct ide_info_t {
84 struct pcmcia_device *p_dev;
90 static void ide_release(struct pcmcia_device *);
91 static int ide_config(struct pcmcia_device *);
93 static void ide_detach(struct pcmcia_device *p_dev);
98 /*======================================================================
100 ide_attach() creates an "instance" of the driver, allocating
101 local data structures for one device. The device is registered
104 ======================================================================*/
106 static int ide_probe(struct pcmcia_device *link)
110 DEBUG(0, "ide_attach()\n");
112 /* Create new ide device */
113 info = kzalloc(sizeof(*info), GFP_KERNEL);
120 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
121 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
122 link->io.IOAddrLines = 3;
123 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
124 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
125 link->conf.Attributes = CONF_ENABLE_IRQ;
126 link->conf.IntType = INT_MEMORY_AND_IO;
128 return ide_config(link);
131 /*======================================================================
133 This deletes a driver "instance". The device is de-registered
134 with Card Services. If it has been released, all local data
135 structures are freed. Otherwise, the structures will be freed
136 when the device is released.
138 ======================================================================*/
140 static void ide_detach(struct pcmcia_device *link)
142 DEBUG(0, "ide_detach(0x%p)\n", link);
149 static void idecs_mmio_fixup(ide_hwif_t *hwif)
151 default_hwif_mmiops(hwif);
154 ide_undecoded_slave(hwif);
157 static int idecs_register(unsigned long io, unsigned long ctl,
158 unsigned long irq, struct pcmcia_device *handle, int is_mmio)
161 memset(&hw, 0, sizeof(hw));
162 ide_init_hwif_ports(&hw, io, ctl, NULL);
164 hw.chipset = ide_pci;
165 hw.dev = &handle->dev;
168 return ide_register_hw_with_fixup(&hw, NULL, idecs_mmio_fixup);
170 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
173 void outb_io(unsigned char value, unsigned long port) {
177 void outb_mem(unsigned char value, unsigned long port) {
178 writeb(value, (void __iomem *) port);
181 /*======================================================================
183 ide_config() is scheduled to run after a CARD_INSERTION event
184 is received, to configure the PCMCIA socket, and to make the
185 ide device available to the system.
187 ======================================================================*/
189 #define CS_CHECK(fn, ret) \
190 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
192 static int ide_config(struct pcmcia_device *link)
194 ide_info_t *info = link->priv;
200 cistpl_cftable_entry_t dflt;
202 cistpl_cftable_entry_t *cfg;
203 int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0;
204 unsigned long io_base, ctl_base, is_mmio, try_slave;
205 void (*my_outb)(unsigned char, unsigned long);
207 DEBUG(0, "ide_config(0x%p)\n", link);
209 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
210 if (!stk) goto err_mem;
211 cfg = &stk->parse.cftable_entry;
213 tuple.TupleData = (cisdata_t *)&stk->buf;
214 tuple.TupleOffset = 0;
215 tuple.TupleDataMax = 255;
216 tuple.Attributes = 0;
217 tuple.DesiredTuple = CISTPL_CONFIG;
218 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
219 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
220 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse));
221 link->conf.ConfigBase = stk->parse.config.base;
222 link->conf.Present = stk->parse.config.rmask[0];
224 tuple.DesiredTuple = CISTPL_MANFID;
225 if (!pcmcia_get_first_tuple(link, &tuple) &&
226 !pcmcia_get_tuple_data(link, &tuple) &&
227 !pcmcia_parse_tuple(link, &tuple, &stk->parse))
228 is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
229 ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
230 (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
232 /* Not sure if this is right... look up the current Vcc */
233 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
235 pass = io_base = ctl_base = is_mmio = try_slave = 0;
236 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
237 tuple.Attributes = 0;
238 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
240 if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
241 if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
243 /* Check for matching Vcc, unless we're desperate */
245 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
246 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
248 } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
249 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
254 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
256 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
257 else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
259 stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
261 if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
262 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
263 link->conf.ConfigIndex = cfg->index;
264 link->io.BasePort1 = io->win[0].base;
265 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
266 if (!(io->flags & CISTPL_IO_16BIT))
267 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
269 link->io.NumPorts1 = 8;
270 link->io.BasePort2 = io->win[1].base;
271 link->io.NumPorts2 = (is_kme) ? 2 : 1;
272 if (pcmcia_request_io(link, &link->io) != 0)
274 io_base = link->io.BasePort1;
275 ctl_base = link->io.BasePort2;
276 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
277 link->io.NumPorts1 = io->win[0].len;
278 link->io.NumPorts2 = 0;
279 if (pcmcia_request_io(link, &link->io) != 0)
281 io_base = link->io.BasePort1;
282 ctl_base = link->io.BasePort1 + 0x0e;
284 if (io->win[0].len >= 0x20)
287 } else goto next_entry;
288 /* If we've got this far, we're done */
292 if ((cfg->mem.nwin > 0) || (stk->dflt.mem.nwin > 0)) {
295 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &stk->dflt.mem;
297 if (mem->win[0].len < 16)
300 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
301 req.Attributes |= WIN_ENABLE;
302 req.Base = mem->win[0].host_addr;
306 if (pcmcia_request_window(&link, &req, &link->win) != 0)
308 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
309 if (pcmcia_map_mem_page(link->win, &map) != 0)
312 io_base = (unsigned long) ioremap(req.Base, req.Size);
313 ctl_base = io_base + 0x0e;
316 if (mem->win[0].len >= 0x20)
323 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
324 memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
326 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
327 } else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
328 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
329 memset(&stk->dflt, 0, sizeof(stk->dflt));
334 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
335 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
342 /* disable drive interrupts during IDE probe */
343 my_outb(0x02, ctl_base);
345 /* special setup for KXLC005 card */
347 my_outb(0x81, ctl_base+1);
349 /* retry registration in case device is still spinning up */
350 for (hd = -1, i = 0; i < 10; i++) {
351 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link, is_mmio);
354 my_outb(0x02, ctl_base + 0x10);
355 hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
356 link->irq.AssignedIRQ, link, is_mmio);
367 printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx"
368 ", irq %u failed\n", io_base, ctl_base,
369 link->irq.AssignedIRQ);
374 sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
375 info->node.major = ide_major[hd];
376 info->node.minor = 0;
378 link->dev_node = &info->node;
379 printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
380 info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
386 printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
390 cs_error(link, last_fn, last_ret);
397 /*======================================================================
399 After a card is removed, ide_release() will unregister the net
400 device, and release the PCMCIA configuration. If the device is
401 still open, this will be postponed until it is closed.
403 ======================================================================*/
405 void ide_release(struct pcmcia_device *link)
407 ide_info_t *info = link->priv;
409 DEBUG(0, "ide_release(0x%p)\n", link);
412 /* FIXME: if this fails we need to queue the cleanup somehow
413 -- need to investigate the required PCMCIA magic */
414 ide_unregister(info->hd);
418 pcmcia_disable_device(link);
422 /*======================================================================
424 The card status event handler. Mostly, this schedules other
425 stuff to run after an event is received. A CARD_REMOVAL event
426 also sets some flags to discourage the ide drivers from
427 talking to the ports.
429 ======================================================================*/
431 static struct pcmcia_device_id ide_ids[] = {
432 PCMCIA_DEVICE_FUNC_ID(4),
433 PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
434 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
435 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
436 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
437 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
438 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
439 PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
440 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
441 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
442 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
443 PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
444 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
445 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
446 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
447 PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
448 PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
449 PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
450 PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
451 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
452 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
453 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
454 PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
455 PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
456 PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
457 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
458 PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
459 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
460 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
461 PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
462 PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
463 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
464 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
465 PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
466 PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
467 PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
468 PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
469 PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
470 PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
471 PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
474 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
476 static struct pcmcia_driver ide_cs_driver = {
477 .owner = THIS_MODULE,
482 .remove = ide_detach,
486 static int __init init_ide_cs(void)
488 return pcmcia_register_driver(&ide_cs_driver);
491 static void __exit exit_ide_cs(void)
493 pcmcia_unregister_driver(&ide_cs_driver);
496 late_initcall(init_ide_cs);
497 module_exit(exit_ide_cs);