Commit f1d82698 authored by Alex Dubov's avatar Alex Dubov Committed by Linus Torvalds

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: default avatarAlex Dubov <oakad@yahoo.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 17017d8d
...@@ -249,8 +249,11 @@ EXPORT_SYMBOL(memstick_next_req); ...@@ -249,8 +249,11 @@ EXPORT_SYMBOL(memstick_next_req);
*/ */
void memstick_new_req(struct memstick_host *host) void memstick_new_req(struct memstick_host *host)
{ {
host->retries = cmd_retries; if (host->card) {
host->request(host); host->retries = cmd_retries;
INIT_COMPLETION(host->card->mrq_complete);
host->request(host);
}
} }
EXPORT_SYMBOL(memstick_new_req); EXPORT_SYMBOL(memstick_new_req);
......
This diff is collapsed.
...@@ -50,6 +50,7 @@ struct jmb38x_ms_host { ...@@ -50,6 +50,7 @@ struct jmb38x_ms_host {
struct jmb38x_ms *chip; struct jmb38x_ms *chip;
void __iomem *addr; void __iomem *addr;
spinlock_t lock; spinlock_t lock;
struct tasklet_struct notify;
int id; int id;
char host_id[32]; char host_id[32];
int irq; int irq;
...@@ -590,25 +591,35 @@ static void jmb38x_ms_abort(unsigned long data) ...@@ -590,25 +591,35 @@ static void jmb38x_ms_abort(unsigned long data)
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
} }
static void jmb38x_ms_request(struct memstick_host *msh) static void jmb38x_ms_req_tasklet(unsigned long data)
{ {
struct memstick_host *msh = (struct memstick_host *)data;
struct jmb38x_ms_host *host = memstick_priv(msh); struct jmb38x_ms_host *host = memstick_priv(msh);
unsigned long flags; unsigned long flags;
int rc; int rc;
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
if (host->req) { if (!host->req) {
spin_unlock_irqrestore(&host->lock, flags); do {
BUG(); rc = memstick_next_req(msh, &host->req);
return; dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc);
} while (!rc && jmb38x_ms_issue_cmd(msh));
} }
do {
rc = memstick_next_req(msh, &host->req);
} while (!rc && jmb38x_ms_issue_cmd(msh));
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
} }
static void jmb38x_ms_dummy_submit(struct memstick_host *msh)
{
return;
}
static void jmb38x_ms_submit_req(struct memstick_host *msh)
{
struct jmb38x_ms_host *host = memstick_priv(msh);
tasklet_schedule(&host->notify);
}
static int jmb38x_ms_reset(struct jmb38x_ms_host *host) static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
{ {
int cnt; int cnt;
...@@ -816,7 +827,9 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt) ...@@ -816,7 +827,9 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
host->id); host->id);
host->irq = jm->pdev->irq; host->irq = jm->pdev->irq;
host->timeout_jiffies = msecs_to_jiffies(1000); host->timeout_jiffies = msecs_to_jiffies(1000);
msh->request = jmb38x_ms_request;
tasklet_init(&host->notify, jmb38x_ms_req_tasklet, (unsigned long)msh);
msh->request = jmb38x_ms_submit_req;
msh->set_param = jmb38x_ms_set_param; msh->set_param = jmb38x_ms_set_param;
msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
...@@ -928,6 +941,8 @@ static void jmb38x_ms_remove(struct pci_dev *dev) ...@@ -928,6 +941,8 @@ static void jmb38x_ms_remove(struct pci_dev *dev)
host = memstick_priv(jm->hosts[cnt]); host = memstick_priv(jm->hosts[cnt]);
jm->hosts[cnt]->request = jmb38x_ms_dummy_submit;
tasklet_kill(&host->notify);
writel(0, host->addr + INT_SIGNAL_ENABLE); writel(0, host->addr + INT_SIGNAL_ENABLE);
writel(0, host->addr + INT_STATUS_ENABLE); writel(0, host->addr + INT_STATUS_ENABLE);
mmiowb(); mmiowb();
......
...@@ -71,6 +71,7 @@ struct tifm_ms { ...@@ -71,6 +71,7 @@ struct tifm_ms {
struct tifm_dev *dev; struct tifm_dev *dev;
struct timer_list timer; struct timer_list timer;
struct memstick_request *req; struct memstick_request *req;
struct tasklet_struct notify;
unsigned int mode_mask; unsigned int mode_mask;
unsigned int block_pos; unsigned int block_pos;
unsigned long timeout_jiffies; unsigned long timeout_jiffies;
...@@ -455,40 +456,45 @@ static void tifm_ms_card_event(struct tifm_dev *sock) ...@@ -455,40 +456,45 @@ static void tifm_ms_card_event(struct tifm_dev *sock)
return; return;
} }
static void tifm_ms_request(struct memstick_host *msh) static void tifm_ms_req_tasklet(unsigned long data)
{ {
struct memstick_host *msh = (struct memstick_host *)data;
struct tifm_ms *host = memstick_priv(msh); struct tifm_ms *host = memstick_priv(msh);
struct tifm_dev *sock = host->dev; struct tifm_dev *sock = host->dev;
unsigned long flags; unsigned long flags;
int rc; int rc;
spin_lock_irqsave(&sock->lock, flags); spin_lock_irqsave(&sock->lock, flags);
if (host->req) { if (!host->req) {
printk(KERN_ERR "%s : unfinished request detected\n", if (host->eject) {
sock->dev.bus_id); do {
spin_unlock_irqrestore(&sock->lock, flags); rc = memstick_next_req(msh, &host->req);
tifm_eject(host->dev); if (!rc)
return; host->req->error = -ETIME;
} } while (!rc);
spin_unlock_irqrestore(&sock->lock, flags);
return;
}
if (host->eject) {
do { do {
rc = memstick_next_req(msh, &host->req); rc = memstick_next_req(msh, &host->req);
if (!rc) } while (!rc && tifm_ms_issue_cmd(host));
host->req->error = -ETIME;
} while (!rc);
spin_unlock_irqrestore(&sock->lock, flags);
return;
} }
do {
rc = memstick_next_req(msh, &host->req);
} while (!rc && tifm_ms_issue_cmd(host));
spin_unlock_irqrestore(&sock->lock, flags); spin_unlock_irqrestore(&sock->lock, flags);
}
static void tifm_ms_dummy_submit(struct memstick_host *msh)
{
return; return;
} }
static void tifm_ms_submit_req(struct memstick_host *msh)
{
struct tifm_ms *host = memstick_priv(msh);
tasklet_schedule(&host->notify);
}
static int tifm_ms_set_param(struct memstick_host *msh, static int tifm_ms_set_param(struct memstick_host *msh,
enum memstick_param param, enum memstick_param param,
int value) int value)
...@@ -569,8 +575,9 @@ static int tifm_ms_probe(struct tifm_dev *sock) ...@@ -569,8 +575,9 @@ static int tifm_ms_probe(struct tifm_dev *sock)
host->timeout_jiffies = msecs_to_jiffies(1000); host->timeout_jiffies = msecs_to_jiffies(1000);
setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host);
tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh);
msh->request = tifm_ms_request; msh->request = tifm_ms_submit_req;
msh->set_param = tifm_ms_set_param; msh->set_param = tifm_ms_set_param;
sock->card_event = tifm_ms_card_event; sock->card_event = tifm_ms_card_event;
sock->data_event = tifm_ms_data_event; sock->data_event = tifm_ms_data_event;
...@@ -592,6 +599,8 @@ static void tifm_ms_remove(struct tifm_dev *sock) ...@@ -592,6 +599,8 @@ static void tifm_ms_remove(struct tifm_dev *sock)
int rc = 0; int rc = 0;
unsigned long flags; unsigned long flags;
msh->request = tifm_ms_dummy_submit;
tasklet_kill(&host->notify);
spin_lock_irqsave(&sock->lock, flags); spin_lock_irqsave(&sock->lock, flags);
host->eject = 1; host->eject = 1;
if (host->req) { if (host->req) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment