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

📄 dasd.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			   e.g. not _IN_IO */			cqr->status = DASD_CQR_FAILED;		cqr->stopclk = get_clock();		rc = 1;		break;	case DASD_CQR_DONE:	case DASD_CQR_FAILED:		/* already finished - do nothing */		break;	default:		DEV_MESSAGE(KERN_ALERT, device,			    "invalid status %02x in request",			    cqr->status);		BUG();	}	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);	dasd_schedule_bh(device);	return rc;}/* * SECTION: Block device operations (request queue, partitions, open, release). *//* * Dasd request queue function. Called from ll_rw_blk.c */static voiddo_dasd_request(request_queue_t * queue){	struct dasd_device *device;	device = (struct dasd_device *) queue->queuedata;	spin_lock(get_ccwdev_lock(device->cdev));	/* Get new request from the block device request queue */	__dasd_process_blk_queue(device);	/* Now check if the head of the ccw queue needs to be started. */	__dasd_start_head(device);	spin_unlock(get_ccwdev_lock(device->cdev));}/* * Allocate and initialize request queue. */static intdasd_alloc_queue(struct dasd_device * device){	device->request_queue = blk_init_queue(do_dasd_request,					       &device->request_queue_lock);	if (device->request_queue == NULL)		return -ENOMEM;	device->request_queue->queuedata = device;#if 0	elevator_exit(device->request_queue);	rc = elevator_init(device->request_queue, &elevator_noop);	if (rc) {		blk_cleanup_queue(device->request_queue);		return rc;	}#endif	return 0;}/* * Allocate and initialize request queue. */static voiddasd_setup_queue(struct dasd_device * device){	int max;	blk_queue_hardsect_size(device->request_queue, device->bp_block);	max = device->discipline->max_blocks << device->s2b_shift;	blk_queue_max_sectors(device->request_queue, max);	blk_queue_max_phys_segments(device->request_queue, -1L);	blk_queue_max_hw_segments(device->request_queue, -1L);	blk_queue_max_segment_size(device->request_queue, -1L);	blk_queue_segment_boundary(device->request_queue, -1L);}/* * Deactivate and free request queue. */static voiddasd_free_queue(struct dasd_device * device){	if (device->request_queue) {		blk_cleanup_queue(device->request_queue);		device->request_queue = NULL;	}}/* * Flush request on the request queue. */static voiddasd_flush_request_queue(struct dasd_device * device){	struct request *req;	if (!device->request_queue)		return;		spin_lock_irq(&device->request_queue_lock);	while (!list_empty(&device->request_queue->queue_head)) {		req = elv_next_request(device->request_queue);		if (req == NULL)			break;		dasd_end_request(req, 0);		blkdev_dequeue_request(req);	}	spin_unlock_irq(&device->request_queue_lock);}static intdasd_open(struct inode *inp, struct file *filp){	struct gendisk *disk = inp->i_bdev->bd_disk;	struct dasd_device *device = disk->private_data;	int rc;        atomic_inc(&device->open_count);	if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) {		rc = -ENODEV;		goto unlock;	}	if (!try_module_get(device->discipline->owner)) {		rc = -EINVAL;		goto unlock;	}	if (dasd_probeonly) {		MESSAGE(KERN_INFO,			"No access to device %s due to probeonly mode",			disk->disk_name);		rc = -EPERM;		goto out;	}	if (device->state < DASD_STATE_BASIC) {		DBF_DEV_EVENT(DBF_ERR, device, " %s",			      " Cannot open unrecognized device");		rc = -ENODEV;		goto out;	}	return 0;out:	module_put(device->discipline->owner);unlock:	atomic_dec(&device->open_count);	return rc;}static intdasd_release(struct inode *inp, struct file *filp){	struct gendisk *disk = inp->i_bdev->bd_disk;	struct dasd_device *device = disk->private_data;	atomic_dec(&device->open_count);	module_put(device->discipline->owner);	return 0;}struct block_device_operationsdasd_device_operations = {	.owner		= THIS_MODULE,	.open		= dasd_open,	.release	= dasd_release,	.ioctl		= dasd_ioctl,};static voiddasd_exit(void){#ifdef CONFIG_PROC_FS	dasd_proc_exit();#endif	dasd_ioctl_exit();	dasd_gendisk_exit();	dasd_devmap_exit();	devfs_remove("dasd");	if (dasd_debug_area != NULL) {		debug_unregister(dasd_debug_area);		dasd_debug_area = NULL;	}}/* * SECTION: common functions for ccw_driver use *//* initial attempt at a probe function. this can be simplified once * the other detection code is gone */intdasd_generic_probe (struct ccw_device *cdev,		    struct dasd_discipline *discipline){	int ret;	ret = dasd_add_sysfs_files(cdev);	if (ret) {		printk(KERN_WARNING		       "dasd_generic_probe: could not add sysfs entries "		       "for %s\n", cdev->dev.bus_id);	}	cdev->handler = &dasd_int_handler;	return ret;}/* this will one day be called from a global not_oper handler. * It is also used by driver_unregister during module unload */voiddasd_generic_remove (struct ccw_device *cdev){	struct dasd_device *device;	dasd_remove_sysfs_files(cdev);	device = dasd_device_from_cdev(cdev);	if (IS_ERR(device))		return;	if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) {		/* Already doing offline processing */		dasd_put_device(device);		return;	}	/*	 * This device is removed unconditionally. Set offline	 * flag to prevent dasd_open from opening it while it is	 * no quite down yet.	 */	dasd_set_target_state(device, DASD_STATE_NEW);	/* dasd_delete_device destroys the device reference. */	dasd_delete_device(device);}/* activate a device. This is called from dasd_{eckd,fba}_probe() when either * the device is detected for the first time and is supposed to be used * or the user has started activation through sysfs */intdasd_generic_set_online (struct ccw_device *cdev,			 struct dasd_discipline *discipline){	struct dasd_device *device;	int rc;	device = dasd_create_device(cdev);	if (IS_ERR(device))		return PTR_ERR(device);	if (test_bit(DASD_FLAG_USE_DIAG, &device->flags)) {	  	if (!dasd_diag_discipline_pointer) {		        printk (KERN_WARNING				"dasd_generic couldn't online device %s "				"- discipline DIAG not available\n",				cdev->dev.bus_id);			dasd_delete_device(device);			return -ENODEV;		}		discipline = dasd_diag_discipline_pointer;	}	device->discipline = discipline;	rc = discipline->check_device(device);	if (rc) {		printk (KERN_WARNING			"dasd_generic couldn't online device %s "			"with discipline %s\n", 			cdev->dev.bus_id, discipline->name);		dasd_delete_device(device);		return rc;	}	dasd_set_target_state(device, DASD_STATE_ONLINE);	if (device->state <= DASD_STATE_KNOWN) {		printk (KERN_WARNING			"dasd_generic discipline not found for %s\n",			cdev->dev.bus_id);		rc = -ENODEV;		dasd_set_target_state(device, DASD_STATE_NEW);		dasd_delete_device(device);	} else		pr_debug("dasd_generic device %s found\n",				cdev->dev.bus_id);	/* FIXME: we have to wait for the root device but we don't want	 * to wait for each single device but for all at once. */	wait_event(dasd_init_waitq, _wait_for_device(device));	dasd_put_device(device);	return rc;}intdasd_generic_set_offline (struct ccw_device *cdev){	struct dasd_device *device;	int max_count;	device = dasd_device_from_cdev(cdev);	if (IS_ERR(device))		return PTR_ERR(device);	if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) {		/* Already doing offline processing */		dasd_put_device(device);		return 0;	}	/*	 * We must make sure that this device is currently not in use.	 * The open_count is increased for every opener, that includes	 * the blkdev_get in dasd_scan_partitions. We are only interested	 * in the other openers.	 */	max_count = device->bdev ? 0 : -1;	if (atomic_read(&device->open_count) > max_count) {		printk (KERN_WARNING "Can't offline dasd device with open"			" count = %i.\n",			atomic_read(&device->open_count));		clear_bit(DASD_FLAG_OFFLINE, &device->flags);		dasd_put_device(device);		return -EBUSY;	}	dasd_set_target_state(device, DASD_STATE_NEW);	/* dasd_delete_device destroys the device reference. */	dasd_delete_device(device);	return 0;}intdasd_generic_notify(struct ccw_device *cdev, int event){	struct dasd_device *device;	struct dasd_ccw_req *cqr;	unsigned long flags;	int ret;	device = dasd_device_from_cdev(cdev);	if (IS_ERR(device))		return 0;	spin_lock_irqsave(get_ccwdev_lock(cdev), flags);	ret = 0;	switch (event) {	case CIO_GONE:	case CIO_NO_PATH:		if (device->state < DASD_STATE_BASIC)			break;		/* Device is active. We want to keep it. */		if (test_bit(DASD_FLAG_DSC_ERROR, &device->flags)) {			list_for_each_entry(cqr, &device->ccw_queue, list)				if (cqr->status == DASD_CQR_IN_IO)					cqr->status = DASD_CQR_FAILED;			device->stopped |= DASD_STOPPED_DC_EIO;			dasd_schedule_bh(device);		} else {			list_for_each_entry(cqr, &device->ccw_queue, list)				if (cqr->status == DASD_CQR_IN_IO)					cqr->status = DASD_CQR_QUEUED;			device->stopped |= DASD_STOPPED_DC_WAIT;			dasd_set_timer(device, 0);		}		ret = 1;		break;	case CIO_OPER:		/* FIXME: add a sanity check. */		device->stopped &= ~(DASD_STOPPED_DC_WAIT|DASD_STOPPED_DC_EIO);		dasd_schedule_bh(device);		ret = 1;		break;	}	spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);	dasd_put_device(device);	return ret;}/* * Automatically online either all dasd devices (dasd_autodetect) or * all devices specified with dasd= parameters. */voiddasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver){	struct device_driver *drv;	struct device *d, *dev;	struct ccw_device *cdev;	drv = get_driver(&dasd_discipline_driver->driver);	down_read(&drv->bus->subsys.rwsem);	dev = NULL;	list_for_each_entry(d, &drv->devices, driver_list) {		dev = get_device(d);		if (!dev)			continue;		cdev = to_ccwdev(dev);		if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)			ccw_device_set_online(cdev);		put_device(dev);	}	up_read(&drv->bus->subsys.rwsem);	put_driver(drv);}static int __initdasd_init(void){	int rc;	init_waitqueue_head(&dasd_init_waitq);	/* register 'common' DASD debug area, used for all DBF_XXX calls */	dasd_debug_area = debug_register("dasd", 0, 2, 8 * sizeof (long));	if (dasd_debug_area == NULL) {		rc = -ENOMEM;		goto failed;	}	debug_register_view(dasd_debug_area, &debug_hex_ascii_view);	debug_set_level(dasd_debug_area, DBF_ERR);	DBF_EVENT(DBF_EMERG, "%s", "debug area created");	dasd_diag_discipline_pointer = NULL;	rc = devfs_mk_dir("dasd");	if (rc)		goto failed;	rc = dasd_devmap_init();	if (rc)		goto failed;	rc = dasd_gendisk_init();	if (rc)		goto failed;	rc = dasd_parse();	if (rc)		goto failed;	rc = dasd_ioctl_init();	if (rc)		goto failed;#ifdef CONFIG_PROC_FS	rc = dasd_proc_init();	if (rc)		goto failed;#endif	return 0;failed:	MESSAGE(KERN_INFO, "%s", "initialization not performed due to errors");	dasd_exit();	return rc;}module_init(dasd_init);module_exit(dasd_exit);EXPORT_SYMBOL(dasd_debug_area);EXPORT_SYMBOL(dasd_diag_discipline_pointer);EXPORT_SYMBOL(dasd_add_request_head);EXPORT_SYMBOL(dasd_add_request_tail);EXPORT_SYMBOL(dasd_cancel_req);EXPORT_SYMBOL(dasd_clear_timer);EXPORT_SYMBOL(dasd_enable_device);EXPORT_SYMBOL(dasd_int_handler);EXPORT_SYMBOL(dasd_kfree_request);EXPORT_SYMBOL(dasd_kick_device);EXPORT_SYMBOL(dasd_kmalloc_request);EXPORT_SYMBOL(dasd_schedule_bh);EXPORT_SYMBOL(dasd_set_target_state);EXPORT_SYMBOL(dasd_set_timer);EXPORT_SYMBOL(dasd_sfree_request);EXPORT_SYMBOL(dasd_sleep_on);EXPORT_SYMBOL(dasd_sleep_on_immediatly);EXPORT_SYMBOL(dasd_sleep_on_interruptible);EXPORT_SYMBOL(dasd_smalloc_request);EXPORT_SYMBOL(dasd_start_IO);EXPORT_SYMBOL(dasd_term_IO);EXPORT_SYMBOL_GPL(dasd_generic_probe);EXPORT_SYMBOL_GPL(dasd_generic_remove);EXPORT_SYMBOL_GPL(dasd_generic_notify);EXPORT_SYMBOL_GPL(dasd_generic_set_online);EXPORT_SYMBOL_GPL(dasd_generic_set_offline);EXPORT_SYMBOL_GPL(dasd_generic_auto_online);/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * indent-tabs-mode: 1 * tab-width: 8 * End: */

⌨️ 快捷键说明

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