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

📄 i2o_block.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		 *    The device list connected to the I2O Controller is doubly linked		 * Here we traverse the end of the list , and start claiming devices		 * from that end. This assures that within an I2O controller atleast		 * the newly created volumes get claimed after the older ones, thus		 * mapping to same major/minor (and hence device file name) after 		 * every reboot.		 * The exception being: 		 * 1. If there was a TID reuse.		 * 2. There was more than one I2O controller. 		 */		if(!bios)		{			for (d=c->devices;d!=NULL;d=d->next)			if(d->next == NULL)				b = d;		}		else			b = c->devices;		while(b != NULL)		{			d=b;			if(bios)				b = b->next;			else				b = b->prev;			if(d->lct_data.class_id!=I2O_CLASS_RANDOM_BLOCK_STORAGE)				continue;			if(d->lct_data.user_tid != 0xFFF)				continue;			if(bios)			{				if(d->lct_data.bios_info != 0x80)					continue;				printk(KERN_INFO "Claiming as Boot device: Controller %d, TID %d\n", c->unit, d->lct_data.tid);			}			else			{				if(d->lct_data.bios_info == 0x80)					continue; /*Already claimed on pass 1 */			}			if(i2o_claim_device(d, &i2o_block_handler))			{				printk(KERN_WARNING "i2o_block: Controller %d, TID %d\n", c->unit,					d->lct_data.tid);				printk(KERN_WARNING "\t%sevice refused claim! Skipping installation\n", bios?"Boot d":"D");				continue;			}			if(scan_unit<MAX_I2OB<<4)			{ 				/*				 * Get the device and fill in the				 * Tid and controller.				 */				dev=&i2ob_dev[scan_unit];				dev->i2odev = d; 				dev->controller = c;				dev->unit = c->unit;				dev->tid = d->lct_data.tid;				if(i2ob_install_device(c,d,scan_unit))					printk(KERN_WARNING "Could not install I2O block device\n");				else				{					scan_unit+=16;					i2ob_dev_count++;					/* We want to know when device goes away */					i2o_device_notify_on(d, &i2o_block_handler);				}			}			else			{				if(!warned++)					printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", scan_unit>>4);			}			i2o_release_device(d, &i2o_block_handler);		}		i2o_unlock_controller(c);	}}static void i2ob_probe(void){	/*	 *      Some overhead/redundancy involved here, while trying to	 *      claim the first boot volume encountered as /dev/i2o/hda	 *      everytime. All the i2o_controllers are searched and the	 *      first i2o block device marked as bootable is claimed	 *      If an I2O block device was booted off , the bios sets	 *      its bios_info field to 0x80, this what we search for.	 *      Assuming that the bootable volume is /dev/i2o/hda	 *      everytime will prevent any kernel panic while mounting	 *      root partition	 */	printk(KERN_INFO "i2o_block: Checking for Boot device...\n");	i2ob_scan(1);	/*	 *      Now the remainder.	 */	printk(KERN_INFO "i2o_block: Checking for I2O Block devices...\n");	i2ob_scan(0);}/* * New device notification handler.  Called whenever a new * I2O block storage device is added to the system. *  * Should we spin lock around this to keep multiple devs from  * getting updated at the same time?  *  */void i2ob_new_device(struct i2o_controller *c, struct i2o_device *d){	struct i2ob_device *dev;	int unit = 0;	printk(KERN_INFO "i2o_block: New device detected\n");	printk(KERN_INFO "   Controller %d Tid %d\n",c->unit, d->lct_data.tid);	/* Check for available space */	if(i2ob_dev_count>=MAX_I2OB<<4)	{		printk(KERN_ERR "i2o_block: No more devices allowed!\n");		return;	}	for(unit = 0; unit < (MAX_I2OB<<4); unit += 16)	{		if(!i2ob_dev[unit].i2odev)			break;	}	if(i2o_claim_device(d, &i2o_block_handler))	{		printk(KERN_INFO 			"i2o_block: Unable to claim device. Installation aborted\n");		return;	}	dev = &i2ob_dev[unit];	dev->i2odev = d; 	dev->controller = c;	dev->tid = d->lct_data.tid;	if(i2ob_install_device(c,d,unit))		printk(KERN_ERR "i2o_block: Could not install new device\n");	else		{		i2ob_dev_count++;		i2o_device_notify_on(d, &i2o_block_handler);	}	i2o_release_device(d, &i2o_block_handler); 	return;}/* * Deleted device notification handler.  Called when a device we * are talking to has been deleted by the user or some other * mysterious fource outside the kernel. */void i2ob_del_device(struct i2o_controller *c, struct i2o_device *d){		int unit = 0;	int i = 0;	unsigned long flags;	spin_lock_irqsave(&io_request_lock, flags);	/*	 * Need to do this...we somtimes get two events from the IRTOS	 * in a row and that causes lots of problems.	 */	i2o_device_notify_off(d, &i2o_block_handler);	printk(KERN_INFO "I2O Block Device Deleted\n");	for(unit = 0; unit < MAX_I2OB<<4; unit += 16)	{		if(i2ob_dev[unit].i2odev == d)		{			printk(KERN_INFO "  /dev/%s: Controller %d Tid %d\n", 				d->dev_name, c->unit, d->lct_data.tid);			break;		}	}	if(unit >= MAX_I2OB<<4)	{		printk(KERN_ERR "i2ob_del_device called, but not in dev table!\n");		spin_unlock_irqrestore(&io_request_lock, flags);		return;	}	/* 	 * This will force errors when i2ob_get_queue() is called	 * by the kenrel.	 */	i2ob_dev[unit].req_queue = NULL;	for(i = unit; i <= unit+15; i++)	{		i2ob_dev[i].i2odev = NULL;		i2ob_sizes[i] = 0;		i2ob_hardsizes[i] = 0;		i2ob_max_sectors[i] = 0;		i2ob[i].nr_sects = 0;		i2ob_gendisk.part[i].nr_sects = 0;	}	spin_unlock_irqrestore(&io_request_lock, flags);	/*	 * Decrease usage count for module	 */		while(i2ob_dev[unit].refcnt--)		MOD_DEC_USE_COUNT;	i2ob_dev[unit].refcnt = 0;		i2ob_dev[i].tid = 0;	/* 	 * Do we need this?	 * The media didn't really change...the device is just gone	 */	i2ob_media_change_flag[unit] = 1;	i2ob_dev_count--;	}/* *	Have we seen a media change ? */static int i2ob_media_change(kdev_t dev){	int i=MINOR(dev);	i>>=4;	if(i2ob_media_change_flag[i])	{		i2ob_media_change_flag[i]=0;		return 1;	}	return 0;}static int i2ob_revalidate(kdev_t dev){	return do_i2ob_revalidate(dev, 0);}/* * Reboot notifier.  This is called by i2o_core when the system * shuts down. */static void i2ob_reboot_event(void){	int i;		for(i=0;i<MAX_I2OB;i++)	{		struct i2ob_device *dev=&i2ob_dev[(i<<4)];				if(dev->refcnt!=0)		{			/*			 *	Flush the onboard cache			 */			u32 msg[5];			int *query_done = &dev->done_flag;			msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;			msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;			msg[2] = i2ob_context|0x40000000;			msg[3] = (u32)query_done;			msg[4] = 60<<16;						DEBUG("Flushing...");			i2o_post_wait(dev->controller, msg, 20, 60);			DEBUG("Unlocking...");			/*			 *	Unlock the media			 */			msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;			msg[1] = I2O_CMD_BLOCK_MUNLOCK<<24|HOST_TID<<12|dev->tid;			msg[2] = i2ob_context|0x40000000;			msg[3] = (u32)query_done;			msg[4] = -1;			i2o_post_wait(dev->controller, msg, 20, 2);						DEBUG("Unlocked.\n");		}	}	}static struct block_device_operations i2ob_fops ={	owner:			THIS_MODULE,	open:			i2ob_open,	release:		i2ob_release,	ioctl:			i2ob_ioctl,	check_media_change:	i2ob_media_change,	revalidate:		i2ob_revalidate,};static struct gendisk i2ob_gendisk = {	major:		MAJOR_NR,	major_name:	"i2o/hd",	minor_shift:	4,	max_p:		1<<4,	part:		i2ob,	sizes:		i2ob_sizes,	nr_real:	MAX_I2OB,	fops:		&i2ob_fops,};/* * And here should be modules and kernel interface  *  (Just smiley confuses emacs :-) */#ifdef MODULE#define i2o_block_init init_module#endifint i2o_block_init(void){	int i;	printk(KERN_INFO "I2O Block Storage OSM v0.9\n");	printk(KERN_INFO "   (c) Copyright 1999-2001 Red Hat Software.\n");		/*	 *	Register the block device interfaces	 */	if (register_blkdev(MAJOR_NR, "i2o_block", &i2ob_fops)) {		printk(KERN_ERR "Unable to get major number %d for i2o_block\n",		       MAJOR_NR);		return -EIO;	}#ifdef MODULE	printk(KERN_INFO "i2o_block: registered device at major %d\n", MAJOR_NR);#endif	/*	 *	Now fill in the boiler plate	 */	 	blksize_size[MAJOR_NR] = i2ob_blksizes;	hardsect_size[MAJOR_NR] = i2ob_hardsizes;	blk_size[MAJOR_NR] = i2ob_sizes;	max_sectors[MAJOR_NR] = i2ob_max_sectors;	blk_dev[MAJOR_NR].queue = i2ob_get_queue;		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request);	blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);	for (i = 0; i < MAX_I2OB << 4; i++) {		i2ob_dev[i].refcnt = 0;		i2ob_dev[i].flags = 0;		i2ob_dev[i].controller = NULL;		i2ob_dev[i].i2odev = NULL;		i2ob_dev[i].tid = 0;		i2ob_dev[i].head = NULL;		i2ob_dev[i].tail = NULL;		i2ob_dev[i].depth = MAX_I2OB_DEPTH;		i2ob_blksizes[i] = 1024;		i2ob_max_sectors[i] = 2;	}		/*	 *	Set up the queue	 */	for(i = 0; i < MAX_I2O_CONTROLLERS; i++)	{		i2ob_queues[i] = NULL;	}	/*	 *	Timers	 */	 	init_timer(&i2ob_timer);	i2ob_timer.function = i2ob_timer_handler;	i2ob_timer.data = 0;		/*	 *	Register the OSM handler as we will need this to probe for	 *	drives, geometry and other goodies.	 */	if(i2o_install_handler(&i2o_block_handler)<0)	{		unregister_blkdev(MAJOR_NR, "i2o_block");		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));		printk(KERN_ERR "i2o_block: unable to register OSM.\n");		return -EINVAL;	}	i2ob_context = i2o_block_handler.context;	 	/*	 * Initialize event handling thread	 */	init_MUTEX_LOCKED(&i2ob_evt_sem);	evt_pid = kernel_thread(i2ob_evt, NULL, CLONE_SIGHAND);	if(evt_pid < 0)	{		printk(KERN_ERR 			"i2o_block: Could not initialize event thread.  Aborting\n");		i2o_remove_handler(&i2o_block_handler);		return 0;	}	/*	 *	Finally see what is actually plugged in to our controllers	 */	for (i = 0; i < MAX_I2OB; i++)		register_disk(&i2ob_gendisk, MKDEV(MAJOR_NR,i<<4), 1<<4,			&i2ob_fops, 0);	i2ob_probe();	/*	 *	Adding i2ob_gendisk into the gendisk list.	 */	add_gendisk(&i2ob_gendisk);	return 0;}#ifdef MODULEEXPORT_NO_SYMBOLS;MODULE_AUTHOR("Red Hat Software");MODULE_DESCRIPTION("I2O Block Device OSM");MODULE_LICENSE("GPL");void cleanup_module(void){	int i;		if(evt_running) {		printk(KERN_INFO "Killing I2O block threads...");		i = kill_proc(evt_pid, SIGTERM, 1);		if(!i) {			printk("waiting...");		}		/* Be sure it died */		wait_for_completion(&i2ob_thread_dead);		printk("done.\n");	}	/*	 * Unregister for updates from any devices..otherwise we still	 * get them and the core jumps to random memory :O	 */	if(i2ob_dev_count) {		struct i2o_device *d;		for(i = 0; i < MAX_I2OB; i++)		if((d=i2ob_dev[i<<4].i2odev)) {			i2o_device_notify_off(d, &i2o_block_handler);			i2o_event_register(d->controller, d->lct_data.tid, 				i2ob_context, i<<4, 0);		}	}		/*	 *	We may get further callbacks for ourself. The i2o_core	 *	code handles this case reasonably sanely. The problem here	 *	is we shouldn't get them .. but a couple of cards feel 	 *	obliged to tell us stuff we dont care about.	 *	 *	This isnt ideal at all but will do for now.	 */	 	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(HZ);		/*	 *	Flush the OSM	 */	i2o_remove_handler(&i2o_block_handler);		 	/*	 *	Return the block device	 */	if (unregister_blkdev(MAJOR_NR, "i2o_block") != 0)		printk("i2o_block: cleanup_module failed\n");	/*	 * free request queue	 */	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));	del_gendisk(&i2ob_gendisk);}#endif

⌨️ 快捷键说明

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