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

📄 mad.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		next_send_buf = send_buf->next;		mad_send_wr->send_wr.wr.ud.ah = send_buf->ah;		if (((struct ib_mad_hdr *) send_buf->mad)->mgmt_class ==		    IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {			ret = handle_outgoing_dr_smp(mad_agent_priv,						     mad_send_wr);			if (ret < 0)		/* error */				goto error;			else if (ret == 1)	/* locally consumed */				continue;		}		mad_send_wr->tid = ((struct ib_mad_hdr *) send_buf->mad)->tid;		/* Timeout will be updated after send completes */		mad_send_wr->timeout = msecs_to_jiffies(send_buf->timeout_ms);		mad_send_wr->retries = send_buf->retries;		/* Reference for work request to QP + response */		mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0);		mad_send_wr->status = IB_WC_SUCCESS;		/* Reference MAD agent until send completes */		atomic_inc(&mad_agent_priv->refcount);		spin_lock_irqsave(&mad_agent_priv->lock, flags);		list_add_tail(&mad_send_wr->agent_list,			      &mad_agent_priv->send_list);		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);		if (mad_agent_priv->agent.rmpp_version) {			ret = ib_send_rmpp_mad(mad_send_wr);			if (ret >= 0 && ret != IB_RMPP_RESULT_CONSUMED)				ret = ib_send_mad(mad_send_wr);		} else			ret = ib_send_mad(mad_send_wr);		if (ret < 0) {			/* Fail send request */			spin_lock_irqsave(&mad_agent_priv->lock, flags);			list_del(&mad_send_wr->agent_list);			spin_unlock_irqrestore(&mad_agent_priv->lock, flags);			atomic_dec(&mad_agent_priv->refcount);			goto error;		}	}	return 0;error:	if (bad_send_buf)		*bad_send_buf = send_buf;	return ret;}EXPORT_SYMBOL(ib_post_send_mad);/* * ib_free_recv_mad - Returns data buffers used to receive *  a MAD to the access layer */void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc){	struct ib_mad_recv_buf *mad_recv_buf, *temp_recv_buf;	struct ib_mad_private_header *mad_priv_hdr;	struct ib_mad_private *priv;	struct list_head free_list;	INIT_LIST_HEAD(&free_list);	list_splice_init(&mad_recv_wc->rmpp_list, &free_list);	list_for_each_entry_safe(mad_recv_buf, temp_recv_buf,					&free_list, list) {		mad_recv_wc = container_of(mad_recv_buf, struct ib_mad_recv_wc,					   recv_buf);		mad_priv_hdr = container_of(mad_recv_wc,					    struct ib_mad_private_header,					    recv_wc);		priv = container_of(mad_priv_hdr, struct ib_mad_private,				    header);		kmem_cache_free(ib_mad_cache, priv);	}}EXPORT_SYMBOL(ib_free_recv_mad);struct ib_mad_agent *ib_redirect_mad_qp(struct ib_qp *qp,					u8 rmpp_version,					ib_mad_send_handler send_handler,					ib_mad_recv_handler recv_handler,					void *context){	return ERR_PTR(-EINVAL);	/* XXX: for now */}EXPORT_SYMBOL(ib_redirect_mad_qp);int ib_process_mad_wc(struct ib_mad_agent *mad_agent,		      struct ib_wc *wc){	printk(KERN_ERR PFX "ib_process_mad_wc() not implemented yet\n");	return 0;}EXPORT_SYMBOL(ib_process_mad_wc);static int method_in_use(struct ib_mad_mgmt_method_table **method,			 struct ib_mad_reg_req *mad_reg_req){	int i;	for (i = find_first_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS);	     i < IB_MGMT_MAX_METHODS;	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,			       1+i)) {		if ((*method)->agent[i]) {			printk(KERN_ERR PFX "Method %d already in use\n", i);			return -EINVAL;		}	}	return 0;}static int allocate_method_table(struct ib_mad_mgmt_method_table **method){	/* Allocate management method table */	*method = kzalloc(sizeof **method, GFP_ATOMIC);	if (!*method) {		printk(KERN_ERR PFX "No memory for "		       "ib_mad_mgmt_method_table\n");		return -ENOMEM;	}	return 0;}/* * Check to see if there are any methods still in use */static int check_method_table(struct ib_mad_mgmt_method_table *method){	int i;	for (i = 0; i < IB_MGMT_MAX_METHODS; i++)		if (method->agent[i])			return 1;	return 0;}/* * Check to see if there are any method tables for this class still in use */static int check_class_table(struct ib_mad_mgmt_class_table *class){	int i;	for (i = 0; i < MAX_MGMT_CLASS; i++)		if (class->method_table[i])			return 1;	return 0;}static int check_vendor_class(struct ib_mad_mgmt_vendor_class *vendor_class){	int i;	for (i = 0; i < MAX_MGMT_OUI; i++)		if (vendor_class->method_table[i])			return 1;	return 0;}static int find_vendor_oui(struct ib_mad_mgmt_vendor_class *vendor_class,			   char *oui){	int i;	for (i = 0; i < MAX_MGMT_OUI; i++)                /* Is there matching OUI for this vendor class ? */                if (!memcmp(vendor_class->oui[i], oui, 3))			return i;	return -1;}static int check_vendor_table(struct ib_mad_mgmt_vendor_class_table *vendor){	int i;	for (i = 0; i < MAX_MGMT_VENDOR_RANGE2; i++)		if (vendor->vendor_class[i])			return 1;	return 0;}static void remove_methods_mad_agent(struct ib_mad_mgmt_method_table *method,				     struct ib_mad_agent_private *agent){	int i;	/* Remove any methods for this mad agent */	for (i = 0; i < IB_MGMT_MAX_METHODS; i++) {		if (method->agent[i] == agent) {			method->agent[i] = NULL;		}	}}static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,			      struct ib_mad_agent_private *agent_priv,			      u8 mgmt_class){	struct ib_mad_port_private *port_priv;	struct ib_mad_mgmt_class_table **class;	struct ib_mad_mgmt_method_table **method;	int i, ret;	port_priv = agent_priv->qp_info->port_priv;	class = &port_priv->version[mad_reg_req->mgmt_class_version].class;	if (!*class) {		/* Allocate management class table for "new" class version */		*class = kzalloc(sizeof **class, GFP_ATOMIC);		if (!*class) {			printk(KERN_ERR PFX "No memory for "			       "ib_mad_mgmt_class_table\n");			ret = -ENOMEM;			goto error1;		}		/* Allocate method table for this management class */		method = &(*class)->method_table[mgmt_class];		if ((ret = allocate_method_table(method)))			goto error2;	} else {		method = &(*class)->method_table[mgmt_class];		if (!*method) {			/* Allocate method table for this management class */			if ((ret = allocate_method_table(method)))				goto error1;		}	}	/* Now, make sure methods are not already in use */	if (method_in_use(method, mad_reg_req))		goto error3;	/* Finally, add in methods being registered */	for (i = find_first_bit(mad_reg_req->method_mask,				IB_MGMT_MAX_METHODS);	     i < IB_MGMT_MAX_METHODS;	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,			       1+i)) {		(*method)->agent[i] = agent_priv;	}	return 0;error3:	/* Remove any methods for this mad agent */	remove_methods_mad_agent(*method, agent_priv);	/* Now, check to see if there are any methods in use */	if (!check_method_table(*method)) {		/* If not, release management method table */		kfree(*method);		*method = NULL;	}	ret = -EINVAL;	goto error1;error2:	kfree(*class);	*class = NULL;error1:	return ret;}static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,			   struct ib_mad_agent_private *agent_priv){	struct ib_mad_port_private *port_priv;	struct ib_mad_mgmt_vendor_class_table **vendor_table;	struct ib_mad_mgmt_vendor_class_table *vendor = NULL;	struct ib_mad_mgmt_vendor_class *vendor_class = NULL;	struct ib_mad_mgmt_method_table **method;	int i, ret = -ENOMEM;	u8 vclass;	/* "New" vendor (with OUI) class */	vclass = vendor_class_index(mad_reg_req->mgmt_class);	port_priv = agent_priv->qp_info->port_priv;	vendor_table = &port_priv->version[				mad_reg_req->mgmt_class_version].vendor;	if (!*vendor_table) {		/* Allocate mgmt vendor class table for "new" class version */		vendor = kzalloc(sizeof *vendor, GFP_ATOMIC);		if (!vendor) {			printk(KERN_ERR PFX "No memory for "			       "ib_mad_mgmt_vendor_class_table\n");			goto error1;		}		*vendor_table = vendor;	}	if (!(*vendor_table)->vendor_class[vclass]) {		/* Allocate table for this management vendor class */		vendor_class = kzalloc(sizeof *vendor_class, GFP_ATOMIC);		if (!vendor_class) {			printk(KERN_ERR PFX "No memory for "			       "ib_mad_mgmt_vendor_class\n");			goto error2;		}		(*vendor_table)->vendor_class[vclass] = vendor_class;	}	for (i = 0; i < MAX_MGMT_OUI; i++) {		/* Is there matching OUI for this vendor class ? */		if (!memcmp((*vendor_table)->vendor_class[vclass]->oui[i],			    mad_reg_req->oui, 3)) {			method = &(*vendor_table)->vendor_class[						vclass]->method_table[i];			BUG_ON(!*method);			goto check_in_use;		}	}	for (i = 0; i < MAX_MGMT_OUI; i++) {		/* OUI slot available ? */		if (!is_vendor_oui((*vendor_table)->vendor_class[				vclass]->oui[i])) {			method = &(*vendor_table)->vendor_class[				vclass]->method_table[i];			BUG_ON(*method);			/* Allocate method table for this OUI */			if ((ret = allocate_method_table(method)))				goto error3;			memcpy((*vendor_table)->vendor_class[vclass]->oui[i],			       mad_reg_req->oui, 3);			goto check_in_use;		}	}	printk(KERN_ERR PFX "All OUI slots in use\n");	goto error3;check_in_use:	/* Now, make sure methods are not already in use */	if (method_in_use(method, mad_reg_req))		goto error4;	/* Finally, add in methods being registered */	for (i = find_first_bit(mad_reg_req->method_mask,				IB_MGMT_MAX_METHODS);	     i < IB_MGMT_MAX_METHODS;	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,			       1+i)) {		(*method)->agent[i] = agent_priv;	}	return 0;error4:	/* Remove any methods for this mad agent */	remove_methods_mad_agent(*method, agent_priv);	/* Now, check to see if there are any methods in use */	if (!check_method_table(*method)) {		/* If not, release management method table */		kfree(*method);		*method = NULL;	}	ret = -EINVAL;error3:	if (vendor_class) {		(*vendor_table)->vendor_class[vclass] = NULL;		kfree(vendor_class);	}error2:	if (vendor) {		*vendor_table = NULL;		kfree(vendor);	}error1:	return ret;}static void remove_mad_reg_req(struct ib_mad_agent_private *agent_priv){	struct ib_mad_port_private *port_priv;	struct ib_mad_mgmt_class_table *class;	struct ib_mad_mgmt_method_table *method;	struct ib_mad_mgmt_vendor_class_table *vendor;	struct ib_mad_mgmt_vendor_class *vendor_class;	int index;	u8 mgmt_class;	/*	 * Was MAD registration request supplied	 * with original registration ?	 */	if (!agent_priv->reg_req) {		goto out;	}	port_priv = agent_priv->qp_info->port_priv;	mgmt_class = convert_mgmt_class(agent_priv->reg_req->mgmt_class);	class = port_priv->version[			agent_priv->reg_req->mgmt_class_version].class;	if (!class)		goto vendor_check;	method = class->method_table[mgmt_class];	if (method) {		/* Remove any methods for this mad agent */		remove_methods_mad_agent(method, agent_priv);		/* Now, check to see if there are any methods still in use */		if (!check_method_table(method)) {			/* If not, release management method table */			 kfree(method);			 class->method_table[mgmt_class] = NULL;			 /* Any management classes left ? */			if (!check_class_table(class)) {				/* If not, release management class table */				kfree(class);				port_priv->version[					agent_priv->reg_req->					mgmt_class_version].class = NULL;			}		}	}vendor_check:	if (!is_vendor_class(mgmt_class))		goto out;	/* normalize mgmt_class to vendor range 2 */	mgmt_class = vendor_class_index(agent_priv->reg_req->mgmt_class);	vendor = port_priv->version[			agent_priv->reg_req->mgmt_class_version].vendor;	if (!vendor)		goto out;	vendor_class = vendor->vendor_class[mgmt_class];	if (vendor_class) {		index = find_vendor_oui(vendor_class, agent_priv->reg_req->oui);		if (index < 0)			goto out;		method = vendor_class->method_table[index];		if (method) {			/* Remove any methods for this mad agent */			remove_methods_mad_agent(method, agent_priv);			/*			 * Now, check to see if there are			 * any methods still in use			 */			if (!check_method_table(method)) {				/* If not, release management method table */				kfree(method);				vendor_class->method_table[index] = NULL;				memset(vendor_class->oui[index], 0, 3);				/* Any OUIs left ? */				if (!check_vendor_class(vendor_class)) {					/* If not, release vendor class table */					kfree(vendor_class);					vendor->vendor_class[mgmt_class] = NULL;					/* Any other vendor classes left ? */					if (!check_vendor_table(vendor)) {						kfree(vendor);						port_priv->version[							agent_priv->reg_req->							mgmt_class_version].							vendor = NULL;					}				}

⌨️ 快捷键说明

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