diff options
Diffstat (limited to 'drivers/scsi/tmscsim.c')
-rw-r--r-- | drivers/scsi/tmscsim.c | 85 |
1 files changed, 33 insertions, 52 deletions
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index e7b85e832eb5..14cba1ca38b3 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c | |||
@@ -457,28 +457,21 @@ static int dc390_pci_map (struct dc390_srb* pSRB) | |||
457 | error = 1; | 457 | error = 1; |
458 | DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle)); | 458 | DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle)); |
459 | /* Map SG list */ | 459 | /* Map SG list */ |
460 | } else if (pcmd->use_sg) { | 460 | } else if (scsi_sg_count(pcmd)) { |
461 | pSRB->pSegmentList = (struct scatterlist *) pcmd->request_buffer; | 461 | int nseg; |
462 | pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, pcmd->use_sg, | 462 | |
463 | pcmd->sc_data_direction); | 463 | nseg = scsi_dma_map(pcmd); |
464 | |||
465 | pSRB->pSegmentList = scsi_sglist(pcmd); | ||
466 | pSRB->SGcount = nseg; | ||
467 | |||
464 | /* TODO: error handling */ | 468 | /* TODO: error handling */ |
465 | if (!pSRB->SGcount) | 469 | if (nseg < 0) |
466 | error = 1; | 470 | error = 1; |
467 | DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\ | 471 | DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\ |
468 | __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg)); | 472 | __FUNCTION__, scsi_sglist(pcmd), nseg, scsi_sg_count(pcmd))); |
469 | /* Map single segment */ | 473 | /* Map single segment */ |
470 | } else if (pcmd->request_buffer && pcmd->request_bufflen) { | 474 | } else |
471 | pSRB->pSegmentList = dc390_sg_build_single(&pSRB->Segmentx, pcmd->request_buffer, pcmd->request_bufflen); | ||
472 | pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, 1, | ||
473 | pcmd->sc_data_direction); | ||
474 | cmdp->saved_dma_handle = sg_dma_address(pSRB->pSegmentList); | ||
475 | |||
476 | /* TODO: error handling */ | ||
477 | if (pSRB->SGcount != 1) | ||
478 | error = 1; | ||
479 | DEBUG1(printk("%s(): Mapped request buffer %p at %x\n", __FUNCTION__, pcmd->request_buffer, cmdp->saved_dma_handle)); | ||
480 | /* No mapping !? */ | ||
481 | } else | ||
482 | pSRB->SGcount = 0; | 475 | pSRB->SGcount = 0; |
483 | 476 | ||
484 | return error; | 477 | return error; |
@@ -494,12 +487,10 @@ static void dc390_pci_unmap (struct dc390_srb* pSRB) | |||
494 | if (pSRB->SRBFlag) { | 487 | if (pSRB->SRBFlag) { |
495 | pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE); | 488 | pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE); |
496 | DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle)); | 489 | DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle)); |
497 | } else if (pcmd->use_sg) { | 490 | } else { |
498 | pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, pcmd->sc_data_direction); | 491 | scsi_dma_unmap(pcmd); |
499 | DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", __FUNCTION__, pcmd->request_buffer, pcmd->use_sg)); | 492 | DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", |
500 | } else if (pcmd->request_buffer && pcmd->request_bufflen) { | 493 | __FUNCTION__, scsi_sglist(pcmd), scsi_sg_count(pcmd))); |
501 | pci_unmap_sg(pdev, &pSRB->Segmentx, 1, pcmd->sc_data_direction); | ||
502 | DEBUG1(printk("%s(): Unmapped request buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle)); | ||
503 | } | 494 | } |
504 | } | 495 | } |
505 | 496 | ||
@@ -1153,9 +1144,9 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) | |||
1153 | struct scatterlist *psgl; | 1144 | struct scatterlist *psgl; |
1154 | pSRB->TotalXferredLen = 0; | 1145 | pSRB->TotalXferredLen = 0; |
1155 | pSRB->SGIndex = 0; | 1146 | pSRB->SGIndex = 0; |
1156 | if (pcmd->use_sg) { | 1147 | if (scsi_sg_count(pcmd)) { |
1157 | size_t saved; | 1148 | size_t saved; |
1158 | pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer; | 1149 | pSRB->pSegmentList = scsi_sglist(pcmd); |
1159 | psgl = pSRB->pSegmentList; | 1150 | psgl = pSRB->pSegmentList; |
1160 | //dc390_pci_sync(pSRB); | 1151 | //dc390_pci_sync(pSRB); |
1161 | 1152 | ||
@@ -1179,12 +1170,6 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) | |||
1179 | printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", | 1170 | printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", |
1180 | pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr); | 1171 | pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr); |
1181 | 1172 | ||
1182 | } else if(pcmd->request_buffer) { | ||
1183 | //dc390_pci_sync(pSRB); | ||
1184 | |||
1185 | sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen - pSRB->Saved_Ptr; | ||
1186 | pSRB->SGcount = 1; | ||
1187 | pSRB->pSegmentList = (struct scatterlist *) &pSRB->Segmentx; | ||
1188 | } else { | 1173 | } else { |
1189 | pSRB->SGcount = 0; | 1174 | pSRB->SGcount = 0; |
1190 | printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n"); | 1175 | printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n"); |
@@ -1579,7 +1564,8 @@ dc390_Disconnect( struct dc390_acb* pACB ) | |||
1579 | if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) || | 1564 | if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) || |
1580 | !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) ) | 1565 | !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) ) |
1581 | { /* Selection time out */ | 1566 | { /* Selection time out */ |
1582 | pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT; | 1567 | pSRB->AdaptStatus = H_SEL_TIMEOUT; |
1568 | pSRB->TargetStatus = 0; | ||
1583 | goto disc1; | 1569 | goto disc1; |
1584 | } | 1570 | } |
1585 | else if (!(pSRB->SRBState & SRB_DISCONNECT) && (pSRB->SRBState & SRB_COMPLETED)) | 1571 | else if (!(pSRB->SRBState & SRB_DISCONNECT) && (pSRB->SRBState & SRB_COMPLETED)) |
@@ -1612,7 +1598,7 @@ dc390_Reselect( struct dc390_acb* pACB ) | |||
1612 | if( !( pACB->scan_devices ) ) | 1598 | if( !( pACB->scan_devices ) ) |
1613 | { | 1599 | { |
1614 | struct scsi_cmnd *pcmd = pSRB->pcmd; | 1600 | struct scsi_cmnd *pcmd = pSRB->pcmd; |
1615 | pcmd->resid = pcmd->request_bufflen; | 1601 | scsi_set_resid(pcmd, scsi_bufflen(pcmd)); |
1616 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); | 1602 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); |
1617 | dc390_Going_remove(pDCB, pSRB); | 1603 | dc390_Going_remove(pDCB, pSRB); |
1618 | dc390_Free_insert(pACB, pSRB); | 1604 | dc390_Free_insert(pACB, pSRB); |
@@ -1695,7 +1681,6 @@ dc390_RequestSense(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_ | |||
1695 | pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN)); | 1681 | pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN)); |
1696 | 1682 | ||
1697 | pSRB->SRBFlag |= AUTO_REQSENSE; | 1683 | pSRB->SRBFlag |= AUTO_REQSENSE; |
1698 | pSRB->SavedSGCount = pcmd->use_sg; | ||
1699 | pSRB->SavedTotXLen = pSRB->TotalXferredLen; | 1684 | pSRB->SavedTotXLen = pSRB->TotalXferredLen; |
1700 | pSRB->AdaptStatus = 0; | 1685 | pSRB->AdaptStatus = 0; |
1701 | pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */ | 1686 | pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */ |
@@ -1728,22 +1713,21 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1728 | { /* Last command was a Request Sense */ | 1713 | { /* Last command was a Request Sense */ |
1729 | pSRB->SRBFlag &= ~AUTO_REQSENSE; | 1714 | pSRB->SRBFlag &= ~AUTO_REQSENSE; |
1730 | pSRB->AdaptStatus = 0; | 1715 | pSRB->AdaptStatus = 0; |
1731 | pSRB->TargetStatus = CHECK_CONDITION << 1; | 1716 | pSRB->TargetStatus = SAM_STAT_CHECK_CONDITION; |
1732 | 1717 | ||
1733 | //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status); | 1718 | //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status); |
1734 | if (status == (CHECK_CONDITION << 1)) | 1719 | if (status == SAM_STAT_CHECK_CONDITION) |
1735 | pcmd->result = MK_RES_LNX(0, DID_BAD_TARGET, 0, /*CHECK_CONDITION*/0); | 1720 | pcmd->result = MK_RES_LNX(0, DID_BAD_TARGET, 0, /*CHECK_CONDITION*/0); |
1736 | else /* Retry */ | 1721 | else /* Retry */ |
1737 | { | 1722 | { |
1738 | if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */) | 1723 | if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */) |
1739 | { | 1724 | { |
1740 | /* Don't retry on TEST_UNIT_READY */ | 1725 | /* Don't retry on TEST_UNIT_READY */ |
1741 | pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION); | 1726 | pcmd->result = MK_RES_LNX(DRIVER_SENSE, DID_OK, 0, SAM_STAT_CHECK_CONDITION); |
1742 | REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\ | 1727 | REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\ |
1743 | (u32) pcmd->result, (u32) pSRB->TotalXferredLen)); | 1728 | (u32) pcmd->result, (u32) pSRB->TotalXferredLen)); |
1744 | } else { | 1729 | } else { |
1745 | SET_RES_DRV(pcmd->result, DRIVER_SENSE); | 1730 | SET_RES_DRV(pcmd->result, DRIVER_SENSE); |
1746 | pcmd->use_sg = pSRB->SavedSGCount; | ||
1747 | //pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8); | 1731 | //pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8); |
1748 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); | 1732 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); |
1749 | pSRB->TotalXferredLen = 0; | 1733 | pSRB->TotalXferredLen = 0; |
@@ -1754,7 +1738,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1754 | } | 1738 | } |
1755 | if( status ) | 1739 | if( status ) |
1756 | { | 1740 | { |
1757 | if( status_byte(status) == CHECK_CONDITION ) | 1741 | if (status == SAM_STAT_CHECK_CONDITION) |
1758 | { | 1742 | { |
1759 | if (dc390_RequestSense(pACB, pDCB, pSRB)) { | 1743 | if (dc390_RequestSense(pACB, pDCB, pSRB)) { |
1760 | SET_RES_DID(pcmd->result, DID_ERROR); | 1744 | SET_RES_DID(pcmd->result, DID_ERROR); |
@@ -1762,22 +1746,14 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1762 | } | 1746 | } |
1763 | return; | 1747 | return; |
1764 | } | 1748 | } |
1765 | else if( status_byte(status) == QUEUE_FULL ) | 1749 | else if (status == SAM_STAT_TASK_SET_FULL) |
1766 | { | 1750 | { |
1767 | scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1); | 1751 | scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1); |
1768 | pcmd->use_sg = pSRB->SavedSGCount; | ||
1769 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); | 1752 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); |
1770 | pSRB->TotalXferredLen = 0; | 1753 | pSRB->TotalXferredLen = 0; |
1771 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); | 1754 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); |
1772 | } | 1755 | } |
1773 | else if(status == SCSI_STAT_SEL_TIMEOUT) | 1756 | else if (status == SAM_STAT_BUSY && |
1774 | { | ||
1775 | pSRB->AdaptStatus = H_SEL_TIMEOUT; | ||
1776 | pSRB->TargetStatus = 0; | ||
1777 | pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0); | ||
1778 | /* Devices are removed below ... */ | ||
1779 | } | ||
1780 | else if (status_byte(status) == BUSY && | ||
1781 | (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) && | 1757 | (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) && |
1782 | pACB->scan_devices) | 1758 | pACB->scan_devices) |
1783 | { | 1759 | { |
@@ -1795,12 +1771,17 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1795 | else | 1771 | else |
1796 | { /* Target status == 0 */ | 1772 | { /* Target status == 0 */ |
1797 | status = pSRB->AdaptStatus; | 1773 | status = pSRB->AdaptStatus; |
1798 | if(status & H_OVER_UNDER_RUN) | 1774 | if (status == H_OVER_UNDER_RUN) |
1799 | { | 1775 | { |
1800 | pSRB->TargetStatus = 0; | 1776 | pSRB->TargetStatus = 0; |
1801 | SET_RES_DID(pcmd->result,DID_OK); | 1777 | SET_RES_DID(pcmd->result,DID_OK); |
1802 | SET_RES_MSG(pcmd->result,pSRB->EndMessage); | 1778 | SET_RES_MSG(pcmd->result,pSRB->EndMessage); |
1803 | } | 1779 | } |
1780 | else if (status == H_SEL_TIMEOUT) | ||
1781 | { | ||
1782 | pcmd->result = MK_RES(0, DID_NO_CONNECT, 0, 0); | ||
1783 | /* Devices are removed below ... */ | ||
1784 | } | ||
1804 | else if( pSRB->SRBStatus & PARITY_ERROR) | 1785 | else if( pSRB->SRBStatus & PARITY_ERROR) |
1805 | { | 1786 | { |
1806 | //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0); | 1787 | //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0); |
@@ -1816,7 +1797,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1816 | } | 1797 | } |
1817 | 1798 | ||
1818 | cmd_done: | 1799 | cmd_done: |
1819 | pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen; | 1800 | scsi_set_resid(pcmd, scsi_bufflen(pcmd) - pSRB->TotalXferredLen); |
1820 | 1801 | ||
1821 | dc390_Going_remove (pDCB, pSRB); | 1802 | dc390_Going_remove (pDCB, pSRB); |
1822 | /* Add to free list */ | 1803 | /* Add to free list */ |