📄 i60uscsi.c
字号:
int se2_rd_all(ORC_HCS * hcsp){ int i; UCHAR *np, chksum = 0; np = (UCHAR *) nvramp; for (i = 0; i < 64; i++, np++) { /* <01> */ if (get_NVRAM(hcsp, (unsigned char) i, np) == FALSE) return -1;// *np++ = get_NVRAM(hcsp, (unsigned char ) i); }/*------ Is ckecksum ok ? ------*/ np = (UCHAR *) nvramp; for (i = 0; i < 63; i++) chksum += *np++; if (nvramp->CheckSum != (UCHAR) chksum) return -1; return 1;}/************************************************************************ Update SCSI H/A configuration parameters from serial EEPROM*************************************************************************/void se2_update_all(ORC_HCS * hcsp){ /* setup default pattern */ int i; UCHAR *np, *np1, chksum = 0; /* Calculate checksum first */ np = (UCHAR *) dftNvRam; for (i = 0; i < 63; i++) chksum += *np++; *np = chksum; np = (UCHAR *) dftNvRam; np1 = (UCHAR *) nvramp; for (i = 0; i < 64; i++, np++, np1++) { if (*np != *np1) { set_NVRAM(hcsp, (unsigned char) i, *np); } } return;}/************************************************************************* Function name : read_eeprom**************************************************************************/void read_eeprom(ORC_HCS * hcsp){ if (se2_rd_all(hcsp) != 1) { se2_update_all(hcsp); /* setup default pattern */ se2_rd_all(hcsp); /* load again */ }}/***************************************************************************/UCHAR load_FW(ORC_HCS * hcsp){ U32 dData; USHORT wBIOSAddress; USHORT i; UCHAR *pData, bData; bData = ORC_RD(hcsp->HCS_Base, ORC_GCFG); ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData | EEPRG); /* Enable EEPROM programming */ ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, 0x00); ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x00); if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0x55) { ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ return (FALSE); } ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x01); if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0xAA) { ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ return (FALSE); } ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Enable SRAM programming */ pData = (UCHAR *) & dData; dData = 0; /* Initial FW address to 0 */ ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x10); *pData = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x11); *(pData + 1) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x12); *(pData + 2) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, *(pData + 2)); ORC_WRLONG(hcsp->HCS_Base + ORC_FWBASEADR, dData); /* Write FW address */ wBIOSAddress = (USHORT) dData; /* FW code locate at BIOS address + ? */ for (i = 0, pData = (UCHAR *) & dData; /* Download the code */ i < 0x1000; /* Firmware code size = 4K */ i++, wBIOSAddress++) { ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ if ((i % 4) == 3) { ORC_WRLONG(hcsp->HCS_Base + ORC_RISCRAM, dData); /* Write every 4 bytes */ pData = (UCHAR *) & dData; } } ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Reset program count 0 */ wBIOSAddress -= 0x1000; /* Reset the BIOS adddress */ for (i = 0, pData = (UCHAR *) & dData; /* Check the code */ i < 0x1000; /* Firmware code size = 4K */ i++, wBIOSAddress++) { ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ if ((i % 4) == 3) { if (ORC_RDLONG(hcsp->HCS_Base, ORC_RISCRAM) != dData) { ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /*Disable EEPROM programming */ return (FALSE); } pData = (UCHAR *) & dData; } } ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ return (TRUE);}/***************************************************************************/void setup_SCBs(ORC_HCS * hcsp){ ORC_SCB *pVirScb; int i; UCHAR j; ESCB *pVirEscb; PVOID pPhysEscb; PVOID tPhysEscb; j = 0; pVirScb = NULL; tPhysEscb = (PVOID) NULL; pPhysEscb = (PVOID) NULL; /* Setup SCB HCS_Base and SCB Size registers */ ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, orc_num_scb); /* Total number of SCBs */ /* SCB HCS_Base address 0 */ ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray); /* SCB HCS_Base address 1 */ ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE1, hcsp->HCS_physScbArray); /* setup scatter list address with one buffer */ pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; pVirEscb = (ESCB *) hcsp->HCS_virEscbArray; for (i = 0; i < orc_num_scb; i++) { pPhysEscb = (PVOID) (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i)); pVirScb->SCB_SGPAddr = (U32) pPhysEscb; pVirScb->SCB_SensePAddr = (U32) pPhysEscb; pVirScb->SCB_EScb = pVirEscb; pVirScb->SCB_ScbIdx = i; pVirScb++; pVirEscb++; } return;}/***************************************************************************/static void initAFlag(ORC_HCS * hcsp){ UCHAR i, j; for (i = 0; i < MAX_CHANNELS; i++) { for (j = 0; j < 8; j++) { hcsp->BitAllocFlag[i][j] = 0xffffffff; } }}/***************************************************************************/int init_orchid(ORC_HCS * hcsp){ UBYTE *readBytep; USHORT revision; UCHAR i; initAFlag(hcsp); ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFF); /* Disable all interrupt */ if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) { /* Orchid is ready */ revision = get_FW_version(hcsp); if (revision == 0xFFFF) { ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ if (waitChipReady(hcsp) == FALSE) return (-1); load_FW(hcsp); /* Download FW */ setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ ORC_WR(hcsp->HCS_Base + ORC_HCTRL, 0); /* clear HOSTSTOP */ if (waitFWReady(hcsp) == FALSE) return (-1); /* Wait for firmware ready */ } else { setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ } } else { /* Orchid is not Ready */ ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ if (waitChipReady(hcsp) == FALSE) return (-1); load_FW(hcsp); /* Download FW */ setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); /* Do Hardware Reset & */ /* clear HOSTSTOP */ if (waitFWReady(hcsp) == FALSE) /* Wait for firmware ready */ return (-1); }/*------------- get serial EEProm settting -------*/ read_eeprom(hcsp); if (nvramp->Revision != 1) return (-1); hcsp->HCS_SCSI_ID = nvramp->SCSI0Id; hcsp->HCS_BIOS = nvramp->BIOSConfig1; hcsp->HCS_MaxTar = MAX_TARGETS; readBytep = (UCHAR *) & (nvramp->Target00Config); for (i = 0; i < 16; readBytep++, i++) { hcsp->TargetFlag[i] = *readBytep; hcsp->MaximumTags[i] = orc_num_scb; } /* for */ if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */ hcsp->HCS_Flags |= HCF_SCSI_RESET; } ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFB); /* enable RP FIFO interrupt */ return (0);}/***************************************************************************** Function name : orc_reset_scsi_bus Description : Reset registers, reset a hanging bus and kill active and disconnected commands for target w/o soft reset Input : pHCB - Pointer to host adapter structure Output : None. Return : pSRB - Pointer to SCSI request block.*****************************************************************************/int orc_reset_scsi_bus(ORC_HCS * pHCB){ /* I need Host Control Block Information */ ULONG flags;#if 0 printk("inia100: enter inia100_reset\n");#endif#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) save_flags(flags); cli();#else spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);#endif initAFlag(pHCB); /* reset scsi bus */ ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST); if (waitSCSIRSTdone(pHCB) == FALSE) {#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);#endif return (SCSI_RESET_ERROR); } else {#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) restore_flags(flags);#else spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);#endif return (SCSI_RESET_SUCCESS); }}/***************************************************************************** Function name : orc_device_reset Description : Reset registers, reset a hanging bus and kill active and disconnected commands for target w/o soft reset Input : pHCB - Pointer to host adapter structure Output : None. Return : pSRB - Pointer to SCSI request block.*****************************************************************************/int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags){ /* I need Host Control Block Information */ ORC_SCB *pScb; ESCB *pVirEscb; ORC_SCB *pVirScb; UCHAR i; ULONG flags;#if 0 printk("inia100: enter inia100_reset\n");#endif#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) save_flags(flags); cli();#else spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);#endif pScb = (ORC_SCB *) NULL; pVirEscb = (ESCB *) NULL; /* setup scatter list address with one buffer */ pVirScb = (ORC_SCB *) pHCB->HCS_virScbArray; initAFlag(pHCB); /* device reset */ for (i = 0; i < orc_num_scb; i++) { pVirEscb = pVirScb->SCB_EScb; if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) break; pVirScb++; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -