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

📄 c2_rnic.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	return err;}/* * Open a single RNIC instance to use with all * low level openib calls */static int c2_rnic_open(struct c2_dev *c2dev){	struct c2_vq_req *vq_req;	union c2wr wr;	struct c2wr_rnic_open_rep *reply;	int err;	vq_req = vq_req_alloc(c2dev);	if (vq_req == NULL) {		return -ENOMEM;	}	memset(&wr, 0, sizeof(wr));	c2_wr_set_id(&wr, CCWR_RNIC_OPEN);	wr.rnic_open.req.hdr.context = (unsigned long) (vq_req);	wr.rnic_open.req.flags = cpu_to_be16(RNIC_PRIV_MODE);	wr.rnic_open.req.port_num = cpu_to_be16(0);	wr.rnic_open.req.user_context = (unsigned long) c2dev;	vq_req_get(c2dev, vq_req);	err = vq_send_wr(c2dev, &wr);	if (err) {		vq_req_put(c2dev, vq_req);		goto bail0;	}	err = vq_wait_for_reply(c2dev, vq_req);	if (err) {		goto bail0;	}	reply = (struct c2wr_rnic_open_rep *) (unsigned long) (vq_req->reply_msg);	if (!reply) {		err = -ENOMEM;		goto bail0;	}	if ((err = c2_errno(reply)) != 0) {		goto bail1;	}	c2dev->adapter_handle = reply->rnic_handle;      bail1:	vq_repbuf_free(c2dev, reply);      bail0:	vq_req_free(c2dev, vq_req);	return err;}/* * Close the RNIC instance */static int c2_rnic_close(struct c2_dev *c2dev){	struct c2_vq_req *vq_req;	union c2wr wr;	struct c2wr_rnic_close_rep *reply;	int err;	vq_req = vq_req_alloc(c2dev);	if (vq_req == NULL) {		return -ENOMEM;	}	memset(&wr, 0, sizeof(wr));	c2_wr_set_id(&wr, CCWR_RNIC_CLOSE);	wr.rnic_close.req.hdr.context = (unsigned long) vq_req;	wr.rnic_close.req.rnic_handle = c2dev->adapter_handle;	vq_req_get(c2dev, vq_req);	err = vq_send_wr(c2dev, &wr);	if (err) {		vq_req_put(c2dev, vq_req);		goto bail0;	}	err = vq_wait_for_reply(c2dev, vq_req);	if (err) {		goto bail0;	}	reply = (struct c2wr_rnic_close_rep *) (unsigned long) (vq_req->reply_msg);	if (!reply) {		err = -ENOMEM;		goto bail0;	}	if ((err = c2_errno(reply)) != 0) {		goto bail1;	}	c2dev->adapter_handle = 0;      bail1:	vq_repbuf_free(c2dev, reply);      bail0:	vq_req_free(c2dev, vq_req);	return err;}/* * Called by c2_probe to initialize the RNIC. This principally * involves initalizing the various limits and resouce pools that * comprise the RNIC instance. */int __devinit c2_rnic_init(struct c2_dev *c2dev){	int err;	u32 qsize, msgsize;	void *q1_pages;	void *q2_pages;	void __iomem *mmio_regs;	/* Device capabilities */	c2dev->device_cap_flags =	    (IB_DEVICE_RESIZE_MAX_WR |	     IB_DEVICE_CURR_QP_STATE_MOD |	     IB_DEVICE_SYS_IMAGE_GUID |	     IB_DEVICE_ZERO_STAG |	     IB_DEVICE_SEND_W_INV | IB_DEVICE_MEM_WINDOW);	/* Allocate the qptr_array */	c2dev->qptr_array = vmalloc(C2_MAX_CQS * sizeof(void *));	if (!c2dev->qptr_array) {		return -ENOMEM;	}	/* Inialize the qptr_array */	memset(c2dev->qptr_array, 0, C2_MAX_CQS * sizeof(void *));	c2dev->qptr_array[0] = (void *) &c2dev->req_vq;	c2dev->qptr_array[1] = (void *) &c2dev->rep_vq;	c2dev->qptr_array[2] = (void *) &c2dev->aeq;	/* Initialize data structures */	init_waitqueue_head(&c2dev->req_vq_wo);	spin_lock_init(&c2dev->vqlock);	spin_lock_init(&c2dev->lock);	/* Allocate MQ shared pointer pool for kernel clients. User	 * mode client pools are hung off the user context	 */	err = c2_init_mqsp_pool(c2dev, GFP_KERNEL, &c2dev->kern_mqsp_pool);	if (err) {		goto bail0;	}	/* Allocate shared pointers for Q0, Q1, and Q2 from	 * the shared pointer pool.	 */	c2dev->hint_count = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,					     &c2dev->hint_count_dma,					     GFP_KERNEL);	c2dev->req_vq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,					     &c2dev->req_vq.shared_dma,					     GFP_KERNEL);	c2dev->rep_vq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,					     &c2dev->rep_vq.shared_dma,					     GFP_KERNEL);	c2dev->aeq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,					  &c2dev->aeq.shared_dma, GFP_KERNEL);	if (!c2dev->hint_count || !c2dev->req_vq.shared ||	    !c2dev->rep_vq.shared || !c2dev->aeq.shared) {		err = -ENOMEM;		goto bail1;	}	mmio_regs = c2dev->kva;	/* Initialize the Verbs Request Queue */	c2_mq_req_init(&c2dev->req_vq, 0,		       be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_QSIZE)),		       be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_MSGSIZE)),		       mmio_regs +		       be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_POOLSTART)),		       mmio_regs +		       be32_to_cpu(readl(mmio_regs + C2_REGS_Q0_SHARED)),		       C2_MQ_ADAPTER_TARGET);	/* Initialize the Verbs Reply Queue */	qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_QSIZE));	msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_MSGSIZE));	q1_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize,				      &c2dev->rep_vq.host_dma, GFP_KERNEL);	if (!q1_pages) {		err = -ENOMEM;		goto bail1;	}	pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma);	pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages,		 (unsigned long long) c2dev->rep_vq.host_dma);	c2_mq_rep_init(&c2dev->rep_vq,		   1,		   qsize,		   msgsize,		   q1_pages,		   mmio_regs +		   be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_SHARED)),		   C2_MQ_HOST_TARGET);	/* Initialize the Asynchronus Event Queue */	qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_QSIZE));	msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_MSGSIZE));	q2_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize,				      &c2dev->aeq.host_dma, GFP_KERNEL);	if (!q2_pages) {		err = -ENOMEM;		goto bail2;	}	pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma);	pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q2_pages,		 (unsigned long long) c2dev->aeq.host_dma);	c2_mq_rep_init(&c2dev->aeq,		       2,		       qsize,		       msgsize,		       q2_pages,		       mmio_regs +		       be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_SHARED)),		       C2_MQ_HOST_TARGET);	/* Initialize the verbs request allocator */	err = vq_init(c2dev);	if (err)		goto bail3;	/* Enable interrupts on the adapter */	writel(0, c2dev->regs + C2_IDIS);	/* create the WR init message */	err = c2_adapter_init(c2dev);	if (err)		goto bail4;	c2dev->init++;	/* open an adapter instance */	err = c2_rnic_open(c2dev);	if (err)		goto bail4;	/* Initialize cached the adapter limits */	if (c2_rnic_query(c2dev, &c2dev->props))		goto bail5;	/* Initialize the PD pool */	err = c2_init_pd_table(c2dev);	if (err)		goto bail5;	/* Initialize the QP pool */	c2_init_qp_table(c2dev);	return 0;      bail5:	c2_rnic_close(c2dev);      bail4:	vq_term(c2dev);      bail3:	dma_free_coherent(&c2dev->pcidev->dev,			  c2dev->aeq.q_size * c2dev->aeq.msg_size,			  q2_pages, pci_unmap_addr(&c2dev->aeq, mapping));      bail2:	dma_free_coherent(&c2dev->pcidev->dev,			  c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,			  q1_pages, pci_unmap_addr(&c2dev->rep_vq, mapping));      bail1:	c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool);      bail0:	vfree(c2dev->qptr_array);	return err;}/* * Called by c2_remove to cleanup the RNIC resources. */void __devexit c2_rnic_term(struct c2_dev *c2dev){	/* Close the open adapter instance */	c2_rnic_close(c2dev);	/* Send the TERM message to the adapter */	c2_adapter_term(c2dev);	/* Disable interrupts on the adapter */	writel(1, c2dev->regs + C2_IDIS);	/* Free the QP pool */	c2_cleanup_qp_table(c2dev);	/* Free the PD pool */	c2_cleanup_pd_table(c2dev);	/* Free the verbs request allocator */	vq_term(c2dev);	/* Free the asynchronus event queue */	dma_free_coherent(&c2dev->pcidev->dev,			  c2dev->aeq.q_size * c2dev->aeq.msg_size,			  c2dev->aeq.msg_pool.host,			  pci_unmap_addr(&c2dev->aeq, mapping));	/* Free the verbs reply queue */	dma_free_coherent(&c2dev->pcidev->dev,			  c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,			  c2dev->rep_vq.msg_pool.host,			  pci_unmap_addr(&c2dev->rep_vq, mapping));	/* Free the MQ shared pointer pool */	c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool);	/* Free the qptr_array */	vfree(c2dev->qptr_array);	return;}

⌨️ 快捷键说明

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