Loading drivers/scsi/tmscsim.c +66 −58 Original line number Diff line number Diff line Loading @@ -351,6 +351,27 @@ static u8 dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20}; * (DCBs, SRBs, Queueing) * **********************************************************************/ static void inline dc390_start_segment(struct dc390_srb* pSRB) { struct scatterlist *psgl = pSRB->pSegmentList; /* start new sg segment */ pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); } static unsigned long inline dc390_advance_segment(struct dc390_srb* pSRB, u32 residue) { unsigned long xfer = pSRB->SGToBeXferLen - residue; /* xfer more bytes transferred */ pSRB->SGBusAddr += xfer; pSRB->TotalXferredLen += xfer; pSRB->SGToBeXferLen = residue; return xfer; } static struct dc390_dcb __inline__ *dc390_findDCB ( struct dc390_acb* pACB, u8 id, u8 lun) { struct dc390_dcb* pDCB = pACB->pLinkDCB; if (!pDCB) return NULL; Loading Loading @@ -744,8 +765,7 @@ static void dc390_DataOut_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) { u8 sstatus; struct scatterlist *psgl; u32 ResidCnt, xferCnt; u32 ResidCnt; u8 dstate = 0; sstatus = *psstatus; Loading Loading @@ -776,25 +796,20 @@ dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); } else pSRB->SGToBeXferLen = 0; } else { ResidCnt = (u32) DC390_read8 (Current_Fifo) & 0x1f; ResidCnt |= (u32) DC390_read8 (CtcReg_High) << 16; ResidCnt |= (u32) DC390_read8 (CtcReg_Mid) << 8; ResidCnt += (u32) DC390_read8 (CtcReg_Low); ResidCnt = ((u32) DC390_read8 (Current_Fifo) & 0x1f) + (((u32) DC390_read8 (CtcReg_High) << 16) | ((u32) DC390_read8 (CtcReg_Mid) << 8) | (u32) DC390_read8 (CtcReg_Low)); xferCnt = pSRB->SGToBeXferLen - ResidCnt; pSRB->SGBusAddr += xferCnt; pSRB->TotalXferredLen += xferCnt; pSRB->SGToBeXferLen = ResidCnt; dc390_advance_segment(pSRB, ResidCnt); } } if ((*psstatus & 7) != SCSI_DATA_OUT) Loading @@ -808,10 +823,8 @@ static void dc390_DataIn_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) { u8 sstatus, residual, bval; struct scatterlist *psgl; u32 ResidCnt, i; unsigned long xferCnt; u8 *ptr; sstatus = *psstatus; Loading Loading @@ -851,10 +864,8 @@ dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); } else pSRB->SGToBeXferLen = 0; Loading Loading @@ -894,41 +905,38 @@ dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) /* It seems a DMA Blast abort isn't that bad ... */ if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n"); //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24; dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24; DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval)); ResidCnt = (u32) DC390_read8 (CtcReg_High); ResidCnt <<= 8; ResidCnt |= (u32) DC390_read8 (CtcReg_Mid); ResidCnt <<= 8; ResidCnt |= (u32) DC390_read8 (CtcReg_Low); ResidCnt = (((u32) DC390_read8 (CtcReg_High) << 16) | ((u32) DC390_read8 (CtcReg_Mid) << 8)) | (u32) DC390_read8 (CtcReg_Low); xferCnt = pSRB->SGToBeXferLen - ResidCnt; pSRB->SGBusAddr += xferCnt; pSRB->TotalXferredLen += xferCnt; pSRB->SGToBeXferLen = ResidCnt; xferCnt = dc390_advance_segment(pSRB, ResidCnt); if (residual) { size_t count = 1; size_t offset = pSRB->SGBusAddr - sg_dma_address(pSRB->pSegmentList); unsigned long flags; u8 *ptr; if( residual ) { static int feedback_requested; bval = DC390_read8 (ScsiFifo); /* get one residual byte */ if (!feedback_requested) { feedback_requested = 1; printk(KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> " "to help improve support for your system.\n", __FILE__); local_irq_save(flags); ptr = scsi_kmap_atomic_sg(pSRB->pSegmentList, pSRB->SGcount, &offset, &count); if (likely(ptr)) { *(ptr + offset) = bval; scsi_kunmap_atomic_sg(ptr); } local_irq_restore(flags); WARN_ON(!ptr); ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr ); *ptr = bval; pSRB->SGBusAddr++; xferCnt++; pSRB->TotalXferredLen++; pSRB->SGToBeXferLen--; /* 1 more byte read */ xferCnt += dc390_advance_segment(pSRB, pSRB->SGToBeXferLen - 1); } DEBUG1(printk (KERN_DEBUG "Xfered: %lu, Total: %lu, Remaining: %lu\n", xferCnt,\ pSRB->TotalXferredLen, pSRB->SGToBeXferLen)); } } if ((*psstatus & 7) != SCSI_DATA_IN) Loading Loading @@ -1137,7 +1145,7 @@ dc390_MsgIn_set_sync (struct dc390_acb* pACB, struct dc390_srb* pSRB) /* handle RESTORE_PTR */ /* I presume, this command is already mapped, so, have to remap. */ /* This doesn't look very healthy... to-be-fixed */ static void dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) { Loading @@ -1146,6 +1154,7 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) pSRB->TotalXferredLen = 0; pSRB->SGIndex = 0; if (pcmd->use_sg) { size_t saved; pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer; psgl = pSRB->pSegmentList; //dc390_pci_sync(pSRB); Loading @@ -1157,15 +1166,16 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); } else pSRB->SGToBeXferLen = 0; } pSRB->SGToBeXferLen -= pSRB->Saved_Ptr - pSRB->TotalXferredLen; pSRB->SGBusAddr += pSRB->Saved_Ptr - pSRB->TotalXferredLen; saved = pSRB->Saved_Ptr - pSRB->TotalXferredLen; pSRB->SGToBeXferLen -= saved; pSRB->SGBusAddr += saved; printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr); Loading Loading @@ -1286,7 +1296,6 @@ dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) static void dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) { struct scatterlist *psgl; unsigned long lval; struct dc390_dcb* pDCB = pACB->pActiveDCB; Loading Loading @@ -1315,9 +1324,8 @@ dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); if( !pSRB->SGToBeXferLen ) { psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.")); } lval = pSRB->SGToBeXferLen; Loading Loading
drivers/scsi/tmscsim.c +66 −58 Original line number Diff line number Diff line Loading @@ -351,6 +351,27 @@ static u8 dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20}; * (DCBs, SRBs, Queueing) * **********************************************************************/ static void inline dc390_start_segment(struct dc390_srb* pSRB) { struct scatterlist *psgl = pSRB->pSegmentList; /* start new sg segment */ pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); } static unsigned long inline dc390_advance_segment(struct dc390_srb* pSRB, u32 residue) { unsigned long xfer = pSRB->SGToBeXferLen - residue; /* xfer more bytes transferred */ pSRB->SGBusAddr += xfer; pSRB->TotalXferredLen += xfer; pSRB->SGToBeXferLen = residue; return xfer; } static struct dc390_dcb __inline__ *dc390_findDCB ( struct dc390_acb* pACB, u8 id, u8 lun) { struct dc390_dcb* pDCB = pACB->pLinkDCB; if (!pDCB) return NULL; Loading Loading @@ -744,8 +765,7 @@ static void dc390_DataOut_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) { u8 sstatus; struct scatterlist *psgl; u32 ResidCnt, xferCnt; u32 ResidCnt; u8 dstate = 0; sstatus = *psstatus; Loading Loading @@ -776,25 +796,20 @@ dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); } else pSRB->SGToBeXferLen = 0; } else { ResidCnt = (u32) DC390_read8 (Current_Fifo) & 0x1f; ResidCnt |= (u32) DC390_read8 (CtcReg_High) << 16; ResidCnt |= (u32) DC390_read8 (CtcReg_Mid) << 8; ResidCnt += (u32) DC390_read8 (CtcReg_Low); ResidCnt = ((u32) DC390_read8 (Current_Fifo) & 0x1f) + (((u32) DC390_read8 (CtcReg_High) << 16) | ((u32) DC390_read8 (CtcReg_Mid) << 8) | (u32) DC390_read8 (CtcReg_Low)); xferCnt = pSRB->SGToBeXferLen - ResidCnt; pSRB->SGBusAddr += xferCnt; pSRB->TotalXferredLen += xferCnt; pSRB->SGToBeXferLen = ResidCnt; dc390_advance_segment(pSRB, ResidCnt); } } if ((*psstatus & 7) != SCSI_DATA_OUT) Loading @@ -808,10 +823,8 @@ static void dc390_DataIn_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) { u8 sstatus, residual, bval; struct scatterlist *psgl; u32 ResidCnt, i; unsigned long xferCnt; u8 *ptr; sstatus = *psstatus; Loading Loading @@ -851,10 +864,8 @@ dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); } else pSRB->SGToBeXferLen = 0; Loading Loading @@ -894,41 +905,38 @@ dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) /* It seems a DMA Blast abort isn't that bad ... */ if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n"); //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24; dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24; DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval)); ResidCnt = (u32) DC390_read8 (CtcReg_High); ResidCnt <<= 8; ResidCnt |= (u32) DC390_read8 (CtcReg_Mid); ResidCnt <<= 8; ResidCnt |= (u32) DC390_read8 (CtcReg_Low); ResidCnt = (((u32) DC390_read8 (CtcReg_High) << 16) | ((u32) DC390_read8 (CtcReg_Mid) << 8)) | (u32) DC390_read8 (CtcReg_Low); xferCnt = pSRB->SGToBeXferLen - ResidCnt; pSRB->SGBusAddr += xferCnt; pSRB->TotalXferredLen += xferCnt; pSRB->SGToBeXferLen = ResidCnt; xferCnt = dc390_advance_segment(pSRB, ResidCnt); if (residual) { size_t count = 1; size_t offset = pSRB->SGBusAddr - sg_dma_address(pSRB->pSegmentList); unsigned long flags; u8 *ptr; if( residual ) { static int feedback_requested; bval = DC390_read8 (ScsiFifo); /* get one residual byte */ if (!feedback_requested) { feedback_requested = 1; printk(KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> " "to help improve support for your system.\n", __FILE__); local_irq_save(flags); ptr = scsi_kmap_atomic_sg(pSRB->pSegmentList, pSRB->SGcount, &offset, &count); if (likely(ptr)) { *(ptr + offset) = bval; scsi_kunmap_atomic_sg(ptr); } local_irq_restore(flags); WARN_ON(!ptr); ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr ); *ptr = bval; pSRB->SGBusAddr++; xferCnt++; pSRB->TotalXferredLen++; pSRB->SGToBeXferLen--; /* 1 more byte read */ xferCnt += dc390_advance_segment(pSRB, pSRB->SGToBeXferLen - 1); } DEBUG1(printk (KERN_DEBUG "Xfered: %lu, Total: %lu, Remaining: %lu\n", xferCnt,\ pSRB->TotalXferredLen, pSRB->SGToBeXferLen)); } } if ((*psstatus & 7) != SCSI_DATA_IN) Loading Loading @@ -1137,7 +1145,7 @@ dc390_MsgIn_set_sync (struct dc390_acb* pACB, struct dc390_srb* pSRB) /* handle RESTORE_PTR */ /* I presume, this command is already mapped, so, have to remap. */ /* This doesn't look very healthy... to-be-fixed */ static void dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) { Loading @@ -1146,6 +1154,7 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) pSRB->TotalXferredLen = 0; pSRB->SGIndex = 0; if (pcmd->use_sg) { size_t saved; pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer; psgl = pSRB->pSegmentList; //dc390_pci_sync(pSRB); Loading @@ -1157,15 +1166,16 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); } else pSRB->SGToBeXferLen = 0; } pSRB->SGToBeXferLen -= pSRB->Saved_Ptr - pSRB->TotalXferredLen; pSRB->SGBusAddr += pSRB->Saved_Ptr - pSRB->TotalXferredLen; saved = pSRB->Saved_Ptr - pSRB->TotalXferredLen; pSRB->SGToBeXferLen -= saved; pSRB->SGBusAddr += saved; printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr); Loading Loading @@ -1286,7 +1296,6 @@ dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) static void dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) { struct scatterlist *psgl; unsigned long lval; struct dc390_dcb* pDCB = pACB->pActiveDCB; Loading Loading @@ -1315,9 +1324,8 @@ dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); if( !pSRB->SGToBeXferLen ) { psgl = pSRB->pSegmentList; pSRB->SGBusAddr = sg_dma_address(psgl); pSRB->SGToBeXferLen = sg_dma_len(psgl); dc390_start_segment(pSRB); DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.")); } lval = pSRB->SGToBeXferLen; Loading