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

📄 sym53c8xx_comm.h

📁 讲述linux的初始化过程
💻 H
📖 第 1 页 / 共 5 页
字号:
#define scsi_sg_dma_address(sc)		sg_dma_address(sc)#define scsi_sg_dma_len(sc)		sg_dma_len(sc)#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->pdev, cmd)#define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->pdev, cmd)#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->pdev, cmd)#define sync_scsi_data(np, cmd)		__sync_scsi_data(np->pdev, cmd)/*==========================================================****	SCSI data transfer direction****	Until some linux kernel version near 2.3.40, **	low-level scsi drivers were not told about data **	transfer direction. We check the existence of this **	feature that has been expected for a _long_ time by **	all SCSI driver developers by just testing against **	the definition of SCSI_DATA_UNKNOWN. Indeed this is **	a hack, but testing against a kernel version would **	have been a shame. ;-)****==========================================================*/#ifdef	SCSI_DATA_UNKNOWN#define scsi_data_direction(cmd)	(cmd->sc_data_direction)#else#define	SCSI_DATA_UNKNOWN	0#define	SCSI_DATA_WRITE		1#define	SCSI_DATA_READ		2#define	SCSI_DATA_NONE		3static __inline__ int scsi_data_direction(Scsi_Cmnd *cmd){	int direction;	switch((int) cmd->cmnd[0]) {	case 0x08:  /*	READ(6)				08 */	case 0x28:  /*	READ(10)			28 */	case 0xA8:  /*	READ(12)			A8 */		direction = SCSI_DATA_READ;		break;	case 0x0A:  /*	WRITE(6)			0A */	case 0x2A:  /*	WRITE(10)			2A */	case 0xAA:  /*	WRITE(12)			AA */		direction = SCSI_DATA_WRITE;		break;	default:		direction = SCSI_DATA_UNKNOWN;		break;	}	return direction;}#endif	/* SCSI_DATA_UNKNOWN *//*==========================================================****	Driver setup.****	This structure is initialized from linux config **	options. It can be overridden at boot-up by the boot **	command line.****==========================================================*/static struct ncr_driver_setup	driver_setup			= SCSI_NCR_DRIVER_SETUP;#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORTstatic struct ncr_driver_setup	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;#endif#define initverbose (driver_setup.verbose)#define bootverbose (np->verbose)/*==========================================================****	Big/Little endian support.****	If the NCR uses big endian addressing mode over the **	PCI, actual io register addresses for byte and word **	accesses must be changed according to lane routing.**	Btw, ncr_offb() and ncr_offw() macros only apply to **	constants and so donnot generate bloated code.****	If the CPU and the NCR use same endian-ness adressing,**	no byte reordering is needed for script patching.**	Macro cpu_to_scr() is to be used for script patching.**	Macro scr_to_cpu() is to be used for getting a DWORD **	from the script.****==========================================================*/#if	defined(SCSI_NCR_BIG_ENDIAN)#define ncr_offb(o)	(((o)&~3)+((~((o)&3))&3))#define ncr_offw(o)	(((o)&~3)+((~((o)&3))&2))#else#define ncr_offb(o)	(o)#define ncr_offw(o)	(o)#endif#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define cpu_to_scr(dw)	cpu_to_le32(dw)#define scr_to_cpu(dw)	le32_to_cpu(dw)#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define cpu_to_scr(dw)	cpu_to_be32(dw)#define scr_to_cpu(dw)	be32_to_cpu(dw)#else#define cpu_to_scr(dw)	(dw)#define scr_to_cpu(dw)	(dw)#endif/*==========================================================****	Access to the controller chip.****	If NCR_IOMAPPED is defined, the driver will use **	normal IOs instead of the MEMORY MAPPED IO method  **	recommended by PCI specifications.**	If all PCI bridges, host brigdes and architectures **	would have been correctly designed for PCI, this **	option would be useless.****	If the CPU and the NCR use same endian-ness adressing,**	no byte reordering is needed for accessing chip io **	registers. Functions suffixed by '_raw' are assumed **	to access the chip over the PCI without doing byte **	reordering. Functions suffixed by '_l2b' are **	assumed to perform little-endian to big-endian byte **	reordering, those suffixed by '_b2l' blah, blah,**	blah, ...****==========================================================*/#if defined(NCR_IOMAPPED)/***	IO mapped only input / ouput*/#define	INB_OFF(o)		inb (np->base_io + ncr_offb(o))#define	OUTB_OFF(o, val)	outb ((val), np->base_io + ncr_offb(o))#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define	INW_OFF(o)		inw_l2b (np->base_io + ncr_offw(o))#define	INL_OFF(o)		inl_l2b (np->base_io + (o))#define	OUTW_OFF(o, val)	outw_b2l ((val), np->base_io + ncr_offw(o))#define	OUTL_OFF(o, val)	outl_b2l ((val), np->base_io + (o))#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define	INW_OFF(o)		inw_b2l (np->base_io + ncr_offw(o))#define	INL_OFF(o)		inl_b2l (np->base_io + (o))#define	OUTW_OFF(o, val)	outw_l2b ((val), np->base_io + ncr_offw(o))#define	OUTL_OFF(o, val)	outl_l2b ((val), np->base_io + (o))#else#define	INW_OFF(o)		inw_raw (np->base_io + ncr_offw(o))#define	INL_OFF(o)		inl_raw (np->base_io + (o))#define	OUTW_OFF(o, val)	outw_raw ((val), np->base_io + ncr_offw(o))#define	OUTL_OFF(o, val)	outl_raw ((val), np->base_io + (o))#endif	/* ENDIANs */#else	/* defined NCR_IOMAPPED *//***	MEMORY mapped IO input / output*/#define INB_OFF(o)		readb((char *)np->reg + ncr_offb(o))#define OUTB_OFF(o, val)	writeb((val), (char *)np->reg + ncr_offb(o))#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o)		readw_l2b((char *)np->reg + ncr_offw(o))#define INL_OFF(o)		readl_l2b((char *)np->reg + (o))#define OUTW_OFF(o, val)	writew_b2l((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val)	writel_b2l((val), (char *)np->reg + (o))#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o)		readw_b2l((char *)np->reg + ncr_offw(o))#define INL_OFF(o)		readl_b2l((char *)np->reg + (o))#define OUTW_OFF(o, val)	writew_l2b((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val)	writel_l2b((val), (char *)np->reg + (o))#else#define INW_OFF(o)		readw_raw((char *)np->reg + ncr_offw(o))#define INL_OFF(o)		readl_raw((char *)np->reg + (o))#define OUTW_OFF(o, val)	writew_raw((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val)	writel_raw((val), (char *)np->reg + (o))#endif#endif	/* defined NCR_IOMAPPED */#define INB(r)		INB_OFF (offsetof(struct ncr_reg,r))#define INW(r)		INW_OFF (offsetof(struct ncr_reg,r))#define INL(r)		INL_OFF (offsetof(struct ncr_reg,r))#define OUTB(r, val)	OUTB_OFF (offsetof(struct ncr_reg,r), (val))#define OUTW(r, val)	OUTW_OFF (offsetof(struct ncr_reg,r), (val))#define OUTL(r, val)	OUTL_OFF (offsetof(struct ncr_reg,r), (val))/***	Set bit field ON, OFF */#define OUTONB(r, m)	OUTB(r, INB(r) | (m))#define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))#define OUTONW(r, m)	OUTW(r, INW(r) | (m))#define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))#define OUTONL(r, m)	OUTL(r, INL(r) | (m))#define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))/*==========================================================****	Structures used by the detection routine to transmit **	device configuration to the attach function.****==========================================================*/typedef struct {	int	bus;	u_char	device_fn;	u_long	base;	u_long	base_2;	u_long	io_port;	int	irq;/* port and reg fields to use INB, OUTB macros */	u_long	base_io;	volatile struct ncr_reg	*reg;} ncr_slot;/*==========================================================****	Structure used to store the NVRAM content.****==========================================================*/typedef struct {	int type;#define	SCSI_NCR_SYMBIOS_NVRAM	(1)#define	SCSI_NCR_TEKRAM_NVRAM	(2)#ifdef	SCSI_NCR_NVRAM_SUPPORT	union {		Symbios_nvram Symbios;		Tekram_nvram Tekram;	} data;#endif} ncr_nvram;/*==========================================================****	Structure used by detection routine to save data on **	each detected board for attach.****==========================================================*/typedef struct {	pcidev_t  pdev;	ncr_slot  slot;	ncr_chip  chip;	ncr_nvram *nvram;	u_char host_id;#ifdef	SCSI_NCR_PQS_PDS_SUPPORT	u_char pqs_pds;#endif	int attach_done;} ncr_device;static int ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device);/*==========================================================****	NVRAM detection and reading.**	 **	Currently supported:**	- 24C16 EEPROM with both Symbios and Tekram layout.**	- 93C46 EEPROM with Tekram layout.****==========================================================*/#ifdef SCSI_NCR_NVRAM_SUPPORT/* *  24C16 EEPROM reading. * *  GPOI0 - data in/data out *  GPIO1 - clock *  Symbios NVRAM wiring now also used by Tekram. */#define SET_BIT 0#define CLR_BIT 1#define SET_CLK 2#define CLR_CLK 3/* *  Set/clear data/clock bit in GPIO0 */static void __initS24C16_set_bit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode){	UDELAY (5);	switch (bit_mode){	case SET_BIT:		*gpreg |= write_bit;		break;	case CLR_BIT:		*gpreg &= 0xfe;		break;	case SET_CLK:		*gpreg |= 0x02;		break;	case CLR_CLK:		*gpreg &= 0xfd;		break;	}	OUTB (nc_gpreg, *gpreg);	UDELAY (5);}/* *  Send START condition to NVRAM to wake it up. */static void __init S24C16_start(ncr_slot *np, u_char *gpreg){	S24C16_set_bit(np, 1, gpreg, SET_BIT);	S24C16_set_bit(np, 0, gpreg, SET_CLK);	S24C16_set_bit(np, 0, gpreg, CLR_BIT);	S24C16_set_bit(np, 0, gpreg, CLR_CLK);}/* *  Send STOP condition to NVRAM - puts NVRAM to sleep... ZZzzzz!! */static void __init S24C16_stop(ncr_slot *np, u_char *gpreg){	S24C16_set_bit(np, 0, gpreg, SET_CLK);	S24C16_set_bit(np, 1, gpreg, SET_BIT);}/* *  Read or write a bit to the NVRAM, *  read if GPIO0 input else write if GPIO0 output */static void __init S24C16_do_bit(ncr_slot *np, u_char *read_bit, u_char write_bit, u_char *gpreg){	S24C16_set_bit(np, write_bit, gpreg, SET_BIT);	S24C16_set_bit(np, 0, gpreg, SET_CLK);	if (read_bit)		*read_bit = INB (nc_gpreg);	S24C16_set_bit(np, 0, gpreg, CLR_CLK);	S24C16_set_bit(np, 0, gpreg, CLR_BIT);}/* *  Output an ACK to the NVRAM after reading, *  change GPIO0 to output and when done back to an input */static void __initS24C16_write_ack(ncr_slot *np, u_char write_bit, u_char *gpreg, u_char *gpcntl){	OUTB (nc_gpcntl, *gpcntl & 0xfe);	S24C16_do_bit(np, 0, write_bit, gpreg);	OUTB (nc_gpcntl, *gpcntl);}/* *  Input an ACK from NVRAM after writing, *  change GPIO0 to input and when done back to an output */static void __init S24C16_read_ack(ncr_slot *np, u_char *read_bit, u_char *gpreg, u_char *gpcntl){	OUTB (nc_gpcntl, *gpcntl | 0x01);	S24C16_do_bit(np, read_bit, 1, gpreg);	OUTB (nc_gpcntl, *gpcntl);}/* *  WRITE a byte to the NVRAM and then get an ACK to see it was accepted OK, *  GPIO0 must already be set as an output */static void __init S24C16_write_byte(ncr_slot *np, u_char *ack_data, u_char write_data, 		  u_char *gpreg, u_char *gpcntl){	int x;		for (x = 0; x < 8; x++)		S24C16_do_bit(np, 0, (write_data >> (7 - x)) & 0x01, gpreg);			S24C16_read_ack(np, ack_data, gpreg, gpcntl);}/* *  READ a byte from the NVRAM and then send an ACK to say we have got it, *  GPIO0 must already be set as an input */static void __init S24C16_read_byte(ncr_slot *np, u_char *read_data, u_char ack_data, 	         u_char *gpreg, u_char *gpcntl){	int x;	u_char read_bit;	*read_data = 0;	for (x = 0; x < 8; x++) {		S24C16_do_bit(np, &read_bit, 1, gpreg);		*read_data |= ((read_bit & 0x01) << (7 - x));	}	S24C16_write_ack(np, ack_data, gpreg, gpcntl);}/* *  Read 'len' bytes starting at 'offset'. */static int __init sym_read_S24C16_nvram (ncr_slot *np, int offset, u_char *data, int len){	u_char	gpcntl, gpreg;	u_char	old_gpcntl, old_gpreg;	u_char	ack_data;	int	retv = 1;	int	x;	/* save current state of GPCNTL and GPREG */	old_gpreg	= INB (nc_gpreg);	old_gpcntl	= INB (nc_gpcntl);	gpcntl		= old_gpcntl & 0xfc;	/* set up GPREG & GPCNTL to set GPIO0 and GPIO1 in to known state */	OUTB (nc_gpreg,  old_gpreg);	OUTB (nc_gpcntl, gpcntl);	/* this is to set NVRAM into a known state with GPIO0/1 both low */	gpreg = old_gpreg;	S24C16_set_bit(np, 0, &gpreg, CLR_CLK);	S24C16_set_bit(np, 0, &gpreg, CLR_BIT);			/* now set NVRAM inactive with GPIO0/1 both high */	S24C16_stop(np, &gpreg);		/* activate NVRAM */	S24C16_start(np, &gpreg);	/* write device code and random address MSB */	S24C16_write_byte(np, &ack_data,		0xa0 | ((offset >> 7) & 0x0e), &gpreg, &gpcntl);	if (ack_data & 0x01)		goto out;	/* write random address LSB */	S24C16_write_byte(np, &ack_data,		offset & 0xff, &gpreg, &gpcntl);	if (ack_data & 0x01)		goto out;	/* regenerate START state to set up for reading */	S24C16_start(np, &gpreg);		/* rewrite device code and address MSB with read bit set (lsb = 0x01) */	S24C16_write_byte(np, &ack_data,		0xa1 | ((offset >> 7) & 0x0e), &gpreg, &gpcntl);	if (ack_data & 0x01)		goto out;	/* now set up GPIO0 for inputting data */	gpcntl |= 0x01;	OUTB (nc_gpcntl, gpcntl);			/* input all requested data - only part of total NVRAM */	for (x = 0; x < len; x++) 		S24C16_read_byte(np, &data[x], (x == (len-1)), &gpreg, &gpcntl);	/* finally put NVRAM back in inactive mode */

⌨️ 快捷键说明

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