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

📄 8253xplx.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
字号:
/* -*- linux-c -*- *//* plx9050.c  * Copyright (C) 2000 by Francois Wautier * based on code from Bjorn Davis *  * Read and write command for the eprom attached to * the PLX9050  *//* Modifications and extensions * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc. * * 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 of the License, or (at your option) any later version. **//* We handle PCI devices */#include <linux/pci.h>      /* We need to use ioremap */ #include <asm/io.h>#include <linux/delay.h>				/* Joachim Martillo modified this file */				/* so that it had no dependencies on specific */				/* Aurora adapter card or ESSC* structures*/				/* The original file use TRUE for 1 and */				/* FALSE for 0.  This convention conflicted */				/* with other conventions throughout LINUX */				/* also TRUE was used for setting an eprom */				/* bit which is a slight semantic confusion. */				/* I just used 0 and 1 */#include "Reg9050.h"/* * Write a single bit to the serial EPROM interface. */				/* eprom_ctl is the */				/* address of the 9050 */				/* eprom control register */				/* The original & operation */				/* looks wrong.  I am surprised */				/* the code worked */ 				/* but I left the parentheses */				/* because readl, writel etc */				/* are macros*/				/* The following function */				/* assumes the proper bit */				/* in the serial eprom */				/* has already been selected*/				/* The 9050 registers are 32 bits */				/* hence the readl and writel */				/* macros are invoked*/				/* eprom_ctl must be a virtual */				/* address*/static void plx9050_eprom_wbit(unsigned int* eprom_ctl, unsigned int val){	unsigned int	 ctrl;		/* get the initial value of the CTRL register */	ctrl = readl((eprom_ctl));		/* set or clear the data bit */	if (val) 	{		ctrl |= PLX_CTRL_SEPWD;	}	else 	{		ctrl &= ~PLX_CTRL_SEPWD;	}		writel(ctrl, (eprom_ctl));		udelay(1);		/* Toggle the clock line */	/* gets to the next bit */	/* in the serial eprom */	ctrl |= PLX_CTRL_SEPCLK;	writel(ctrl, (eprom_ctl));		udelay(1);		/* Toggle the clock line */	ctrl &= ~PLX_CTRL_SEPCLK;	writel(ctrl, (eprom_ctl));	udelay(1);}/* * Run a serial EPROM command.  Returns 1 on success, *  0 otherwise. *//* This routine does the write of data but only sets up *//* for a read*//* the write goes from most significant to least significant */unsigned int plx9050_eprom_cmd(unsigned int* eprom_ctl, unsigned char cmd, unsigned char addr, unsigned short data){	unsigned int ctrl;	unsigned char shiftb;	unsigned short shiftw;	unsigned int l, v;	unsigned char ret;	int i;		ret = 1;	shiftb = addr << (NM93_BITS_PER_BYTE - NM93_ADDRBITS); /* looks a bizarre way to mask out unused bits */		ctrl = readl((eprom_ctl));		ctrl &= ~(PLX_CTRL_SEPCLK | PLX_CTRL_SEPWD);	writel(ctrl, (eprom_ctl));	udelay(1);		ctrl |= PLX_CTRL_SEPCS;	writel(ctrl, (eprom_ctl));		plx9050_eprom_wbit(eprom_ctl, 1);		/*	 * Clock out the command	 */		plx9050_eprom_wbit(eprom_ctl, (cmd & 0x02) != 0);	plx9050_eprom_wbit(eprom_ctl, (cmd & 0x01) != 0);		/*	 * Clock out the address	 */		i = NM93_ADDRBITS;	while (i != 0)		/* here we get to the correct */				/* short in the serial eprom*/	{		/* printf("Loop #1\n"); */		plx9050_eprom_wbit(eprom_ctl, (shiftb & 0x80) != 0);				shiftb <<= 1;		i--;	}		if (cmd == NM93_WRITECMD)	/* now do the write if */		/* a write is to be done*/	{			/* write data? */		/*		 * Clock out the data		 */				shiftw = data;				i = NM93_BITS_PER_WORD;		while (i != 0) {			/* printf("Loop #2\n"); */			plx9050_eprom_wbit(eprom_ctl, (shiftw & 0x8000) != 0);						shiftw <<= 1;			i--;		}				/*		 * De-assert chip select for a short period of time		 */		ctrl = readl((eprom_ctl));				ctrl &= ~PLX_CTRL_SEPCS;		writel(ctrl, (eprom_ctl));		udelay(2);				/*		 * Re-assert chip select		 */		ctrl |= PLX_CTRL_SEPCS;		writel(ctrl, (eprom_ctl));				/*		 * Wait for a low to high transition of DO		 */				i = 20000;		ctrl = readl((eprom_ctl));		l = (ctrl & PLX_CTRL_SEPRD);				while (i != 0) 		{			/* printf("Loop #3\n"); */			ctrl = readl((eprom_ctl));			v = (ctrl & PLX_CTRL_SEPRD);			if (v != 0 && l == 0) 			{				break;			}			l = v;			udelay(1);			i--;		}				if (i == 0) 		{			printk("plx9050: eprom didn't go low to high");			ret = 0;		}	}		if (cmd != NM93_READCMD)	/* not a read -- terminate */	{		/*		 * De-assert the chip select.		 */				ctrl = readl((eprom_ctl));		ctrl &= ~PLX_CTRL_SEPCS;		writel(ctrl,(eprom_ctl));	}	/* otherwise left in read state */	return ret;}/* * Read the serial EPROM.  Returns 1 on success, 0 on failure. * reads in shorts (i.e., 16 bits at a time.) * */unsigned intplx9050_eprom_read(unsigned int* eprom_ctl, unsigned short *ptr, unsigned char addr, unsigned short len){	unsigned short shiftw;	int i;	unsigned int ctrl;		if (!plx9050_eprom_cmd(eprom_ctl, NM93_READCMD, addr, (unsigned short) 0x0)) /* set up read */	{		return 0;	}		ctrl = readl((eprom_ctl));	/* synchronize */		while (len-- > 0)		/* now read one word at a time */	{		shiftw = 0;				ctrl &= ~PLX_CTRL_SEPCLK;		writel(ctrl, (eprom_ctl));				udelay(1);				i = NM93_BITS_PER_WORD;		while (1)			/* now read one bit at a time, */			/* left shifting each bit */		{			ctrl |= PLX_CTRL_SEPCLK;			writel(ctrl, (eprom_ctl));						udelay(1);						ctrl = readl((eprom_ctl));									if ((ctrl & PLX_CTRL_SEPRD) != 0) 			{				shiftw |= 0x1;			}						i--;			if (i == 0) 			{				break;			}			shiftw <<= 1;						ctrl &= ~PLX_CTRL_SEPCLK;			writel(ctrl, (eprom_ctl));			udelay(1);		}				*ptr++ = shiftw;	}		ctrl &= ~PLX_CTRL_SEPCS;	writel(ctrl, (eprom_ctl));		udelay(1);	ctrl &= ~PLX_CTRL_SEPCLK;	writel(ctrl, (eprom_ctl));		return 1;}

⌨️ 快捷键说明

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