From b77899985bdfd85a8e5a6e485033a9b4713d2471 Mon Sep 17 00:00:00 2001 From: Alex Dubov Date: Fri, 25 Jul 2008 19:45:00 -0700 Subject: memstick: allow "set_param" method to return an error code Some controllers (Jmicron, for instance) can report temporal failure condition during power-on. It is desirable to account for this using a return value of "set_param" device method. The return value can also be handy to distinguish between supported and unsupported device parameters in run time. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Alex Dubov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/host/tifm_ms.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers/memstick/host/tifm_ms.c') diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 8577de4ebb0..14458764588 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c @@ -489,15 +489,12 @@ static void tifm_ms_request(struct memstick_host *msh) return; } -static void tifm_ms_set_param(struct memstick_host *msh, - enum memstick_param param, - int value) +static int tifm_ms_set_param(struct memstick_host *msh, + enum memstick_param param, + int value) { struct tifm_ms *host = memstick_priv(msh); struct tifm_dev *sock = host->dev; - unsigned long flags; - - spin_lock_irqsave(&sock->lock, flags); switch (param) { case MEMSTICK_POWER: @@ -512,7 +509,8 @@ static void tifm_ms_set_param(struct memstick_host *msh, writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, sock->addr + SOCK_MS_SYSTEM); writel(0xffffffff, sock->addr + SOCK_MS_STATUS); - } + } else + return -EINVAL; break; case MEMSTICK_INTERFACE: if (value == MEMSTICK_SERIAL) { @@ -525,11 +523,12 @@ static void tifm_ms_set_param(struct memstick_host *msh, writel(TIFM_CTRL_FAST_CLK | readl(sock->addr + SOCK_CONTROL), sock->addr + SOCK_CONTROL); - } + } else + return -EINVAL; break; }; - spin_unlock_irqrestore(&sock->lock, flags); + return 0; } static void tifm_ms_abort(unsigned long data) -- cgit v1.2.3 From f1d82698029b92a88f5500b99f66514b6dee2bc3 Mon Sep 17 00:00:00 2001 From: Alex Dubov Date: Fri, 25 Jul 2008 19:45:02 -0700 Subject: 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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/host/tifm_ms.c | 49 ++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'drivers/memstick/host/tifm_ms.c') diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 14458764588..d32d6ad8f3f 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c @@ -71,6 +71,7 @@ struct tifm_ms { struct tifm_dev *dev; struct timer_list timer; struct memstick_request *req; + struct tasklet_struct notify; unsigned int mode_mask; unsigned int block_pos; unsigned long timeout_jiffies; @@ -455,40 +456,45 @@ static void tifm_ms_card_event(struct tifm_dev *sock) 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_dev *sock = host->dev; unsigned long flags; int rc; spin_lock_irqsave(&sock->lock, flags); - if (host->req) { - printk(KERN_ERR "%s : unfinished request detected\n", - sock->dev.bus_id); - spin_unlock_irqrestore(&sock->lock, flags); - tifm_eject(host->dev); - return; - } + if (!host->req) { + if (host->eject) { + do { + rc = memstick_next_req(msh, &host->req); + if (!rc) + host->req->error = -ETIME; + } while (!rc); + spin_unlock_irqrestore(&sock->lock, flags); + return; + } - if (host->eject) { do { rc = memstick_next_req(msh, &host->req); - if (!rc) - host->req->error = -ETIME; - } while (!rc); - spin_unlock_irqrestore(&sock->lock, flags); - return; + } while (!rc && tifm_ms_issue_cmd(host)); } - - do { - rc = memstick_next_req(msh, &host->req); - } while (!rc && tifm_ms_issue_cmd(host)); - spin_unlock_irqrestore(&sock->lock, flags); +} + +static void tifm_ms_dummy_submit(struct memstick_host *msh) +{ 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, enum memstick_param param, int value) @@ -569,8 +575,9 @@ static int tifm_ms_probe(struct tifm_dev *sock) host->timeout_jiffies = msecs_to_jiffies(1000); 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; sock->card_event = tifm_ms_card_event; sock->data_event = tifm_ms_data_event; @@ -592,6 +599,8 @@ static void tifm_ms_remove(struct tifm_dev *sock) int rc = 0; unsigned long flags; + msh->request = tifm_ms_dummy_submit; + tasklet_kill(&host->notify); spin_lock_irqsave(&sock->lock, flags); host->eject = 1; if (host->req) { -- cgit v1.2.3