📄 i60uscsi.c
字号:
if (i == orc_num_scb) { printk("Unable to Reset - No SCB Found\n");#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);#endif return (SCSI_RESET_NOT_RUNNING); } if ((pScb = orc_alloc_scb(pHCB)) == NULL) {#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);#endif return (SCSI_RESET_NOT_RUNNING); } pScb->SCB_Opcode = ORC_BUSDEVRST; pScb->SCB_Target = target; pScb->SCB_HaStat = 0; pScb->SCB_TaStat = 0; pScb->SCB_Status = 0x0; pScb->SCB_Link = 0xFF; pScb->SCB_Reserved0 = 0; pScb->SCB_Reserved1 = 0; pScb->SCB_XferLen = 0; pScb->SCB_SGLen = 0; pVirEscb->SCB_Srb = 0; if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { pVirEscb->SCB_Srb = (unsigned char *) SCpnt; } orc_exec_scb(pHCB, pScb); /* Start execute SCB */#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);#endif return SCSI_RESET_PENDING;}/***************************************************************************/ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp){ ORC_SCB *pTmpScb; UCHAR Ch; ULONG idx; UCHAR index; UCHAR i; ULONG flags;#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) save_flags(flags); cli();#else spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);#endif Ch = hcsp->HCS_Index; for (i = 0; i < 8; i++) { for (index = 0; index < 32; index++) { if ((hcsp->BitAllocFlag[Ch][i] >> index) & 0x01) { hcsp->BitAllocFlag[Ch][i] &= ~(1 << index); break; } } idx = index + 32 * i; pTmpScb = (PVOID) ((ULONG) hcsp->HCS_virScbArray + (idx * sizeof(ORC_SCB)));#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);#endif return (pTmpScb); }#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);#endif return (NULL);}/***************************************************************************/void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp){ ULONG flags; UCHAR Index; UCHAR i; UCHAR Ch;#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) save_flags(flags); cli();#else spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);#endif Ch = hcsp->HCS_Index; Index = scbp->SCB_ScbIdx; i = Index / 32; Index %= 32; hcsp->BitAllocFlag[Ch][i] |= (1 << Index);#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);#endif}/***************************************************************************** Function name : Addinia100_into_Adapter_table Description : This function will scan PCI bus to get all Orchid card Input : None. Output : None. Return : SUCCESSFUL - Successful scan ohterwise - No drives founded*****************************************************************************/int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, BYTE bBus, BYTE bDevice){ unsigned int i, j; for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { if (inia100_adpt[i].ADPT_BIOS < wBIOS) continue; if (inia100_adpt[i].ADPT_BIOS == wBIOS) { if (inia100_adpt[i].ADPT_BASE == wBASE) { if (inia100_adpt[i].ADPT_Bus != 0xFF) return (FAILURE); } else if (inia100_adpt[i].ADPT_BASE < wBASE) continue; } for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) { inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE; inia100_adpt[j].ADPT_INTR = inia100_adpt[j - 1].ADPT_INTR; inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS; inia100_adpt[j].ADPT_Bus = inia100_adpt[j - 1].ADPT_Bus; inia100_adpt[j].ADPT_Device = inia100_adpt[j - 1].ADPT_Device; } inia100_adpt[i].ADPT_BASE = wBASE; inia100_adpt[i].ADPT_INTR = bInterrupt; inia100_adpt[i].ADPT_BIOS = wBIOS; inia100_adpt[i].ADPT_Bus = bBus; inia100_adpt[i].ADPT_Device = bDevice; return (SUCCESSFUL); } return (FAILURE);}/***************************************************************************** Function name : init_inia100Adapter_table Description : This function will scan PCI bus to get all Orchid card Input : None. Output : None. Return : SUCCESSFUL - Successful scan ohterwise - No drives founded*****************************************************************************/void init_inia100Adapter_table(void){ int i; for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { /* Initialize adapter structure */ inia100_adpt[i].ADPT_BIOS = 0xffff; inia100_adpt[i].ADPT_BASE = 0xffff; inia100_adpt[i].ADPT_INTR = 0xff; inia100_adpt[i].ADPT_Bus = 0xff; inia100_adpt[i].ADPT_Device = 0xff; }}/***************************************************************************** Function name : get_orcPCIConfig Description : Input : pHCB - Pointer to host adapter structure Output : None. Return : pSRB - Pointer to SCSI request block.*****************************************************************************/void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx){ pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE; /* Supply base address */ pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */ pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_INTR; /* Supply interrupt line */ return;}/***************************************************************************** Function name : abort_SCB Description : Abort a queued command. (commands that are on the bus can't be aborted easily) Input : pHCB - Pointer to host adapter structure Output : None. Return : pSRB - Pointer to SCSI request block.*****************************************************************************/int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb){ unsigned char bData, bStatus; ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_ABORT_SCB); /* Write command */ ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ return (FALSE); ORC_WR(hcsp->HCS_Base + ORC_HDATA, pScb->SCB_ScbIdx); /* Write address */ ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ return (FALSE); if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ return (FALSE); bStatus = ORC_RD(hcsp->HCS_Base, ORC_HDATA); ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ if (bStatus == 1) /* 0 - Successfully */ return (FALSE); /* 1 - Fail */ return (TRUE);}/***************************************************************************** Function name : inia100_abort Description : Abort a queued command. (commands that are on the bus can't be aborted easily) Input : pHCB - Pointer to host adapter structure Output : None. Return : pSRB - Pointer to SCSI request block.*****************************************************************************/int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt){ ESCB *pVirEscb; ORC_SCB *pVirScb; UCHAR i; ULONG flags;#if 0 printk("inia100: abort SRB \n");#endif#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) save_flags(flags); cli();#else spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);#endif pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; for (i = 0; i < orc_num_scb; i++, pVirScb++) { pVirEscb = pVirScb->SCB_EScb; if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) { if (pVirScb->SCB_TagMsg == 0) {#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);#endif return (SCSI_ABORT_BUSY); } else { if (abort_SCB(hcsp, pVirScb)) { pVirEscb->SCB_Srb = NULL;#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);#endif return (SCSI_ABORT_SUCCESS); } else {#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);#endif return (SCSI_ABORT_NOT_RUNNING); } } } }#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);#endif return (SCSI_ABORT_NOT_RUNNING);}/*********************************************************************** Routine Description: This is the interrupt service routine for the Orchid SCSI adapter. It reads the interrupt register to determine if the adapter is indeed the source of the interrupt and clears the interrupt at the device. Arguments: HwDeviceExtension - HBA miniport driver's adapter data storage Return Value:***********************************************************************/void orc_interrupt( ORC_HCS * hcsp){ BYTE bScbIdx; ORC_SCB *pScb; if (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT) == 0) { return; // (FALSE); } do { bScbIdx = ORC_RD(hcsp->HCS_Base, ORC_RQUEUE); pScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (ULONG) (sizeof(ORC_SCB) * bScbIdx)); pScb->SCB_Status = 0x0; inia100SCBPost((BYTE *) hcsp, (BYTE *) pScb); } while (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT)); return; //(TRUE);} /* End of I1060Interrupt() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -