diff options
Diffstat (limited to 'drivers/scsi/pcmcia/qlogic_stub.c')
-rw-r--r-- | drivers/scsi/pcmcia/qlogic_stub.c | 127 |
1 files changed, 45 insertions, 82 deletions
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index bb091a45a880..dce7e687fd4a 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c | |||
@@ -98,15 +98,8 @@ typedef struct scsi_info_t { | |||
98 | } scsi_info_t; | 98 | } scsi_info_t; |
99 | 99 | ||
100 | static void qlogic_release(dev_link_t *link); | 100 | static void qlogic_release(dev_link_t *link); |
101 | static int qlogic_event(event_t event, int priority, event_callback_args_t * args); | 101 | static void qlogic_detach(struct pcmcia_device *p_dev); |
102 | 102 | static void qlogic_config(dev_link_t * link); | |
103 | static dev_link_t *qlogic_attach(void); | ||
104 | static void qlogic_detach(dev_link_t *); | ||
105 | |||
106 | |||
107 | static dev_link_t *dev_list = NULL; | ||
108 | |||
109 | static dev_info_t dev_info = "qlogic_cs"; | ||
110 | 103 | ||
111 | static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, | 104 | static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, |
112 | dev_link_t *link, int qbase, int qlirq) | 105 | dev_link_t *link, int qbase, int qlirq) |
@@ -163,19 +156,17 @@ free_scsi_host: | |||
163 | err: | 156 | err: |
164 | return NULL; | 157 | return NULL; |
165 | } | 158 | } |
166 | static dev_link_t *qlogic_attach(void) | 159 | static int qlogic_attach(struct pcmcia_device *p_dev) |
167 | { | 160 | { |
168 | scsi_info_t *info; | 161 | scsi_info_t *info; |
169 | client_reg_t client_reg; | ||
170 | dev_link_t *link; | 162 | dev_link_t *link; |
171 | int ret; | ||
172 | 163 | ||
173 | DEBUG(0, "qlogic_attach()\n"); | 164 | DEBUG(0, "qlogic_attach()\n"); |
174 | 165 | ||
175 | /* Create new SCSI device */ | 166 | /* Create new SCSI device */ |
176 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 167 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
177 | if (!info) | 168 | if (!info) |
178 | return NULL; | 169 | return -ENOMEM; |
179 | memset(info, 0, sizeof(*info)); | 170 | memset(info, 0, sizeof(*info)); |
180 | link = &info->link; | 171 | link = &info->link; |
181 | link->priv = info; | 172 | link->priv = info; |
@@ -189,45 +180,26 @@ static dev_link_t *qlogic_attach(void) | |||
189 | link->conf.IntType = INT_MEMORY_AND_IO; | 180 | link->conf.IntType = INT_MEMORY_AND_IO; |
190 | link->conf.Present = PRESENT_OPTION; | 181 | link->conf.Present = PRESENT_OPTION; |
191 | 182 | ||
192 | /* Register with Card Services */ | 183 | link->handle = p_dev; |
193 | link->next = dev_list; | 184 | p_dev->instance = link; |
194 | dev_list = link; | ||
195 | client_reg.dev_info = &dev_info; | ||
196 | client_reg.Version = 0x0210; | ||
197 | client_reg.event_callback_args.client_data = link; | ||
198 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
199 | if (ret != 0) { | ||
200 | cs_error(link->handle, RegisterClient, ret); | ||
201 | qlogic_detach(link); | ||
202 | return NULL; | ||
203 | } | ||
204 | 185 | ||
205 | return link; | 186 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
187 | qlogic_config(link); | ||
188 | |||
189 | return 0; | ||
206 | } /* qlogic_attach */ | 190 | } /* qlogic_attach */ |
207 | 191 | ||
208 | /*====================================================================*/ | 192 | /*====================================================================*/ |
209 | 193 | ||
210 | static void qlogic_detach(dev_link_t * link) | 194 | static void qlogic_detach(struct pcmcia_device *p_dev) |
211 | { | 195 | { |
212 | dev_link_t **linkp; | 196 | dev_link_t *link = dev_to_instance(p_dev); |
213 | 197 | ||
214 | DEBUG(0, "qlogic_detach(0x%p)\n", link); | 198 | DEBUG(0, "qlogic_detach(0x%p)\n", link); |
215 | 199 | ||
216 | /* Locate device structure */ | ||
217 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
218 | if (*linkp == link) | ||
219 | break; | ||
220 | if (*linkp == NULL) | ||
221 | return; | ||
222 | |||
223 | if (link->state & DEV_CONFIG) | 200 | if (link->state & DEV_CONFIG) |
224 | qlogic_release(link); | 201 | qlogic_release(link); |
225 | 202 | ||
226 | if (link->handle) | ||
227 | pcmcia_deregister_client(link->handle); | ||
228 | |||
229 | /* Unlink device structure, free bits */ | ||
230 | *linkp = link->next; | ||
231 | kfree(link->priv); | 203 | kfree(link->priv); |
232 | 204 | ||
233 | } /* qlogic_detach */ | 205 | } /* qlogic_detach */ |
@@ -349,48 +321,39 @@ static void qlogic_release(dev_link_t *link) | |||
349 | 321 | ||
350 | /*====================================================================*/ | 322 | /*====================================================================*/ |
351 | 323 | ||
352 | static int qlogic_event(event_t event, int priority, event_callback_args_t * args) | 324 | static int qlogic_suspend(struct pcmcia_device *dev) |
353 | { | 325 | { |
354 | dev_link_t *link = args->client_data; | 326 | dev_link_t *link = dev_to_instance(dev); |
355 | 327 | ||
356 | DEBUG(1, "qlogic_event(0x%06x)\n", event); | 328 | link->state |= DEV_SUSPEND; |
357 | 329 | if (link->state & DEV_CONFIG) | |
358 | switch (event) { | 330 | pcmcia_release_configuration(link->handle); |
359 | case CS_EVENT_CARD_REMOVAL: | 331 | |
360 | link->state &= ~DEV_PRESENT; | 332 | return 0; |
361 | if (link->state & DEV_CONFIG) | 333 | } |
362 | qlogic_release(link); | 334 | |
363 | break; | 335 | static int qlogic_resume(struct pcmcia_device *dev) |
364 | case CS_EVENT_CARD_INSERTION: | 336 | { |
365 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 337 | dev_link_t *link = dev_to_instance(dev); |
366 | qlogic_config(link); | 338 | |
367 | break; | 339 | link->state &= ~DEV_SUSPEND; |
368 | case CS_EVENT_PM_SUSPEND: | 340 | if (link->state & DEV_CONFIG) { |
369 | link->state |= DEV_SUSPEND; | 341 | scsi_info_t *info = link->priv; |
370 | /* Fall through... */ | 342 | |
371 | case CS_EVENT_RESET_PHYSICAL: | 343 | pcmcia_request_configuration(link->handle, &link->conf); |
372 | if (link->state & DEV_CONFIG) | 344 | if ((info->manf_id == MANFID_MACNICA) || |
373 | pcmcia_release_configuration(link->handle); | 345 | (info->manf_id == MANFID_PIONEER) || |
374 | break; | 346 | (info->manf_id == 0x0098)) { |
375 | case CS_EVENT_PM_RESUME: | 347 | outb(0x80, link->io.BasePort1 + 0xd); |
376 | link->state &= ~DEV_SUSPEND; | 348 | outb(0x24, link->io.BasePort1 + 0x9); |
377 | /* Fall through... */ | 349 | outb(0x04, link->io.BasePort1 + 0xd); |
378 | case CS_EVENT_CARD_RESET: | ||
379 | if (link->state & DEV_CONFIG) { | ||
380 | scsi_info_t *info = link->priv; | ||
381 | pcmcia_request_configuration(link->handle, &link->conf); | ||
382 | if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { | ||
383 | outb(0x80, link->io.BasePort1 + 0xd); | ||
384 | outb(0x24, link->io.BasePort1 + 0x9); | ||
385 | outb(0x04, link->io.BasePort1 + 0xd); | ||
386 | } | ||
387 | /* Ugggglllyyyy!!! */ | ||
388 | qlogicfas408_bus_reset(NULL); | ||
389 | } | 350 | } |
390 | break; | 351 | /* Ugggglllyyyy!!! */ |
352 | qlogicfas408_bus_reset(NULL); | ||
391 | } | 353 | } |
354 | |||
392 | return 0; | 355 | return 0; |
393 | } /* qlogic_event */ | 356 | } |
394 | 357 | ||
395 | static struct pcmcia_device_id qlogic_ids[] = { | 358 | static struct pcmcia_device_id qlogic_ids[] = { |
396 | PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6), | 359 | PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6), |
@@ -419,10 +382,11 @@ static struct pcmcia_driver qlogic_cs_driver = { | |||
419 | .drv = { | 382 | .drv = { |
420 | .name = "qlogic_cs", | 383 | .name = "qlogic_cs", |
421 | }, | 384 | }, |
422 | .attach = qlogic_attach, | 385 | .probe = qlogic_attach, |
423 | .event = qlogic_event, | 386 | .remove = qlogic_detach, |
424 | .detach = qlogic_detach, | ||
425 | .id_table = qlogic_ids, | 387 | .id_table = qlogic_ids, |
388 | .suspend = qlogic_suspend, | ||
389 | .resume = qlogic_resume, | ||
426 | }; | 390 | }; |
427 | 391 | ||
428 | static int __init init_qlogic_cs(void) | 392 | static int __init init_qlogic_cs(void) |
@@ -433,7 +397,6 @@ static int __init init_qlogic_cs(void) | |||
433 | static void __exit exit_qlogic_cs(void) | 397 | static void __exit exit_qlogic_cs(void) |
434 | { | 398 | { |
435 | pcmcia_unregister_driver(&qlogic_cs_driver); | 399 | pcmcia_unregister_driver(&qlogic_cs_driver); |
436 | BUG_ON(dev_list != NULL); | ||
437 | } | 400 | } |
438 | 401 | ||
439 | MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); | 402 | MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); |