aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/arcmsr/arcmsr_hba.c
diff options
context:
space:
mode:
authorNick Cheng <nick.cheng@areca.com.tw>2008-02-05 02:53:24 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-07 19:02:44 -0500
commit76d78300a6eb8b7f08e47703b7e68a659ffc2053 (patch)
tree8677873e725417a8b8eaede4d4a76e247ed15eaa /drivers/scsi/arcmsr/arcmsr_hba.c
parent63adcc5862cf95f29c8c07d59458f102700da100 (diff)
[SCSI] arcmsr: updates (1.20.00.15)
- add arcmsr_enable_eoi_mode()and readl(reg->iop2drv_doorbell_reg) in arcmsr_handle_hbb_isr() on adapter Type B in case of the doorbell interrupt clearance is cached - add conditional declaration for arcmsr_pci_error_detected() and arcmsr_pci_slot_reset - check if the sg list member number exceeds arcmsr default limit in arcmsr_build_ccb() - change the returned value type of arcmsr_build_ccb()from "void" to "int" returns FAILED in arcmsr_queue_command() - modify arcmsr_drain_donequeue() to ignore unknown command and let kernel process command timeout. This could handle IO request violating maximum segments, i.e. Linux XFS over DM-CRYPT. Thanks to Milan Broz's comments <mbroz@redhat.com> - fix the release of dma memory for type B in arcmsr_free_ccb_pool() - fix the arcmsr_polling_hbb_ccbdone() Signed-off-by: Nick Cheng <nick.cheng@areca.com.tw> Cc: Milan Broz <mbroz@redhat.com> Cc: <thenzl@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/arcmsr/arcmsr_hba.c')
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c87
1 files changed, 61 insertions, 26 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f4a202e8df26..4f9ff32cfed0 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -315,9 +315,6 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
315 (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); 315 (0x20 - ((unsigned long)dma_coherent_handle & 0x1F));
316 } 316 }
317 317
318 reg = (struct MessageUnit_B *)(dma_coherent +
319 ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock));
320
321 dma_addr = dma_coherent_handle; 318 dma_addr = dma_coherent_handle;
322 ccb_tmp = (struct CommandControlBlock *)dma_coherent; 319 ccb_tmp = (struct CommandControlBlock *)dma_coherent;
323 for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { 320 for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
@@ -371,8 +368,8 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
371 368
372out: 369out:
373 dma_free_coherent(&acb->pdev->dev, 370 dma_free_coherent(&acb->pdev->dev,
374 ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20, 371 (ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20 +
375 acb->dma_coherent, acb->dma_coherent_handle); 372 sizeof(struct MessageUnit_B)), acb->dma_coherent, acb->dma_coherent_handle);
376 return -ENOMEM; 373 return -ENOMEM;
377} 374}
378 375
@@ -509,6 +506,7 @@ static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
509 & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { 506 & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
510 writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN 507 writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN
511 , reg->iop2drv_doorbell_reg); 508 , reg->iop2drv_doorbell_reg);
509 writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell_reg);
512 return 0x00; 510 return 0x00;
513 } 511 }
514 msleep(10); 512 msleep(10);
@@ -748,6 +746,7 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, uint32_t fla
748 , ccb->startdone 746 , ccb->startdone
749 , atomic_read(&acb->ccboutstandingcount)); 747 , atomic_read(&acb->ccboutstandingcount));
750 } 748 }
749 else
751 arcmsr_report_ccb_state(acb, ccb, flag_ccb); 750 arcmsr_report_ccb_state(acb, ccb, flag_ccb);
752} 751}
753 752
@@ -886,7 +885,7 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \
886 } 885 }
887} 886}
888 887
889static void arcmsr_build_ccb(struct AdapterControlBlock *acb, 888static int arcmsr_build_ccb(struct AdapterControlBlock *acb,
890 struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd) 889 struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd)
891{ 890{
892 struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; 891 struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb;
@@ -906,6 +905,8 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
906 memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len); 905 memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len);
907 906
908 nseg = scsi_dma_map(pcmd); 907 nseg = scsi_dma_map(pcmd);
908 if (nseg > ARCMSR_MAX_SG_ENTRIES)
909 return FAILED;
909 BUG_ON(nseg < 0); 910 BUG_ON(nseg < 0);
910 911
911 if (nseg) { 912 if (nseg) {
@@ -946,6 +947,7 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
946 arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE; 947 arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
947 ccb->ccb_flags |= CCB_FLAG_WRITE; 948 ccb->ccb_flags |= CCB_FLAG_WRITE;
948 } 949 }
950 return SUCCESS;
949} 951}
950 952
951static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) 953static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb)
@@ -1036,18 +1038,22 @@ static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb)
1036 switch (acb->adapter_type) { 1038 switch (acb->adapter_type) {
1037 case ACB_ADAPTER_TYPE_A: { 1039 case ACB_ADAPTER_TYPE_A: {
1038 iounmap(acb->pmuA); 1040 iounmap(acb->pmuA);
1041 dma_free_coherent(&acb->pdev->dev,
1042 ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20,
1043 acb->dma_coherent,
1044 acb->dma_coherent_handle);
1039 break; 1045 break;
1040 } 1046 }
1041 case ACB_ADAPTER_TYPE_B: { 1047 case ACB_ADAPTER_TYPE_B: {
1042 struct MessageUnit_B *reg = acb->pmuB; 1048 struct MessageUnit_B *reg = acb->pmuB;
1043 iounmap(reg->drv2iop_doorbell_reg - ARCMSR_DRV2IOP_DOORBELL); 1049 iounmap(reg->drv2iop_doorbell_reg - ARCMSR_DRV2IOP_DOORBELL);
1044 iounmap(reg->ioctl_wbuffer_reg - ARCMSR_IOCTL_WBUFFER); 1050 iounmap(reg->ioctl_wbuffer_reg - ARCMSR_IOCTL_WBUFFER);
1051 dma_free_coherent(&acb->pdev->dev,
1052 (ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20 +
1053 sizeof(struct MessageUnit_B)), acb->dma_coherent, acb->dma_coherent_handle);
1045 } 1054 }
1046 } 1055 }
1047 dma_free_coherent(&acb->pdev->dev, 1056
1048 ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20,
1049 acb->dma_coherent,
1050 acb->dma_coherent_handle);
1051} 1057}
1052 1058
1053void arcmsr_iop_message_read(struct AdapterControlBlock *acb) 1059void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
@@ -1273,7 +1279,9 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb)
1273 return 1; 1279 return 1;
1274 1280
1275 writel(~outbound_doorbell, reg->iop2drv_doorbell_reg); 1281 writel(~outbound_doorbell, reg->iop2drv_doorbell_reg);
1276 1282 /*in case the last action of doorbell interrupt clearance is cached, this action can push HW to write down the clear bit*/
1283 readl(reg->iop2drv_doorbell_reg);
1284 writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell_reg);
1277 if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) { 1285 if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) {
1278 arcmsr_iop2drv_data_wrote_handle(acb); 1286 arcmsr_iop2drv_data_wrote_handle(acb);
1279 } 1287 }
@@ -1380,12 +1388,13 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
1380 1388
1381 case ARCMSR_MESSAGE_READ_RQBUFFER: { 1389 case ARCMSR_MESSAGE_READ_RQBUFFER: {
1382 unsigned long *ver_addr; 1390 unsigned long *ver_addr;
1383 dma_addr_t buf_handle;
1384 uint8_t *pQbuffer, *ptmpQbuffer; 1391 uint8_t *pQbuffer, *ptmpQbuffer;
1385 int32_t allxfer_len = 0; 1392 int32_t allxfer_len = 0;
1393 void *tmp;
1386 1394
1387 ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); 1395 tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
1388 if (!ver_addr) { 1396 ver_addr = (unsigned long *)tmp;
1397 if (!tmp) {
1389 retvalue = ARCMSR_MESSAGE_FAIL; 1398 retvalue = ARCMSR_MESSAGE_FAIL;
1390 goto message_out; 1399 goto message_out;
1391 } 1400 }
@@ -1421,18 +1430,19 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
1421 memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len); 1430 memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len);
1422 pcmdmessagefld->cmdmessage.Length = allxfer_len; 1431 pcmdmessagefld->cmdmessage.Length = allxfer_len;
1423 pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; 1432 pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
1424 pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); 1433 kfree(tmp);
1425 } 1434 }
1426 break; 1435 break;
1427 1436
1428 case ARCMSR_MESSAGE_WRITE_WQBUFFER: { 1437 case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
1429 unsigned long *ver_addr; 1438 unsigned long *ver_addr;
1430 dma_addr_t buf_handle;
1431 int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; 1439 int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
1432 uint8_t *pQbuffer, *ptmpuserbuffer; 1440 uint8_t *pQbuffer, *ptmpuserbuffer;
1441 void *tmp;
1433 1442
1434 ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); 1443 tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
1435 if (!ver_addr) { 1444 ver_addr = (unsigned long *)tmp;
1445 if (!tmp) {
1436 retvalue = ARCMSR_MESSAGE_FAIL; 1446 retvalue = ARCMSR_MESSAGE_FAIL;
1437 goto message_out; 1447 goto message_out;
1438 } 1448 }
@@ -1482,7 +1492,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
1482 retvalue = ARCMSR_MESSAGE_FAIL; 1492 retvalue = ARCMSR_MESSAGE_FAIL;
1483 } 1493 }
1484 } 1494 }
1485 pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); 1495 kfree(tmp);
1486 } 1496 }
1487 break; 1497 break;
1488 1498
@@ -1682,8 +1692,11 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
1682 ccb = arcmsr_get_freeccb(acb); 1692 ccb = arcmsr_get_freeccb(acb);
1683 if (!ccb) 1693 if (!ccb)
1684 return SCSI_MLQUEUE_HOST_BUSY; 1694 return SCSI_MLQUEUE_HOST_BUSY;
1685 1695 if ( arcmsr_build_ccb( acb, ccb, cmd ) == FAILED ) {
1686 arcmsr_build_ccb(acb, ccb, cmd); 1696 cmd->result = (DID_ERROR << 16) | (RESERVATION_CONFLICT << 1);
1697 cmd->scsi_done(cmd);
1698 return 0;
1699 }
1687 arcmsr_post_ccb(acb, ccb); 1700 arcmsr_post_ccb(acb, ccb);
1688 return 0; 1701 return 0;
1689} 1702}
@@ -1844,7 +1857,7 @@ static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
1844 } 1857 }
1845} 1858}
1846 1859
1847static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, \ 1860static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb,
1848 struct CommandControlBlock *poll_ccb) 1861 struct CommandControlBlock *poll_ccb)
1849{ 1862{
1850 struct MessageUnit_B *reg = acb->pmuB; 1863 struct MessageUnit_B *reg = acb->pmuB;
@@ -1878,7 +1891,7 @@ static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, \
1878 (acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/ 1891 (acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/
1879 poll_ccb_done = (ccb == poll_ccb) ? 1:0; 1892 poll_ccb_done = (ccb == poll_ccb) ? 1:0;
1880 if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { 1893 if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
1881 if (ccb->startdone == ARCMSR_CCB_ABORTED) { 1894 if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) {
1882 printk(KERN_NOTICE "arcmsr%d: \ 1895 printk(KERN_NOTICE "arcmsr%d: \
1883 scsi id = %d lun = %d ccb = '0x%p' poll command abort successfully \n" 1896 scsi id = %d lun = %d ccb = '0x%p' poll command abort successfully \n"
1884 ,acb->host->host_no 1897 ,acb->host->host_no
@@ -1901,7 +1914,7 @@ static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, \
1901 } /*drain reply FIFO*/ 1914 } /*drain reply FIFO*/
1902} 1915}
1903 1916
1904static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, \ 1917static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
1905 struct CommandControlBlock *poll_ccb) 1918 struct CommandControlBlock *poll_ccb)
1906{ 1919{
1907 switch (acb->adapter_type) { 1920 switch (acb->adapter_type) {
@@ -2026,6 +2039,7 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
2026 do { 2039 do {
2027 firmware_state = readl(reg->iop2drv_doorbell_reg); 2040 firmware_state = readl(reg->iop2drv_doorbell_reg);
2028 } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0); 2041 } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0);
2042 writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell_reg);
2029 } 2043 }
2030 break; 2044 break;
2031 } 2045 }
@@ -2090,19 +2104,39 @@ static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb)
2090 } 2104 }
2091} 2105}
2092 2106
2107static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
2108{
2109 switch (acb->adapter_type) {
2110 case ACB_ADAPTER_TYPE_A:
2111 return;
2112 case ACB_ADAPTER_TYPE_B:
2113 {
2114 struct MessageUnit_B *reg = acb->pmuB;
2115 writel(ARCMSR_MESSAGE_ACTIVE_EOI_MODE, reg->drv2iop_doorbell_reg);
2116 if(arcmsr_hbb_wait_msgint_ready(acb)) {
2117 printk(KERN_NOTICE "ARCMSR IOP enables EOI_MODE TIMEOUT");
2118 return;
2119 }
2120 }
2121 break;
2122 }
2123 return;
2124}
2125
2093static void arcmsr_iop_init(struct AdapterControlBlock *acb) 2126static void arcmsr_iop_init(struct AdapterControlBlock *acb)
2094{ 2127{
2095 uint32_t intmask_org; 2128 uint32_t intmask_org;
2096 2129
2097 arcmsr_wait_firmware_ready(acb);
2098 arcmsr_iop_confirm(acb);
2099 /* disable all outbound interrupt */ 2130 /* disable all outbound interrupt */
2100 intmask_org = arcmsr_disable_outbound_ints(acb); 2131 intmask_org = arcmsr_disable_outbound_ints(acb);
2132 arcmsr_wait_firmware_ready(acb);
2133 arcmsr_iop_confirm(acb);
2101 arcmsr_get_firmware_spec(acb); 2134 arcmsr_get_firmware_spec(acb);
2102 /*start background rebuild*/ 2135 /*start background rebuild*/
2103 arcmsr_start_adapter_bgrb(acb); 2136 arcmsr_start_adapter_bgrb(acb);
2104 /* empty doorbell Qbuffer if door bell ringed */ 2137 /* empty doorbell Qbuffer if door bell ringed */
2105 arcmsr_clear_doorbell_queue_buffer(acb); 2138 arcmsr_clear_doorbell_queue_buffer(acb);
2139 arcmsr_enable_eoi_mode(acb);
2106 /* enable outbound Post Queue,outbound doorbell Interrupt */ 2140 /* enable outbound Post Queue,outbound doorbell Interrupt */
2107 arcmsr_enable_outbound_ints(acb, intmask_org); 2141 arcmsr_enable_outbound_ints(acb, intmask_org);
2108 acb->acb_flags |= ACB_F_IOP_INITED; 2142 acb->acb_flags |= ACB_F_IOP_INITED;
@@ -2275,6 +2309,7 @@ static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev)
2275 arcmsr_start_adapter_bgrb(acb); 2309 arcmsr_start_adapter_bgrb(acb);
2276 /* empty doorbell Qbuffer if door bell ringed */ 2310 /* empty doorbell Qbuffer if door bell ringed */
2277 arcmsr_clear_doorbell_queue_buffer(acb); 2311 arcmsr_clear_doorbell_queue_buffer(acb);
2312 arcmsr_enable_eoi_mode(acb);
2278 /* enable outbound Post Queue,outbound doorbell Interrupt */ 2313 /* enable outbound Post Queue,outbound doorbell Interrupt */
2279 arcmsr_enable_outbound_ints(acb, intmask_org); 2314 arcmsr_enable_outbound_ints(acb, intmask_org);
2280 acb->acb_flags |= ACB_F_IOP_INITED; 2315 acb->acb_flags |= ACB_F_IOP_INITED;