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

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

?? device.c

?? linux2.6.16版本
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* *  drivers/s390/cio/device.c *  bus driver for ccw devices * *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, *			 IBM Corporation *    Author(s): Arnd Bergmann (arndb@de.ibm.com) *		 Cornelia Huck (cornelia.huck@de.ibm.com) *		 Martin Schwidefsky (schwidefsky@de.ibm.com) */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/spinlock.h>#include <linux/errno.h>#include <linux/err.h>#include <linux/slab.h>#include <linux/list.h>#include <linux/device.h>#include <linux/workqueue.h>#include <asm/ccwdev.h>#include <asm/cio.h>#include <asm/param.h>		/* HZ */#include "cio.h"#include "css.h"#include "device.h"#include "ioasm.h"/******************* bus type handling ***********************//* The Linux driver model distinguishes between a bus type and * the bus itself. Of course we only have one channel * subsystem driver and one channel system per machine, but * we still use the abstraction. T.R. says it's a good idea. */static intccw_bus_match (struct device * dev, struct device_driver * drv){	struct ccw_device *cdev = to_ccwdev(dev);	struct ccw_driver *cdrv = to_ccwdrv(drv);	const struct ccw_device_id *ids = cdrv->ids, *found;	if (!ids)		return 0;	found = ccw_device_id_match(ids, &cdev->id);	if (!found)		return 0;	cdev->id.driver_info = found->driver_info;	return 1;}/* * Hotplugging interface for ccw devices. * Heavily modeled on pci and usb hotplug. */static intccw_uevent (struct device *dev, char **envp, int num_envp,	     char *buffer, int buffer_size){	struct ccw_device *cdev = to_ccwdev(dev);	int i = 0;	int length = 0;	if (!cdev)		return -ENODEV;	/* what we want to pass to /sbin/hotplug */	envp[i++] = buffer;	length += scnprintf(buffer, buffer_size - length, "CU_TYPE=%04X",			   cdev->id.cu_type);	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	++length;	buffer += length;	envp[i++] = buffer;	length += scnprintf(buffer, buffer_size - length, "CU_MODEL=%02X",			   cdev->id.cu_model);	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	++length;	buffer += length;	/* The next two can be zero, that's ok for us */	envp[i++] = buffer;	length += scnprintf(buffer, buffer_size - length, "DEV_TYPE=%04X",			   cdev->id.dev_type);	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	++length;	buffer += length;	envp[i++] = buffer;	length += scnprintf(buffer, buffer_size - length, "DEV_MODEL=%02X",			   cdev->id.dev_model);	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	envp[i] = 0;	return 0;}struct bus_type ccw_bus_type;static int io_subchannel_probe (struct subchannel *);static int io_subchannel_remove (struct subchannel *);void io_subchannel_irq (struct device *);static int io_subchannel_notify(struct device *, int);static void io_subchannel_verify(struct device *);static void io_subchannel_ioterm(struct device *);static void io_subchannel_shutdown(struct subchannel *);struct css_driver io_subchannel_driver = {	.subchannel_type = SUBCHANNEL_TYPE_IO,	.drv = {		.name = "io_subchannel",		.bus  = &css_bus_type,	},	.irq = io_subchannel_irq,	.notify = io_subchannel_notify,	.verify = io_subchannel_verify,	.termination = io_subchannel_ioterm,	.probe = io_subchannel_probe,	.remove = io_subchannel_remove,	.shutdown = io_subchannel_shutdown,};struct workqueue_struct *ccw_device_work;struct workqueue_struct *ccw_device_notify_work;static wait_queue_head_t ccw_device_init_wq;static atomic_t ccw_device_init_count;static int __initinit_ccw_bus_type (void){	int ret;	init_waitqueue_head(&ccw_device_init_wq);	atomic_set(&ccw_device_init_count, 0);	ccw_device_work = create_singlethread_workqueue("cio");	if (!ccw_device_work)		return -ENOMEM; /* FIXME: better errno ? */	ccw_device_notify_work = create_singlethread_workqueue("cio_notify");	if (!ccw_device_notify_work) {		ret = -ENOMEM; /* FIXME: better errno ? */		goto out_err;	}	slow_path_wq = create_singlethread_workqueue("kslowcrw");	if (!slow_path_wq) {		ret = -ENOMEM; /* FIXME: better errno ? */		goto out_err;	}	if ((ret = bus_register (&ccw_bus_type)))		goto out_err;	if ((ret = driver_register(&io_subchannel_driver.drv)))		goto out_err;	wait_event(ccw_device_init_wq,		   atomic_read(&ccw_device_init_count) == 0);	flush_workqueue(ccw_device_work);	return 0;out_err:	if (ccw_device_work)		destroy_workqueue(ccw_device_work);	if (ccw_device_notify_work)		destroy_workqueue(ccw_device_notify_work);	if (slow_path_wq)		destroy_workqueue(slow_path_wq);	return ret;}static void __exitcleanup_ccw_bus_type (void){	driver_unregister(&io_subchannel_driver.drv);	bus_unregister(&ccw_bus_type);	destroy_workqueue(ccw_device_notify_work);	destroy_workqueue(ccw_device_work);}subsys_initcall(init_ccw_bus_type);module_exit(cleanup_ccw_bus_type);/************************ device handling **************************//* * A ccw_device has some interfaces in sysfs in addition to the * standard ones. * The following entries are designed to export the information which * resided in 2.4 in /proc/subchannels. Subchannel and device number * are obvious, so they don't have an entry :) * TODO: Split chpids and pimpampom up? Where is "in use" in the tree? */static ssize_tchpids_show (struct device * dev, struct device_attribute *attr, char * buf){	struct subchannel *sch = to_subchannel(dev);	struct ssd_info *ssd = &sch->ssd_info;	ssize_t ret = 0;	int chp;	for (chp = 0; chp < 8; chp++)		ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);	ret += sprintf (buf+ret, "\n");	return min((ssize_t)PAGE_SIZE, ret);}static ssize_tpimpampom_show (struct device * dev, struct device_attribute *attr, char * buf){	struct subchannel *sch = to_subchannel(dev);	struct pmcw *pmcw = &sch->schib.pmcw;	return sprintf (buf, "%02x %02x %02x\n",			pmcw->pim, pmcw->pam, pmcw->pom);}static ssize_tdevtype_show (struct device *dev, struct device_attribute *attr, char *buf){	struct ccw_device *cdev = to_ccwdev(dev);	struct ccw_device_id *id = &(cdev->id);	if (id->dev_type != 0)		return sprintf(buf, "%04x/%02x\n",				id->dev_type, id->dev_model);	else		return sprintf(buf, "n/a\n");}static ssize_tcutype_show (struct device *dev, struct device_attribute *attr, char *buf){	struct ccw_device *cdev = to_ccwdev(dev);	struct ccw_device_id *id = &(cdev->id);	return sprintf(buf, "%04x/%02x\n",		       id->cu_type, id->cu_model);}static ssize_tmodalias_show (struct device *dev, struct device_attribute *attr, char *buf){	struct ccw_device *cdev = to_ccwdev(dev);	struct ccw_device_id *id = &(cdev->id);	int ret;	ret = sprintf(buf, "ccw:t%04Xm%02X",			id->cu_type, id->cu_model);	if (id->dev_type != 0)		ret += sprintf(buf + ret, "dt%04Xdm%02X\n",				id->dev_type, id->dev_model);	else		ret += sprintf(buf + ret, "dtdm\n");	return ret;}static ssize_tonline_show (struct device *dev, struct device_attribute *attr, char *buf){	struct ccw_device *cdev = to_ccwdev(dev);	return sprintf(buf, cdev->online ? "1\n" : "0\n");}static voidccw_device_remove_disconnected(struct ccw_device *cdev){	struct subchannel *sch;	/*	 * Forced offline in disconnected state means	 * 'throw away device'.	 */	sch = to_subchannel(cdev->dev.parent);	device_unregister(&sch->dev);	/* Reset intparm to zeroes. */	sch->schib.pmcw.intparm = 0;	cio_modify(sch);	put_device(&sch->dev);}intccw_device_set_offline(struct ccw_device *cdev){	int ret;	if (!cdev)		return -ENODEV;	if (!cdev->online || !cdev->drv)		return -EINVAL;	if (cdev->drv->set_offline) {		ret = cdev->drv->set_offline(cdev);		if (ret != 0)			return ret;	}	cdev->online = 0;	spin_lock_irq(cdev->ccwlock);	ret = ccw_device_offline(cdev);	if (ret == -ENODEV) {		if (cdev->private->state != DEV_STATE_NOT_OPER) {			cdev->private->state = DEV_STATE_OFFLINE;			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);		}		spin_unlock_irq(cdev->ccwlock);		return ret;	}	spin_unlock_irq(cdev->ccwlock);	if (ret == 0)		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));	else {		pr_debug("ccw_device_offline returned %d, device %s\n",			 ret, cdev->dev.bus_id);		cdev->online = 1;	} 	return ret;}intccw_device_set_online(struct ccw_device *cdev){	int ret;	if (!cdev)		return -ENODEV;	if (cdev->online || !cdev->drv)		return -EINVAL;	spin_lock_irq(cdev->ccwlock);	ret = ccw_device_online(cdev);	spin_unlock_irq(cdev->ccwlock);	if (ret == 0)		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));	else {		pr_debug("ccw_device_online returned %d, device %s\n",			 ret, cdev->dev.bus_id);		return ret;	}	if (cdev->private->state != DEV_STATE_ONLINE)		return -ENODEV;	if (!cdev->drv->set_online || cdev->drv->set_online(cdev) == 0) {		cdev->online = 1;		return 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 		pr_debug("ccw_device_offline returned %d, device %s\n",			 ret, cdev->dev.bus_id);	return (ret == 0) ? -ENODEV : ret;}static ssize_tonline_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct ccw_device *cdev = to_ccwdev(dev);	int i, force, ret;	char *tmp;	if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)		return -EAGAIN;	if (cdev->drv && !try_module_get(cdev->drv->owner)) {		atomic_set(&cdev->private->onoff, 0);		return -EINVAL;	}	if (!strncmp(buf, "force\n", count)) {		force = 1;		i = 1;	} else {		force = 0;		i = simple_strtoul(buf, &tmp, 16);	}	if (i == 1) {		/* Do device recognition, if needed. */		if (cdev->id.cu_type == 0) {			ret = ccw_device_recognition(cdev);			if (ret) {				printk(KERN_WARNING"Couldn't start recognition "				       "for device %s (ret=%d)\n",				       cdev->dev.bus_id, ret);				goto out;			}			wait_event(cdev->private->wait_q,				   cdev->private->flags.recog_done);		}		if (cdev->drv && cdev->drv->set_online)			ccw_device_set_online(cdev);	} else if (i == 0) {		if (cdev->private->state == DEV_STATE_DISCONNECTED)			ccw_device_remove_disconnected(cdev);		else if (cdev->drv && cdev->drv->set_offline)			ccw_device_set_offline(cdev);	}	if (force && cdev->private->state == DEV_STATE_BOXED) {		ret = ccw_device_stlck(cdev);		if (ret) {			printk(KERN_WARNING"ccw_device_stlck for device %s "			       "returned %d!\n", cdev->dev.bus_id, ret);			goto out;		}		/* Do device recognition, if needed. */		if (cdev->id.cu_type == 0) {			cdev->private->state = DEV_STATE_NOT_OPER;			ret = ccw_device_recognition(cdev);			if (ret) {				printk(KERN_WARNING"Couldn't start recognition "				       "for device %s (ret=%d)\n",				       cdev->dev.bus_id, ret);				goto out;			}			wait_event(cdev->private->wait_q,				   cdev->private->flags.recog_done);		}		if (cdev->drv && cdev->drv->set_online)			ccw_device_set_online(cdev);	}	out:	if (cdev->drv)		module_put(cdev->drv->owner);	atomic_set(&cdev->private->onoff, 0);	return count;}static ssize_tavailable_show (struct device *dev, struct device_attribute *attr, char *buf){	struct ccw_device *cdev = to_ccwdev(dev);	struct subchannel *sch;	switch (cdev->private->state) {	case DEV_STATE_BOXED:		return sprintf(buf, "boxed\n");	case DEV_STATE_DISCONNECTED:	case DEV_STATE_DISCONNECTED_SENSE_ID:	case DEV_STATE_NOT_OPER:		sch = to_subchannel(dev->parent);		if (!sch->lpm)			return sprintf(buf, "no path\n");		else			return sprintf(buf, "no device\n");	default:		/* All other states considered fine. */		return sprintf(buf, "good\n");	}}static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);static DEVICE_ATTR(online, 0644, online_show, online_store);extern struct device_attribute dev_attr_cmb_enable;static DEVICE_ATTR(availability, 0444, available_show, NULL);static struct attribute * subch_attrs[] = {	&dev_attr_chpids.attr,	&dev_attr_pimpampom.attr,	NULL,};static struct attribute_group subch_attr_group = {	.attrs = subch_attrs,};static inline intsubchannel_add_files (struct device *dev){	return sysfs_create_group(&dev->kobj, &subch_attr_group);}static struct attribute * ccwdev_attrs[] = {	&dev_attr_devtype.attr,	&dev_attr_cutype.attr,	&dev_attr_modalias.attr,	&dev_attr_online.attr,	&dev_attr_cmb_enable.attr,	&dev_attr_availability.attr,	NULL,};static struct attribute_group ccwdev_attr_group = {	.attrs = ccwdev_attrs,};static inline intdevice_add_files (struct device *dev){	return sysfs_create_group(&dev->kobj, &ccwdev_attr_group);}static inline voiddevice_remove_files(struct device *dev){	sysfs_remove_group(&dev->kobj, &ccwdev_attr_group);}/* this is a simple abstraction for device_register that sets the * correct bus type and adds the bus specific files */intccw_device_register(struct ccw_device *cdev){	struct device *dev = &cdev->dev;	int ret;	dev->bus = &ccw_bus_type;	if ((ret = device_add(dev)))		return ret;	set_bit(1, &cdev->private->registered);	if ((ret = device_add_files(dev))) {		if (test_and_clear_bit(1, &cdev->private->registered))			device_del(dev);	}	return ret;}struct match_data {	unsigned int devno;	unsigned int ssid;	struct ccw_device * sibling;};static intmatch_devno(struct device * dev, void * data){	struct match_data * d = (struct match_data *)data;	struct ccw_device * cdev;	cdev = to_ccwdev(dev);	if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&	    (cdev->private->devno == d->devno) &&	    (cdev->private->ssid == d->ssid) &&	    (cdev != d->sibling)) {		cdev->private->state = DEV_STATE_NOT_OPER;		return 1;	}	return 0;}static struct ccw_device *get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid,			 struct ccw_device *sibling){	struct device *dev;	struct match_data data = {		.devno   = devno,		.ssid    = ssid,		.sibling = sibling,	};	dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);	return dev ? to_ccwdev(dev) : NULL;}static voidccw_device_add_changed(void *data){	struct ccw_device *cdev;	cdev = (struct ccw_device *)data;	if (device_add(&cdev->dev)) {		put_device(&cdev->dev);		return;	}	set_bit(1, &cdev->private->registered);	if (device_add_files(&cdev->dev)) {		if (test_and_clear_bit(1, &cdev->private->registered))

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美精品一区二区在线播放| 欧美亚洲日本国产| 精品三级在线看| 紧缚捆绑精品一区二区| 欧美成人一区二区三区| 国产一区二区剧情av在线| 精品国产免费人成电影在线观看四季 | 在线这里只有精品| 亚洲综合激情小说| 91精品国产91久久久久久一区二区 | 欧美成人性战久久| 国产精品1区二区.| 国产精品久久久久影院老司| 色综合色综合色综合色综合色综合| 一区二区国产盗摄色噜噜| 欧美在线一二三四区| 蜜臀久久久99精品久久久久久| 日韩精品在线看片z| 丁香婷婷综合激情五月色| 依依成人综合视频| 日韩欧美久久一区| 不卡的av中国片| 婷婷一区二区三区| 久久久午夜精品理论片中文字幕| 成人av第一页| 无码av免费一区二区三区试看 | 久久久美女毛片| 色国产综合视频| 免费不卡在线视频| 中文字幕亚洲综合久久菠萝蜜| 欧美日韩国产片| 国产成人免费av在线| 亚洲国产精品天堂| 久久久久国产精品麻豆ai换脸| 在线亚洲+欧美+日本专区| 韩国欧美国产1区| 一区二区高清在线| 久久久久久久久久久久电影| 在线欧美一区二区| 国产福利精品一区| 日本不卡中文字幕| 亚洲欧洲日产国码二区| 欧美成人艳星乳罩| 欧美日韩国产精品成人| 99久久99久久精品免费观看| 青青草97国产精品免费观看无弹窗版 | 欧美一区二区三区视频在线| 北岛玲一区二区三区四区| 免费成人美女在线观看.| 一区二区欧美精品| 国产精品理论在线观看| 精品少妇一区二区| 91麻豆精品国产无毒不卡在线观看| av电影在线不卡| 国产一区二区三区精品欧美日韩一区二区三区 | 国产亚洲精品中文字幕| 制服.丝袜.亚洲.中文.综合| 色悠悠久久综合| 国产成人8x视频一区二区| 另类欧美日韩国产在线| 香蕉久久夜色精品国产使用方法| 欧美国产一区视频在线观看| 欧美一区二区日韩| 欧美日本在线视频| 在线观看欧美黄色| 色综合天天综合网天天狠天天| 国产精品自在欧美一区| 麻豆91精品视频| 日韩1区2区3区| 香蕉久久夜色精品国产使用方法| 一区二区久久久久久| 亚洲精品欧美专区| 亚洲精品美腿丝袜| 亚洲三级在线免费| 亚洲天堂成人在线观看| 一色桃子久久精品亚洲| 国产精品久久久久天堂| 国产精品久久久久久久裸模| 欧美极品美女视频| 国产精品午夜久久| 国产精品国产三级国产aⅴ入口| 国产色综合一区| 国产欧美一区视频| 国产精品黄色在线观看| 亚洲同性gay激情无套| 一区二区在线看| 亚洲电影视频在线| 日韩经典一区二区| 蜜臀国产一区二区三区在线播放| 日本色综合中文字幕| 人禽交欧美网站| 国产在线精品视频| 丁香亚洲综合激情啪啪综合| 成人91在线观看| 色国产综合视频| 欧美一区二区三区的| 亚洲精品一区二区精华| 中文字幕第一区| 一区二区三区欧美日| 亚洲制服丝袜一区| 日韩成人午夜精品| 国产99久久久国产精品| 91欧美一区二区| 亚洲精品你懂的| 日日夜夜免费精品| 中文字幕免费观看一区| 国产视频亚洲色图| 一区二区三区日韩| 麻豆视频观看网址久久| 国产成人在线视频网站| 91蜜桃网址入口| 欧美精品第一页| 国产成人在线视频播放| 伊人婷婷欧美激情| 久久精品人人做| 在线观看三级视频欧美| 国产麻豆精品在线观看| 亚洲第一综合色| 国产精品卡一卡二| 精品国产三级电影在线观看| 色婷婷国产精品| 国产成人自拍网| 另类成人小视频在线| 亚洲乱码中文字幕| 欧美经典三级视频一区二区三区| 欧美日韩二区三区| 99国产精品久久久久久久久久久| 久久99久久精品| 日韩在线a电影| 一区二区在线电影| 国产精品美女久久久久久2018| 欧美大片一区二区三区| 欧美亚洲图片小说| 91天堂素人约啪| 国产成人在线影院| 国产一区二区三区美女| 日本特黄久久久高潮| 亚洲一区二区精品视频| 亚洲伦理在线精品| 综合久久久久久久| 中文字幕中文字幕一区| 国产亚洲欧美日韩在线一区| 日韩欧美国产综合| 欧美人与禽zozo性伦| 在线观看不卡一区| 色综合 综合色| 91福利在线观看| 欧日韩精品视频| 色婷婷国产精品| 欧美在线免费视屏| 欧美自拍丝袜亚洲| 欧美性猛交xxxxxx富婆| 91福利视频久久久久| 色成人在线视频| 欧美在线不卡视频| 在线观看日韩毛片| 69堂成人精品免费视频| 欧美一级淫片007| 欧美一级高清片在线观看| 日韩欧美在线一区二区三区| 日韩视频一区在线观看| 精品久久久久久亚洲综合网| 精品久久久久久久久久久久久久久 | 日韩国产精品91| 青青国产91久久久久久| 精品在线一区二区三区| 国产不卡视频在线观看| 99v久久综合狠狠综合久久| 91小视频免费观看| 欧美日韩一级大片网址| 欧美一区二区三区免费大片| 精品1区2区在线观看| 中文欧美字幕免费| 亚洲愉拍自拍另类高清精品| 五月激情综合网| 国产精品白丝av| 91国偷自产一区二区开放时间| 制服.丝袜.亚洲.中文.综合| 久久九九99视频| 一区二区三区四区不卡视频| 免费一级欧美片在线观看| 粉嫩嫩av羞羞动漫久久久| 色综合久久久久综合| 在线播放中文一区| 国产女同性恋一区二区| 一区二区三区中文字幕| 青青草原综合久久大伊人精品| 高清不卡一区二区| 欧美日韩在线电影| 久久精品视频免费观看| 亚洲一区二区在线视频| 国产福利91精品一区二区三区| 日本韩国欧美一区| 26uuu欧美日本| 午夜在线成人av| 不卡视频一二三| 久久婷婷综合激情| 午夜精品久久久久久久99水蜜桃| 国产99久久久国产精品| 91精品蜜臀在线一区尤物|