aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick
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
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')
-rw-r--r--drivers/memstick/core/memstick.c9
-rw-r--r--drivers/memstick/core/mspro_block.c15
-rw-r--r--drivers/memstick/host/jmb38x_ms.c48
-rw-r--r--drivers/memstick/host/tifm_ms.c17
4 files changed, 49 insertions, 40 deletions
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index de80dba12f9b..946e3d3506ac 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -276,8 +276,6 @@ void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
276 mrq->need_card_int = 1; 276 mrq->need_card_int = 1;
277 else 277 else
278 mrq->need_card_int = 0; 278 mrq->need_card_int = 0;
279
280 mrq->get_int_reg = 0;
281} 279}
282EXPORT_SYMBOL(memstick_init_req_sg); 280EXPORT_SYMBOL(memstick_init_req_sg);
283 281
@@ -311,8 +309,6 @@ void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
311 mrq->need_card_int = 1; 309 mrq->need_card_int = 1;
312 else 310 else
313 mrq->need_card_int = 0; 311 mrq->need_card_int = 0;
314
315 mrq->get_int_reg = 0;
316} 312}
317EXPORT_SYMBOL(memstick_init_req); 313EXPORT_SYMBOL(memstick_init_req);
318 314
@@ -342,6 +338,7 @@ static int h_memstick_read_dev_id(struct memstick_dev *card,
342 card->id.class = id_reg.class; 338 card->id.class = id_reg.class;
343 } 339 }
344 complete(&card->mrq_complete); 340 complete(&card->mrq_complete);
341 dev_dbg(&card->dev, "if_mode = %02x\n", id_reg.if_mode);
345 return -EAGAIN; 342 return -EAGAIN;
346 } 343 }
347} 344}
@@ -422,7 +419,6 @@ static void memstick_power_on(struct memstick_host *host)
422{ 419{
423 host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); 420 host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON);
424 host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); 421 host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL);
425 msleep(1);
426} 422}
427 423
428static void memstick_check(struct work_struct *work) 424static void memstick_check(struct work_struct *work)
@@ -579,7 +575,8 @@ EXPORT_SYMBOL(memstick_suspend_host);
579void memstick_resume_host(struct memstick_host *host) 575void memstick_resume_host(struct memstick_host *host)
580{ 576{
581 mutex_lock(&host->lock); 577 mutex_lock(&host->lock);
582 host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); 578 if (host->card)
579 memstick_power_on(host);
583 mutex_unlock(&host->lock); 580 mutex_unlock(&host->lock);
584 memstick_detect_change(host); 581 memstick_detect_change(host);
585} 582}
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 1d637e4561d3..e5356f97d076 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -133,6 +133,7 @@ struct mspro_devinfo {
133struct mspro_block_data { 133struct mspro_block_data {
134 struct memstick_dev *card; 134 struct memstick_dev *card;
135 unsigned int usage_count; 135 unsigned int usage_count;
136 unsigned int caps;
136 struct gendisk *disk; 137 struct gendisk *disk;
137 struct request_queue *queue; 138 struct request_queue *queue;
138 spinlock_t q_lock; 139 spinlock_t q_lock;
@@ -577,7 +578,6 @@ static int h_mspro_block_wait_for_ced(struct memstick_dev *card,
577static int h_mspro_block_transfer_data(struct memstick_dev *card, 578static int h_mspro_block_transfer_data(struct memstick_dev *card,
578 struct memstick_request **mrq) 579 struct memstick_request **mrq)
579{ 580{
580 struct memstick_host *host = card->host;
581 struct mspro_block_data *msb = memstick_get_drvdata(card); 581 struct mspro_block_data *msb = memstick_get_drvdata(card);
582 unsigned char t_val = 0; 582 unsigned char t_val = 0;
583 struct scatterlist t_sg = { 0 }; 583 struct scatterlist t_sg = { 0 };
@@ -591,12 +591,12 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card,
591 switch ((*mrq)->tpc) { 591 switch ((*mrq)->tpc) {
592 case MS_TPC_WRITE_REG: 592 case MS_TPC_WRITE_REG:
593 memstick_init_req(*mrq, MS_TPC_SET_CMD, &msb->transfer_cmd, 1); 593 memstick_init_req(*mrq, MS_TPC_SET_CMD, &msb->transfer_cmd, 1);
594 (*mrq)->get_int_reg = 1; 594 (*mrq)->need_card_int = 1;
595 return 0; 595 return 0;
596 case MS_TPC_SET_CMD: 596 case MS_TPC_SET_CMD:
597 t_val = (*mrq)->int_reg; 597 t_val = (*mrq)->int_reg;
598 memstick_init_req(*mrq, MS_TPC_GET_INT, NULL, 1); 598 memstick_init_req(*mrq, MS_TPC_GET_INT, NULL, 1);
599 if (host->caps & MEMSTICK_CAP_AUTO_GET_INT) 599 if (msb->caps & MEMSTICK_CAP_AUTO_GET_INT)
600 goto has_int_reg; 600 goto has_int_reg;
601 return 0; 601 return 0;
602 case MS_TPC_GET_INT: 602 case MS_TPC_GET_INT:
@@ -646,12 +646,12 @@ has_int_reg:
646 ? MS_TPC_READ_LONG_DATA 646 ? MS_TPC_READ_LONG_DATA
647 : MS_TPC_WRITE_LONG_DATA, 647 : MS_TPC_WRITE_LONG_DATA,
648 &t_sg); 648 &t_sg);
649 (*mrq)->get_int_reg = 1; 649 (*mrq)->need_card_int = 1;
650 return 0; 650 return 0;
651 case MS_TPC_READ_LONG_DATA: 651 case MS_TPC_READ_LONG_DATA:
652 case MS_TPC_WRITE_LONG_DATA: 652 case MS_TPC_WRITE_LONG_DATA:
653 msb->current_page++; 653 msb->current_page++;
654 if (host->caps & MEMSTICK_CAP_AUTO_GET_INT) { 654 if (msb->caps & MEMSTICK_CAP_AUTO_GET_INT) {
655 t_val = (*mrq)->int_reg; 655 t_val = (*mrq)->int_reg;
656 goto has_int_reg; 656 goto has_int_reg;
657 } else { 657 } else {
@@ -1052,7 +1052,8 @@ static int mspro_block_init_card(struct memstick_dev *card)
1052 if (memstick_set_rw_addr(card)) 1052 if (memstick_set_rw_addr(card))
1053 return -EIO; 1053 return -EIO;
1054 1054
1055 if (host->caps & MEMSTICK_CAP_PAR4) { 1055 msb->caps = host->caps;
1056 if (msb->caps & MEMSTICK_CAP_PAR4) {
1056 if (mspro_block_switch_to_parallel(card)) 1057 if (mspro_block_switch_to_parallel(card))
1057 printk(KERN_WARNING "%s: could not switch to " 1058 printk(KERN_WARNING "%s: could not switch to "
1058 "parallel interface\n", card->dev.bus_id); 1059 "parallel interface\n", card->dev.bus_id);
@@ -1062,6 +1063,8 @@ static int mspro_block_init_card(struct memstick_dev *card)
1062 if (rc) 1063 if (rc)
1063 return rc; 1064 return rc;
1064 dev_dbg(&card->dev, "card activated\n"); 1065 dev_dbg(&card->dev, "card activated\n");
1066 if (msb->system != MEMSTICK_SYS_SERIAL)
1067 msb->caps |= MEMSTICK_CAP_AUTO_GET_INT;
1065 1068
1066 card->next_request = h_mspro_block_req_init; 1069 card->next_request = h_mspro_block_req_init;
1067 msb->mrq_handler = h_mspro_block_get_ro; 1070 msb->mrq_handler = h_mspro_block_get_ro;
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