aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/legacy/ide-cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/legacy/ide-cs.c')
-rw-r--r--drivers/ide/legacy/ide-cs.c132
1 files changed, 48 insertions, 84 deletions
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index ef79805218e4..4c2af9020905 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -88,15 +88,12 @@ typedef struct ide_info_t {
88} ide_info_t; 88} ide_info_t;
89 89
90static void ide_release(dev_link_t *); 90static void ide_release(dev_link_t *);
91static int ide_event(event_t event, int priority, 91static void ide_config(dev_link_t *);
92 event_callback_args_t *args); 92
93static void ide_detach(struct pcmcia_device *p_dev);
93 94
94static dev_info_t dev_info = "ide-cs";
95 95
96static dev_link_t *ide_attach(void);
97static void ide_detach(dev_link_t *);
98 96
99static dev_link_t *dev_list = NULL;
100 97
101/*====================================================================== 98/*======================================================================
102 99
@@ -106,18 +103,17 @@ static dev_link_t *dev_list = NULL;
106 103
107======================================================================*/ 104======================================================================*/
108 105
109static dev_link_t *ide_attach(void) 106static int ide_attach(struct pcmcia_device *p_dev)
110{ 107{
111 ide_info_t *info; 108 ide_info_t *info;
112 dev_link_t *link; 109 dev_link_t *link;
113 client_reg_t client_reg; 110
114 int ret;
115
116 DEBUG(0, "ide_attach()\n"); 111 DEBUG(0, "ide_attach()\n");
117 112
118 /* Create new ide device */ 113 /* Create new ide device */
119 info = kzalloc(sizeof(*info), GFP_KERNEL); 114 info = kzalloc(sizeof(*info), GFP_KERNEL);
120 if (!info) return NULL; 115 if (!info)
116 return -ENOMEM;
121 link = &info->link; link->priv = info; 117 link = &info->link; link->priv = info;
122 118
123 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 119 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -128,21 +124,14 @@ static dev_link_t *ide_attach(void)
128 link->conf.Attributes = CONF_ENABLE_IRQ; 124 link->conf.Attributes = CONF_ENABLE_IRQ;
129 link->conf.Vcc = 50; 125 link->conf.Vcc = 50;
130 link->conf.IntType = INT_MEMORY_AND_IO; 126 link->conf.IntType = INT_MEMORY_AND_IO;
131 127
132 /* Register with Card Services */ 128 link->handle = p_dev;
133 link->next = dev_list; 129 p_dev->instance = link;
134 dev_list = link; 130
135 client_reg.dev_info = &dev_info; 131 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
136 client_reg.Version = 0x0210; 132 ide_config(link);
137 client_reg.event_callback_args.client_data = link; 133
138 ret = pcmcia_register_client(&link->handle, &client_reg); 134 return 0;
139 if (ret != CS_SUCCESS) {
140 cs_error(link->handle, RegisterClient, ret);
141 ide_detach(link);
142 return NULL;
143 }
144
145 return link;
146} /* ide_attach */ 135} /* ide_attach */
147 136
148/*====================================================================== 137/*======================================================================
@@ -154,32 +143,16 @@ static dev_link_t *ide_attach(void)
154 143
155======================================================================*/ 144======================================================================*/
156 145
157static void ide_detach(dev_link_t *link) 146static void ide_detach(struct pcmcia_device *p_dev)
158{ 147{
159 dev_link_t **linkp; 148 dev_link_t *link = dev_to_instance(p_dev);
160 int ret;
161 149
162 DEBUG(0, "ide_detach(0x%p)\n", link); 150 DEBUG(0, "ide_detach(0x%p)\n", link);
163
164 /* Locate device structure */
165 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
166 if (*linkp == link) break;
167 if (*linkp == NULL)
168 return;
169 151
170 if (link->state & DEV_CONFIG) 152 if (link->state & DEV_CONFIG)
171 ide_release(link); 153 ide_release(link);
172 154
173 if (link->handle) {
174 ret = pcmcia_deregister_client(link->handle);
175 if (ret != CS_SUCCESS)
176 cs_error(link->handle, DeregisterClient, ret);
177 }
178
179 /* Unlink, free device structure */
180 *linkp = link->next;
181 kfree(link->priv); 155 kfree(link->priv);
182
183} /* ide_detach */ 156} /* ide_detach */
184 157
185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) 158static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
@@ -406,6 +379,28 @@ void ide_release(dev_link_t *link)
406 379
407} /* ide_release */ 380} /* ide_release */
408 381
382static int ide_suspend(struct pcmcia_device *dev)
383{
384 dev_link_t *link = dev_to_instance(dev);
385
386 link->state |= DEV_SUSPEND;
387 if (link->state & DEV_CONFIG)
388 pcmcia_release_configuration(link->handle);
389
390 return 0;
391}
392
393static int ide_resume(struct pcmcia_device *dev)
394{
395 dev_link_t *link = dev_to_instance(dev);
396
397 link->state &= ~DEV_SUSPEND;
398 if (DEV_OK(link))
399 pcmcia_request_configuration(link->handle, &link->conf);
400
401 return 0;
402}
403
409/*====================================================================== 404/*======================================================================
410 405
411 The card status event handler. Mostly, this schedules other 406 The card status event handler. Mostly, this schedules other
@@ -415,48 +410,15 @@ void ide_release(dev_link_t *link)
415 410
416======================================================================*/ 411======================================================================*/
417 412
418int ide_event(event_t event, int priority,
419 event_callback_args_t *args)
420{
421 dev_link_t *link = args->client_data;
422
423 DEBUG(1, "ide_event(0x%06x)\n", event);
424
425 switch (event) {
426 case CS_EVENT_CARD_REMOVAL:
427 link->state &= ~DEV_PRESENT;
428 if (link->state & DEV_CONFIG)
429 ide_release(link);
430 break;
431 case CS_EVENT_CARD_INSERTION:
432 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
433 ide_config(link);
434 break;
435 case CS_EVENT_PM_SUSPEND:
436 link->state |= DEV_SUSPEND;
437 /* Fall through... */
438 case CS_EVENT_RESET_PHYSICAL:
439 if (link->state & DEV_CONFIG)
440 pcmcia_release_configuration(link->handle);
441 break;
442 case CS_EVENT_PM_RESUME:
443 link->state &= ~DEV_SUSPEND;
444 /* Fall through... */
445 case CS_EVENT_CARD_RESET:
446 if (DEV_OK(link))
447 pcmcia_request_configuration(link->handle, &link->conf);
448 break;
449 }
450 return 0;
451} /* ide_event */
452
453static struct pcmcia_device_id ide_ids[] = { 413static struct pcmcia_device_id ide_ids[] = {
454 PCMCIA_DEVICE_FUNC_ID(4), 414 PCMCIA_DEVICE_FUNC_ID(4),
415 PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
455 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), 416 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
456 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), 417 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
457 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ 418 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
458 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), 419 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
459 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ 420 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
421 PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
460 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), 422 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
461 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */ 423 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
462 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), 424 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
@@ -471,6 +433,8 @@ static struct pcmcia_device_id ide_ids[] = {
471 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), 433 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
472 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), 434 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
473 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), 435 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
436 PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
437 PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
474 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), 438 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
475 PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), 439 PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
476 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), 440 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -494,10 +458,11 @@ static struct pcmcia_driver ide_cs_driver = {
494 .drv = { 458 .drv = {
495 .name = "ide-cs", 459 .name = "ide-cs",
496 }, 460 },
497 .attach = ide_attach, 461 .probe = ide_attach,
498 .event = ide_event, 462 .remove = ide_detach,
499 .detach = ide_detach,
500 .id_table = ide_ids, 463 .id_table = ide_ids,
464 .suspend = ide_suspend,
465 .resume = ide_resume,
501}; 466};
502 467
503static int __init init_ide_cs(void) 468static int __init init_ide_cs(void)
@@ -508,7 +473,6 @@ static int __init init_ide_cs(void)
508static void __exit exit_ide_cs(void) 473static void __exit exit_ide_cs(void)
509{ 474{
510 pcmcia_unregister_driver(&ide_cs_driver); 475 pcmcia_unregister_driver(&ide_cs_driver);
511 BUG_ON(dev_list != NULL);
512} 476}
513 477
514late_initcall(init_ide_cs); 478late_initcall(init_ide_cs);