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

📄 pd.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
		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++;	}}static inline int pd_new_segment(request_queue_t *q, struct request *req, int max_segments){	if (max_segments > cluster)		max_segments = cluster;	if (req->nr_segments < max_segments) {		req->nr_segments++;		q->elevator.nr_segments++;		return 1;	}	return 0;}static int pd_back_merge_fn(request_queue_t *q, struct request *req, 			    struct buffer_head *bh, int max_segments){	if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)		return 1;	return pd_new_segment(q, req, max_segments);}static int pd_front_merge_fn(request_queue_t *q, struct request *req, 			     struct buffer_head *bh, int max_segments){	if (bh->b_data + bh->b_size == req->bh->b_data)		return 1;	return pd_new_segment(q, req, max_segments);}static int pd_merge_requests_fn(request_queue_t *q, struct request *req,				struct request *next, int max_segments){	int total_segments = req->nr_segments + next->nr_segments;	int same_segment;	if (max_segments > cluster)		max_segments = cluster;	same_segment = 0;	if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) {		total_segments--;		same_segment = 1;	}    	if (total_segments > max_segments)		return 0;	q->elevator.nr_segments -= same_segment;	req->nr_segments = total_segments;	return 1;}int pd_init (void){       int i;	request_queue_t * q; 	if (disable) return -1;        if (devfs_register_blkdev(MAJOR_NR,name,&pd_fops)) {                printk("%s: unable to get major number %d\n",                        name,major);                return -1;        }	q = BLK_DEFAULT_QUEUE(MAJOR_NR);	blk_init_queue(q, DEVICE_REQUEST);	q->back_merge_fn = pd_back_merge_fn;	q->front_merge_fn = pd_front_merge_fn;	q->merge_requests_fn = pd_merge_requests_fn;        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);	pd_init_units();	pd_valid = 0;	pd_gendisk.nr_real = pd_detect();	pd_valid = 1;#ifdef MODULE        if (!pd_gendisk.nr_real) {		cleanup_module();		return -1;	}#endif        return 0;}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;	wait_event (pd_wait_open, pd_valid);        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 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 BLKRRPART:		if (!capable(CAP_SYS_ADMIN))			return -EACCES;                return pd_revalidate(inode->i_rdev);	    case BLKROSET:	    case BLKROGET:	    case BLKRASET:	    case BLKRAGET:	    case BLKFLSBUF:	    case BLKPG:		return blk_ioctl(inode->i_rdev, cmd, arg);            default:                return -EINVAL;        }}static int 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 -EINVAL;	PD.access--;        if (!PD.access && PD.removable)		pd_doorlock(unit,IDE_DOORUNLOCK);        MOD_DEC_USE_COUNT;	return 0;}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;	struct super_block *sb;        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);                sb = get_super(devp);                if (sb) invalidate_inodes(sb);                invalidate_buffers(devp);                pd_hd[minor].start_sect = 0;                pd_hd[minor].nr_sects = 0;        }	if (pd_identify(unit))		grok_partitions(&pd_gendisk,unit,1<<PD_BITS,PD.capacity);        pd_valid = 1;        wake_up(&pd_wait_open);        return 0;}#ifdef MODULE/* Glue for modules ... */void    cleanup_module(void);int     init_module(void){#ifdef PARIDE_JUMBO       { extern paride_init();         paride_init();       } #endif        return pd_init();}void    cleanup_module(void){       struct gendisk **gdp;	int unit;        devfs_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);}

⌨️ 快捷键说明

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