]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/ide/legacy/ide-cs.c
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[mirror_ubuntu-artful-kernel.git] / drivers / ide / legacy / ide-cs.c
CommitLineData
1da177e4
LT
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>
2aad5f03 46#include <linux/delay.h>
1da177e4
LT
47#include <asm/io.h>
48#include <asm/system.h>
49
1da177e4
LT
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
61MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
62MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
63MODULE_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
68INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
69#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
70static 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
78static const char ide_major[] = {
79 IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
80 IDE4_MAJOR, IDE5_MAJOR
81};
82
83typedef struct ide_info_t {
fd238232 84 struct pcmcia_device *p_dev;
1da177e4
LT
85 int ndev;
86 dev_node_t node;
87 int hd;
88} ide_info_t;
89
fba395ee 90static void ide_release(struct pcmcia_device *);
15b99ac1 91static int ide_config(struct pcmcia_device *);
1da177e4 92
cc3b4866 93static void ide_detach(struct pcmcia_device *p_dev);
1da177e4 94
b4635811
DB
95
96
1da177e4
LT
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
15b99ac1 106static int ide_probe(struct pcmcia_device *link)
1da177e4
LT
107{
108 ide_info_t *info;
f8cfa618 109
1da177e4
LT
110 DEBUG(0, "ide_attach()\n");
111
112 /* Create new ide device */
f5e3c2fa 113 info = kzalloc(sizeof(*info), GFP_KERNEL);
f8cfa618
DB
114 if (!info)
115 return -ENOMEM;
fd238232 116
fba395ee 117 info->p_dev = link;
fd238232 118 link->priv = info;
1da177e4
LT
119
120 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
121 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
122 link->io.IOAddrLines = 3;
53a04c6f 123 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
1da177e4
LT
124 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
125 link->conf.Attributes = CONF_ENABLE_IRQ;
1da177e4 126 link->conf.IntType = INT_MEMORY_AND_IO;
f8cfa618 127
15b99ac1 128 return ide_config(link);
1da177e4
LT
129} /* ide_attach */
130
131/*======================================================================
132
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.
137
138======================================================================*/
139
fba395ee 140static void ide_detach(struct pcmcia_device *link)
1da177e4 141{
1da177e4 142 DEBUG(0, "ide_detach(0x%p)\n", link);
1da177e4 143
e2d40963 144 ide_release(link);
b4635811 145
1da177e4 146 kfree(link->priv);
1da177e4
LT
147} /* ide_detach */
148
2f1b9250 149static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
1da177e4
LT
150{
151 hw_regs_t hw;
152 memset(&hw, 0, sizeof(hw));
153 ide_init_hwif_ports(&hw, io, ctl, NULL);
154 hw.irq = irq;
155 hw.chipset = ide_pci;
4349d5cd 156 hw.dev = &handle->dev;
2f1b9250 157 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
1da177e4
LT
158}
159
160/*======================================================================
161
162 ide_config() is scheduled to run after a CARD_INSERTION event
163 is received, to configure the PCMCIA socket, and to make the
164 ide device available to the system.
165
166======================================================================*/
167
168#define CS_CHECK(fn, ret) \
169do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
170
15b99ac1 171static int ide_config(struct pcmcia_device *link)
1da177e4 172{
1da177e4
LT
173 ide_info_t *info = link->priv;
174 tuple_t tuple;
175 struct {
176 u_short buf[128];
177 cisparse_t parse;
178 config_info_t conf;
179 cistpl_cftable_entry_t dflt;
180 } *stk = NULL;
181 cistpl_cftable_entry_t *cfg;
182 int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0;
2f1b9250 183 unsigned long io_base, ctl_base;
1da177e4
LT
184
185 DEBUG(0, "ide_config(0x%p)\n", link);
186
f5e3c2fa 187 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
1da177e4 188 if (!stk) goto err_mem;
1da177e4
LT
189 cfg = &stk->parse.cftable_entry;
190
191 tuple.TupleData = (cisdata_t *)&stk->buf;
192 tuple.TupleOffset = 0;
193 tuple.TupleDataMax = 255;
194 tuple.Attributes = 0;
195 tuple.DesiredTuple = CISTPL_CONFIG;
fba395ee
DB
196 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
197 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
198 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse));
1da177e4
LT
199 link->conf.ConfigBase = stk->parse.config.base;
200 link->conf.Present = stk->parse.config.rmask[0];
201
202 tuple.DesiredTuple = CISTPL_MANFID;
fba395ee
DB
203 if (!pcmcia_get_first_tuple(link, &tuple) &&
204 !pcmcia_get_tuple_data(link, &tuple) &&
205 !pcmcia_parse_tuple(link, &tuple, &stk->parse))
1da177e4
LT
206 is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
207 ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
208 (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
209
1da177e4 210 /* Not sure if this is right... look up the current Vcc */
fba395ee 211 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
1da177e4 212
2f1b9250 213 pass = io_base = ctl_base = 0;
1da177e4
LT
214 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
215 tuple.Attributes = 0;
fba395ee 216 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
1da177e4 217 while (1) {
fba395ee
DB
218 if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
219 if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
1da177e4
LT
220
221 /* Check for matching Vcc, unless we're desperate */
222 if (!pass) {
223 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
224 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
225 goto next_entry;
226 } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
227 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
228 goto next_entry;
229 }
230 }
231
232 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
70294b46 233 link->conf.Vpp =
1da177e4
LT
234 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
235 else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
70294b46 236 link->conf.Vpp =
1da177e4
LT
237 stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
238
239 if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
240 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
241 link->conf.ConfigIndex = cfg->index;
242 link->io.BasePort1 = io->win[0].base;
243 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
244 if (!(io->flags & CISTPL_IO_16BIT))
245 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
246 if (io->nwin == 2) {
247 link->io.NumPorts1 = 8;
248 link->io.BasePort2 = io->win[1].base;
249 link->io.NumPorts2 = (is_kme) ? 2 : 1;
fba395ee 250 if (pcmcia_request_io(link, &link->io) != 0)
1da177e4
LT
251 goto next_entry;
252 io_base = link->io.BasePort1;
253 ctl_base = link->io.BasePort2;
254 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
255 link->io.NumPorts1 = io->win[0].len;
256 link->io.NumPorts2 = 0;
fba395ee 257 if (pcmcia_request_io(link, &link->io) != 0)
1da177e4
LT
258 goto next_entry;
259 io_base = link->io.BasePort1;
260 ctl_base = link->io.BasePort1 + 0x0e;
261 } else goto next_entry;
262 /* If we've got this far, we're done */
263 break;
264 }
265
266 next_entry:
267 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
268 memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
269 if (pass) {
fba395ee
DB
270 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
271 } else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
272 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
1da177e4
LT
273 memset(&stk->dflt, 0, sizeof(stk->dflt));
274 pass++;
275 }
276 }
277
fba395ee
DB
278 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
279 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
1da177e4
LT
280
281 /* disable drive interrupts during IDE probe */
2f1b9250 282 outb(0x02, ctl_base);
1da177e4
LT
283
284 /* special setup for KXLC005 card */
285 if (is_kme)
2f1b9250 286 outb(0x81, ctl_base+1);
1da177e4
LT
287
288 /* retry registration in case device is still spinning up */
289 for (hd = -1, i = 0; i < 10; i++) {
2f1b9250 290 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
1da177e4 291 if (hd >= 0) break;
2f1b9250
LT
292 if (link->io.NumPorts1 == 0x20) {
293 outb(0x02, ctl_base + 0x10);
1da177e4 294 hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
2f1b9250 295 link->irq.AssignedIRQ, link);
1da177e4
LT
296 if (hd >= 0) {
297 io_base += 0x10;
298 ctl_base += 0x10;
299 break;
300 }
301 }
2aad5f03 302 msleep(100);
1da177e4
LT
303 }
304
305 if (hd < 0) {
306 printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx"
307 ", irq %u failed\n", io_base, ctl_base,
308 link->irq.AssignedIRQ);
309 goto failed;
310 }
311
312 info->ndev = 1;
313 sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
314 info->node.major = ide_major[hd];
315 info->node.minor = 0;
316 info->hd = hd;
fd238232 317 link->dev_node = &info->node;
70294b46
DB
318 printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
319 info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
1da177e4 320
1da177e4 321 kfree(stk);
15b99ac1 322 return 0;
1da177e4
LT
323
324err_mem:
325 printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
326 goto failed;
327
328cs_failed:
fba395ee 329 cs_error(link, last_fn, last_ret);
1da177e4
LT
330failed:
331 kfree(stk);
332 ide_release(link);
15b99ac1 333 return -ENODEV;
1da177e4
LT
334} /* ide_config */
335
336/*======================================================================
337
338 After a card is removed, ide_release() will unregister the net
339 device, and release the PCMCIA configuration. If the device is
340 still open, this will be postponed until it is closed.
341
342======================================================================*/
343
fba395ee 344void ide_release(struct pcmcia_device *link)
1da177e4
LT
345{
346 ide_info_t *info = link->priv;
347
348 DEBUG(0, "ide_release(0x%p)\n", link);
349
350 if (info->ndev) {
351 /* FIXME: if this fails we need to queue the cleanup somehow
352 -- need to investigate the required PCMCIA magic */
353 ide_unregister(info->hd);
354 }
355 info->ndev = 0;
1da177e4 356
fba395ee 357 pcmcia_disable_device(link);
1da177e4
LT
358} /* ide_release */
359
98e4c28b 360
1da177e4
LT
361/*======================================================================
362
363 The card status event handler. Mostly, this schedules other
364 stuff to run after an event is received. A CARD_REMOVAL event
365 also sets some flags to discourage the ide drivers from
366 talking to the ports.
367
368======================================================================*/
369
f70b7d40
DB
370static struct pcmcia_device_id ide_ids[] = {
371 PCMCIA_DEVICE_FUNC_ID(4),
725a6abf 372 PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
f70b7d40 373 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
d3feb184
DB
374 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
375 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
f70b7d40 376 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
d3feb184 377 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
725a6abf 378 PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
f70b7d40 379 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
d3feb184 380 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
f70b7d40
DB
381 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
382 PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
383 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
384 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
385 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
386 PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
387 PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
388 PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
d277ad0e 389 PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
f70b7d40
DB
390 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
391 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
392 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
725a6abf
RP
393 PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
394 PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
264a3412 395 PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
f70b7d40
DB
396 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
397 PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
398 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
399 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
400 PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
4fa902a9 401 PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
2570b746 402 PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
f70b7d40
DB
403 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
404 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
405 PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
4fa902a9
MJ
406 PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
407 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
408 PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
f70b7d40 409 PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
42935656 410 PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
4fa902a9 411 PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
f70b7d40
DB
412 PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
413 PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
d3feb184 414 PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
698e22c4 415 PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
f70b7d40
DB
416 PCMCIA_DEVICE_NULL,
417};
418MODULE_DEVICE_TABLE(pcmcia, ide_ids);
419
1da177e4
LT
420static struct pcmcia_driver ide_cs_driver = {
421 .owner = THIS_MODULE,
422 .drv = {
423 .name = "ide-cs",
424 },
15b99ac1 425 .probe = ide_probe,
cc3b4866 426 .remove = ide_detach,
f70b7d40 427 .id_table = ide_ids,
1da177e4
LT
428};
429
430static int __init init_ide_cs(void)
431{
432 return pcmcia_register_driver(&ide_cs_driver);
433}
434
435static void __exit exit_ide_cs(void)
436{
437 pcmcia_unregister_driver(&ide_cs_driver);
1da177e4
LT
438}
439
2b8d4669 440late_initcall(init_ide_cs);
1da177e4 441module_exit(exit_ide_cs);