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