aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia/qlogic_stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pcmcia/qlogic_stub.c')
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c127
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
100static void qlogic_release(dev_link_t *link); 100static void qlogic_release(dev_link_t *link);
101static int qlogic_event(event_t event, int priority, event_callback_args_t * args); 101static void qlogic_detach(struct pcmcia_device *p_dev);
102 102static void qlogic_config(dev_link_t * link);
103static dev_link_t *qlogic_attach(void);
104static void qlogic_detach(dev_link_t *);
105
106
107static dev_link_t *dev_list = NULL;
108
109static dev_info_t dev_info = "qlogic_cs";
110 103
111static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, 104static 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:
163err: 156err:
164 return NULL; 157 return NULL;
165} 158}
166static dev_link_t *qlogic_attach(void) 159static 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
210static void qlogic_detach(dev_link_t * link) 194static 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
352static int qlogic_event(event_t event, int priority, event_callback_args_t * args) 324static 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; 335static 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
395static struct pcmcia_device_id qlogic_ids[] = { 358static 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
428static int __init init_qlogic_cs(void) 392static int __init init_qlogic_cs(void)
@@ -433,7 +397,6 @@ static int __init init_qlogic_cs(void)
433static void __exit exit_qlogic_cs(void) 397static 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
439MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); 402MODULE_AUTHOR("Tom Zerucha, Michael Griffith");