Re: [PATCH 2/2] FC pass through support - revised III

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Nov 11, 2008, at 1:41 AM, FUJITA Tomonori wrote:

On Fri, 31 Oct 2008 08:34:47 -0700
Seokmann Ju <seokmann.ju@xxxxxxxxxx> wrote:

Attachment is also available at the bottom.
---
From 4c6fc04a25afd6dd495975434e9732ede4a1bae1 Mon Sep 17 00:00:00 2001
From: root <root@xxxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 31 Oct 2008 08:15:56 -0700
Subject: [PATCH] qla2xxx: FC pass through support

This patch will add FC passs through support.
With this patch, the driver support,
- ELS (Extended Link Services)
- FC-CT (Generic Services)

Signed-off-by: Seokmann Ju <seokmann.ju@xxxxxxxxxx>
---
drivers/scsi/qla2xxx/qla_attr.c | 253 ++++++++++++++++++++++++++++ ++
+++++++++
 drivers/scsi/qla2xxx/qla_def.h  |    5 +
 drivers/scsi/qla2xxx/qla_fw.h   |   35 ++++++
 drivers/scsi/qla2xxx/qla_gbl.h  |    4 +
 drivers/scsi/qla2xxx/qla_gs.c   |    2 +-
 drivers/scsi/qla2xxx/qla_init.c |   11 ++
 drivers/scsi/qla2xxx/qla_iocb.c |    9 +-
 drivers/scsi/qla2xxx/qla_isr.c  |   68 +++++++++++
 8 files changed, 380 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/
qla_attr.c
index b223842..945c840 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1257,6 +1257,253 @@ qla24xx_vport_disable(struct fc_vport
*fc_vport, bool disable)
 	return 0;
 }

+static int
+qla2x00_execute_fc_service(struct fc_service *service)
+{
+	struct fc_rport *rport = service->rport;
+	fc_port_t *fcport = *(fc_port_t **) rport->dd_data;
+	struct Scsi_Host *host = rport_to_shost(rport);
+	scsi_qla_host_t *vha = shost_priv(host);
+	struct qla_hw_data *ha = vha->hw;
+	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+	struct req_que *req = ha->req;
+	struct els_entry_24xx *els_iocb;
+	struct ct_entry_24xx *ct_iocb;
+	request_t *iocb;
+	srb_t *sp;
+	unsigned long flags;
+	uint32_t  handle;
+	int  index;
+	int  req_sg_cnt, rsp_sg_cnt;
+	uint8_t  els_pkt[20];
+	size_t   copy_size;
+	uint16_t avail_dsds;
+	uint32_t *cur_dsd;
+	struct scatterlist *sg;
+
+	/* At this time, pass throug supported by 4Gb or higher */
+	if (!IS_FWI2_CAPABLE(ha))
+		goto pt_error0;
+
+	if (rport->port_state != FC_PORTSTATE_ONLINE || !fcport)
+		goto pt_error0;
+
+	if ((service->srv_request->request_type != FC_FRAME_TYPE_ELS) &&
+	    (service->srv_request->request_type != FC_FRAME_TYPE_FC_CT))
+		goto pt_error0;
+
+	/* ELS doesn't support multiple SG */
+	if ((service->srv_request->request_type == FC_FRAME_TYPE_ELS) &&
+	    (service->req_sg_cnt > 1 || service->rsp_sg_cnt > 1)) {
+		printk(KERN_WARNING "ERROR: multiple SG of request/response "
+		    "[%u/%u]  are not supported for ELS services\n",
+		    service->req_sg_cnt, service->rsp_sg_cnt);
+		service->srv_reply.status = FC_SERVICE_UNSUPPORTED;
+		goto pt_error0;
+	}
+
+	sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
+	if (!sp)
+		goto pt_error0;
+
+	sp->vha = vha;
+	sp->fcport = fcport;
+	sp->cmd = (struct scsi_cmnd *)service;
+	sp->flags = SRB_ELS_CT;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	iocb = qla2x00_req_pkt(base_vha);
+	if (iocb == NULL) {
+		qla_printk(KERN_WARNING, ha,
+		    "Passthru request failed to get request packet\n");
+		goto pt_error1;
+	}
+
+	req_sg_cnt = dma_map_sg(&ha->pdev->dev, service->sg_req,
+	    service->req_sg_cnt, DMA_TO_DEVICE);
+	if (!req_sg_cnt)
+		goto pt_error1;
+	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, service->sg_rsp,
+	    service->rsp_sg_cnt, DMA_FROM_DEVICE);
+	if (!rsp_sg_cnt)
+		goto pt_error2;
+
+	copy_size = sg_copy_to_buffer(service->sg_req, req_sg_cnt,
+	    els_pkt, 20);

You need to use service->sg_rsp instead of req_sg_cnt here.

sg_copy_to_buffer takes the number entry of scatter gather. dma_map_sg
returns the number of physical segments mapped. They could be
different (when IOMMU merges the entries).
Yes, I've got your point. I will make change it.




+	if (!copy_size)
+		goto pt_error3;
+
+	/* Check for room in outstanding command list. */
+	handle = req->current_outstanding_cmd;
+	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
+		handle++;
+		if (handle == MAX_OUTSTANDING_COMMANDS)
+			handle = 1;
+		if (!req->outstanding_cmds[handle])
+			break;
+	}

Hmm, needs to check the index overflow here?
I think I've missed your point, here.
Could you please elaborate a bit further?

Thank you,
Seokmann

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux