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

📄 pd.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		PD.access = 0;		PD.changed = 1;		PD.capacity = 0;		PD.drive = DU[D_SLV];		PD.present = 0;		j = 0;		while ((j < PD_NAMELEN-2) && (PD.name[j]=name[j])) j++;		PD.name[j++] = 'a' + unit;		PD.name[j] = 0;		PD.alt_geom = DU[D_GEO];		PD.standby = DU[D_SBY];		if (DU[D_PRT]) pd_drive_count++;	}}int pd_init (void){       int i;	if (disable) return -1;        if (register_blkdev(MAJOR_NR,name,&pd_fops)) {                printk("%s: unable to get major number %d\n",                        name,major);                return -1;        }        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */        	pd_gendisk.major = major;	pd_gendisk.major_name = name;	pd_gendisk.next = gendisk_head;        gendisk_head = &pd_gendisk;        for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;        blksize_size[MAJOR_NR] = pd_blocksizes;        printk("%s: %s version %s, major %d, cluster %d, nice %d\n",                name,name,PD_VERSION,major,cluster,nice);	        return 0;}static void pd_geninit (struct gendisk *ignored){	pd_init_units();	pd_gendisk.nr_real = pd_detect();#ifdef MODULE        if (!pd_gendisk.nr_real) cleanup_module();#endif}static int pd_open (struct inode *inode, struct file *file){       int unit = DEVICE_NR(inode->i_rdev);        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;        MOD_INC_USE_COUNT;        while (!pd_valid) sleep_on(&pd_wait_open);        PD.access++;        if (PD.removable) {		pd_media_check(unit);		pd_doorlock(unit,IDE_DOORLOCK);	}        return 0;}static int pd_ioctl(struct inode *inode,struct file *file,                    unsigned int cmd, unsigned long arg){       struct hd_geometry *geo = (struct hd_geometry *) arg;        int dev, err, unit;        if ((!inode) || (!inode->i_rdev)) return -EINVAL;        dev = MINOR(inode->i_rdev);	unit = DEVICE_NR(inode->i_rdev);        if (dev >= PD_DEVS) return -EINVAL;	if (!PD.present) return -ENODEV;        switch (cmd) {	    case CDROMEJECT:		if (PD.access == 1) pd_eject(unit);		return 0;            case HDIO_GETGEO:                if (!geo) return -EINVAL;                err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));                if (err) return err;		if (PD.alt_geom) {                    put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS), 		    		(short *) &geo->cylinders);                    put_user(PD_LOG_HEADS, (char *) &geo->heads);                    put_user(PD_LOG_SECTS, (char *) &geo->sectors);		} else {                    put_user(PD.cylinders, (short *) &geo->cylinders);                    put_user(PD.heads, (char *) &geo->heads);                    put_user(PD.sectors, (char *) &geo->sectors);		}                put_user(pd_hd[dev].start_sect,(long *)&geo->start);                return 0;            case BLKRASET:                if(!suser()) return -EACCES;                if(!(inode->i_rdev)) return -EINVAL;                if(arg > 0xff) return -EINVAL;                read_ahead[MAJOR(inode->i_rdev)] = arg;                return 0;            case BLKRAGET:                if (!arg) return -EINVAL;                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));                if (err) return (err);                put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);                return (0);            case BLKGETSIZE:                if (!arg) return -EINVAL;                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));                if (err) return (err);                put_user(pd_hd[dev].nr_sects,(long *) arg);                return (0);            case BLKFLSBUF:                if(!suser())  return -EACCES;                if(!(inode->i_rdev)) return -EINVAL;                fsync_dev(inode->i_rdev);                invalidate_buffers(inode->i_rdev);                return 0;            case BLKRRPART:		if (!suser()) return -EACCES;                return pd_revalidate(inode->i_rdev);            RO_IOCTLS(inode->i_rdev,arg);            default:                return -EINVAL;        }}static void pd_release (struct inode *inode, struct file *file){       kdev_t devp;	int	unit;        devp = inode->i_rdev;	unit = DEVICE_NR(devp);	if ((unit >= PD_UNITS) || (PD.access <= 0)) 		return;	PD.access--;        if (!PD.access)  {                fsync_dev(devp);		invalidate_inodes(devp);                invalidate_buffers(devp);		if (PD.removable) pd_doorlock(unit,IDE_DOORUNLOCK);	}        MOD_DEC_USE_COUNT;}static int pd_check_media( kdev_t dev){       int r, unit;	unit = DEVICE_NR(dev);	if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;        if (!PD.removable) return 0;	pd_media_check(unit);	r = PD.changed;	PD.changed = 0;	return r;}static int pd_revalidate(kdev_t dev){       int p, unit, minor;        long flags;        kdev_t devp;        unit = DEVICE_NR(dev);        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;        save_flags(flags);        cli();         if (PD.access > 1) {                restore_flags(flags);                return -EBUSY;        }        pd_valid = 0;        restore_flags(flags);           for (p=(PD_PARTNS-1);p>=0;p--) {		minor = p + unit*PD_PARTNS;                devp = MKDEV(MAJOR_NR, minor);                fsync_dev(devp);                invalidate_inodes(devp);                invalidate_buffers(devp);                pd_hd[minor].start_sect = 0;                pd_hd[minor].nr_sects = 0;        }	pd_identify(unit);        resetup_one_dev(&pd_gendisk,unit);        pd_valid = 1;        wake_up(&pd_wait_open);        return 0;}#ifdef MODULE/* Glue for modules ... */void    cleanup_module(void);int     init_module(void){       int     err, unit;#ifdef PARIDE_JUMBO       { extern paride_init();         paride_init();       } #endif        err = pd_init();        if (err) return err;	pd_geninit(&pd_gendisk);        if (!pd_gendisk.nr_real)  return -1;        pd_valid = 0;	for (unit=0;unit<PD_UNITS;unit++)           if (PD.present) resetup_one_dev(&pd_gendisk,unit);        pd_valid = 1;        return 0;}void    cleanup_module(void){       struct gendisk **gdp;	int unit;        unregister_blkdev(MAJOR_NR,name);        for(gdp=&gendisk_head;*gdp;gdp=&((*gdp)->next))                if (*gdp == &pd_gendisk) break;        if (*gdp) *gdp = (*gdp)->next;	for (unit=0;unit<PD_UNITS;unit++) 	   if (PD.present) pi_release(PI);}#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*PD.drive)/*  ide command interface */static void pd_print_error( int unit, char * msg, int status ){       int     i;	printk("%s: %s: status = 0x%x =",PD.name,msg,status);        for(i=0;i<18;i++) if (status & (1<<i)) printk(" %s",pd_errs[i]);	printk("\n");}static void pd_reset( int unit )    /* called only for MASTER drive */{       pi_connect(PI);	WR(1,6,4);        udelay(50);        WR(1,6,0);	pi_disconnect(PI);	udelay(250);}#define DBMSG(msg)    ((verbose>1)?(msg):NULL)static int pd_wait_for( int unit, int w, char * msg )    /* polled wait */{       int     k, r, e;        k=0;        while(k < PD_SPIN) {             r = RR(1,6);            k++;            if (((r & w) == w) && !(r & STAT_BUSY)) break;            udelay(PD_SPIN_DEL);        }        e = (RR(0,1)<<8) + RR(0,7);        if (k >= PD_SPIN)  e |= ERR_TMO;        if ((e & (STAT_ERR|ERR_TMO)) && (msg != NULL)) 		pd_print_error(unit,msg,e);        return e;}static void pd_send_command( int unit, int n, int s, int h, 			     int c0, int c1, int func ){        WR(0,6,DRIVE+h);        WR(0,1,0);                /* the IDE task file */        WR(0,2,n);        WR(0,3,s);        WR(0,4,c0);        WR(0,5,c1);        WR(0,7,func);        udelay(1);}static void pd_ide_command( int unit, int func, int block, int count )/* Don't use this call if the capacity is zero. */{       int c1, c0, h, s;        s  = ( block % PD.sectors) + 1;        h  = ( block / PD.sectors) % PD.heads;        c0 = ( block / (PD.sectors*PD.heads)) % 256;        c1 = ( block / (PD.sectors*PD.heads*256));        pd_send_command(unit,count,s,h,c0,c1,func);}/* According to the ATA standard, the default CHS geometry should be   available following a reset.  Some Western Digital drives come up   in a mode where only LBA addresses are accepted until the device   parameters are initialised.*/static void pd_init_dev_parms( int unit ) {       pi_connect(PI);        pd_wait_for(unit,0,DBMSG("before init_dev_parms"));        pd_send_command(unit,PD.sectors,0,PD.heads-1,0,0,IDE_INIT_DEV_PARMS);        udelay(300);        pd_wait_for(unit,0,"Initialise device parameters");        pi_disconnect(PI);}static void pd_doorlock( int unit, int func ){       pi_connect(PI);        if (pd_wait_for(unit,STAT_READY,"Lock") & STAT_ERR) {                pi_disconnect(PI);                return;        }        pd_send_command(unit,1,0,0,0,0,func);        pd_wait_for(unit,STAT_READY,"Lock done");        pi_disconnect(PI);}static void pd_eject( int unit ){	pi_connect(PI);        pd_wait_for(unit,0,DBMSG("before unlock on eject"));

⌨️ 快捷键说明

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