aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2014-11-24 09:37:24 -0500
committerChristoph Hellwig <hch@lst.de>2014-11-24 10:10:24 -0500
commit3170866f8865809290f4b99e61a096ba39a01472 (patch)
treeab438dafb72fca138179a3e00232e23000912a09
parent9535fff3c5f9382b46f656c46a80bc190645dd32 (diff)
esp_scsi: use FIFO for command submission
Using DMA for command submission has the drawback that it might generate additional DMA completion interrupts after the command has been submitted to the device. Additionally the am53c974 has a design flaw causing it to generate spurious interrupts even though DMA completion interrupts are not enabled. This can be avoided by using the FIFO for command submission. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/esp_scsi.c46
-rw-r--r--drivers/scsi/esp_scsi.h1
2 files changed, 30 insertions, 17 deletions
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index 7ebf2c7d17a4..25cc6fa0535c 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -143,6 +143,24 @@ void scsi_esp_cmd(struct esp *esp, u8 val)
143} 143}
144EXPORT_SYMBOL(scsi_esp_cmd); 144EXPORT_SYMBOL(scsi_esp_cmd);
145 145
146static void esp_send_dma_cmd(struct esp *esp, int len, int max_len, int cmd)
147{
148 if (esp->flags & ESP_FLAG_USE_FIFO) {
149 int i;
150
151 scsi_esp_cmd(esp, ESP_CMD_FLUSH);
152 for (i = 0; i < len; i++)
153 esp_write8(esp->command_block[i], ESP_FDATA);
154 scsi_esp_cmd(esp, cmd);
155 } else {
156 if (esp->rev == FASHME)
157 scsi_esp_cmd(esp, ESP_CMD_FLUSH);
158 cmd |= ESP_CMD_DMA;
159 esp->ops->send_dma_cmd(esp, esp->command_block_dma,
160 len, max_len, 0, cmd);
161 }
162}
163
146static void esp_event(struct esp *esp, u8 val) 164static void esp_event(struct esp *esp, u8 val)
147{ 165{
148 struct esp_event_ent *p; 166 struct esp_event_ent *p;
@@ -650,10 +668,7 @@ static void esp_autosense(struct esp *esp, struct esp_cmd_entry *ent)
650 668
651 val = (p - esp->command_block); 669 val = (p - esp->command_block);
652 670
653 if (esp->rev == FASHME) 671 esp_send_dma_cmd(esp, val, 16, ESP_CMD_SELA);
654 scsi_esp_cmd(esp, ESP_CMD_FLUSH);
655 esp->ops->send_dma_cmd(esp, esp->command_block_dma,
656 val, 16, 0, ESP_CMD_DMA | ESP_CMD_SELA);
657} 672}
658 673
659static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp) 674static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp)
@@ -789,12 +804,12 @@ build_identify:
789 } 804 }
790 805
791 if (!(esp->flags & ESP_FLAG_DOING_SLOWCMD)) { 806 if (!(esp->flags & ESP_FLAG_DOING_SLOWCMD)) {
792 start_cmd = ESP_CMD_DMA | ESP_CMD_SELA; 807 start_cmd = ESP_CMD_SELA;
793 if (ent->tag[0]) { 808 if (ent->tag[0]) {
794 *p++ = ent->tag[0]; 809 *p++ = ent->tag[0];
795 *p++ = ent->tag[1]; 810 *p++ = ent->tag[1];
796 811
797 start_cmd = ESP_CMD_DMA | ESP_CMD_SA3; 812 start_cmd = ESP_CMD_SA3;
798 } 813 }
799 814
800 for (i = 0; i < cmd->cmd_len; i++) 815 for (i = 0; i < cmd->cmd_len; i++)
@@ -814,7 +829,7 @@ build_identify:
814 esp->msg_out_len += 2; 829 esp->msg_out_len += 2;
815 } 830 }
816 831
817 start_cmd = ESP_CMD_DMA | ESP_CMD_SELAS; 832 start_cmd = ESP_CMD_SELAS;
818 esp->select_state = ESP_SELECT_MSGOUT; 833 esp->select_state = ESP_SELECT_MSGOUT;
819 } 834 }
820 val = tgt; 835 val = tgt;
@@ -834,10 +849,7 @@ build_identify:
834 printk("]\n"); 849 printk("]\n");
835 } 850 }
836 851
837 if (esp->rev == FASHME) 852 esp_send_dma_cmd(esp, val, 16, start_cmd);
838 scsi_esp_cmd(esp, ESP_CMD_FLUSH);
839 esp->ops->send_dma_cmd(esp, esp->command_block_dma,
840 val, 16, 0, start_cmd);
841} 853}
842 854
843static struct esp_cmd_entry *esp_get_ent(struct esp *esp) 855static struct esp_cmd_entry *esp_get_ent(struct esp *esp)
@@ -1646,7 +1658,7 @@ static int esp_msgin_process(struct esp *esp)
1646 1658
1647static int esp_process_event(struct esp *esp) 1659static int esp_process_event(struct esp *esp)
1648{ 1660{
1649 int write; 1661 int write, i;
1650 1662
1651again: 1663again:
1652 write = 0; 1664 write = 0;
@@ -1872,6 +1884,10 @@ again:
1872 if (esp->msg_out_len == 1) { 1884 if (esp->msg_out_len == 1) {
1873 esp_write8(esp->msg_out[0], ESP_FDATA); 1885 esp_write8(esp->msg_out[0], ESP_FDATA);
1874 scsi_esp_cmd(esp, ESP_CMD_TI); 1886 scsi_esp_cmd(esp, ESP_CMD_TI);
1887 } else if (esp->flags & ESP_FLAG_USE_FIFO) {
1888 for (i = 0; i < esp->msg_out_len; i++)
1889 esp_write8(esp->msg_out[i], ESP_FDATA);
1890 scsi_esp_cmd(esp, ESP_CMD_TI);
1875 } else { 1891 } else {
1876 /* Use DMA. */ 1892 /* Use DMA. */
1877 memcpy(esp->command_block, 1893 memcpy(esp->command_block,
@@ -1949,11 +1965,7 @@ again:
1949 case ESP_EVENT_CMD_START: 1965 case ESP_EVENT_CMD_START:
1950 memcpy(esp->command_block, esp->cmd_bytes_ptr, 1966 memcpy(esp->command_block, esp->cmd_bytes_ptr,
1951 esp->cmd_bytes_left); 1967 esp->cmd_bytes_left);
1952 if (esp->rev == FASHME) 1968 esp_send_dma_cmd(esp, esp->cmd_bytes_left, 16, ESP_CMD_TI);
1953 scsi_esp_cmd(esp, ESP_CMD_FLUSH);
1954 esp->ops->send_dma_cmd(esp, esp->command_block_dma,
1955 esp->cmd_bytes_left, 16, 0,
1956 ESP_CMD_DMA | ESP_CMD_TI);
1957 esp_event(esp, ESP_EVENT_CMD_DONE); 1969 esp_event(esp, ESP_EVENT_CMD_DONE);
1958 esp->flags |= ESP_FLAG_QUICKIRQ_CHECK; 1970 esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
1959 break; 1971 break;
diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h
index 975d2934d42a..27dcaf84e717 100644
--- a/drivers/scsi/esp_scsi.h
+++ b/drivers/scsi/esp_scsi.h
@@ -478,6 +478,7 @@ struct esp {
478#define ESP_FLAG_WIDE_CAPABLE 0x00000008 478#define ESP_FLAG_WIDE_CAPABLE 0x00000008
479#define ESP_FLAG_QUICKIRQ_CHECK 0x00000010 479#define ESP_FLAG_QUICKIRQ_CHECK 0x00000010
480#define ESP_FLAG_DISABLE_SYNC 0x00000020 480#define ESP_FLAG_DISABLE_SYNC 0x00000020
481#define ESP_FLAG_USE_FIFO 0x00000040
481 482
482 u8 select_state; 483 u8 select_state;
483#define ESP_SELECT_NONE 0x00 /* Not selecting */ 484#define ESP_SELECT_NONE 0x00 /* Not selecting */