54702cc8e0d43f50882e3d506b6b37fcff1d0663
[linux-2.6-microblaze.git] / drivers / ide / 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/cistpl.h>
47 #include <pcmcia/ds.h>
48 #include <pcmcia/cisreg.h>
49 #include <pcmcia/ciscode.h>
50
51 #define DRV_NAME "ide-cs"
52
53 /*====================================================================*/
54
55 /* Module parameters */
56
57 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
58 MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
59 MODULE_LICENSE("Dual MPL/GPL");
60
61 /*====================================================================*/
62
63 typedef struct ide_info_t {
64         struct pcmcia_device    *p_dev;
65         struct ide_host         *host;
66         int                     ndev;
67 } ide_info_t;
68
69 static void ide_release(struct pcmcia_device *);
70 static int ide_config(struct pcmcia_device *);
71
72 static void ide_detach(struct pcmcia_device *p_dev);
73
74
75
76
77 /*======================================================================
78
79     ide_attach() creates an "instance" of the driver, allocating
80     local data structures for one device.  The device is registered
81     with Card Services.
82
83 ======================================================================*/
84
85 static int ide_probe(struct pcmcia_device *link)
86 {
87     ide_info_t *info;
88
89     dev_dbg(&link->dev, "ide_attach()\n");
90
91     /* Create new ide device */
92     info = kzalloc(sizeof(*info), GFP_KERNEL);
93     if (!info)
94         return -ENOMEM;
95
96     info->p_dev = link;
97     link->priv = info;
98
99     link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
100             CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
101
102     return ide_config(link);
103 } /* ide_attach */
104
105 /*======================================================================
106
107     This deletes a driver "instance".  The device is de-registered
108     with Card Services.  If it has been released, all local data
109     structures are freed.  Otherwise, the structures will be freed
110     when the device is released.
111
112 ======================================================================*/
113
114 static void ide_detach(struct pcmcia_device *link)
115 {
116     ide_info_t *info = link->priv;
117
118     dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
119
120     ide_release(link);
121
122     kfree(info);
123 } /* ide_detach */
124
125 static const struct ide_port_ops idecs_port_ops = {
126         .quirkproc              = ide_undecoded_slave,
127 };
128
129 static const struct ide_port_info idecs_port_info = {
130         .port_ops               = &idecs_port_ops,
131         .host_flags             = IDE_HFLAG_NO_DMA,
132         .irq_flags              = IRQF_SHARED,
133         .chipset                = ide_pci,
134 };
135
136 static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
137                                 unsigned long irq, struct pcmcia_device *handle)
138 {
139     struct ide_host *host;
140     ide_hwif_t *hwif;
141     int i, rc;
142     struct ide_hw hw, *hws[] = { &hw };
143
144     if (!request_region(io, 8, DRV_NAME)) {
145         printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
146                         DRV_NAME, io, io + 7);
147         return NULL;
148     }
149
150     if (!request_region(ctl, 1, DRV_NAME)) {
151         printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
152                         DRV_NAME, ctl);
153         release_region(io, 8);
154         return NULL;
155     }
156
157     memset(&hw, 0, sizeof(hw));
158     ide_std_init_ports(&hw, io, ctl);
159     hw.irq = irq;
160     hw.dev = &handle->dev;
161
162     rc = ide_host_add(&idecs_port_info, hws, 1, &host);
163     if (rc)
164         goto out_release;
165
166     hwif = host->ports[0];
167
168     if (hwif->present)
169         return host;
170
171     /* retry registration in case device is still spinning up */
172     for (i = 0; i < 10; i++) {
173         msleep(100);
174         ide_port_scan(hwif);
175         if (hwif->present)
176             return host;
177     }
178
179     return host;
180
181 out_release:
182     release_region(ctl, 1);
183     release_region(io, 8);
184     return NULL;
185 }
186
187 /*======================================================================
188
189     ide_config() is scheduled to run after a CARD_INSERTION event
190     is received, to configure the PCMCIA socket, and to make the
191     ide device available to the system.
192
193 ======================================================================*/
194
195 static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
196 {
197         int *is_kme = priv_data;
198
199         if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
200                 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
201                 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
202         }
203         pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
204         pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
205
206         if (pdev->resource[1]->end) {
207                 pdev->resource[0]->end = 8;
208                 pdev->resource[1]->end = (*is_kme) ? 2 : 1;
209         } else {
210                 if (pdev->resource[0]->end < 16)
211                         return -ENODEV;
212         }
213
214         return pcmcia_request_io(pdev);
215 }
216
217 static int ide_config(struct pcmcia_device *link)
218 {
219     ide_info_t *info = link->priv;
220     int ret = 0, is_kme = 0;
221     unsigned long io_base, ctl_base;
222     struct ide_host *host;
223
224     dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
225
226     is_kme = ((link->manf_id == MANFID_KME) &&
227               ((link->card_id == PRODID_KME_KXLC005_A) ||
228                (link->card_id == PRODID_KME_KXLC005_B)));
229
230     if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
231             link->config_flags &= ~CONF_AUTO_CHECK_VCC;
232             if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
233                     goto failed; /* No suitable config found */
234     }
235     io_base = link->resource[0]->start;
236     if (link->resource[1]->end)
237             ctl_base = link->resource[1]->start;
238     else
239             ctl_base = link->resource[0]->start + 0x0e;
240
241     if (!link->irq)
242             goto failed;
243
244     ret = pcmcia_enable_device(link);
245     if (ret)
246             goto failed;
247
248     /* disable drive interrupts during IDE probe */
249     outb(0x02, ctl_base);
250
251     /* special setup for KXLC005 card */
252     if (is_kme)
253         outb(0x81, ctl_base+1);
254
255      host = idecs_register(io_base, ctl_base, link->irq, link);
256      if (host == NULL && resource_size(link->resource[0]) == 0x20) {
257             outb(0x02, ctl_base + 0x10);
258             host = idecs_register(io_base + 0x10, ctl_base + 0x10,
259                                   link->irq, link);
260     }
261
262     if (host == NULL)
263         goto failed;
264
265     info->ndev = 1;
266     info->host = host;
267     dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n",
268             'a' + host->ports[0]->index * 2,
269             link->vpp / 10, link->vpp % 10);
270
271     return 0;
272
273 failed:
274     ide_release(link);
275     return -ENODEV;
276 } /* ide_config */
277
278 /*======================================================================
279
280     After a card is removed, ide_release() will unregister the net
281     device, and release the PCMCIA configuration.  If the device is
282     still open, this will be postponed until it is closed.
283
284 ======================================================================*/
285
286 static void ide_release(struct pcmcia_device *link)
287 {
288     ide_info_t *info = link->priv;
289     struct ide_host *host = info->host;
290
291     dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
292
293     if (info->ndev) {
294         ide_hwif_t *hwif = host->ports[0];
295         unsigned long data_addr, ctl_addr;
296
297         data_addr = hwif->io_ports.data_addr;
298         ctl_addr = hwif->io_ports.ctl_addr;
299
300         ide_host_remove(host);
301         info->ndev = 0;
302
303         release_region(ctl_addr, 1);
304         release_region(data_addr, 8);
305     }
306
307     pcmcia_disable_device(link);
308 } /* ide_release */
309
310
311 /*======================================================================
312
313     The card status event handler.  Mostly, this schedules other
314     stuff to run after an event is received.  A CARD_REMOVAL event
315     also sets some flags to discourage the ide drivers from
316     talking to the ports.
317
318 ======================================================================*/
319
320 static struct pcmcia_device_id ide_ids[] = {
321         PCMCIA_DEVICE_FUNC_ID(4),
322         PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000),        /* Corsair */
323         PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),        /* Hitachi */
324         PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000),        /* I-O Data CFA */
325         PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001),        /* Mitsubishi CFA */
326         PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
327         PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
328         PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),        /* SanDisk CFA */
329         PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000),        /* Kingston */
330         PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620),        /* TI emulated */
331         PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
332         PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
333         PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
334         PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),        /* Hitachi */
335         PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
336         PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100),        /* Viking CFA */
337         PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),        /* Lexar, Viking CFA */
338         PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
339         PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
340         PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
341         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
342         PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
343         PCMCIA_DEVICE_PROD_ID12("CNF   ", "CD-ROM", 0x46d7db81, 0x66536591),
344         PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
345         PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
346         PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
347         PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
348         PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
349         PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
350         PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
351         PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
352         PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
353         PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
354         PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
355         PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
356         PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
357         PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
358         PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
359         PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
360         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
361         PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
362         PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
363         PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
364         PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
365         PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
366         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
367         PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
368         PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
369         PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
370         PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
371         PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
372         PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
373         PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
374         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
375         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
376         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
377         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
378         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
379         PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
380         PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
381         PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
382         PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
383         PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
384         PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
385         PCMCIA_DEVICE_PROD_ID2("Flash Card", 0x5a362506),
386         PCMCIA_DEVICE_NULL,
387 };
388 MODULE_DEVICE_TABLE(pcmcia, ide_ids);
389
390 static struct pcmcia_driver ide_cs_driver = {
391         .owner          = THIS_MODULE,
392         .name           = "ide-cs",
393         .probe          = ide_probe,
394         .remove         = ide_detach,
395         .id_table       = ide_ids,
396 };
397
398 static int __init init_ide_cs(void)
399 {
400         return pcmcia_register_driver(&ide_cs_driver);
401 }
402
403 static void __exit exit_ide_cs(void)
404 {
405         pcmcia_unregister_driver(&ide_cs_driver);
406 }
407
408 late_initcall(init_ide_cs);
409 module_exit(exit_ide_cs);