diff options
author | Alex Dubov <oakad@yahoo.com> | 2008-07-25 22:45:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 15:00:04 -0400 |
commit | f1d82698029b92a88f5500b99f66514b6dee2bc3 (patch) | |
tree | eaedb613a05e1471fbeca212b3b1229ab252627d /drivers/memstick/host | |
parent | 17017d8d2c005734d7088d8281ce2daab8fcb097 (diff) |
memstick: use fully asynchronous request processing
Instead of using a separate thread to pump requests from block layer queue
to memstick, do so inline, utilizing the callback design of the memstick.
[akpm@linux-foundation.org: fix warnings]
Signed-off-by: Alex Dubov <oakad@yahoo.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/memstick/host')
-rw-r--r-- | drivers/memstick/host/jmb38x_ms.c | 35 | ||||
-rw-r--r-- | drivers/memstick/host/tifm_ms.c | 49 |
2 files changed, 54 insertions, 30 deletions
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 9d82e67737db..3485c63d20b0 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c | |||
@@ -50,6 +50,7 @@ struct jmb38x_ms_host { | |||
50 | struct jmb38x_ms *chip; | 50 | struct jmb38x_ms *chip; |
51 | void __iomem *addr; | 51 | void __iomem *addr; |
52 | spinlock_t lock; | 52 | spinlock_t lock; |
53 | struct tasklet_struct notify; | ||
53 | int id; | 54 | int id; |
54 | char host_id[32]; | 55 | char host_id[32]; |
55 | int irq; | 56 | int irq; |
@@ -590,25 +591,35 @@ static void jmb38x_ms_abort(unsigned long data) | |||
590 | spin_unlock_irqrestore(&host->lock, flags); | 591 | spin_unlock_irqrestore(&host->lock, flags); |
591 | } | 592 | } |
592 | 593 | ||
593 | static void jmb38x_ms_request(struct memstick_host *msh) | 594 | static void jmb38x_ms_req_tasklet(unsigned long data) |
594 | { | 595 | { |
596 | struct memstick_host *msh = (struct memstick_host *)data; | ||
595 | struct jmb38x_ms_host *host = memstick_priv(msh); | 597 | struct jmb38x_ms_host *host = memstick_priv(msh); |
596 | unsigned long flags; | 598 | unsigned long flags; |
597 | int rc; | 599 | int rc; |
598 | 600 | ||
599 | spin_lock_irqsave(&host->lock, flags); | 601 | spin_lock_irqsave(&host->lock, flags); |
600 | if (host->req) { | 602 | if (!host->req) { |
601 | spin_unlock_irqrestore(&host->lock, flags); | 603 | do { |
602 | BUG(); | 604 | rc = memstick_next_req(msh, &host->req); |
603 | return; | 605 | dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc); |
606 | } while (!rc && jmb38x_ms_issue_cmd(msh)); | ||
604 | } | 607 | } |
605 | |||
606 | do { | ||
607 | rc = memstick_next_req(msh, &host->req); | ||
608 | } while (!rc && jmb38x_ms_issue_cmd(msh)); | ||
609 | spin_unlock_irqrestore(&host->lock, flags); | 608 | spin_unlock_irqrestore(&host->lock, flags); |
610 | } | 609 | } |
611 | 610 | ||
611 | static void jmb38x_ms_dummy_submit(struct memstick_host *msh) | ||
612 | { | ||
613 | return; | ||
614 | } | ||
615 | |||
616 | static void jmb38x_ms_submit_req(struct memstick_host *msh) | ||
617 | { | ||
618 | struct jmb38x_ms_host *host = memstick_priv(msh); | ||
619 | |||
620 | tasklet_schedule(&host->notify); | ||
621 | } | ||
622 | |||
612 | static int jmb38x_ms_reset(struct jmb38x_ms_host *host) | 623 | static int jmb38x_ms_reset(struct jmb38x_ms_host *host) |
613 | { | 624 | { |
614 | int cnt; | 625 | int cnt; |
@@ -816,7 +827,9 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt) | |||
816 | host->id); | 827 | host->id); |
817 | host->irq = jm->pdev->irq; | 828 | host->irq = jm->pdev->irq; |
818 | host->timeout_jiffies = msecs_to_jiffies(1000); | 829 | host->timeout_jiffies = msecs_to_jiffies(1000); |
819 | msh->request = jmb38x_ms_request; | 830 | |
831 | tasklet_init(&host->notify, jmb38x_ms_req_tasklet, (unsigned long)msh); | ||
832 | msh->request = jmb38x_ms_submit_req; | ||
820 | msh->set_param = jmb38x_ms_set_param; | 833 | msh->set_param = jmb38x_ms_set_param; |
821 | 834 | ||
822 | msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; | 835 | msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; |
@@ -928,6 +941,8 @@ static void jmb38x_ms_remove(struct pci_dev *dev) | |||
928 | 941 | ||
929 | host = memstick_priv(jm->hosts[cnt]); | 942 | host = memstick_priv(jm->hosts[cnt]); |
930 | 943 | ||
944 | jm->hosts[cnt]->request = jmb38x_ms_dummy_submit; | ||
945 | tasklet_kill(&host->notify); | ||
931 | writel(0, host->addr + INT_SIGNAL_ENABLE); | 946 | writel(0, host->addr + INT_SIGNAL_ENABLE); |
932 | writel(0, host->addr + INT_STATUS_ENABLE); | 947 | writel(0, host->addr + INT_STATUS_ENABLE); |
933 | mmiowb(); | 948 | mmiowb(); |
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 | ||
458 | static void tifm_ms_request(struct memstick_host *msh) | 459 | static 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 | |||
486 | static void tifm_ms_dummy_submit(struct memstick_host *msh) | ||
487 | { | ||
489 | return; | 488 | return; |
490 | } | 489 | } |
491 | 490 | ||
491 | static 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 | |||
492 | static int tifm_ms_set_param(struct memstick_host *msh, | 498 | static 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) { |