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

📄 i60uscsi.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************** * Initio A100 device driver for Linux. * * Copyright (c) 1994-1998 Initio Corporation * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING.  If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * -------------------------------------------------------------------------- * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions, and the following disclaimer, *    without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * Where this Software is combined with software released under the terms of  * the GNU General Public License ("GPL") and the terms of the GPL would require the  * combined work to also be released under the terms of the GPL, the terms * and conditions of this License will apply in addition to those of the * GPL with the exception of any terms or conditions of this License that * conflict with, or are expressly prohibited by, the GPL. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ************************************************************************* * * module: i60uscsi.c  * DESCRIPTION: * 	This is the Linux low-level SCSI driver for Initio INIA100 SCSI host * adapters * * 07/02/98 hl	- v.91n Initial drivers. * 09/14/98 hl - v1.01 Support new Kernel. * 09/22/98 hl - v1.01a Support reset. * 09/24/98 hl - v1.01b Fixed reset. * 10/05/98 hl - v1.02 split the source code and release. * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up * 01/31/99 bv - v1.02b Use mdelay instead of waitForPause * 08/08/99 bv - v1.02c Use waitForPause again. **************************************************************************/#include <linux/version.h>#include <linux/sched.h>#include <asm/io.h>#include "i60uscsi.h"#define JIFFIES_TO_MS(t) ((t) * 1000 / HZ)#define MS_TO_JIFFIES(j) ((j * HZ) / 1000)/* ---- INTERNAL FUNCTIONS ---- */static UCHAR waitChipReady(ORC_HCS * hcsp);static UCHAR waitFWReady(ORC_HCS * hcsp);static UCHAR waitFWReady(ORC_HCS * hcsp);static UCHAR waitSCSIRSTdone(ORC_HCS * hcsp);static UCHAR waitHDOoff(ORC_HCS * hcsp);static UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData);static unsigned short get_FW_version(ORC_HCS * hcsp);static UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value);static UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn);static int se2_rd_all(ORC_HCS * hcsp);static void se2_update_all(ORC_HCS * hcsp);	/* setup default pattern        */static void read_eeprom(ORC_HCS * hcsp);static UCHAR load_FW(ORC_HCS * hcsp);static void setup_SCBs(ORC_HCS * hcsp);static void initAFlag(ORC_HCS * hcsp);ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);/* ---- EXTERNAL FUNCTIONS ---- */extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb);/* ---- INTERNAL VARIABLES ---- */ORC_HCS orc_hcs[MAX_SUPPORTED_ADAPTERS];static INIA100_ADPT_STRUCT inia100_adpt[MAX_SUPPORTED_ADAPTERS];/* set by inia100_setup according to the command line */int orc_num_scb;NVRAM nvram, *nvramp = &nvram;static UCHAR dftNvRam[64] ={/*----------header -------------*/	0x01,			/* 0x00: Sub System Vendor ID 0 */	0x11,			/* 0x01: Sub System Vendor ID 1 */	0x60,			/* 0x02: Sub System ID 0        */	0x10,			/* 0x03: Sub System ID 1        */	0x00,			/* 0x04: SubClass               */	0x01,			/* 0x05: Vendor ID 0            */	0x11,			/* 0x06: Vendor ID 1            */	0x60,			/* 0x07: Device ID 0            */	0x10,			/* 0x08: Device ID 1            */	0x00,			/* 0x09: Reserved               */	0x00,			/* 0x0A: Reserved               */	0x01,			/* 0x0B: Revision of Data Structure     */				/* -- Host Adapter Structure --- */	0x01,			/* 0x0C: Number Of SCSI Channel */	0x01,			/* 0x0D: BIOS Configuration 1   */	0x00,			/* 0x0E: BIOS Configuration 2   */	0x00,			/* 0x0F: BIOS Configuration 3   */				/* --- SCSI Channel 0 Configuration --- */	0x07,			/* 0x10: H/A ID                 */	0x83,			/* 0x11: Channel Configuration  */	0x20,			/* 0x12: MAX TAG per target     */	0x0A,			/* 0x13: SCSI Reset Recovering time     */	0x00,			/* 0x14: Channel Configuration4 */	0x00,			/* 0x15: Channel Configuration5 */				/* SCSI Channel 0 Target Configuration  */				/* 0x16-0x25                    */	0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,	0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,				/* --- SCSI Channel 1 Configuration --- */	0x07,			/* 0x26: H/A ID                 */	0x83,			/* 0x27: Channel Configuration  */	0x20,			/* 0x28: MAX TAG per target     */	0x0A,			/* 0x29: SCSI Reset Recovering time     */	0x00,			/* 0x2A: Channel Configuration4 */	0x00,			/* 0x2B: Channel Configuration5 */				/* SCSI Channel 1 Target Configuration  */				/* 0x2C-0x3B                    */	0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,	0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,	0x00,			/* 0x3C: Reserved               */	0x00,			/* 0x3D: Reserved               */	0x00,			/* 0x3E: Reserved               */	0x00			/* 0x3F: Checksum               */};/***************************************************************************/static void waitForPause(unsigned amount){	ULONG the_time = jiffies + MS_TO_JIFFIES(amount);	while (time_before_eq(jiffies, the_time))		cpu_relax();}/***************************************************************************/UCHAR waitChipReady(ORC_HCS * hcsp){	int i;	for (i = 0; i < 10; i++) {	/* Wait 1 second for report timeout     */		if (ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HOSTSTOP)	/* Wait HOSTSTOP set */			return (TRUE);		waitForPause(100);	/* wait 100ms before try again  */	}	return (FALSE);}/***************************************************************************/UCHAR waitFWReady(ORC_HCS * hcsp){	int i;	for (i = 0; i < 10; i++) {	/* Wait 1 second for report timeout     */		if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY)		/* Wait READY set */			return (TRUE);		waitForPause(100);	/* wait 100ms before try again  */	}	return (FALSE);}/***************************************************************************/UCHAR waitSCSIRSTdone(ORC_HCS * hcsp){	int i;	for (i = 0; i < 10; i++) {	/* Wait 1 second for report timeout     */		if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & SCSIRST))	/* Wait SCSIRST done */			return (TRUE);		waitForPause(100);	/* wait 100ms before try again  */	}	return (FALSE);}/***************************************************************************/UCHAR waitHDOoff(ORC_HCS * hcsp){	int i;	for (i = 0; i < 10; i++) {	/* Wait 1 second for report timeout     */		if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HDO))		/* Wait HDO off */			return (TRUE);		waitForPause(100);	/* wait 100ms before try again  */	}	return (FALSE);}/***************************************************************************/UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData){	int i;	for (i = 0; i < 10; i++) {	/* Wait 1 second for report timeout     */		if ((*pData = ORC_RD(hcsp->HCS_Base, ORC_HSTUS)) & HDI)			return (TRUE);	/* Wait HDI set */		waitForPause(100);	/* wait 100ms before try again  */	}	return (FALSE);}/***************************************************************************/unsigned short get_FW_version(ORC_HCS * hcsp){	UCHAR bData;	union {		unsigned short sVersion;		unsigned char cVersion[2];	} Version;	ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_VERSION);	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);	Version.cVersion[0] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);	ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData);	/* Clear HDI            */	if (waitHDIset(hcsp, &bData) == FALSE)	/* Wait HDI set   */		return (FALSE);	Version.cVersion[1] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);	ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData);	/* Clear HDI            */	return (Version.sVersion);}/***************************************************************************/UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value){	ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_SET_NVM);	/* 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, address);	/* Write address */	ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);	if (waitHDOoff(hcsp) == FALSE)	/* Wait HDO off   */		return (FALSE);	ORC_WR(hcsp->HCS_Base + ORC_HDATA, value);	/* Write value  */	ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);	if (waitHDOoff(hcsp) == FALSE)	/* Wait HDO off   */		return (FALSE);	return (TRUE);}/***************************************************************************/UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn){	unsigned char bData;	ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_GET_NVM);	/* 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, address);	/* 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);	*pDataIn = ORC_RD(hcsp->HCS_Base, ORC_HDATA);	ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData);	/* Clear HDI    */	return (TRUE);}/***************************************************************************/void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp){	scbp->SCB_Status = SCB_POST;	ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx);	return;}/*********************************************************************** Read SCSI H/A configuration parameters from serial EEPROM************************************************************************/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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -