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

📄 sym_nvram.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* 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);	/* NVRAM has to be written in segments of 16 bytes */	for (x = 0; x < len ; x += 16) {		do {			S24C16_start(np, &gpreg);			S24C16_write_byte(np, &ack_data,					  0xa0 | (((offset+x) >> 7) & 0x0e),					  &gpreg, &gpcntl);		} while (ack_data & 0x01);		S24C16_write_byte(np, &ack_data, (offset+x) & 0xff, 				  &gpreg, &gpcntl);		for (y = 0; y < 16; y++)			S24C16_write_byte(np, &ack_data, data[x+y], 					  &gpreg, &gpcntl);		S24C16_stop(np, &gpreg);	}	/* return GPIO0/1 to original states after having accessed NVRAM */	OUTB(np, nc_gpcntl, old_gpcntl);	OUTB(np, nc_gpreg,  old_gpreg);	return 0;}#endif /* SYM_CONF_NVRAM_WRITE_SUPPORT *//* *  Read 'len' bytes starting at 'offset'. */static int sym_read_S24C16_nvram(struct sym_device *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(np, nc_gpreg);	old_gpcntl	= INB(np, nc_gpcntl);	gpcntl		= old_gpcntl & 0x1c;	/* set up GPREG & GPCNTL to set GPIO0 and GPIO1 in to known state */	OUTB(np, nc_gpreg,  old_gpreg);	OUTB(np, 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(np, 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 */	gpcntl &= 0xfe;	OUTB(np, nc_gpcntl, gpcntl);	S24C16_stop(np, &gpreg);	retv = 0;out:	/* return GPIO0/1 to original states after having accessed NVRAM */	OUTB(np, nc_gpcntl, old_gpcntl);	OUTB(np, nc_gpreg,  old_gpreg);	return retv;}#undef SET_BIT#undef CLR_BIT#undef SET_CLK#undef CLR_CLK/* *  Try reading Symbios NVRAM. *  Return 0 if OK. */static int sym_read_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram){	static u_char Symbios_trailer[6] = {0xfe, 0xfe, 0, 0, 0, 0};	u_char *data = (u_char *) nvram;	int len  = sizeof(*nvram);	u_short	csum;	int x;	/* probe the 24c16 and read the SYMBIOS 24c16 area */	if (sym_read_S24C16_nvram (np, SYMBIOS_NVRAM_ADDRESS, data, len))		return 1;	/* check valid NVRAM signature, verify byte count and checksum */	if (nvram->type != 0 ||	    memcmp(nvram->trailer, Symbios_trailer, 6) ||	    nvram->byte_count != len - 12)		return 1;	/* verify checksum */	for (x = 6, csum = 0; x < len - 6; x++)		csum += data[x];	if (csum != nvram->checksum)		return 1;	return 0;}/* *  93C46 EEPROM reading. * *  GPOI0 - data in *  GPIO1 - data out *  GPIO2 - clock *  GPIO4 - chip select * *  Used by Tekram. *//* *  Pulse clock bit in GPIO0 */static void T93C46_Clk(struct sym_device *np, u_char *gpreg){	OUTB(np, nc_gpreg, *gpreg | 0x04);	INB(np, nc_mbox1);	udelay(2);	OUTB(np, nc_gpreg, *gpreg);}/*  *  Read bit from NVRAM */static void T93C46_Read_Bit(struct sym_device *np, u_char *read_bit, u_char *gpreg){	udelay(2);	T93C46_Clk(np, gpreg);	*read_bit = INB(np, nc_gpreg);}/* *  Write bit to GPIO0 */static void T93C46_Write_Bit(struct sym_device *np, u_char write_bit, u_char *gpreg){	if (write_bit & 0x01)		*gpreg |= 0x02;	else		*gpreg &= 0xfd;			*gpreg |= 0x10;			OUTB(np, nc_gpreg, *gpreg);	INB(np, nc_mbox1);	udelay(2);	T93C46_Clk(np, gpreg);}/* *  Send STOP condition to NVRAM - puts NVRAM to sleep... ZZZzzz!! */static void T93C46_Stop(struct sym_device *np, u_char *gpreg){	*gpreg &= 0xef;	OUTB(np, nc_gpreg, *gpreg);	INB(np, nc_mbox1);	udelay(2);	T93C46_Clk(np, gpreg);}/* *  Send read command and address to NVRAM */static void T93C46_Send_Command(struct sym_device *np, u_short write_data, 				u_char *read_bit, u_char *gpreg){	int x;	/* send 9 bits, start bit (1), command (2), address (6)  */	for (x = 0; x < 9; x++)		T93C46_Write_Bit(np, (u_char) (write_data >> (8 - x)), gpreg);	*read_bit = INB(np, nc_gpreg);}/* *  READ 2 bytes from the NVRAM */static void T93C46_Read_Word(struct sym_device *np,		unsigned short *nvram_data, unsigned char *gpreg){	int x;	u_char read_bit;	*nvram_data = 0;	for (x = 0; x < 16; x++) {		T93C46_Read_Bit(np, &read_bit, gpreg);		if (read_bit & 0x01)			*nvram_data |=  (0x01 << (15 - x));		else			*nvram_data &= ~(0x01 << (15 - x));	}}/* *  Read Tekram NvRAM data. */static int T93C46_Read_Data(struct sym_device *np, unsigned short *data,		int len, unsigned char *gpreg){	int x;	for (x = 0; x < len; x++)  {		unsigned char read_bit;		/* output read command and address */		T93C46_Send_Command(np, 0x180 | x, &read_bit, gpreg);		if (read_bit & 0x01)			return 1; /* Bad */		T93C46_Read_Word(np, &data[x], gpreg);		T93C46_Stop(np, gpreg);	}	return 0;}/* *  Try reading 93C46 Tekram NVRAM. */static int sym_read_T93C46_nvram(struct sym_device *np, Tekram_nvram *nvram){	u_char gpcntl, gpreg;	u_char old_gpcntl, old_gpreg;	int retv = 1;	/* save current state of GPCNTL and GPREG */	old_gpreg	= INB(np, nc_gpreg);	old_gpcntl	= INB(np, nc_gpcntl);	/* set up GPREG & GPCNTL to set GPIO0/1/2/4 in to known state, 0 in,	   1/2/4 out */	gpreg = old_gpreg & 0xe9;	OUTB(np, nc_gpreg, gpreg);	gpcntl = (old_gpcntl & 0xe9) | 0x09;	OUTB(np, nc_gpcntl, gpcntl);	/* input all of NVRAM, 64 words */	retv = T93C46_Read_Data(np, (u_short *) nvram,				sizeof(*nvram) / sizeof(short), &gpreg);		/* return GPIO0/1/2/4 to original states after having accessed NVRAM */	OUTB(np, nc_gpcntl, old_gpcntl);	OUTB(np, nc_gpreg,  old_gpreg);	return retv;}/* *  Try reading Tekram NVRAM. *  Return 0 if OK. */static int sym_read_Tekram_nvram (struct sym_device *np, Tekram_nvram *nvram){	u_char *data = (u_char *) nvram;	int len = sizeof(*nvram);	u_short	csum;	int x;	switch (np->device_id) {	case PCI_DEVICE_ID_NCR_53C885:	case PCI_DEVICE_ID_NCR_53C895:	case PCI_DEVICE_ID_NCR_53C896:		x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,					  data, len);		break;	case PCI_DEVICE_ID_NCR_53C875:		x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,					  data, len);		if (!x)			break;	default:		x = sym_read_T93C46_nvram(np, nvram);		break;	}	if (x)		return 1;	/* verify checksum */	for (x = 0, csum = 0; x < len - 1; x += 2)		csum += data[x] + (data[x+1] << 8);	if (csum != 0x1234)		return 1;	return 0;}#ifdef CONFIG_PARISC/* * Host firmware (PDC) keeps a table for altering SCSI capabilities. * Many newer machines export one channel of 53c896 chip as SE, 50-pin HD. * Also used for Multi-initiator SCSI clusters to set the SCSI Initiator ID. */static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *pdc){	struct hardware_path hwpath;	get_pci_node_path(np->pdev, &hwpath);	if (!pdc_get_initiator(&hwpath, pdc))		return 0;	return SYM_PARISC_PDC;}#elsestatic inline int sym_read_parisc_pdc(struct sym_device *np,					struct pdc_initiator *x){	return 0;}#endif/* *  Try reading Symbios or Tekram NVRAM */int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp){	if (!sym_read_Symbios_nvram(np, &nvp->data.Symbios)) {		nvp->type = SYM_SYMBIOS_NVRAM;		sym_display_Symbios_nvram(np, &nvp->data.Symbios);	} else if (!sym_read_Tekram_nvram(np, &nvp->data.Tekram)) {		nvp->type = SYM_TEKRAM_NVRAM;		sym_display_Tekram_nvram(np, &nvp->data.Tekram);	} else {		nvp->type = sym_read_parisc_pdc(np, &nvp->data.parisc);	}	return nvp->type;}char *sym_nvram_type(struct sym_nvram *nvp){	switch (nvp->type) {	case SYM_SYMBIOS_NVRAM:		return "Symbios NVRAM";	case SYM_TEKRAM_NVRAM:		return "Tekram NVRAM";	case SYM_PARISC_PDC:		return "PA-RISC Firmware";	default:		return "No NVRAM";	}}

⌨️ 快捷键说明

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