diff options
Diffstat (limited to 'drivers/ide/legacy/ide-cs.c')
-rw-r--r-- | drivers/ide/legacy/ide-cs.c | 132 |
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 | ||
90 | static void ide_release(dev_link_t *); | 90 | static void ide_release(dev_link_t *); |
91 | static int ide_event(event_t event, int priority, | 91 | static void ide_config(dev_link_t *); |
92 | event_callback_args_t *args); | 92 | |
93 | static void ide_detach(struct pcmcia_device *p_dev); | ||
93 | 94 | ||
94 | static dev_info_t dev_info = "ide-cs"; | ||
95 | 95 | ||
96 | static dev_link_t *ide_attach(void); | ||
97 | static void ide_detach(dev_link_t *); | ||
98 | 96 | ||
99 | static 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 | ||
109 | static dev_link_t *ide_attach(void) | 106 | static 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 | ||
157 | static void ide_detach(dev_link_t *link) | 146 | static 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 | ||
185 | static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) | 158 | static 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 | ||
382 | static 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 | |||
393 | static 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 | ||
418 | int 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 | |||
453 | static struct pcmcia_device_id ide_ids[] = { | 413 | static 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 | ||
503 | static int __init init_ide_cs(void) | 468 | static int __init init_ide_cs(void) |
@@ -508,7 +473,6 @@ static int __init init_ide_cs(void) | |||
508 | static void __exit exit_ide_cs(void) | 473 | static 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 | ||
514 | late_initcall(init_ide_cs); | 478 | late_initcall(init_ide_cs); |