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

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

?? device.c

?? linux 內(nèi)核源代碼
?? C
?? 第 1 頁(yè) / 共 3 頁(yè)
字號(hào):
/* *  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/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 <asm/cmb.h>#include "cio.h"#include "cio_debug.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;}/* Store modalias string delimited by prefix/suffix string into buffer with * specified size. Return length of resulting string (excluding trailing '\0') * even if string doesn't fit buffer (snprintf semantics). */static int snprint_alias(char *buf, size_t size,			 struct ccw_device_id *id, const char *suffix){	int len;	len = snprintf(buf, size, "ccw:t%04Xm%02X", id->cu_type, id->cu_model);	if (len > size)		return len;	buf += len;	size -= len;	if (id->dev_type != 0)		len += snprintf(buf, size, "dt%04Xdm%02X%s", id->dev_type,				id->dev_model, suffix);	else		len += snprintf(buf, size, "dtdm%s", suffix);	return len;}/* Set up environment variables for ccw device uevent. Return 0 on success, * non-zero otherwise. */static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env){	struct ccw_device *cdev = to_ccwdev(dev);	struct ccw_device_id *id = &(cdev->id);	int ret;	char modalias_buf[30];	/* CU_TYPE= */	ret = add_uevent_var(env, "CU_TYPE=%04X", id->cu_type);	if (ret)		return ret;	/* CU_MODEL= */	ret = add_uevent_var(env, "CU_MODEL=%02X", id->cu_model);	if (ret)		return ret;	/* The next two can be zero, that's ok for us */	/* DEV_TYPE= */	ret = add_uevent_var(env, "DEV_TYPE=%04X", id->dev_type);	if (ret)		return ret;	/* DEV_MODEL= */	ret = add_uevent_var(env, "DEV_MODEL=%02X", id->dev_model);	if (ret)		return ret;	/* MODALIAS=  */	snprint_alias(modalias_buf, sizeof(modalias_buf), id, "");	ret = add_uevent_var(env, "MODALIAS=%s", modalias_buf);	return ret;}struct bus_type ccw_bus_type;static int io_subchannel_probe (struct subchannel *);static int io_subchannel_remove (struct subchannel *);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 *);static 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;wait_queue_head_t ccw_device_init_wq;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 chsc_ssd_info *ssd = &sch->ssd_info;	ssize_t ret = 0;	int chp;	int mask;	for (chp = 0; chp < 8; chp++) {		mask = 0x80 >> chp;		if (ssd->path_mask & mask)			ret += sprintf(buf + ret, "%02x ", ssd->chpid[chp].id);		else			ret += sprintf(buf + ret, "00 ");	}	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 len;	len = snprint_alias(buf, PAGE_SIZE, id, "\n");	return len > PAGE_SIZE ? PAGE_SIZE : len;}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");}int ccw_device_is_orphan(struct ccw_device *cdev){	return sch_is_pseudo_sch(to_subchannel(cdev->dev.parent));}static void ccw_device_unregister(struct ccw_device *cdev){	if (test_and_clear_bit(1, &cdev->private->registered))		device_del(&cdev->dev);}static void ccw_device_remove_orphan_cb(struct device *dev){	struct ccw_device *cdev = to_ccwdev(dev);	ccw_device_unregister(cdev);	put_device(&cdev->dev);}static void ccw_device_remove_sch_cb(struct device *dev){	struct subchannel *sch;	sch = to_subchannel(dev);	css_sch_device_unregister(sch);	/* Reset intparm to zeroes. */	sch->schib.pmcw.intparm = 0;	cio_modify(sch);	put_device(&sch->dev);}static voidccw_device_remove_disconnected(struct ccw_device *cdev){	unsigned long flags;	int rc;	/*	 * Forced offline in disconnected state means	 * 'throw away device'.	 */	if (ccw_device_is_orphan(cdev)) {		/*		 * Deregister ccw device.		 * Unfortunately, we cannot do this directly from the		 * attribute method.		 */		spin_lock_irqsave(cdev->ccwlock, flags);		cdev->private->state = DEV_STATE_NOT_OPER;		spin_unlock_irqrestore(cdev->ccwlock, flags);		rc = device_schedule_callback(&cdev->dev,					      ccw_device_remove_orphan_cb);		if (rc)			CIO_MSG_EVENT(2, "Couldn't unregister orphan "				      "0.%x.%04x\n",				      cdev->private->dev_id.ssid,				      cdev->private->dev_id.devno);		return;	}	/* Deregister subchannel, which will kill the ccw device. */	rc = device_schedule_callback(cdev->dev.parent,				      ccw_device_remove_sch_cb);	if (rc)		CIO_MSG_EVENT(2, "Couldn't unregister disconnected device "			      "0.%x.%04x\n",			      cdev->private->dev_id.ssid,			      cdev->private->dev_id.devno);}/** * ccw_device_set_offline() - disable a ccw device for I/O * @cdev: target ccw device * * This function calls the driver's set_offline() function for @cdev, if * given, and then disables @cdev. * Returns: *   %0 on success and a negative error value on failure. * Context: *  enabled, ccw device lock not held */int ccw_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 {		CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "			      "device 0.%x.%04x\n",			      ret, cdev->private->dev_id.ssid,			      cdev->private->dev_id.devno);		cdev->online = 1;	} 	return ret;}/** * ccw_device_set_online() - enable a ccw device for I/O * @cdev: target ccw device * * This function first enables @cdev and then calls the driver's set_online() * function for @cdev, if given. If set_online() returns an error, @cdev is * disabled again. * Returns: *   %0 on success and a negative error value on failure. * Context: *  enabled, ccw device lock not held */int ccw_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 {		CIO_MSG_EVENT(2, "ccw_device_online returned %d, "			      "device 0.%x.%04x\n",			      ret, cdev->private->dev_id.ssid,			      cdev->private->dev_id.devno);		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		CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "			      "device 0.%x.%04x\n",			      ret, cdev->private->dev_id.ssid,			      cdev->private->dev_id.devno);	return (ret == 0) ? -ENODEV : ret;}static void online_store_handle_offline(struct ccw_device *cdev){	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);}static int online_store_recog_and_online(struct ccw_device *cdev){	int ret;	/* Do device recognition, if needed. */	if (cdev->id.cu_type == 0) {		ret = ccw_device_recognition(cdev);		if (ret) {			CIO_MSG_EVENT(0, "Couldn't start recognition "				      "for device 0.%x.%04x (ret=%d)\n",				      cdev->private->dev_id.ssid,				      cdev->private->dev_id.devno, ret);			return ret;		}		wait_event(cdev->private->wait_q,			   cdev->private->flags.recog_done);	}	if (cdev->drv && cdev->drv->set_online)		ccw_device_set_online(cdev);	return 0;}static void online_store_handle_online(struct ccw_device *cdev, int force){	int ret;	ret = online_store_recog_and_online(cdev);	if (ret)		return;	if (force && cdev->private->state == DEV_STATE_BOXED) {		ret = ccw_device_stlck(cdev);		if (ret) {			dev_warn(&cdev->dev,				 "ccw_device_stlck returned %d!\n", ret);			return;		}		if (cdev->id.cu_type == 0)			cdev->private->state = DEV_STATE_NOT_OPER;		online_store_recog_and_online(cdev);	}

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
精品福利av导航| 久久嫩草精品久久久精品| 成人av网址在线| 国产在线视视频有精品| 精品一区二区三区影院在线午夜 | 蜜桃精品视频在线观看| 丝袜美腿亚洲一区二区图片| 亚洲国产日韩a在线播放| 亚洲一区二区偷拍精品| 亚洲伊人伊色伊影伊综合网| 亚洲一区成人在线| 亚洲成人激情av| 免费在线观看精品| 精品一二三四在线| 成人综合婷婷国产精品久久 | 日韩西西人体444www| 欧美一级艳片视频免费观看| 欧美一区二区成人6969| 精品91自产拍在线观看一区| 国产日韩亚洲欧美综合| 中文字幕在线一区免费| 一区二区三区在线免费观看| 日精品一区二区三区| 日本大胆欧美人术艺术动态| 国产一区二区91| 91小视频免费观看| 欧美三级日本三级少妇99| 日韩欧美的一区| 中文字幕第一区二区| 亚洲一区在线视频| 99视频一区二区三区| 欧洲在线/亚洲| 4438亚洲最大| 国产精品电影一区二区| 日韩精品乱码免费| 波多野结衣精品在线| 欧美日韩国产免费一区二区 | 在线观看www91| 久久久亚洲欧洲日产国码αv| 亚洲天堂网中文字| 久久精品国产**网站演员| 高清不卡在线观看av| 欧美日韩在线综合| 日本一区二区免费在线观看视频| 亚洲九九爱视频| 国产一区不卡在线| 欧美日韩精品专区| 国产精品欧美久久久久无广告 | 中文字幕 久热精品 视频在线| 亚洲国产综合在线| 成人av午夜影院| 26uuu亚洲综合色| 日本中文字幕一区二区有限公司| 成人免费毛片片v| 欧美成人a在线| 亚洲va欧美va人人爽午夜| 成人av网站免费| 久久精品一区蜜桃臀影院| 五月天激情综合网| 色狠狠一区二区三区香蕉| 久久久99久久| 久草这里只有精品视频| 在线播放91灌醉迷j高跟美女| 亚洲男人的天堂一区二区| 国产91丝袜在线观看| 欧美精品一区二区三区在线播放| 香蕉av福利精品导航| 日本国产一区二区| 亚洲日本在线天堂| 99免费精品视频| 国产精品久久久久久久裸模 | 亚洲视频一区二区在线| 成人美女视频在线观看18| 久久久久亚洲蜜桃| 国产一区二区不卡老阿姨| 欧美xxx久久| 久久福利资源站| 精品少妇一区二区三区在线播放 | 777亚洲妇女| 亚洲风情在线资源站| 在线观看亚洲a| 亚洲国产毛片aaaaa无费看| 欧美色倩网站大全免费| 一区二区成人在线观看| 欧美午夜电影一区| 午夜一区二区三区在线观看| 欧美男同性恋视频网站| 免费成人在线网站| www国产成人| fc2成人免费人成在线观看播放| 国产精品欧美极品| 91国模大尺度私拍在线视频| 亚洲激情成人在线| 欧美精品久久一区二区三区| 日韩成人av影视| 久久精品水蜜桃av综合天堂| 国产电影一区在线| 亚洲黄色av一区| 日韩欧美国产午夜精品| 国产精品白丝av| 亚洲精品国产成人久久av盗摄| 欧美中文字幕不卡| 久久精品国产网站| 中文字幕一区二区三区视频| 欧美午夜精品久久久久久孕妇| 免费在线观看视频一区| 中文av一区二区| 欧美日本在线一区| 国产激情一区二区三区四区| 亚洲欧美国产高清| 欧美大片国产精品| 91热门视频在线观看| 蜜臀精品久久久久久蜜臀| 日本一区二区在线不卡| 欧美在线短视频| 国产成人免费视| 香蕉成人伊视频在线观看| 久久久99免费| 7777精品伊人久久久大香线蕉 | 美女视频黄久久| 中文字幕一区免费在线观看| 欧美一级免费观看| 一本久道久久综合中文字幕| 日本特黄久久久高潮| 国产精品不卡在线| 久久亚洲影视婷婷| 3751色影院一区二区三区| 91在线高清观看| 国产精品91xxx| 免费高清在线一区| 亚洲国产色一区| 中文字幕日韩一区| 国产欧美精品一区二区三区四区| 3atv在线一区二区三区| 欧美影视一区在线| 99视频精品免费视频| 国产电影一区在线| 极品瑜伽女神91| 青椒成人免费视频| 亚洲成人动漫一区| 一区二区三区欧美| 亚洲女人的天堂| 国产精品久久99| 欧美国产日韩精品免费观看| 欧美精品一区二区久久久| 欧美一三区三区四区免费在线看 | 亚洲精品一区二区三区香蕉| 欧美日韩国产成人在线91| 色综合欧美在线| 99re6这里只有精品视频在线观看| 国产在线日韩欧美| 国产一区在线不卡| 国产精品原创巨作av| 国产成人日日夜夜| 成人网男人的天堂| 成人午夜av电影| 91啪亚洲精品| 在线精品观看国产| 欧美老肥妇做.爰bbww视频| 欧美视频日韩视频| 91精品国产一区二区三区| 日韩视频一区在线观看| 日韩精品一区二区三区中文不卡| 欧美一级日韩不卡播放免费| 欧美日韩国产首页| 日韩欧美一二三| 久久久国产午夜精品 | 欧美影视一区在线| 在线电影欧美成精品| 日韩午夜精品视频| 久久久精品黄色| 亚洲美女一区二区三区| 亚洲成在线观看| 久久66热re国产| 99久久精品免费观看| 欧美日韩中文精品| 欧美成人猛片aaaaaaa| 国产精品私人影院| 亚洲第一成人在线| 国产精选一区二区三区| 一本大道久久a久久精品综合| 欧美三片在线视频观看| 亚洲精品在线一区二区| 亚洲人成精品久久久久| 天天av天天翘天天综合网| 国产丶欧美丶日本不卡视频| 日本道在线观看一区二区| 日韩欧美久久久| 亚洲天堂网中文字| 久久精品国产色蜜蜜麻豆| 97超碰欧美中文字幕| 日韩欧美激情在线| 亚洲欧美日韩电影| 国产在线播放一区二区三区| 欧洲一区在线观看| 久久久精品综合| 人人爽香蕉精品| 色婷婷国产精品| 久久久久9999亚洲精品| 日韩av电影免费观看高清完整版|