📄 i91uscsi.c
字号:
if (scbp->SCB_TagMsg) pCurHcb->HCS_ActTags[scbp->SCB_Target]++; else pCurHcb->HCS_Tcs[scbp->SCB_Target].TCS_Flags |= TCF_BUSY; scbp->SCB_Status = SCB_BUSY; scbp->SCB_NxtScb = NULL; if (pCurHcb->HCS_LastBusy != NULL) { pCurHcb->HCS_LastBusy->SCB_NxtScb = scbp; pCurHcb->HCS_LastBusy = scbp; } else { pCurHcb->HCS_FirstBusy = scbp; pCurHcb->HCS_LastBusy = scbp; }}/***************************************************************************/SCB *tul_pop_busy_scb(HCS * pCurHcb){ SCB *pTmpScb; if ((pTmpScb = pCurHcb->HCS_FirstBusy) != NULL) { if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) pCurHcb->HCS_LastBusy = NULL; pTmpScb->SCB_NxtScb = NULL; if (pTmpScb->SCB_TagMsg) pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; else pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY; }#if DEBUG_QUEUE printk("Pop busy SCB %lx; ", (ULONG) pTmpScb);#endif return (pTmpScb);}/***************************************************************************/void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb){ SCB *pTmpScb, *pPrevScb;#if DEBUG_QUEUE printk("unlink busy SCB %lx; ", (ULONG) pCurScb);#endif pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; while (pTmpScb != NULL) { if (pCurScb == pTmpScb) { /* Unlink this SCB */ if (pTmpScb == pCurHcb->HCS_FirstBusy) { if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) pCurHcb->HCS_LastBusy = NULL; } else { pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; if (pTmpScb == pCurHcb->HCS_LastBusy) pCurHcb->HCS_LastBusy = pPrevScb; } pTmpScb->SCB_NxtScb = NULL; if (pTmpScb->SCB_TagMsg) pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; else pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY; break; } pPrevScb = pTmpScb; pTmpScb = pTmpScb->SCB_NxtScb; } return;}/***************************************************************************/SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun){ SCB *pTmpScb, *pPrevScb; WORD scbp_tarlun; pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; while (pTmpScb != NULL) { scbp_tarlun = (pTmpScb->SCB_Lun << 8) | (pTmpScb->SCB_Target); if (scbp_tarlun == tarlun) { /* Unlink this SCB */ break; } pPrevScb = pTmpScb; pTmpScb = pTmpScb->SCB_NxtScb; }#if DEBUG_QUEUE printk("find busy SCB %lx; ", (ULONG) pTmpScb);#endif return (pTmpScb);}/***************************************************************************/void tul_append_done_scb(HCS * pCurHcb, SCB * scbp){#if DEBUG_QUEUE printk("append done SCB %lx; ", (ULONG) scbp);#endif scbp->SCB_Status = SCB_DONE; scbp->SCB_NxtScb = NULL; if (pCurHcb->HCS_LastDone != NULL) { pCurHcb->HCS_LastDone->SCB_NxtScb = scbp; pCurHcb->HCS_LastDone = scbp; } else { pCurHcb->HCS_FirstDone = scbp; pCurHcb->HCS_LastDone = scbp; }}/***************************************************************************/SCB *tul_find_done_scb(HCS * pCurHcb){ SCB *pTmpScb; if ((pTmpScb = pCurHcb->HCS_FirstDone) != NULL) { if ((pCurHcb->HCS_FirstDone = pTmpScb->SCB_NxtScb) == NULL) pCurHcb->HCS_LastDone = NULL; pTmpScb->SCB_NxtScb = NULL; }#if DEBUG_QUEUE printk("find done SCB %lx; ", (ULONG) pTmpScb);#endif return (pTmpScb);}/***************************************************************************/int tul_abort_srb(HCS * pCurHcb, ULONG srbp){ ULONG flags; SCB *pTmpScb, *pPrevScb;#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#else save_flags(flags); cli();#endif if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) { TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); /* disable Jasmin SCSI Int */#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#endif tulip_main(pCurHcb);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#endif pCurHcb->HCS_Semaph = 1; TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_ABORT_SNOOZE; } pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend; /* Check Pend queue */ while (pTmpScb != NULL) { /* 07/27/98 */ if (pTmpScb->SCB_Srb == (unsigned char *) srbp) { if (pTmpScb == pCurHcb->HCS_ActScb) {#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_ABORT_BUSY; } else if (pTmpScb == pCurHcb->HCS_FirstPend) { if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL) pCurHcb->HCS_LastPend = NULL; } else { pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; if (pTmpScb == pCurHcb->HCS_LastPend) pCurHcb->HCS_LastPend = pPrevScb; } pTmpScb->SCB_HaStat = HOST_ABORTED; pTmpScb->SCB_Flags |= SCF_DONE; if (pTmpScb->SCB_Flags & SCF_POST) (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_ABORT_SUCCESS; } pPrevScb = pTmpScb; pTmpScb = pTmpScb->SCB_NxtScb; } pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ while (pTmpScb != NULL) { if (pTmpScb->SCB_Srb == (unsigned char *) srbp) { if (pTmpScb == pCurHcb->HCS_ActScb) {#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_ABORT_BUSY; } else if (pTmpScb->SCB_TagMsg == 0) {#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_ABORT_BUSY; } else { pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; if (pTmpScb == pCurHcb->HCS_FirstBusy) { if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) pCurHcb->HCS_LastBusy = NULL; } else { pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; if (pTmpScb == pCurHcb->HCS_LastBusy) pCurHcb->HCS_LastBusy = pPrevScb; } pTmpScb->SCB_NxtScb = NULL; pTmpScb->SCB_HaStat = HOST_ABORTED; pTmpScb->SCB_Flags |= SCF_DONE; if (pTmpScb->SCB_Flags & SCF_POST) (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_ABORT_SUCCESS; } } pPrevScb = pTmpScb; pTmpScb = pTmpScb->SCB_NxtScb; }#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return (SCSI_ABORT_NOT_RUNNING);}/***************************************************************************/int tul_bad_seq(HCS * pCurHcb){ SCB *pCurScb; printk("tul_bad_seg c=%d\n", pCurHcb->HCS_Index); if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) { tul_unlink_busy_scb(pCurHcb, pCurScb); pCurScb->SCB_HaStat = HOST_BAD_PHAS; pCurScb->SCB_TaStat = 0; tul_append_done_scb(pCurHcb, pCurScb); } tul_stop_bm(pCurHcb); tul_reset_scsi(pCurHcb, 8); /* 7/29/98 */ return (tul_post_scsi_rst(pCurHcb));}/************************************************************************/int tul_device_reset(HCS * pCurHcb, ULONG pSrb, unsigned int target, unsigned int ResetFlags){ ULONG flags; SCB *pScb;#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#else save_flags(flags); cli();#endif if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) { if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) { TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); /* disable Jasmin SCSI Int */#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#endif tulip_main(pCurHcb);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#endif pCurHcb->HCS_Semaph = 1; TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_RESET_SNOOZE; } pScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ while (pScb != NULL) { if (pScb->SCB_Srb == (unsigned char *) pSrb) break; pScb = pScb->SCB_NxtScb; } if (pScb == NULL) { printk("Unable to Reset - No SCB Found\n");#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_RESET_NOT_RUNNING; } } if ((pScb = tul_alloc_scb(pCurHcb)) == NULL) {#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_RESET_NOT_RUNNING; } pScb->SCB_Opcode = BusDevRst; pScb->SCB_Flags = SCF_POST; pScb->SCB_Target = target; pScb->SCB_Mode = 0; pScb->SCB_Srb = 0; if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { pScb->SCB_Srb = (unsigned char *) pSrb; } tul_push_pend_scb(pCurHcb, pScb); /* push this SCB to Pending queue */ if (pCurHcb->HCS_Semaph == 1) { TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); /* disable Jasmin SCSI Int */ pCurHcb->HCS_Semaph = 0;#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#endif tulip_main(pCurHcb);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#endif pCurHcb->HCS_Semaph = 1; TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); }#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return SCSI_RESET_PENDING;}int tul_reset_scsi_bus(HCS * pCurHcb){ ULONG flags;#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#else save_flags(flags); cli();#endif TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); pCurHcb->HCS_Semaph = 0;#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif tul_stop_bm(pCurHcb); tul_reset_scsi(pCurHcb, 2); /* 7/29/98 */#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#else save_flags(flags); cli();#endif tul_post_scsi_rst(pCurHcb);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#endif tulip_main(pCurHcb);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#endif pCurHcb->HCS_Semaph = 1; TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);#else restore_flags(flags);#endif return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);}/************************************************************************/void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb){ ULONG flags; pCurScb->SCB_Mode = 0; pCurScb->SCB_SGIdx = 0; pCurScb->SCB_SGMax = pCurScb->SCB_SGLen;#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);#else save_flags(flags); cli();#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -