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

📄 exec-osm.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
 *	Returns number of bytes printed into buffer. */static ssize_t i2o_exec_show_product_id(struct device *d, struct device_attribute *attr, char *buf){	struct i2o_device *dev = to_i2o_device(d);	u16 id;	if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {		sprintf(buf, "0x%04x", id);		return strlen(buf) + 1;	}	return 0;};/* Exec-OSM device attributes */static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL);static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);/** *	i2o_exec_probe - Called if a new I2O device (executive class) appears *	@dev: I2O device which should be probed * *	Registers event notification for every event from Executive device. The *	return is always 0, because we want all devices of class Executive. * *	Returns 0 on success. */static int i2o_exec_probe(struct device *dev){	struct i2o_device *i2o_dev = to_i2o_device(dev);	struct i2o_controller *c = i2o_dev->iop;	i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);	c->exec = i2o_dev;	i2o_exec_lct_notify(c, c->lct->change_ind + 1);	device_create_file(dev, &dev_attr_vendor_id);	device_create_file(dev, &dev_attr_product_id);	return 0;};/** *	i2o_exec_remove - Called on I2O device removal *	@dev: I2O device which was removed * *	Unregisters event notification from Executive I2O device. * *	Returns 0 on success. */static int i2o_exec_remove(struct device *dev){	device_remove_file(dev, &dev_attr_product_id);	device_remove_file(dev, &dev_attr_vendor_id);	i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);	return 0;};/** *	i2o_exec_lct_modified - Called on LCT NOTIFY reply *	@c: I2O controller on which the LCT has modified * *	This function handles asynchronus LCT NOTIFY replies. It parses the *	new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY *	again, otherwise send LCT NOTIFY to get informed on next LCT change. */static void i2o_exec_lct_modified(struct i2o_controller *c){	u32 change_ind = 0;	if (i2o_device_parse_lct(c) != -EAGAIN)		change_ind = c->lct->change_ind + 1;	i2o_exec_lct_notify(c, change_ind);};/** *	i2o_exec_reply -  I2O Executive reply handler *	@c: I2O controller from which the reply comes *	@m: message id *	@msg: pointer to the I2O reply message * *	This function is always called from interrupt context. If a POST WAIT *	reply was received, pass it to the complete function. If a LCT NOTIFY *	reply was received, a new event is created to handle the update. * *	Returns 0 on success and if the reply should not be flushed or > 0 *	on success and if the reply should be flushed. Returns negative error *	code on failure and if the reply should be flushed. */static int i2o_exec_reply(struct i2o_controller *c, u32 m,			  struct i2o_message *msg){	u32 context;	if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {		/*		 * If Fail bit is set we must take the transaction context of		 * the preserved message to find the right request again.		 */		struct i2o_message __iomem *pmsg;		u32 pm;		pm = le32_to_cpu(msg->body[3]);		pmsg = i2o_msg_in_to_virt(c, pm);		i2o_report_status(KERN_INFO, "i2o_core", msg);		context = readl(&pmsg->u.s.tcntxt);		/* Release the preserved msg */		i2o_msg_nop(c, pm);	} else		context = le32_to_cpu(msg->u.s.tcntxt);	if (context & 0x80000000)		return i2o_msg_post_wait_complete(c, m, msg, context);	if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {		struct work_struct *work;		pr_debug("%s: LCT notify received\n", c->name);		work = kmalloc(sizeof(*work), GFP_ATOMIC);		if (!work)			return -ENOMEM;		INIT_WORK(work, (void (*)(void *))i2o_exec_lct_modified, c);		queue_work(i2o_exec_driver.event_queue, work);		return 1;	}	/*	 * If this happens, we want to dump the message to the syslog so	 * it can be sent back to the card manufacturer by the end user	 * to aid in debugging.	 *	 */	printk(KERN_WARNING "%s: Unsolicited message reply sent to core!"	       "Message dumped to syslog\n", c->name);	i2o_dump_message(msg);	return -EFAULT;}/** *	i2o_exec_event - Event handling function *	@evt: Event which occurs * *	Handles events send by the Executive device. At the moment does not do *	anything useful. */static void i2o_exec_event(struct i2o_event *evt){	if (likely(evt->i2o_dev))		osm_debug("Event received from device: %d\n",			  evt->i2o_dev->lct_data.tid);	kfree(evt);};/** *	i2o_exec_lct_get - Get the IOP's Logical Configuration Table *	@c: I2O controller from which the LCT should be fetched * *	Send a LCT NOTIFY request to the controller, and wait *	I2O_TIMEOUT_LCT_GET seconds until arrival of response. If the LCT is *	to large, retry it. * *	Returns 0 on success or negative error code on failure. */int i2o_exec_lct_get(struct i2o_controller *c){	struct i2o_message __iomem *msg;	u32 m;	int i = 0;	int rc = -EAGAIN;	for (i = 1; i <= I2O_LCT_GET_TRIES; i++) {		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);		if (m == I2O_QUEUE_EMPTY)			return -ETIMEDOUT;		writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);		writel(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | ADAPTER_TID,		       &msg->u.head[1]);		writel(0xffffffff, &msg->body[0]);		writel(0x00000000, &msg->body[1]);		writel(0xd0000000 | c->dlct.len, &msg->body[2]);		writel(c->dlct.phys, &msg->body[3]);		rc = i2o_msg_post_wait(c, m, I2O_TIMEOUT_LCT_GET);		if (rc < 0)			break;		rc = i2o_device_parse_lct(c);		if (rc != -EAGAIN)			break;	}	return rc;}/** *	i2o_exec_lct_notify - Send a asynchronus LCT NOTIFY request *	@c: I2O controller to which the request should be send *	@change_ind: change indicator * *	This function sends a LCT NOTIFY request to the I2O controller with *	the change indicator change_ind. If the change_ind == 0 the controller *	replies immediately after the request. If change_ind > 0 the reply is *	send after change indicator of the LCT is > change_ind. */static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind){	i2o_status_block *sb = c->status_block.virt;	struct device *dev;	struct i2o_message __iomem *msg;	u32 m;	dev = &c->pdev->dev;	if (i2o_dma_realloc(dev, &c->dlct, sb->expected_lct_size, GFP_KERNEL))		return -ENOMEM;	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);	if (m == I2O_QUEUE_EMPTY)		return -ETIMEDOUT;	writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);	writel(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | ADAPTER_TID,	       &msg->u.head[1]);	writel(i2o_exec_driver.context, &msg->u.s.icntxt);	writel(0, &msg->u.s.tcntxt);	/* FIXME */	writel(0xffffffff, &msg->body[0]);	writel(change_ind, &msg->body[1]);	writel(0xd0000000 | c->dlct.len, &msg->body[2]);	writel(c->dlct.phys, &msg->body[3]);	i2o_msg_post(c, m);	return 0;};/* Exec OSM driver struct */struct i2o_driver i2o_exec_driver = {	.name = OSM_NAME,	.reply = i2o_exec_reply,	.event = i2o_exec_event,	.classes = i2o_exec_class_id,	.driver = {		   .probe = i2o_exec_probe,		   .remove = i2o_exec_remove,		   },};/** *	i2o_exec_init - Registers the Exec OSM * *	Registers the Exec OSM in the I2O core. * *	Returns 0 on success or negative error code on failure. */int __init i2o_exec_init(void){	return i2o_driver_register(&i2o_exec_driver);};/** *	i2o_exec_exit - Removes the Exec OSM * *	Unregisters the Exec OSM from the I2O core. */void __exit i2o_exec_exit(void){	i2o_driver_unregister(&i2o_exec_driver);};EXPORT_SYMBOL(i2o_msg_post_wait_mem);EXPORT_SYMBOL(i2o_exec_lct_get);

⌨️ 快捷键说明

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