diff options
| -rw-r--r-- | Documentation/scsi/ChangeLog.arcmsr | 41 | ||||
| -rw-r--r-- | drivers/scsi/arcmsr/arcmsr.h | 4 | ||||
| -rw-r--r-- | drivers/scsi/arcmsr/arcmsr_hba.c | 87 |
3 files changed, 105 insertions, 27 deletions
diff --git a/Documentation/scsi/ChangeLog.arcmsr b/Documentation/scsi/ChangeLog.arcmsr index cd8403a33ee6..de2bcacfa870 100644 --- a/Documentation/scsi/ChangeLog.arcmsr +++ b/Documentation/scsi/ChangeLog.arcmsr | |||
| @@ -68,4 +68,45 @@ | |||
| 68 | ** 2. modify the arcmsr_pci_slot_reset function | 68 | ** 2. modify the arcmsr_pci_slot_reset function |
| 69 | ** 3. modify the arcmsr_pci_ers_disconnect_forepart function | 69 | ** 3. modify the arcmsr_pci_ers_disconnect_forepart function |
| 70 | ** 4. modify the arcmsr_pci_ers_need_reset_forepart function | 70 | ** 4. modify the arcmsr_pci_ers_need_reset_forepart function |
| 71 | ** 1.20.00.15 09/27/2007 Erich Chen & Nick Cheng | ||
| 72 | ** 1. add arcmsr_enable_eoi_mode() on adapter Type B | ||
| 73 | ** 2. add readl(reg->iop2drv_doorbell_reg) in arcmsr_handle_hbb_isr() | ||
| 74 | ** in case of the doorbell interrupt clearance is cached | ||
| 75 | ** 1.20.00.15 10/01/2007 Erich Chen & Nick Cheng | ||
| 76 | ** 1. modify acb->devstate[i][j] | ||
| 77 | ** as ARECA_RAID_GOOD instead of | ||
| 78 | ** ARECA_RAID_GONE in arcmsr_alloc_ccb_pool | ||
| 79 | ** 1.20.00.15 11/06/2007 Erich Chen & Nick Cheng | ||
| 80 | ** 1. add conditional declaration for | ||
| 81 | ** arcmsr_pci_error_detected() and | ||
| 82 | ** arcmsr_pci_slot_reset | ||
| 83 | ** 1.20.00.15 11/23/2007 Erich Chen & Nick Cheng | ||
| 84 | ** 1.check if the sg list member number | ||
| 85 | ** exceeds arcmsr default limit in arcmsr_build_ccb() | ||
| 86 | ** 2.change the returned value type of arcmsr_build_ccb() | ||
| 87 | ** from "void" to "int" | ||
| 88 | ** 3.add the conditional check if arcmsr_build_ccb() | ||
| 89 | ** returns FAILED | ||
| 90 | ** 1.20.00.15 12/04/2007 Erich Chen & Nick Cheng | ||
| 91 | ** 1. modify arcmsr_drain_donequeue() to ignore unknown | ||
| 92 | ** command and let kernel process command timeout. | ||
| 93 | ** This could handle IO request violating max. segments | ||
| 94 | ** while Linux XFS over DM-CRYPT. | ||
| 95 | ** Thanks to Milan Broz's comments <mbroz@redhat.com> | ||
| 96 | ** 1.20.00.15 12/24/2007 Erich Chen & Nick Cheng | ||
| 97 | ** 1.fix the portability problems | ||
| 98 | ** 2.fix type B where we should _not_ iounmap() acb->pmu; | ||
| 99 | ** it's not ioremapped. | ||
| 100 | ** 3.add return -ENOMEM if ioremap() fails | ||
| 101 | ** 4.transfer IS_SG64_ADDR w/ cpu_to_le32() | ||
| 102 | ** in arcmsr_build_ccb | ||
| 103 | ** 5. modify acb->devstate[i][j] as ARECA_RAID_GONE instead of | ||
| 104 | ** ARECA_RAID_GOOD in arcmsr_alloc_ccb_pool() | ||
| 105 | ** 6.fix arcmsr_cdb->Context as (unsigned long)arcmsr_cdb | ||
| 106 | ** 7.add the checking state of | ||
| 107 | ** (outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT) == 0 | ||
| 108 | ** in arcmsr_handle_hba_isr | ||
| 109 | ** 8.replace pci_alloc_consistent()/pci_free_consistent() with kmalloc()/kfree() in arcmsr_iop_message_xfer() | ||
| 110 | ** 9. fix the release of dma memory for type B in arcmsr_free_ccb_pool() | ||
| 111 | ** 10.fix the arcmsr_polling_hbb_ccbdone() | ||
| 71 | ************************************************************************** | 112 | ************************************************************************** |
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index a67e29f83ae5..57786502e3ec 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h | |||
| @@ -48,7 +48,7 @@ struct class_device_attribute; | |||
| 48 | /*The limit of outstanding scsi command that firmware can handle*/ | 48 | /*The limit of outstanding scsi command that firmware can handle*/ |
| 49 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 | 49 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 |
| 50 | #define ARCMSR_MAX_FREECCB_NUM 320 | 50 | #define ARCMSR_MAX_FREECCB_NUM 320 |
| 51 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007/08/30" | 51 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007/12/24" |
| 52 | #define ARCMSR_SCSI_INITIATOR_ID 255 | 52 | #define ARCMSR_SCSI_INITIATOR_ID 255 |
| 53 | #define ARCMSR_MAX_XFER_SECTORS 512 | 53 | #define ARCMSR_MAX_XFER_SECTORS 512 |
| 54 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 | 54 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 |
| @@ -248,6 +248,7 @@ struct FIRMWARE_INFO | |||
| 248 | #define ARCMSR_MESSAGE_START_BGRB 0x00060008 | 248 | #define ARCMSR_MESSAGE_START_BGRB 0x00060008 |
| 249 | #define ARCMSR_MESSAGE_START_DRIVER_MODE 0x000E0008 | 249 | #define ARCMSR_MESSAGE_START_DRIVER_MODE 0x000E0008 |
| 250 | #define ARCMSR_MESSAGE_SET_POST_WINDOW 0x000F0008 | 250 | #define ARCMSR_MESSAGE_SET_POST_WINDOW 0x000F0008 |
| 251 | #define ARCMSR_MESSAGE_ACTIVE_EOI_MODE 0x00100008 | ||
| 251 | /* ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK */ | 252 | /* ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK */ |
| 252 | #define ARCMSR_MESSAGE_FIRMWARE_OK 0x80000000 | 253 | #define ARCMSR_MESSAGE_FIRMWARE_OK 0x80000000 |
| 253 | /* ioctl transfer */ | 254 | /* ioctl transfer */ |
| @@ -256,6 +257,7 @@ struct FIRMWARE_INFO | |||
| 256 | #define ARCMSR_DRV2IOP_DATA_READ_OK 0x00000002 | 257 | #define ARCMSR_DRV2IOP_DATA_READ_OK 0x00000002 |
| 257 | #define ARCMSR_DRV2IOP_CDB_POSTED 0x00000004 | 258 | #define ARCMSR_DRV2IOP_CDB_POSTED 0x00000004 |
| 258 | #define ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED 0x00000008 | 259 | #define ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED 0x00000008 |
| 260 | #define ARCMSR_DRV2IOP_END_OF_INTERRUPT 0x00000010 | ||
| 259 | 261 | ||
| 260 | /* data tunnel buffer between user space program and its firmware */ | 262 | /* data tunnel buffer between user space program and its firmware */ |
| 261 | /* user space data to iop 128bytes */ | 263 | /* user space data to iop 128bytes */ |
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 | ||
| 372 | out: | 369 | out: |
| 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 | ||
| 889 | static void arcmsr_build_ccb(struct AdapterControlBlock *acb, | 888 | static 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 | ||
| 951 | static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) | 953 | static 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 | ||
| 1053 | void arcmsr_iop_message_read(struct AdapterControlBlock *acb) | 1059 | void 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 | ||
| 1847 | static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, \ | 1860 | static 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 | ||
| 1904 | static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, \ | 1917 | static 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 | ||
| 2107 | static 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 | |||
| 2093 | static void arcmsr_iop_init(struct AdapterControlBlock *acb) | 2126 | static 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; |
