diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pcmcia/cs.c | 88 |
1 files changed, 39 insertions, 49 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 83d2753814c2..613f2f1fbfdd 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -309,41 +309,6 @@ struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr) | |||
309 | } | 309 | } |
310 | EXPORT_SYMBOL(pcmcia_get_socket_by_nr); | 310 | EXPORT_SYMBOL(pcmcia_get_socket_by_nr); |
311 | 311 | ||
312 | |||
313 | /** | ||
314 | * socket_setup() and shutdown_socket() are called by the main event | ||
315 | * handler when card insertion and removal events are received. | ||
316 | * socket_setup() turns on socket power and resets the socket, in two stages. | ||
317 | * shutdown_socket() unconfigures a socket and turns off socket power. | ||
318 | */ | ||
319 | static void shutdown_socket(struct pcmcia_socket *s) | ||
320 | { | ||
321 | cs_dbg(s, 1, "shutdown_socket\n"); | ||
322 | |||
323 | /* Blank out the socket state */ | ||
324 | s->socket = dead_socket; | ||
325 | s->ops->init(s); | ||
326 | s->ops->set_socket(s, &s->socket); | ||
327 | s->irq.AssignedIRQ = s->irq.Config = 0; | ||
328 | s->lock_count = 0; | ||
329 | destroy_cis_cache(s); | ||
330 | #ifdef CONFIG_CARDBUS | ||
331 | cb_free(s); | ||
332 | #endif | ||
333 | s->functions = 0; | ||
334 | kfree(s->config); | ||
335 | s->config = NULL; | ||
336 | |||
337 | { | ||
338 | int status; | ||
339 | s->ops->get_status(s, &status); | ||
340 | if (status & SS_POWERON) { | ||
341 | printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); | ||
342 | } | ||
343 | } | ||
344 | } /* shutdown_socket */ | ||
345 | |||
346 | |||
347 | /** | 312 | /** |
348 | * The central event handler. Send_event() sends an event to the | 313 | * The central event handler. Send_event() sends an event to the |
349 | * 16-bit subsystem, which then calls the relevant device drivers. | 314 | * 16-bit subsystem, which then calls the relevant device drivers. |
@@ -383,17 +348,6 @@ static void socket_remove_drivers(struct pcmcia_socket *skt) | |||
383 | send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); | 348 | send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); |
384 | } | 349 | } |
385 | 350 | ||
386 | static void socket_shutdown(struct pcmcia_socket *skt) | ||
387 | { | ||
388 | cs_dbg(skt, 4, "shutdown\n"); | ||
389 | |||
390 | socket_remove_drivers(skt); | ||
391 | skt->state &= SOCKET_INUSE|SOCKET_PRESENT; | ||
392 | msleep(shutdown_delay * 10); | ||
393 | skt->state &= SOCKET_INUSE; | ||
394 | shutdown_socket(skt); | ||
395 | } | ||
396 | |||
397 | static int socket_reset(struct pcmcia_socket *skt) | 351 | static int socket_reset(struct pcmcia_socket *skt) |
398 | { | 352 | { |
399 | int status, i; | 353 | int status, i; |
@@ -424,6 +378,45 @@ static int socket_reset(struct pcmcia_socket *skt) | |||
424 | return CS_GENERAL_FAILURE; | 378 | return CS_GENERAL_FAILURE; |
425 | } | 379 | } |
426 | 380 | ||
381 | /** | ||
382 | * socket_setup() and socket_shutdown() are called by the main event handler | ||
383 | * when card insertion and removal events are received. | ||
384 | * socket_setup() turns on socket power and resets the socket, in two stages. | ||
385 | * socket_shutdown() unconfigures a socket and turns off socket power. | ||
386 | */ | ||
387 | static void socket_shutdown(struct pcmcia_socket *s) | ||
388 | { | ||
389 | int status; | ||
390 | |||
391 | cs_dbg(s, 4, "shutdown\n"); | ||
392 | |||
393 | socket_remove_drivers(s); | ||
394 | s->state &= SOCKET_INUSE | SOCKET_PRESENT; | ||
395 | msleep(shutdown_delay * 10); | ||
396 | s->state &= SOCKET_INUSE; | ||
397 | |||
398 | /* Blank out the socket state */ | ||
399 | s->socket = dead_socket; | ||
400 | s->ops->init(s); | ||
401 | s->ops->set_socket(s, &s->socket); | ||
402 | s->irq.AssignedIRQ = s->irq.Config = 0; | ||
403 | s->lock_count = 0; | ||
404 | destroy_cis_cache(s); | ||
405 | #ifdef CONFIG_CARDBUS | ||
406 | cb_free(s); | ||
407 | #endif | ||
408 | s->functions = 0; | ||
409 | kfree(s->config); | ||
410 | s->config = NULL; | ||
411 | |||
412 | s->ops->get_status(s, &status); | ||
413 | if (status & SS_POWERON) { | ||
414 | printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); | ||
415 | } | ||
416 | |||
417 | cs_socket_put(s); | ||
418 | } | ||
419 | |||
427 | static int socket_setup(struct pcmcia_socket *skt, int initial_delay) | 420 | static int socket_setup(struct pcmcia_socket *skt, int initial_delay) |
428 | { | 421 | { |
429 | int status, i; | 422 | int status, i; |
@@ -529,7 +522,6 @@ static int socket_insert(struct pcmcia_socket *skt) | |||
529 | send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); | 522 | send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); |
530 | } else { | 523 | } else { |
531 | socket_shutdown(skt); | 524 | socket_shutdown(skt); |
532 | cs_socket_put(skt); | ||
533 | } | 525 | } |
534 | 526 | ||
535 | return ret; | 527 | return ret; |
@@ -593,7 +585,6 @@ static int socket_resume(struct pcmcia_socket *skt) | |||
593 | } | 585 | } |
594 | } else { | 586 | } else { |
595 | socket_shutdown(skt); | 587 | socket_shutdown(skt); |
596 | cs_socket_put(skt); | ||
597 | } | 588 | } |
598 | 589 | ||
599 | skt->state &= ~SOCKET_SUSPEND; | 590 | skt->state &= ~SOCKET_SUSPEND; |
@@ -605,7 +596,6 @@ static void socket_remove(struct pcmcia_socket *skt) | |||
605 | { | 596 | { |
606 | printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); | 597 | printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); |
607 | socket_shutdown(skt); | 598 | socket_shutdown(skt); |
608 | cs_socket_put(skt); | ||
609 | } | 599 | } |
610 | 600 | ||
611 | /* | 601 | /* |