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

📄 pt.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	if ((k >= tmo) || (s & STAT_ERR)) {	   if (k >= tmo) printk("%s: %s DSC timeout\n",PT.name,msg);	     else printk("%s: %s stat=0x%x err=0x%x\n",PT.name,msg,s,e);	   pt_req_sense(unit,0);	   return 0;	}	return 1;}static void pt_media_access_cmd( int unit, int tmo, char *cmd, char *fun){	if (pt_command(unit,cmd,0,fun)) {		pt_req_sense(unit,0);		return;	}	pi_disconnect(PI);	pt_poll_dsc(unit,HZ,tmo,fun);}static void pt_rewind( int unit ){	char	rw_cmd[12] = {ATAPI_REWIND,0,0,0,0,0,0,0,0,0,0,0};	pt_media_access_cmd(unit,PT_REWIND_TMO,rw_cmd,"rewind");}static void pt_write_fm( int unit ){	char	wm_cmd[12] = {ATAPI_WFM,0,0,0,1,0,0,0,0,0,0,0};        pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark");}#define DBMSG(msg)      ((verbose>1)?(msg):NULL)static int pt_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);	pt_sleep(20*HZ/1000);        k = 0;        while ((k++ < PT_RESET_TMO) && (RR(1,6)&STAT_BUSY))                pt_sleep(HZ/10);	flg = 1;	for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);	if (verbose) {		printk("%s: Reset (%d) signature = ",PT.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 int pt_ready_wait( int unit, int tmo ){	char	tr_cmd[12] = {ATAPI_TEST_READY,0,0,0,0,0,0,0,0,0,0,0};	int	k, p;	k = 0;	while (k < tmo) {	  PT.last_sense = 0;	  pt_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));	  p = PT.last_sense;	  if (!p) return 0;	  if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;	  k++;          pt_sleep(HZ);	}	return 0x000020;	/* timeout */}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 xn( char *buf, int offs, int size ){	int	v,k;	v=0; 	for(k=0;k<size;k++) v=v*256+(buf[k+offs]&0xff);	return v;}static int pt_identify( int unit ){	int 	dt, 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    ms_cmd[12] = { ATAPI_MODE_SENSE,0,0x2a,0,36,0,0,0,0,0,0,0};	char    ls_cmd[12] = { ATAPI_LOG_SENSE,0,0x71,0,0,0,0,0,36,0,0,0};	char	buf[36];        s = pt_atapi(unit,id_cmd,36,buf,"identify");	if (s) return -1;	dt = buf[0] & 0x1f;	if (dt != 1) {	  	if (verbose) 		   printk("%s: Drive %d, unsupported type %d\n",				PT.name,PT.drive,dt);	  	return -1;       	}	xs(buf,mf,8,8);	xs(buf,id,16,16);	PT.flags = 0;	PT.capacity = 0;	PT.bs = 0;	if (!pt_ready_wait(unit,PT_READY_TMO)) PT.flags |= PT_MEDIA;        if (!pt_atapi(unit,ms_cmd,36,buf,"mode sense")) {          if (!(buf[2] & 0x80)) PT.flags |= PT_WRITE_OK;	  PT.bs = xn(buf,10,2);	}        if (!pt_atapi(unit,ls_cmd,36,buf,"log sense")) 		PT.capacity = xn(buf,24,4);        printk("%s: %s %s, %s",		PT.name,mf,id,ms[PT.drive]);        if (!(PT.flags & PT_MEDIA))                 printk(", no media\n");        else {  if (!(PT.flags & PT_WRITE_OK)) printk(", RO");                printk(", blocksize %d, %d MB\n",		       PT.bs,PT.capacity/1024);        }	return 0;}static int pt_probe( int unit )/*	returns  0, with id set if drive is detected	        -1, if drive detection failed*/{	if (PT.drive == -1) {	   for (PT.drive=0;PT.drive<=1;PT.drive++)		if (!pt_reset(unit)) return pt_identify(unit);	} else {	   if (!pt_reset(unit)) return pt_identify(unit);	}        return -1; }static int pt_detect( void ){	int	k, unit;	printk("%s: %s version %s, major %d\n",		name,name,PT_VERSION,major);	k = 0;	if (pt_drive_count == 0) {	    unit = 0;	    if (pi_init(PI,1,-1,-1,-1,-1,-1,pt_scratch,                        PI_PT,verbose,PT.name)) {	        if (!pt_probe(unit)) {			PT.present = 1;			k++;	        } else pi_release(PI);	    }	} else for (unit=0;unit<PT_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],pt_scratch,PI_PT,verbose,			PT.name)) {                 if (!pt_probe(unit)) {                        PT.present = 1;                        k++;                } else pi_release(PI);            }	if (k) return 0;	printk("%s: No ATAPI tape drive detected\n",name);	return -1;}#define DEVICE_NR(dev)	(MINOR(dev) % 128)static int pt_open (struct inode *inode, struct file *file){       int	unit = DEVICE_NR(inode->i_rdev);        if ((unit >= PT_UNITS) || (!PT.present)) return -ENODEV;        PT.access++;	if (PT.access > 1) {		PT.access--;		return -EBUSY;	}	pt_identify(unit);	if (!PT.flags & PT_MEDIA) {		PT.access--;		return -ENODEV;		}	if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) {		PT.access--;		return -EROFS;		}	if (!(MINOR(inode->i_rdev) & 128))		PT.flags |= PT_REWIND;	PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL);	if (PT.bufptr == NULL) {		PT.access--;		printk("%s: buffer allocation failed\n",PT.name);		return -ENOMEM;	}        return 0;}static int pt_ioctl(struct inode *inode,struct file *file,                    unsigned int cmd, unsigned long arg){	int unit;	struct mtop mtop;        if (!inode || !inode->i_rdev)		return -EINVAL;        unit = DEVICE_NR(inode->i_rdev);        if (unit >= PT_UNITS)		return -EINVAL;        if (!PT.present)		return -ENODEV;        switch (cmd) {	    case MTIOCTOP:			if (copy_from_user((char *)&mtop, (char *)arg, 			           sizeof(struct mtop))) return -EFAULT;		switch (mtop.mt_op) {		    case MTREW: 			pt_rewind(unit);			return 0;		    case MTWEOF:			pt_write_fm(unit);			return 0;		    default:				printk("%s: Unimplemented mt_op %d\n",PT.name,					mtop.mt_op);			return -EINVAL;		}            default:		printk("%s: Unimplemented ioctl 0x%x\n",PT.name,cmd);                return -EINVAL;        }}static int pt_release (struct inode *inode, struct file *file){        int	unit = DEVICE_NR(inode->i_rdev);        if ((unit >= PT_UNITS) || (PT.access <= 0))                 return -EINVAL;	lock_kernel();	if (PT.flags & PT_WRITING) pt_write_fm(unit);	if (PT.flags & PT_REWIND) pt_rewind(unit);		PT.access--;	kfree(PT.bufptr);	PT.bufptr = NULL;	unlock_kernel();	return 0;}static ssize_t pt_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);	char	rd_cmd[12] = {ATAPI_READ_6,1,0,0,0,0,0,0,0,0,0,0};	int	k, n, r, p, s, t, b;	if (!(PT.flags & (PT_READING|PT_WRITING))) {	    PT.flags |= PT_READING;	    if (pt_atapi(unit,rd_cmd,0,NULL,"start read-ahead"))			return -EIO;	} else if (PT.flags & PT_WRITING) return -EIO;	if (PT.flags & PT_EOF) return 0;	t = 0;	while (count > 0) {	    if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"read")) return -EIO;	    n = count;	    if (n > 32768) n = 32768;   /* max per command */	    b = (n-1+PT.bs)/PT.bs;	    n = b*PT.bs;		/* rounded up to even block */	    rd_cmd[4] = b;	    r = pt_command(unit,rd_cmd,n,"read");	    mdelay(1);	    if (r) {	        pt_req_sense(unit,0);	        return -EIO;	    }	    while (1) {	        r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,                                           DBMSG("read DRQ"),"");	        if (r & STAT_SENSE) {	            pi_disconnect(PI);		    pt_req_sense(unit,0);		    return -EIO;	        }	        if (r) PT.flags |= PT_EOF; 	        s = RR(0,7);	        if (!(s & STAT_DRQ)) break;	    	n = (RR(0,4)+256*RR(0,5));	    	p = (RR(0,2)&3);	    	if (p != 2) {		    pi_disconnect(PI);		    printk("%s: Phase error on read: %d\n",PT.name,p);		    return -EIO;	    	}	        while (n > 0) {		    k = n;		    if (k > PT_BUFSIZE) k = PT_BUFSIZE; 		    pi_read_block(PI,PT.bufptr,k);		    n -= k;		    b = k;		    if (b > count) b = count;		    if (copy_to_user(buf + t, PT.bufptr, b)) {	    		pi_disconnect(PI);			return -EFAULT;		    }		    t += b;		    count -= b;	        }	    }	    pi_disconnect(PI);	    if (PT.flags & PT_EOF) break;	}	return t;}static ssize_t pt_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);        char    wr_cmd[12] = {ATAPI_WRITE_6,1,0,0,0,0,0,0,0,0,0,0};        int     k, n, r, p, s, t, b;	if (!(PT.flags & PT_WRITE_OK)) return -EROFS;        if (!(PT.flags & (PT_READING|PT_WRITING))) {            PT.flags |= PT_WRITING;            if (pt_atapi(unit,wr_cmd,0,NULL,"start buffer-available mode"))                        return -EIO;        } else if (PT.flags&PT_READING) return -EIO;	if (PT.flags & PT_EOF) return -ENOSPC;	t = 0;	while (count > 0) {	    if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"write")) return -EIO;            n = count;            if (n > 32768) n = 32768;	/* max per command */            b = (n-1+PT.bs)/PT.bs;            n = b*PT.bs;                /* rounded up to even block */            wr_cmd[4] = b;            r = pt_command(unit,wr_cmd,n,"write");            mdelay(1);            if (r) {			/* error delivering command only */                pt_req_sense(unit,0);                return -EIO;            }	    while (1) {                r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,			                        DBMSG("write DRQ"),NULL);                if (r & STAT_SENSE) {                    pi_disconnect(PI);                    pt_req_sense(unit,0);                    return -EIO;                }                if (r) PT.flags |= PT_EOF;	        s = RR(0,7);	        if (!(s & STAT_DRQ)) break;                n = (RR(0,4)+256*RR(0,5));                p = (RR(0,2)&3);                if (p != 0) {                    pi_disconnect(PI);                    printk("%s: Phase error on write: %d \n",PT.name,p);                    return -EIO;                }                while (n > 0) {		    k = n;		    if (k > PT_BUFSIZE) k = PT_BUFSIZE;		    b = k;		    if (b > count) b = count;		    if (copy_from_user(PT.bufptr, buf + t, b)) {			pi_disconnect(PI);			return -EFAULT;		    }                    pi_write_block(PI,PT.bufptr,k);		    t += b;		    count -= b;		    n -= k;                }	    }	    pi_disconnect(PI);	    if (PT.flags & PT_EOF) break;	}	return t;}/* end of pt.c */MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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