Messages in this thread Patch in this message | | | From | Maxim Levitsky <> | Subject | [PATCH 24/29] memstick: jmb38x_ms: rework processing of the TPC one after another. | Date | Sat, 23 Oct 2010 01:53:52 +0200 |
| |
Lift some common code. Also make sure new TPC is always exacuted from a tasklet. While this decreases IO speed a bit, this makes sure we won't have large latency.
Signed-off-by: Maxim Levitsky <maxim-levitsky@gmail.com> --- drivers/memstick/host/jmb38x_ms.c | 74 ++++++++++++++++++------------------- drivers/memstick/host/jmb38x_ms.h | 5 ++- 2 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 77e4971..16d022e 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -263,6 +263,11 @@ static int j38ms_execute_tpc(struct j38ms_host *host) bool is_read = host->req->data_dir == READ; dma_addr_t dma_address; + if (host->dead) { + host->req->error = -ETIME; + return 0; + } + if (!(j38ms_read_reg(host, STATUS) & STATUS_HAS_MEDIA)) { dbg(host, "IO: card removed, refusing to send TPC"); host->req->error = -ENODEV; @@ -384,10 +389,9 @@ exec: } /* Cleanups execution of current TPC */ -static void j38ms_complete_tpc(struct memstick_host *msh, int last) +static void j38ms_complete_tpc(struct memstick_host *msh) { struct j38ms_host *host = memstick_priv(msh); - int rc; del_timer(&host->timer); dbg(host, "IO: TPC complete (error : %d)", host->req->error); @@ -422,18 +426,6 @@ static void j38ms_complete_tpc(struct memstick_host *msh, int last) } j38ms_clear_reg_mask(host, HOST_CONTROL, HOST_CONTROL_LED); - - if (!last) { - do { - rc = memstick_next_req(msh, &host->req); - } while (!rc && j38ms_execute_tpc(host)); - } else { - do { - rc = memstick_next_req(msh, &host->req); - if (!rc) - host->req->error = -ETIME; - } while (!rc); - } } /* Interrupt handler */ @@ -507,7 +499,8 @@ out: if (host->req && (((host->cmd_flags & CMD_READY) && (host->cmd_flags & FIFO_READY)) || host->req->error)) { - j38ms_complete_tpc(msh, 0); + j38ms_complete_tpc(msh); + tasklet_schedule(&host->tasklet); } spin_unlock(&host->lock); @@ -525,7 +518,8 @@ static void j38ms_irq_timeout(unsigned long data) spin_lock_irqsave(&host->lock, flags); if (host->req) { host->req->error = -ETIME; - j38ms_complete_tpc(msh, 0); + j38ms_complete_tpc(msh); + tasklet_schedule(&host->tasklet); } spin_unlock_irqrestore(&host->lock, flags); } @@ -535,30 +529,29 @@ static void j38ms_submit_tasklet(unsigned long data) struct memstick_host *msh = (struct memstick_host *)data; struct j38ms_host *host = memstick_priv(msh); unsigned long flags; - int rc; spin_lock_irqsave(&host->lock, flags); - if (!host->req) { - do { - rc = memstick_next_req(msh, &host->req); - dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc); - } while (!rc && j38ms_execute_tpc(host)); - } + j38ms_next_request(host); spin_unlock_irqrestore(&host->lock, flags); } -static void j38ms_dummy_submit(struct memstick_host *msh) -{ - return; -} - static void j38ms_submit_req(struct memstick_host *msh) { struct j38ms_host *host = memstick_priv(msh); - tasklet_schedule(&host->notify); + if (!host->req) + tasklet_schedule(&host->tasklet); } +/* Asks for next request from upper layer and starts its execution */ +static void j38ms_next_request(struct j38ms_host *host) +{ + while (!memstick_next_req(host->msh, &host->req)) + if (!j38ms_execute_tpc(host)) + return; +} + + /* hardware reset */ static int j38ms_reset(struct j38ms_host *host) { @@ -747,7 +740,6 @@ static int j38ms_count_slots(struct pci_dev *pdev) if (256 != pci_resource_len(pdev, cnt)) break; - ++rc; } return rc; @@ -816,6 +808,7 @@ static void j38ms_free_host(struct memstick_host *msh) pci_free_consistent(host->chip->pdev, PAGE_SIZE, host->dma_bounce_page, host->dma_bus_address); + memstick_free_host(msh); } @@ -905,21 +898,26 @@ static void j38ms_remove(struct pci_dev *dev) host = memstick_priv(jm->hosts[cnt]); - jm->hosts[cnt]->request = j38ms_dummy_submit; - tasklet_kill(&host->notify); - writel(0, host->addr + INT_SIGNAL_ENABLE); - writel(0, host->addr + INT_STATUS_ENABLE); - mmiowb(); - dev_dbg(&jm->pdev->dev, "interrupts off\n"); + tasklet_kill(&host->tasklet); + spin_lock_irqsave(&host->lock, flags); + host->dead = true; + + j38ms_write_reg(host, INT_SIGNAL_ENABLE, 0); + j38ms_write_reg(host, INT_STATUS_ENABLE, 0); + + mmiowb(); + dbg(host, "interrupts off"); + if (host->req) { host->req->error = -ETIME; - j38ms_complete_tpc(jm->hosts[cnt], 1); + j38ms_complete_tpc(jm->hosts[cnt]); } + spin_unlock_irqrestore(&host->lock, flags); memstick_remove_host(jm->hosts[cnt]); - dev_dbg(&jm->pdev->dev, "host removed\n"); + dbg(host, "host removed"); j38ms_free_host(jm->hosts[cnt]); } diff --git a/drivers/memstick/host/jmb38x_ms.h b/drivers/memstick/host/jmb38x_ms.h index 5599803..5d7ad18 100644 --- a/drivers/memstick/host/jmb38x_ms.h +++ b/drivers/memstick/host/jmb38x_ms.h @@ -146,8 +146,9 @@ struct j38ms_host { struct j38ms *chip; struct memstick_host *msh; void __iomem *addr; + bool dead; spinlock_t lock; - struct tasklet_struct notify; + struct tasklet_struct tasklet; int id; char host_id[32]; int irq; @@ -196,3 +197,5 @@ enum { #define dbg(host, format, ...) __dbg(host, 1, format, ## __VA_ARGS__) #define dbg_v(host, format, ...) __dbg(host, 2, format, ## __VA_ARGS__) #define dbg_reg(host, format, ...) __dbg(host, 3, format, ## __VA_ARGS__) + +static void j38ms_next_request(struct j38ms_host *host); -- 1.7.1
| |