⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i60uscsi.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -