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

📄 pg.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 2 页
字号:
}#endif#define	WR(c,r,v)	pi_write_regr(PI,c,r,v)#define	RR(c,r)		(pi_read_regr(PI,c,r))#define DRIVE           (0xa0+0x10*PG.drive)static void pg_sleep( int cs ){       current->state = TASK_INTERRUPTIBLE;	schedule_timeout(cs);}static int pg_wait( int unit, int go, int stop, int tmo, char * msg ){       int j, r, e, s, p;	PG.status = 0;	j = 0;	while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(time_before(jiffies,tmo))) {		if (j++ < PG_SPIN) udelay(PG_SPIN_DEL);		else pg_sleep(1);	}	if ((r&(STAT_ERR&stop))||time_after_eq(jiffies, tmo)) {	   s = RR(0,7);	   e = RR(0,1);	   p = RR(0,2);	   if (verbose > 1)	     printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n",		   PG.name,msg,s,e,p,time_after_eq(jiffies, tmo)?" timeout":"");	   if (time_after_eq(jiffies, tmo)) e |= 0x100;	   PG.status = (e >> 4) & 0xff;	   return -1;	}	return 0;}static int pg_command( int unit, char * cmd, int dlen, int tmo ){       int k;	pi_connect(PI);	WR(0,6,DRIVE);	if (pg_wait(unit,STAT_BUSY|STAT_DRQ,0,tmo,"before command")) {		pi_disconnect(PI);		return -1;	}	WR(0,4,dlen % 256);	WR(0,5,dlen / 256);	WR(0,7,0xa0);          /* ATAPI packet command */	if (pg_wait(unit,STAT_BUSY,STAT_DRQ,tmo,"command DRQ")) {		pi_disconnect(PI);		return -1;	}	if (RR(0,2) != 1) {	   printk("%s: command phase error\n",PG.name);	   pi_disconnect(PI);	   return -1;	}	pi_write_block(PI,cmd,12);	if (verbose > 1) {		printk("%s: Command sent, dlen=%d packet= ", PG.name,dlen);		for (k=0;k<12;k++) printk("%02x ",cmd[k]&0xff);		printk("\n");	}	return 0;}static int pg_completion( int unit, char * buf, int tmo){       int r, d, n, p;	r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,			tmo,"completion");	PG.dlen = 0;	while (RR(0,7)&STAT_DRQ) {	   d = (RR(0,4)+256*RR(0,5));	   n = ((d+3)&0xfffc);	   p = RR(0,2)&3;	   if (p == 0) pi_write_block(PI,buf,n);	   if (p == 2) pi_read_block(PI,buf,n);	   if (verbose > 1) printk("%s: %s %d bytes\n",PG.name,				    p?"Read":"Write",n);	   PG.dlen += (1-p)*d;	   buf += d;	   r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,			tmo,"completion");	}	pi_disconnect(PI); 	return r;}static int pg_reset( int unit ){	int	i, k, flg;	int	expect[5] = {1,1,1,0x14,0xeb};	pi_connect(PI);	WR(0,6,DRIVE);	WR(0,7,8);	pg_sleep(20*HZ/1000);	k = 0;	while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))		pg_sleep(1);	flg = 1;	for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);	if (verbose) {		printk("%s: Reset (%d) signature = ",PG.name,k);		for (i=0;i<5;i++) printk("%3x",RR(0,i+1));		if (!flg) printk(" (incorrect)");		printk("\n");	}		pi_disconnect(PI);	return flg-1;	}static void xs( char *buf, char *targ, int offs, int len ){	int	j,k,l;	j=0; l=0;	for (k=0;k<len;k++) 	   if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))		l=targ[j++]=buf[k+offs];	if (l==0x20) j--;	targ[j]=0;}static int pg_identify( int unit, int log ){	int 	s;	char	*ms[2] = {"master","slave"};	char	mf[10], id[18];	char    id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};	char	buf[36];	s = pg_command(unit,id_cmd,36,jiffies+PG_TMO);	if (s) return -1;	s = pg_completion(unit,buf,jiffies+PG_TMO);	if (s) return -1;	if (log) {		xs(buf,mf,8,8);		xs(buf,id,16,16);		printk("%s: %s %s, %s\n",PG.name,mf,id,ms[PG.drive]);	}	return 0;}static int pg_probe( int unit )/*	returns  0, with id set if drive is detected		-1, if drive detection failed*/{	if (PG.drive == -1) {	   for (PG.drive=0;PG.drive<=1;PG.drive++)		if (!pg_reset(unit)) return pg_identify(unit,1);	} else {	   if (!pg_reset(unit)) return pg_identify(unit,1);	}	return -1; }static int pg_detect( void ){	int	k, unit;	printk("%s: %s version %s, major %d\n",		name,name,PG_VERSION,major);	k = 0;	if (pg_drive_count == 0) {	    unit = 0;	    if (pi_init(PI,1,-1,-1,-1,-1,-1,pg_scratch,			PI_PG,verbose,PG.name)) {		if (!pg_probe(unit)) {			PG.present = 1;			k++;		} else pi_release(PI);	    }	} else for (unit=0;unit<PG_UNITS;unit++) if (DU[D_PRT])	    if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],			DU[D_PRO],DU[D_DLY],pg_scratch,PI_PG,verbose,			PG.name)) { 		if (!pg_probe(unit)) {			PG.present = 1;			k++;		} else pi_release(PI);	    }	if (k) return 0;	printk("%s: No ATAPI device detected\n",name);	return -1;}#define DEVICE_NR(dev)	(minor(dev) & 0x7F)static int pg_open (struct inode *inode, struct file *file){       int	unit = DEVICE_NR(inode->i_rdev);	if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;	if ( test_and_set_bit(0, &PG.access) ) {		return -EBUSY;	}	if (PG.busy) {		pg_reset(unit);		PG.busy = 0;	}	pg_identify(unit,(verbose>1));	PG.bufptr = kmalloc(PG_MAX_DATA,GFP_KERNEL);	if (PG.bufptr == NULL) {		clear_bit( 0, &PG.access ) ;		printk("%s: buffer allocation failed\n",PG.name);		return -ENOMEM;	}	return 0;}static int pg_release (struct inode *inode, struct file *file){	int	unit = DEVICE_NR(inode->i_rdev);	if ( unit >= PG_UNITS || !test_bit(0,&PG.access) )		return -EINVAL;	clear_bit( 0, &PG.access);	kfree(PG.bufptr);	PG.bufptr = NULL;	return 0;}static ssize_t pg_write(struct file * filp, const char * buf, 			size_t count, loff_t *ppos){       struct inode            *ino = filp->f_dentry->d_inode;	int                     unit = DEVICE_NR(ino->i_rdev);	struct pg_write_hdr     hdr;	int                     hs = sizeof(hdr);	if (PG.busy) return -EBUSY;	if (count < hs) return -EINVAL;		copy_from_user((char *)&hdr,buf,hs);	if (hdr.magic != PG_MAGIC) return -EINVAL;	if (hdr.dlen > PG_MAX_DATA) return -EINVAL;	if ((count - hs) > PG_MAX_DATA) return -EINVAL;	if (hdr.func == PG_RESET) {		if (count != hs) return -EINVAL;		if (pg_reset(unit)) return -EIO;		return count;	}	if (hdr.func != PG_COMMAND) return -EINVAL;	PG.start = jiffies;	PG.timeout = hdr.timeout*HZ + HZ/2 + jiffies;	if (pg_command(unit,hdr.packet,hdr.dlen,jiffies+PG_TMO)) {		if (PG.status & 0x10) return -ETIME;		return -EIO;	}	PG.busy = 1;	copy_from_user(PG.bufptr,buf+hs,count-hs);	return count;}static ssize_t pg_read(struct file * filp, char * buf, 		       size_t count, loff_t *ppos){  	struct inode 		*ino = filp->f_dentry->d_inode;	int			unit = DEVICE_NR(ino->i_rdev);	struct pg_read_hdr 	hdr;	int			hs = sizeof(hdr);	int			copy;	if (!PG.busy) return -EINVAL;	if (count < hs) return -EINVAL;	PG.busy = 0;	if (pg_completion(unit,PG.bufptr,PG.timeout))	  if (PG.status & 0x10) return -ETIME;	hdr.magic = PG_MAGIC;	hdr.dlen = PG.dlen;	copy = 0;	if (hdr.dlen < 0) {		hdr.dlen = -1 * hdr.dlen;		copy = hdr.dlen;		if (copy > (count - hs)) copy = count - hs;	}	hdr.duration = (jiffies - PG.start + HZ/2) / HZ;	hdr.scsi = PG.status & 0x0f;	copy_to_user(buf,(char *)&hdr,hs);	if (copy > 0) copy_to_user(buf+hs,PG.bufptr,copy);		return copy+hs;}/* end of pg.c */MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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