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

📄 iop.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!systab) {		osm_err("unable to allocate memory for System Table\n");		return -ENOMEM;	}	memset(systab, 0, i2o_systab.len);	systab->version = I2OVERSION;	systab->change_ind = change_ind + 1;	list_for_each_entry_safe(c, tmp, &i2o_controllers, list) {		i2o_status_block *sb;		if (count >= num_controllers) {			osm_err("controller added while building system table"				"\n");			break;		}		sb = c->status_block.virt;		/*		 * Get updated IOP state so we have the latest information		 *		 * We should delete the controller at this point if it		 * doesn't respond since if it's not on the system table		 * it is techninically not part of the I2O subsystem...		 */		if (unlikely(i2o_status_get(c))) {			osm_err("%s: Deleting b/c could not get status while "				"attempting to build system table\n", c->name);			i2o_iop_remove(c);			continue;	// try the next one		}		systab->iops[count].org_id = sb->org_id;		systab->iops[count].iop_id = c->unit + 2;		systab->iops[count].seg_num = 0;		systab->iops[count].i2o_version = sb->i2o_version;		systab->iops[count].iop_state = sb->iop_state;		systab->iops[count].msg_type = sb->msg_type;		systab->iops[count].frame_size = sb->inbound_frame_size;		systab->iops[count].last_changed = change_ind;		systab->iops[count].iop_capabilities = sb->iop_capabilities;		systab->iops[count].inbound_low =		    i2o_dma_low(c->base.phys + I2O_IN_PORT);		systab->iops[count].inbound_high =		    i2o_dma_high(c->base.phys + I2O_IN_PORT);		count++;	}	systab->num_entries = count;	return 0;};/** *	i2o_parse_hrt - Parse the hardware resource table. *	@c: I2O controller * *	We don't do anything with it except dumping it (in debug mode). * *	Returns 0. */static int i2o_parse_hrt(struct i2o_controller *c){	i2o_dump_hrt(c);	return 0;};/** *	i2o_status_get - Get the status block from the I2O controller *	@c: I2O controller * *	Issue a status query on the controller. This updates the attached *	status block. The status block could then be accessed through *	c->status_block. * *	Returns 0 on sucess or negative error code on failure. */int i2o_status_get(struct i2o_controller *c){	struct i2o_message __iomem *msg;	u32 m;	volatile u8 *status_block;	unsigned long timeout;	status_block = (u8 *) c->status_block.virt;	memset(c->status_block.virt, 0, sizeof(i2o_status_block));	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);	if (m == I2O_QUEUE_EMPTY)		return -ETIMEDOUT;	writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);	writel(I2O_CMD_STATUS_GET << 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: use resonable transaction context	writel(0, &msg->body[0]);	writel(0, &msg->body[1]);	writel(i2o_dma_low(c->status_block.phys), &msg->body[2]);	writel(i2o_dma_high(c->status_block.phys), &msg->body[3]);	writel(sizeof(i2o_status_block), &msg->body[4]);	/* always 88 bytes */	i2o_msg_post(c, m);	/* Wait for a reply */	timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ;	while (status_block[87] != 0xFF) {		if (time_after(jiffies, timeout)) {			osm_err("%s: Get status timeout.\n", c->name);			return -ETIMEDOUT;		}		schedule_timeout_uninterruptible(1);	}#ifdef DEBUG	i2o_debug_state(c);#endif	return 0;}/* *	i2o_hrt_get - Get the Hardware Resource Table from the I2O controller *	@c: I2O controller from which the HRT should be fetched * *	The HRT contains information about possible hidden devices but is *	mostly useless to us. * *	Returns 0 on success or negativer error code on failure. */static int i2o_hrt_get(struct i2o_controller *c){	int rc;	int i;	i2o_hrt *hrt = c->hrt.virt;	u32 size = sizeof(i2o_hrt);	struct device *dev = &c->pdev->dev;	for (i = 0; i < I2O_HRT_GET_TRIES; i++) {		struct i2o_message __iomem *msg;		u32 m;		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);		if (m == I2O_QUEUE_EMPTY)			return -ETIMEDOUT;		writel(SIX_WORD_MSG_SIZE | SGL_OFFSET_4, &msg->u.head[0]);		writel(I2O_CMD_HRT_GET << 24 | HOST_TID << 12 | ADAPTER_TID,		       &msg->u.head[1]);		writel(0xd0000000 | c->hrt.len, &msg->body[0]);		writel(c->hrt.phys, &msg->body[1]);		rc = i2o_msg_post_wait_mem(c, m, 20, &c->hrt);		if (rc < 0) {			osm_err("%s: Unable to get HRT (status=%#x)\n", c->name,				-rc);			return rc;		}		size = hrt->num_entries * hrt->entry_len << 2;		if (size > c->hrt.len) {			if (i2o_dma_realloc(dev, &c->hrt, size, GFP_KERNEL))				return -ENOMEM;			else				hrt = c->hrt.virt;		} else			return i2o_parse_hrt(c);	}	osm_err("%s: Unable to get HRT after %d tries, giving up\n", c->name,		I2O_HRT_GET_TRIES);	return -EBUSY;}/** *	i2o_iop_free - Free the i2o_controller struct *	@c: I2O controller to free */void i2o_iop_free(struct i2o_controller *c){	kfree(c);};/** *	i2o_iop_release - release the memory for a I2O controller *	@dev: I2O controller which should be released * *	Release the allocated memory. This function is called if refcount of *	device reaches 0 automatically. */static void i2o_iop_release(struct device *dev){	struct i2o_controller *c = to_i2o_controller(dev);	i2o_iop_free(c);};/* I2O controller class */static struct class *i2o_controller_class;/** *	i2o_iop_alloc - Allocate and initialize a i2o_controller struct * *	Allocate the necessary memory for a i2o_controller struct and *	initialize the lists. * *	Returns a pointer to the I2O controller or a negative error code on *	failure. */struct i2o_controller *i2o_iop_alloc(void){	static int unit = 0;	/* 0 and 1 are NULL IOP and Local Host */	struct i2o_controller *c;	c = kmalloc(sizeof(*c), GFP_KERNEL);	if (!c) {		osm_err("i2o: Insufficient memory to allocate a I2O controller."			"\n");		return ERR_PTR(-ENOMEM);	}	memset(c, 0, sizeof(*c));	INIT_LIST_HEAD(&c->devices);	spin_lock_init(&c->lock);	init_MUTEX(&c->lct_lock);	c->unit = unit++;	sprintf(c->name, "iop%d", c->unit);	device_initialize(&c->device);	c->device.release = &i2o_iop_release;	snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);#if BITS_PER_LONG == 64	spin_lock_init(&c->context_list_lock);	atomic_set(&c->context_list_counter, 0);	INIT_LIST_HEAD(&c->context_list);#endif	return c;};/** *	i2o_iop_add - Initialize the I2O controller and add him to the I2O core *	@c: controller * *	Initialize the I2O controller and if no error occurs add him to the I2O *	core. * *	Returns 0 on success or negative error code on failure. */int i2o_iop_add(struct i2o_controller *c){	int rc;	if ((rc = device_add(&c->device))) {		osm_err("%s: could not add controller\n", c->name);		goto iop_reset;	}	c->classdev = class_device_create(i2o_controller_class, NULL, MKDEV(0,0),			&c->device, "iop%d", c->unit);	if (IS_ERR(c->classdev)) {		osm_err("%s: could not add controller class\n", c->name);		goto device_del;	}	osm_info("%s: Activating I2O controller...\n", c->name);	osm_info("%s: This may take a few minutes if there are many devices\n",		 c->name);	if ((rc = i2o_iop_activate(c))) {		osm_err("%s: could not activate controller\n", c->name);		goto class_del;	}	osm_debug("%s: building sys table...\n", c->name);	if ((rc = i2o_systab_build()))		goto class_del;	osm_debug("%s: online controller...\n", c->name);	if ((rc = i2o_iop_online(c)))		goto class_del;	osm_debug("%s: getting LCT...\n", c->name);	if ((rc = i2o_exec_lct_get(c)))		goto class_del;	list_add(&c->list, &i2o_controllers);	i2o_driver_notify_controller_add_all(c);	osm_info("%s: Controller added\n", c->name);	return 0;      class_del:	class_device_unregister(c->classdev);      device_del:	device_del(&c->device);      iop_reset:	i2o_iop_reset(c);	return rc;};/** *	i2o_event_register - Turn on/off event notification for a I2O device *	@dev: I2O device which should receive the event registration request *	@drv: driver which want to get notified *	@tcntxt: transaction context to use with this notifier *	@evt_mask: mask of events * *	Create and posts an event registration message to the task. No reply *	is waited for, or expected. If you do not want further notifications, *	call the i2o_event_register again with a evt_mask of 0. * *	Returns 0 on success or -ETIMEDOUT if no message could be fetched for *	sending the request. */int i2o_event_register(struct i2o_device *dev, struct i2o_driver *drv,		       int tcntxt, u32 evt_mask){	struct i2o_controller *c = dev->iop;	struct i2o_message __iomem *msg;	u32 m;	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);	if (m == I2O_QUEUE_EMPTY)		return -ETIMEDOUT;	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);	writel(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | dev->lct_data.	       tid, &msg->u.head[1]);	writel(drv->context, &msg->u.s.icntxt);	writel(tcntxt, &msg->u.s.tcntxt);	writel(evt_mask, &msg->body[0]);	i2o_msg_post(c, m);	return 0;};/** *	i2o_iop_init - I2O main initialization function * *	Initialize the I2O drivers (OSM) functions, register the Executive OSM, *	initialize the I2O PCI part and finally initialize I2O device stuff. * *	Returns 0 on success or negative error code on failure. */static int __init i2o_iop_init(void){	int rc = 0;	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");	i2o_controller_class = class_create(THIS_MODULE, "i2o_controller");	if (IS_ERR(i2o_controller_class)) {		osm_err("can't register class i2o_controller\n");		goto exit;	}	if ((rc = i2o_driver_init()))		goto class_exit;	if ((rc = i2o_exec_init()))		goto driver_exit;	if ((rc = i2o_pci_init()))		goto exec_exit;	return 0;      exec_exit:	i2o_exec_exit();      driver_exit:	i2o_driver_exit();      class_exit:	class_destroy(i2o_controller_class);      exit:	return rc;}/** *	i2o_iop_exit - I2O main exit function * *	Removes I2O controllers from PCI subsystem and shut down OSMs. */static void __exit i2o_iop_exit(void){	i2o_pci_exit();	i2o_exec_exit();	i2o_driver_exit();	class_destroy(i2o_controller_class);};module_init(i2o_iop_init);module_exit(i2o_iop_exit);MODULE_AUTHOR("Red Hat Software");MODULE_LICENSE("GPL");MODULE_DESCRIPTION(OSM_DESCRIPTION);MODULE_VERSION(OSM_VERSION);#if BITS_PER_LONG == 64EXPORT_SYMBOL(i2o_cntxt_list_add);EXPORT_SYMBOL(i2o_cntxt_list_get);EXPORT_SYMBOL(i2o_cntxt_list_remove);EXPORT_SYMBOL(i2o_cntxt_list_get_ptr);#endifEXPORT_SYMBOL(i2o_msg_get_wait);EXPORT_SYMBOL(i2o_msg_nop);EXPORT_SYMBOL(i2o_find_iop);EXPORT_SYMBOL(i2o_iop_find_device);EXPORT_SYMBOL(i2o_event_register);EXPORT_SYMBOL(i2o_status_get);EXPORT_SYMBOL(i2o_controllers);

⌨️ 快捷键说明

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