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

📄 iop.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
	i2o_driver_notify_controller_remove_all(c);	list_del(&c->list);	list_for_each_entry_safe(dev, tmp, &c->devices, list)	    i2o_device_remove(dev);	/* Ask the IOP to switch to RESET state */	i2o_iop_reset(c);}/** *	i2o_systab_build - Build system table * *	The system table contains information about all the IOPs in the system *	(duh) and is used by the Executives on the IOPs to establish peer2peer *	connections. We're not supporting peer2peer at the moment, but this *	will be needed down the road for things like lan2lan forwarding. * *	Returns 0 on success or negative error code on failure. */static int i2o_systab_build(void){	struct i2o_controller *c, *tmp;	int num_controllers = 0;	u32 change_ind = 0;	int count = 0;	struct i2o_sys_tbl *systab = i2o_systab.virt;	list_for_each_entry_safe(c, tmp, &i2o_controllers, list)	    num_controllers++;	if (systab) {		change_ind = systab->change_ind;		kfree(i2o_systab.virt);	}	/* Header + IOPs */	i2o_systab.len = sizeof(struct i2o_sys_tbl) + num_controllers *	    sizeof(struct i2o_sys_tbl_entry);	systab = i2o_systab.virt = kmalloc(i2o_systab.len, GFP_KERNEL);	if (!systab) {		printk(KERN_ERR "i2o: 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) {			printk(KERN_ERR "i2o: 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))) {			printk(KERN_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_ptr_low(c->post_port);		systab->iops[count].inbound_high = i2o_ptr_high(c->post_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;	u8 *status_block;	unsigned long timeout;	status_block = (u8 *) c->status_block.virt;	memset(status_block, 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_ptr_low((void *)c->status_block.phys), &msg->body[2]);	writel(i2o_ptr_high((void *)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)) {			printk(KERN_ERR "%s: Get status timeout.\n", c->name);			return -ETIMEDOUT;		}		set_current_state(TASK_UNINTERRUPTIBLE);		schedule_timeout(1);		rmb();	}#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) {			printk(KERN_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);	}	printk(KERN_ERR "%s: Unable to get HRT after %d tries, giving up\n",	       c->name, I2O_HRT_GET_TRIES);	return -EBUSY;}/** *	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) {		printk(KERN_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);#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_free - Free the i2o_controller struct *	@c: I2O controller to free */void i2o_iop_free(struct i2o_controller *c){	kfree(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;	printk(KERN_INFO "%s: Activating I2O controller...\n", c->name);	printk(KERN_INFO "%s: This may take a few minutes if there are many "	       "devices\n", c->name);	if ((rc = i2o_iop_activate(c))) {		printk(KERN_ERR "%s: could not activate controller\n",		       c->name);		i2o_iop_reset(c);		return rc;	}	pr_debug("%s: building sys table...\n", c->name);	if ((rc = i2o_systab_build())) {		i2o_iop_reset(c);		return rc;	}	pr_debug("%s: online controller...\n", c->name);	if ((rc = i2o_iop_online(c))) {		i2o_iop_reset(c);		return rc;	}	pr_debug("%s: getting LCT...\n", c->name);	if ((rc = i2o_exec_lct_get(c))) {		i2o_iop_reset(c);		return rc;	}	list_add(&c->list, &i2o_controllers);	i2o_driver_notify_controller_add_all(c);	printk(KERN_INFO "%s: Controller added\n", c->name);	return 0;};/** *	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");	rc = i2o_device_init();	if (rc)		goto exit;	rc = i2o_driver_init();	if (rc)		goto device_exit;	rc = i2o_exec_init();	if (rc)		goto driver_exit;	rc = i2o_pci_init();	if (rc < 0)		goto exec_exit;	return 0;      exec_exit:	i2o_exec_exit();      driver_exit:	i2o_driver_exit();      device_exit:	i2o_device_exit();      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();	i2o_device_exit();};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 + -