aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick/host/tifm_ms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/memstick/host/tifm_ms.c')
-rw-r--r--drivers/memstick/host/tifm_ms.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index 14458764588c..d32d6ad8f3fc 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -71,6 +71,7 @@ struct tifm_ms {
71 struct tifm_dev *dev; 71 struct tifm_dev *dev;
72 struct timer_list timer; 72 struct timer_list timer;
73 struct memstick_request *req; 73 struct memstick_request *req;
74 struct tasklet_struct notify;
74 unsigned int mode_mask; 75 unsigned int mode_mask;
75 unsigned int block_pos; 76 unsigned int block_pos;
76 unsigned long timeout_jiffies; 77 unsigned long timeout_jiffies;
@@ -455,40 +456,45 @@ static void tifm_ms_card_event(struct tifm_dev *sock)
455 return; 456 return;
456} 457}
457 458
458static void tifm_ms_request(struct memstick_host *msh) 459static void tifm_ms_req_tasklet(unsigned long data)
459{ 460{
461 struct memstick_host *msh = (struct memstick_host *)data;
460 struct tifm_ms *host = memstick_priv(msh); 462 struct tifm_ms *host = memstick_priv(msh);
461 struct tifm_dev *sock = host->dev; 463 struct tifm_dev *sock = host->dev;
462 unsigned long flags; 464 unsigned long flags;
463 int rc; 465 int rc;
464 466
465 spin_lock_irqsave(&sock->lock, flags); 467 spin_lock_irqsave(&sock->lock, flags);
466 if (host->req) { 468 if (!host->req) {
467 printk(KERN_ERR "%s : unfinished request detected\n", 469 if (host->eject) {
468 sock->dev.bus_id); 470 do {
469 spin_unlock_irqrestore(&sock->lock, flags); 471 rc = memstick_next_req(msh, &host->req);
470 tifm_eject(host->dev); 472 if (!rc)
471 return; 473 host->req->error = -ETIME;
472 } 474 } while (!rc);
475 spin_unlock_irqrestore(&sock->lock, flags);
476 return;
477 }
473 478
474 if (host->eject) {
475 do { 479 do {
476 rc = memstick_next_req(msh, &host->req); 480 rc = memstick_next_req(msh, &host->req);
477 if (!rc) 481 } while (!rc && tifm_ms_issue_cmd(host));
478 host->req->error = -ETIME;
479 } while (!rc);
480 spin_unlock_irqrestore(&sock->lock, flags);
481 return;
482 } 482 }
483
484 do {
485 rc = memstick_next_req(msh, &host->req);
486 } while (!rc && tifm_ms_issue_cmd(host));
487
488 spin_unlock_irqrestore(&sock->lock, flags); 483 spin_unlock_irqrestore(&sock->lock, flags);
484}
485
486static void tifm_ms_dummy_submit(struct memstick_host *msh)
487{
489 return; 488 return;
490} 489}
491 490
491static void tifm_ms_submit_req(struct memstick_host *msh)
492{
493 struct tifm_ms *host = memstick_priv(msh);
494
495 tasklet_schedule(&host->notify);
496}
497
492static int tifm_ms_set_param(struct memstick_host *msh, 498static int tifm_ms_set_param(struct memstick_host *msh,
493 enum memstick_param param, 499 enum memstick_param param,
494 int value) 500 int value)
@@ -569,8 +575,9 @@ static int tifm_ms_probe(struct tifm_dev *sock)
569 host->timeout_jiffies = msecs_to_jiffies(1000); 575 host->timeout_jiffies = msecs_to_jiffies(1000);
570 576
571 setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); 577 setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host);
578 tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh);
572 579
573 msh->request = tifm_ms_request; 580 msh->request = tifm_ms_submit_req;
574 msh->set_param = tifm_ms_set_param; 581 msh->set_param = tifm_ms_set_param;
575 sock->card_event = tifm_ms_card_event; 582 sock->card_event = tifm_ms_card_event;
576 sock->data_event = tifm_ms_data_event; 583 sock->data_event = tifm_ms_data_event;
@@ -592,6 +599,8 @@ static void tifm_ms_remove(struct tifm_dev *sock)
592 int rc = 0; 599 int rc = 0;
593 unsigned long flags; 600 unsigned long flags;
594 601
602 msh->request = tifm_ms_dummy_submit;
603 tasklet_kill(&host->notify);
595 spin_lock_irqsave(&sock->lock, flags); 604 spin_lock_irqsave(&sock->lock, flags);
596 host->eject = 1; 605 host->eject = 1;
597 if (host->req) { 606 if (host->req) {