aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick/host
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2008-03-19 20:01:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-19 21:53:37 -0400
commitead70773608a5d97f81cb492f117d20b5e9f323e (patch)
treefa71036f83c49c3b7aee99c11d152ddeb2b3599e /drivers/memstick/host
parent9df130392fb642ecd5564163b574ce69ffda1afa (diff)
memstick: automatically retrieve "INT" value from command response
MemoryStick storage cards, when in parallel mode, send several meaningful bits of their "INT" register as part of command response. This data is stored by host and can be used to spare invocation of "GET_INT" TPC on each data page transferred between host and card. 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.c48
-rw-r--r--drivers/memstick/host/tifm_ms.c17
2 files changed, 37 insertions, 28 deletions
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 9a57504183c7..f91037d50422 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -57,8 +57,6 @@ struct jmb38x_ms_host {
57 unsigned long timeout_jiffies; 57 unsigned long timeout_jiffies;
58 struct timer_list timer; 58 struct timer_list timer;
59 struct memstick_request *req; 59 struct memstick_request *req;
60 unsigned char eject:1,
61 use_dma:1;
62 unsigned char cmd_flags; 60 unsigned char cmd_flags;
63 unsigned char io_pos; 61 unsigned char io_pos;
64 unsigned int io_word[2]; 62 unsigned int io_word[2];
@@ -95,9 +93,22 @@ struct jmb38x_ms {
95#define HOST_CONTROL_IF_PAR4 0x1 93#define HOST_CONTROL_IF_PAR4 0x1
96#define HOST_CONTROL_IF_PAR8 0x3 94#define HOST_CONTROL_IF_PAR8 0x3
97 95
96#define STATUS_BUSY 0x00080000
97#define STATUS_MS_DAT7 0x00040000
98#define STATUS_MS_DAT6 0x00020000
99#define STATUS_MS_DAT5 0x00010000
100#define STATUS_MS_DAT4 0x00008000
101#define STATUS_MS_DAT3 0x00004000
102#define STATUS_MS_DAT2 0x00002000
103#define STATUS_MS_DAT1 0x00001000
104#define STATUS_MS_DAT0 0x00000800
98#define STATUS_HAS_MEDIA 0x00000400 105#define STATUS_HAS_MEDIA 0x00000400
99#define STATUS_FIFO_EMPTY 0x00000200 106#define STATUS_FIFO_EMPTY 0x00000200
100#define STATUS_FIFO_FULL 0x00000100 107#define STATUS_FIFO_FULL 0x00000100
108#define STATUS_MS_CED 0x00000080
109#define STATUS_MS_ERR 0x00000040
110#define STATUS_MS_BRQ 0x00000020
111#define STATUS_MS_CNK 0x00000001
101 112
102#define INT_STATUS_TPC_ERR 0x00080000 113#define INT_STATUS_TPC_ERR 0x00080000
103#define INT_STATUS_CRC_ERR 0x00040000 114#define INT_STATUS_CRC_ERR 0x00040000
@@ -124,7 +135,7 @@ enum {
124 CMD_READY = 0x01, 135 CMD_READY = 0x01,
125 FIFO_READY = 0x02, 136 FIFO_READY = 0x02,
126 REG_DATA = 0x04, 137 REG_DATA = 0x04,
127 AUTO_GET_INT = 0x08 138 DMA_DATA = 0x08
128}; 139};
129 140
130static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host, 141static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host,
@@ -367,28 +378,27 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
367 cmd |= TPC_DIR; 378 cmd |= TPC_DIR;
368 if (host->req->need_card_int) 379 if (host->req->need_card_int)
369 cmd |= TPC_WAIT_INT; 380 cmd |= TPC_WAIT_INT;
370 if (host->req->get_int_reg)
371 cmd |= TPC_GET_INT;
372 381
373 data = host->req->data; 382 data = host->req->data;
374 383
375 host->use_dma = !no_dma; 384 if (!no_dma)
385 host->cmd_flags |= DMA_DATA;
376 386
377 if (host->req->long_data) { 387 if (host->req->long_data) {
378 data_len = host->req->sg.length; 388 data_len = host->req->sg.length;
379 } else { 389 } else {
380 data_len = host->req->data_len; 390 data_len = host->req->data_len;
381 host->use_dma = 0; 391 host->cmd_flags &= ~DMA_DATA;
382 } 392 }
383 393
384 if (data_len <= 8) { 394 if (data_len <= 8) {
385 cmd &= ~(TPC_DATA_SEL | 0xf); 395 cmd &= ~(TPC_DATA_SEL | 0xf);
386 host->cmd_flags |= REG_DATA; 396 host->cmd_flags |= REG_DATA;
387 cmd |= data_len & 0xf; 397 cmd |= data_len & 0xf;
388 host->use_dma = 0; 398 host->cmd_flags &= ~DMA_DATA;
389 } 399 }
390 400
391 if (host->use_dma) { 401 if (host->cmd_flags & DMA_DATA) {
392 if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1, 402 if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1,
393 host->req->data_dir == READ 403 host->req->data_dir == READ
394 ? PCI_DMA_FROMDEVICE 404 ? PCI_DMA_FROMDEVICE
@@ -451,13 +461,12 @@ static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
451 readl(host->addr + INT_STATUS)); 461 readl(host->addr + INT_STATUS));
452 dev_dbg(msh->cdev.dev, "c hstatus %08x\n", readl(host->addr + STATUS)); 462 dev_dbg(msh->cdev.dev, "c hstatus %08x\n", readl(host->addr + STATUS));
453 463
454 if (host->req->get_int_reg) { 464 host->req->int_reg = readl(host->addr + STATUS) & 0xff;
455 t_val = readl(host->addr + TPC_P0); 465
456 host->req->int_reg = (t_val & 0xff); 466 writel(0, host->addr + BLOCK);
457 } 467 writel(0, host->addr + DMA_CONTROL);
458 468
459 if (host->use_dma) { 469 if (host->cmd_flags & DMA_DATA) {
460 writel(0, host->addr + DMA_CONTROL);
461 pci_unmap_sg(host->chip->pdev, &host->req->sg, 1, 470 pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
462 host->req->data_dir == READ 471 host->req->data_dir == READ
463 ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); 472 ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
@@ -509,7 +518,7 @@ static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
509 else 518 else
510 host->req->error = -ETIME; 519 host->req->error = -ETIME;
511 } else { 520 } else {
512 if (host->use_dma) { 521 if (host->cmd_flags & DMA_DATA) {
513 if (irq_status & INT_STATUS_EOTRAN) 522 if (irq_status & INT_STATUS_EOTRAN)
514 host->cmd_flags |= FIFO_READY; 523 host->cmd_flags |= FIFO_READY;
515 } else { 524 } else {
@@ -775,13 +784,10 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
775 snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d", 784 snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d",
776 host->id); 785 host->id);
777 host->irq = jm->pdev->irq; 786 host->irq = jm->pdev->irq;
778 host->timeout_jiffies = msecs_to_jiffies(4000); 787 host->timeout_jiffies = msecs_to_jiffies(1000);
779 msh->request = jmb38x_ms_request; 788 msh->request = jmb38x_ms_request;
780 msh->set_param = jmb38x_ms_set_param; 789 msh->set_param = jmb38x_ms_set_param;
781 /* 790
782 msh->caps = MEMSTICK_CAP_AUTO_GET_INT | MEMSTICK_CAP_PAR4
783 | MEMSTICK_CAP_PAR8;
784 */
785 msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; 791 msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
786 792
787 setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh); 793 setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh);
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index 2b5bf52a8302..eb150dfb637f 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -340,11 +340,20 @@ static void tifm_ms_complete_cmd(struct tifm_ms *host)
340 340
341 del_timer(&host->timer); 341 del_timer(&host->timer);
342 342
343 if (host->use_dma) 343 host->req->int_reg = readl(sock->addr + SOCK_MS_STATUS) & 0xff;
344 host->req->int_reg = (host->req->int_reg & 1)
345 | ((host->req->int_reg << 4) & 0xe0);
346
347 writel(TIFM_FIFO_INT_SETALL,
348 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
349 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
350
351 if (host->use_dma) {
344 tifm_unmap_sg(sock, &host->req->sg, 1, 352 tifm_unmap_sg(sock, &host->req->sg, 1,
345 host->req->data_dir == READ 353 host->req->data_dir == READ
346 ? PCI_DMA_FROMDEVICE 354 ? PCI_DMA_FROMDEVICE
347 : PCI_DMA_TODEVICE); 355 : PCI_DMA_TODEVICE);
356 }
348 357
349 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), 358 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
350 sock->addr + SOCK_CONTROL); 359 sock->addr + SOCK_CONTROL);
@@ -424,12 +433,6 @@ static void tifm_ms_card_event(struct tifm_dev *sock)
424 else if (host_status & TIFM_MS_STAT_CRC) 433 else if (host_status & TIFM_MS_STAT_CRC)
425 host->req->error = -EILSEQ; 434 host->req->error = -EILSEQ;
426 435
427 if (host->req->error) {
428 writel(TIFM_FIFO_INT_SETALL,
429 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
430 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
431 }
432
433 if (host_status & TIFM_MS_STAT_RDY) 436 if (host_status & TIFM_MS_STAT_RDY)
434 host->cmd_flags |= CMD_READY; 437 host->cmd_flags |= CMD_READY;
435 438