亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? device.c

?? LINUX 2.6.17.4的源碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
		if (test_and_clear_bit(1, &cdev->private->registered))			device_unregister(&cdev->dev);	}}extern int css_get_ssd_info(struct subchannel *sch);voidccw_device_do_unreg_rereg(void *data){	struct ccw_device *cdev;	struct subchannel *sch;	int need_rename;	cdev = (struct ccw_device *)data;	sch = to_subchannel(cdev->dev.parent);	if (cdev->private->devno != sch->schib.pmcw.dev) {		/*		 * The device number has changed. This is usually only when		 * a device has been detached under VM and then re-appeared		 * on another subchannel because of a different attachment		 * order than before. Ideally, we should should just switch		 * subchannels, but unfortunately, this is not possible with		 * the current implementation.		 * Instead, we search for the old subchannel for this device		 * number and deregister so there are no collisions with the		 * newly registered ccw_device.		 * FIXME: Find another solution so the block layer doesn't		 *        get possibly sick...		 */		struct ccw_device *other_cdev;		need_rename = 1;		other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev,						      sch->schid.ssid, cdev);		if (other_cdev) {			struct subchannel *other_sch;			other_sch = to_subchannel(other_cdev->dev.parent);			if (get_device(&other_sch->dev)) {				stsch(other_sch->schid, &other_sch->schib);				if (other_sch->schib.pmcw.dnv) {					other_sch->schib.pmcw.intparm = 0;					cio_modify(other_sch);				}				device_unregister(&other_sch->dev);			}		}		/* Update ssd info here. */		css_get_ssd_info(sch);		cdev->private->devno = sch->schib.pmcw.dev;	} else		need_rename = 0;	device_remove_files(&cdev->dev);	if (test_and_clear_bit(1, &cdev->private->registered))		device_del(&cdev->dev);	if (need_rename)		snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",			  sch->schid.ssid, sch->schib.pmcw.dev);	PREPARE_WORK(&cdev->private->kick_work,		     ccw_device_add_changed, (void *)cdev);	queue_work(ccw_device_work, &cdev->private->kick_work);}static voidccw_device_release(struct device *dev){	struct ccw_device *cdev;	cdev = to_ccwdev(dev);	kfree(cdev->private);	kfree(cdev);}/* * Register recognized device. */static voidio_subchannel_register(void *data){	struct ccw_device *cdev;	struct subchannel *sch;	int ret;	unsigned long flags;	cdev = (struct ccw_device *) data;	sch = to_subchannel(cdev->dev.parent);	if (klist_node_attached(&cdev->dev.knode_parent)) {		bus_rescan_devices(&ccw_bus_type);		goto out;	}	/* make it known to the system */	ret = ccw_device_register(cdev);	if (ret) {		printk (KERN_WARNING "%s: could not register %s\n",			__func__, cdev->dev.bus_id);		put_device(&cdev->dev);		spin_lock_irqsave(&sch->lock, flags);		sch->dev.driver_data = NULL;		spin_unlock_irqrestore(&sch->lock, flags);		kfree (cdev->private);		kfree (cdev);		put_device(&sch->dev);		if (atomic_dec_and_test(&ccw_device_init_count))			wake_up(&ccw_device_init_wq);		return;	}	ret = subchannel_add_files(cdev->dev.parent);	if (ret)		printk(KERN_WARNING "%s: could not add attributes to %s\n",		       __func__, sch->dev.bus_id);	put_device(&cdev->dev);out:	cdev->private->flags.recog_done = 1;	put_device(&sch->dev);	wake_up(&cdev->private->wait_q);	if (atomic_dec_and_test(&ccw_device_init_count))		wake_up(&ccw_device_init_wq);}voidccw_device_call_sch_unregister(void *data){	struct ccw_device *cdev = data;	struct subchannel *sch;	sch = to_subchannel(cdev->dev.parent);	device_unregister(&sch->dev);	/* Reset intparm to zeroes. */	sch->schib.pmcw.intparm = 0;	cio_modify(sch);	put_device(&cdev->dev);	put_device(&sch->dev);}/* * subchannel recognition done. Called from the state machine. */voidio_subchannel_recog_done(struct ccw_device *cdev){	struct subchannel *sch;	if (css_init_done == 0) {		cdev->private->flags.recog_done = 1;		return;	}	switch (cdev->private->state) {	case DEV_STATE_NOT_OPER:		cdev->private->flags.recog_done = 1;		/* Remove device found not operational. */		if (!get_device(&cdev->dev))			break;		sch = to_subchannel(cdev->dev.parent);		PREPARE_WORK(&cdev->private->kick_work,			     ccw_device_call_sch_unregister, (void *) cdev);		queue_work(slow_path_wq, &cdev->private->kick_work);		if (atomic_dec_and_test(&ccw_device_init_count))			wake_up(&ccw_device_init_wq);		break;	case DEV_STATE_BOXED:		/* Device did not respond in time. */	case DEV_STATE_OFFLINE:		/* 		 * We can't register the device in interrupt context so		 * we schedule a work item.		 */		if (!get_device(&cdev->dev))			break;		PREPARE_WORK(&cdev->private->kick_work,			     io_subchannel_register, (void *) cdev);		queue_work(slow_path_wq, &cdev->private->kick_work);		break;	}}static intio_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch){	int rc;	struct ccw_device_private *priv;	sch->dev.driver_data = cdev;	sch->driver = &io_subchannel_driver;	cdev->ccwlock = &sch->lock;	/* Init private data. */	priv = cdev->private;	priv->devno = sch->schib.pmcw.dev;	priv->ssid = sch->schid.ssid;	priv->sch_no = sch->schid.sch_no;	priv->state = DEV_STATE_NOT_OPER;	INIT_LIST_HEAD(&priv->cmb_list);	init_waitqueue_head(&priv->wait_q);	init_timer(&priv->timer);	/* Set an initial name for the device. */	snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",		  sch->schid.ssid, sch->schib.pmcw.dev);	/* Increase counter of devices currently in recognition. */	atomic_inc(&ccw_device_init_count);	/* Start async. device sensing. */	spin_lock_irq(&sch->lock);	rc = ccw_device_recognition(cdev);	spin_unlock_irq(&sch->lock);	if (rc) {		if (atomic_dec_and_test(&ccw_device_init_count))			wake_up(&ccw_device_init_wq);	}	return rc;}static intio_subchannel_probe (struct subchannel *sch){	struct ccw_device *cdev;	int rc;	unsigned long flags;	if (sch->dev.driver_data) {		/*		 * This subchannel already has an associated ccw_device.		 * Register it and exit. This happens for all early		 * device, e.g. the console.		 */		cdev = sch->dev.driver_data;		device_initialize(&cdev->dev);		ccw_device_register(cdev);		subchannel_add_files(&sch->dev);		/*		 * Check if the device is already online. If it is		 * the reference count needs to be corrected		 * (see ccw_device_online and css_init_done for the		 * ugly details).		 */		if (cdev->private->state != DEV_STATE_NOT_OPER &&		    cdev->private->state != DEV_STATE_OFFLINE &&		    cdev->private->state != DEV_STATE_BOXED)			get_device(&cdev->dev);		return 0;	}	cdev = kzalloc (sizeof(*cdev), GFP_KERNEL);	if (!cdev)		return -ENOMEM;	cdev->private = kzalloc(sizeof(struct ccw_device_private),				GFP_KERNEL | GFP_DMA);	if (!cdev->private) {		kfree(cdev);		return -ENOMEM;	}	atomic_set(&cdev->private->onoff, 0);	cdev->dev = (struct device) {		.parent = &sch->dev,		.release = ccw_device_release,	};	INIT_LIST_HEAD(&cdev->private->kick_work.entry);	/* Do first half of device_register. */	device_initialize(&cdev->dev);	if (!get_device(&sch->dev)) {		if (cdev->dev.release)			cdev->dev.release(&cdev->dev);		return -ENODEV;	}	rc = io_subchannel_recog(cdev, sch);	if (rc) {		spin_lock_irqsave(&sch->lock, flags);		sch->dev.driver_data = NULL;		spin_unlock_irqrestore(&sch->lock, flags);		if (cdev->dev.release)			cdev->dev.release(&cdev->dev);	}	return rc;}static voidccw_device_unregister(void *data){	struct ccw_device *cdev;	cdev = (struct ccw_device *)data;	if (test_and_clear_bit(1, &cdev->private->registered))		device_unregister(&cdev->dev);	put_device(&cdev->dev);}static intio_subchannel_remove (struct subchannel *sch){	struct ccw_device *cdev;	unsigned long flags;	if (!sch->dev.driver_data)		return 0;	cdev = sch->dev.driver_data;	/* Set ccw device to not operational and drop reference. */	spin_lock_irqsave(cdev->ccwlock, flags);	sch->dev.driver_data = NULL;	cdev->private->state = DEV_STATE_NOT_OPER;	spin_unlock_irqrestore(cdev->ccwlock, flags);	/*	 * Put unregistration on workqueue to avoid livelocks on the css bus	 * semaphore.	 */	if (get_device(&cdev->dev)) {		PREPARE_WORK(&cdev->private->kick_work,			     ccw_device_unregister, (void *) cdev);		queue_work(ccw_device_work, &cdev->private->kick_work);	}	return 0;}static intio_subchannel_notify(struct device *dev, int event){	struct ccw_device *cdev;	cdev = dev->driver_data;	if (!cdev)		return 0;	if (!cdev->drv)		return 0;	if (!cdev->online)		return 0;	return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;}static voidio_subchannel_verify(struct device *dev){	struct ccw_device *cdev;	cdev = dev->driver_data;	if (cdev)		dev_fsm_event(cdev, DEV_EVENT_VERIFY);}static voidio_subchannel_ioterm(struct device *dev){	struct ccw_device *cdev;	cdev = dev->driver_data;	if (!cdev)		return;	cdev->private->state = DEV_STATE_CLEAR_VERIFY;	if (cdev->handler)		cdev->handler(cdev, cdev->private->intparm,			      ERR_PTR(-EIO));}static voidio_subchannel_shutdown(struct subchannel *sch){	struct ccw_device *cdev;	int ret;	cdev = sch->dev.driver_data;	if (cio_is_console(sch->schid))		return;	if (!sch->schib.pmcw.ena)		/* Nothing to do. */		return;	ret = cio_disable_subchannel(sch);	if (ret != -EBUSY)		/* Subchannel is disabled, we're done. */		return;	cdev->private->state = DEV_STATE_QUIESCE;	if (cdev->handler)		cdev->handler(cdev, cdev->private->intparm,			      ERR_PTR(-EIO));	ret = ccw_device_cancel_halt_clear(cdev);	if (ret == -EBUSY) {		ccw_device_set_timeout(cdev, HZ/10);		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));	}	cio_disable_subchannel(sch);}#ifdef CONFIG_CCW_CONSOLEstatic struct ccw_device console_cdev;static struct ccw_device_private console_private;static int console_cdev_in_use;static intccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch){	int rc;	/* Initialize the ccw_device structure. */	cdev->dev = (struct device) {		.parent = &sch->dev,	};	rc = io_subchannel_recog(cdev, sch);	if (rc)		return rc;	/* Now wait for the async. recognition to come to an end. */	spin_lock_irq(cdev->ccwlock);	while (!dev_fsm_final_state(cdev))		wait_cons_dev();	rc = -EIO;	if (cdev->private->state != DEV_STATE_OFFLINE)		goto out_unlock;	ccw_device_online(cdev);	while (!dev_fsm_final_state(cdev))		wait_cons_dev();	if (cdev->private->state != DEV_STATE_ONLINE)		goto out_unlock;	rc = 0;out_unlock:	spin_unlock_irq(cdev->ccwlock);	return 0;}struct ccw_device *ccw_device_probe_console(void){	struct subchannel *sch;	int ret;	if (xchg(&console_cdev_in_use, 1) != 0)		return ERR_PTR(-EBUSY);	sch = cio_probe_console();	if (IS_ERR(sch)) {		console_cdev_in_use = 0;		return (void *) sch;	}	memset(&console_cdev, 0, sizeof(struct ccw_device));	memset(&console_private, 0, sizeof(struct ccw_device_private));	console_cdev.private = &console_private;	ret = ccw_device_console_enable(&console_cdev, sch);	if (ret) {		cio_release_console();		console_cdev_in_use = 0;		return ERR_PTR(ret);	}	console_cdev.online = 1;	return &console_cdev;}#endif/* * get ccw_device matching the busid, but only if owned by cdrv */static int__ccwdev_check_busid(struct device *dev, void *id){	char *bus_id;	bus_id = (char *)id;	return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0);}struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id){	struct device *dev;	struct device_driver *drv;	drv = get_driver(&cdrv->driver);	if (!drv)		return NULL;	dev = driver_find_device(drv, NULL, (void *)bus_id,				 __ccwdev_check_busid);	put_driver(drv);	return dev ? to_ccwdev(dev) : 0;}/************************** device driver handling ************************//* This is the implementation of the ccw_driver class. The probe, remove * and release methods are initially very similar to the device_driver * implementations, with the difference that they have ccw_device * arguments. * * A ccw driver also contains the information that is needed for * device matching. */static intccw_device_probe (struct device *dev){	struct ccw_device *cdev = to_ccwdev(dev);	struct ccw_driver *cdrv = to_ccwdrv(dev->driver);	int ret;	cdev->drv = cdrv; /* to let the driver call _set_online */	ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV;	if (ret) {		cdev->drv = 0;		return ret;	}	return 0;}static intccw_device_remove (struct device *dev){	struct ccw_device *cdev = to_ccwdev(dev);	struct ccw_driver *cdrv = cdev->drv;	int ret;	pr_debug("removing device %s\n", cdev->dev.bus_id);	if (cdrv->remove)		cdrv->remove(cdev);	if (cdev->online) {		cdev->online = 0;		spin_lock_irq(cdev->ccwlock);		ret = ccw_device_offline(cdev);		spin_unlock_irq(cdev->ccwlock);		if (ret == 0)			wait_event(cdev->private->wait_q,				   dev_fsm_final_state(cdev));		else			//FIXME: we can't fail!			pr_debug("ccw_device_offline returned %d, device %s\n",				 ret, cdev->dev.bus_id);	}	ccw_device_set_timeout(cdev, 0);	cdev->drv = 0;	return 0;}struct bus_type ccw_bus_type = {	.name   = "ccw",	.match  = ccw_bus_match,	.uevent = ccw_uevent,	.probe  = ccw_device_probe,	.remove = ccw_device_remove,};intccw_driver_register (struct ccw_driver *cdriver){	struct device_driver *drv = &cdriver->driver;	drv->bus = &ccw_bus_type;	drv->name = cdriver->name;	return driver_register(drv);}voidccw_driver_unregister (struct ccw_driver *cdriver){	driver_unregister(&cdriver->driver);}/* Helper func for qdio. */struct subchannel_idccw_device_get_subchannel_id(struct ccw_device *cdev){	struct subchannel *sch;	sch = to_subchannel(cdev->dev.parent);	return sch->schid;}MODULE_LICENSE("GPL");EXPORT_SYMBOL(ccw_device_set_online);EXPORT_SYMBOL(ccw_device_set_offline);EXPORT_SYMBOL(ccw_driver_register);EXPORT_SYMBOL(ccw_driver_unregister);EXPORT_SYMBOL(get_ccwdev_by_busid);EXPORT_SYMBOL(ccw_bus_type);EXPORT_SYMBOL(ccw_device_work);EXPORT_SYMBOL(ccw_device_notify_work);EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩视频在线你懂得| 国产一区二区在线看| 欧美专区在线观看一区| 亚洲综合激情网| 91福利视频网站| 亚洲电影在线免费观看| 欧美一级免费观看| 久久国产精品第一页| 久久精品一区二区| av男人天堂一区| 亚洲福中文字幕伊人影院| 日韩久久免费av| 成人免费视频视频| 亚洲成人午夜电影| 欧美精品一区二区精品网| 成人av资源在线| 亚洲福利视频导航| 久久久777精品电影网影网| 91理论电影在线观看| 欧美日韩中文字幕精品| 香蕉久久一区二区不卡无毒影院| 91精品欧美久久久久久动漫| 国产一区二区视频在线播放| 99久久国产免费看| 午夜激情久久久| 久久精品男人天堂av| 91成人网在线| 国产**成人网毛片九色| 国产激情视频一区二区在线观看| 91在线播放网址| 日韩一区二区三区四区五区六区 | 精品日韩欧美一区二区| 久久久国产精品麻豆| 一区二区三区视频在线看| 麻豆精品在线播放| 色嗨嗨av一区二区三区| 日韩欧美国产1| 欧美国产精品劲爆| 日本欧美一区二区三区乱码| 波多野结衣精品在线| 日韩一区和二区| 亚洲日本青草视频在线怡红院| 日韩高清不卡一区二区| 99国产精品国产精品毛片| 日韩一卡二卡三卡| 亚洲欧美aⅴ...| 国产精品一品二品| 欧美一区二区三区四区久久| 亚洲欧美日韩一区二区| 狠狠v欧美v日韩v亚洲ⅴ| 欧美日韩中文字幕精品| 亚洲少妇30p| 国产成人av自拍| 日韩三级av在线播放| 亚洲成人免费视频| 色综合色综合色综合| 日本一区二区在线不卡| 极品少妇xxxx精品少妇| 日韩一区二区三区视频| 亚洲国产精品一区二区久久| 91蜜桃婷婷狠狠久久综合9色| 久久久久久久综合色一本| 日本人妖一区二区| 欧美一区二区三区在线观看| 亚洲一区二区五区| 欧美在线短视频| 亚洲国产综合在线| 91精品办公室少妇高潮对白| 亚洲欧美另类在线| 91美女视频网站| 国产精品久久久久一区二区三区 | 久久av中文字幕片| 337p亚洲精品色噜噜狠狠| 亚洲成人资源在线| 欧美日韩国产高清一区二区三区| 亚洲伦理在线精品| 欧美在线小视频| 性久久久久久久久久久久| 欧美羞羞免费网站| 午夜精品免费在线| 欧美一区二区免费| 久久se精品一区二区| 久久精品欧美日韩| 99精品欧美一区| 亚洲最大成人综合| 91麻豆精品国产自产在线观看一区| 日韩电影一区二区三区四区| 日韩三级在线免费观看| 国产电影一区二区三区| 亚洲欧美色综合| 在线观看www91| 青青青伊人色综合久久| 久久久久久黄色| 91在线视频免费观看| 亚洲一区在线电影| 日韩欧美综合一区| 成人a区在线观看| 亚洲一区二区三区四区在线观看| 制服丝袜日韩国产| 国产成人精品免费在线| 一区二区三区免费在线观看| 91精品国产免费| 成人综合在线网站| 亚洲成人1区2区| 久久精品一区二区三区不卡| 色av成人天堂桃色av| 麻豆久久久久久久| 亚洲视频在线一区观看| 欧美一区二区成人| 成人开心网精品视频| 天堂av在线一区| 国产欧美日韩另类视频免费观看| 色天天综合久久久久综合片| 蜜桃av一区二区三区电影| 中文字幕不卡三区| 日韩欧美不卡在线观看视频| 99国产精品99久久久久久| 男女激情视频一区| 亚洲精品中文在线影院| 亚洲精品一区二区在线观看| 在线视频亚洲一区| 国产酒店精品激情| 日本不卡一区二区| 亚洲蜜臀av乱码久久精品| 久久婷婷综合激情| 欧美一级高清片在线观看| 欧美性色aⅴ视频一区日韩精品| 国产伦精品一区二区三区免费 | 99精品黄色片免费大全| 麻豆久久一区二区| 天天综合天天综合色| 亚洲美女视频一区| 欧美激情一区二区三区在线| 欧美一区二区三区小说| 欧美性欧美巨大黑白大战| a在线播放不卡| 丁香另类激情小说| 国产在线观看一区二区| 美日韩一区二区| 日韩在线观看一区二区| 亚洲精品国产成人久久av盗摄| 国产精品天天看| 久久精品一区蜜桃臀影院| 久久综合色鬼综合色| 日韩一区二区三区观看| 欧美日韩国产精选| 欧美丰满高潮xxxx喷水动漫 | 亚洲福利视频三区| 亚洲一二三四久久| 亚洲精品视频一区| 一区二区在线观看av| 夜夜亚洲天天久久| 一区二区高清在线| 亚洲女同一区二区| 亚洲精品乱码久久久久久久久| 国产精品欧美综合在线| 国产精品乱人伦| 国产精品成人一区二区艾草| 国产精品国产a级| 亚洲精品亚洲人成人网在线播放| 亚洲三级免费电影| 亚洲愉拍自拍另类高清精品| 亚洲午夜精品网| 日韩av一区二区三区四区| 久久精品国产99国产| 国产精品一区二区久久不卡| 国产成人亚洲精品狼色在线| 91一区二区在线观看| 欧美日韩国产综合视频在线观看 | 色乱码一区二区三区88| 在线免费观看日本欧美| 91精品视频网| 久久久久久97三级| 最新欧美精品一区二区三区| 亚洲成年人网站在线观看| 精品一区二区在线免费观看| 成人午夜在线视频| 欧美在线你懂得| 久久免费偷拍视频| 一区二区不卡在线播放| 久久www免费人成看片高清| 不卡电影一区二区三区| 欧美天堂一区二区三区| 精品国产3级a| 亚洲柠檬福利资源导航| 精品在线视频一区| 一道本成人在线| ww久久中文字幕| 亚洲制服丝袜av| 国产精品一区二区在线观看网站 | 日韩一区二区免费视频| 日本一区二区免费在线观看视频| 一区二区久久久| 国产黑丝在线一区二区三区| 在线观看欧美黄色| 国产视频一区二区在线| 日韩高清在线一区| 色婷婷综合五月| 中文欧美字幕免费| 免费在线观看视频一区|