ide-cs.c revision dca3983059a4481e4ae97bbf0ac4b4c21429e1a5
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
59MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
60MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
61MODULE_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
66INT_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
74typedef 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
81static void ide_release(struct pcmcia_device *);
82static int ide_config(struct pcmcia_device *);
83
84static 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
97static 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
131static 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
150static const struct ide_port_ops idecs_port_ops = {
151	.quirkproc		= ide_undecoded_slave,
152};
153
154static 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
161static 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    hw_regs_t 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
206out_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) \
221do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
222
223struct pcmcia_config_check {
224	unsigned long ctl_base;
225	int skip_vcc;
226	int is_kme;
227};
228
229static 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
281static 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
341err_mem:
342    printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
343    goto failed;
344
345cs_failed:
346    cs_error(link, last_fn, last_ret);
347failed:
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
361static 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
388static 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-M", "CD-ROM", 0x7d93b852, 0x66536591),
412	PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
413	PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
414	PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
415	PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
416	PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
417	PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
418	PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
419	PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
420	PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
421	PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
422	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
423	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
424	PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
425	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
426	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
427	PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
428	PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
429	PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
430	PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
431	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
432	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
433	PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
434	PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
435	PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
436	PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
437	PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
438	PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
439	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
440	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
441	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
442	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
443	PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
444	PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
445	PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
446	PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
447	PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
448	PCMCIA_DEVICE_PROD_ID2("Flash Card", 0x5a362506),
449	PCMCIA_DEVICE_NULL,
450};
451MODULE_DEVICE_TABLE(pcmcia, ide_ids);
452
453static struct pcmcia_driver ide_cs_driver = {
454	.owner		= THIS_MODULE,
455	.drv		= {
456		.name	= "ide-cs",
457	},
458	.probe		= ide_probe,
459	.remove		= ide_detach,
460	.id_table       = ide_ids,
461};
462
463static int __init init_ide_cs(void)
464{
465	return pcmcia_register_driver(&ide_cs_driver);
466}
467
468static void __exit exit_ide_cs(void)
469{
470	pcmcia_unregister_driver(&ide_cs_driver);
471}
472
473late_initcall(init_ide_cs);
474module_exit(exit_ide_cs);
475