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

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

 




On Oct 30, 2008, at 8:19 AM, Seokmann Ju wrote:


On Oct 29, 2008, at 9:18 PM, FUJITA Tomonori wrote:

On Wed, 29 Oct 2008 05:48:08 -0700
Seokmann Ju <seokmann.ju@xxxxxxxxxx> wrote:

[snip]
+	service->payload_sg_cnt = dma_map_sg(&rport->dev,
+	    service->payload_dma, service->payload_sg_cnt, DMA_TO_DEVICE);
+	service->response_sg_cnt = dma_map_sg(&rport->dev,
+ service->response_dma, service->response_sg_cnt, DMA_FROM_DEVICE);

Please check the return values, service->payload_sg_cnt and
service->response_sg_cnt. dma_map_sg could fail.
OK. Thanks.

+	if (service->srv_request->request_type == FC_FRAME_TYPE_ELS) {
+		els_iocb = (struct els_entry_24xx *)iocb;
+		els_iocb->entry_type = ELS_IOCB_TYPE;
+		els_iocb->entry_count = 1;
+		els_iocb->sys_define = 0;
+		els_iocb->entry_status = 0;
+		els_iocb->nport_handle = cpu_to_le16(fcport->loop_id);
+		els_iocb->tx_dsd_count = __constant_cpu_to_le16(1);
+		els_iocb->vp_index = vha->vp_idx;
+		els_iocb->sof_type = EST_SOFI3;
+		els_iocb->rx_dsd_count = __constant_cpu_to_le16(1);
+		els_iocb->opcode = els_pkt[0];
+		els_iocb->port_id[0] = fcport->d_id.b.al_pa;
+		els_iocb->port_id[1] = fcport->d_id.b.area;
+		els_iocb->port_id[2] = fcport->d_id.b.domain;
+		els_iocb->control_flags = 0;
+		els_iocb->rx_byte_count = cpu_to_le32(service->response_size);
+		els_iocb->tx_byte_count = cpu_to_le32(service->payload_size);
+		els_iocb->tx_address[0] = cpu_to_le32(LSD(sg_dma_address
+		    (&service->payload_dma[0])));
+		els_iocb->tx_address[1] = cpu_to_le32(MSD(sg_dma_address
+		    (&service->payload_dma[0])));
+
+		els_iocb->tx_len = cpu_to_le32(sg_dma_len
+		    (&service->payload_dma[0]));
+
+		els_iocb->rx_address[0] = cpu_to_le32(LSD(sg_dma_address
+		    (&service->response_dma[0])));
+		els_iocb->rx_address[1] = cpu_to_le32(MSD(sg_dma_address
+		    (&service->response_dma[0])));
+
+		els_iocb->rx_len = cpu_to_le32(sg_dma_len
+		    (&service->response_dma[0]));
+	
+		/* lld_pkt is only for ELS services in case of abort */
+		service->lld_pkt = (void *) els_iocb;
+	} else {
+		ct_iocb = (struct ct_entry_24xx *)iocb;
+		ct_iocb->entry_type = CT_IOCB_TYPE;
+		ct_iocb->entry_count = 1;
+		ct_iocb->entry_status = 0;
+		ct_iocb->comp_status = __constant_cpu_to_le16(0);
+		if (IS_FWI2_CAPABLE(ha))
+			ct_iocb->nport_handle = cpu_to_le16(NPH_SNS);
+		else
+			ct_iocb->nport_handle =
+			    cpu_to_le16(SIMPLE_NAME_SERVER);
+		ct_iocb->cmd_dsd_count =
+		    __constant_cpu_to_le16(service->payload_sg_cnt);
+		ct_iocb->vp_index = vha->vp_idx;
+		ct_iocb->timeout =
+		    __constant_cpu_to_le16(service->timeout);
+		ct_iocb->rsp_dsd_count =
+		    __constant_cpu_to_le16(service->response_sg_cnt);
+		ct_iocb->rsp_byte_count =
+		    cpu_to_le32(service->response_size);
+		ct_iocb->cmd_byte_count =
+		    cpu_to_le32(service->payload_size);
+		ct_iocb->dseg_0_address[0] = cpu_to_le32(LSD(sg_dma_address
+		    (&service->payload_dma[0])));
+		ct_iocb->dseg_0_address[1] = cpu_to_le32(MSD(sg_dma_address
+		    (&service->payload_dma[0])));
+
+		ct_iocb->dseg_0_len = cpu_to_le32(sg_dma_len
+		    (&service->payload_dma[0]));
+
+		sg_cnt = service->response_sg_cnt;
+		avail_dsds = 1;
+		cur_dsd = (uint32_t *)ct_iocb->dseg_1_address;
+		index = 0;
+		while (sg_cnt) {
+			cont_a64_entry_t *cont_pkt;
+
+			/* Allocate additional continuation packets? */
+			if (avail_dsds == 0) {
+				/*
+				 * Five DSDs are available in the Continuation
+				 * Type 1 IOCB.
+				 */
+				cont_pkt = qla2x00_prep_cont_type1_iocb(vha);
+				cur_dsd =
+				    (uint32_t *) cont_pkt->dseg_0_address;
+				avail_dsds = 5;
+			}
+
+			*cur_dsd++ = cpu_to_le32(LSD(sg_dma_address
+			    (&service->response_dma[index])));
+			*cur_dsd++ = cpu_to_le32(MSD(sg_dma_address
+			    (&service->response_dma[index])));
+			*cur_dsd++ = cpu_to_le32(sg_dma_len
+			    (&service->response_dma[index]));
+			avail_dsds--;
+			sg_cnt--;
+			index++;

Can you use the standard API, for_each_sg(), to go through scatter
list? With sg chaining, you must use the API.
I see your point but, for_each_sg() is not applicable here as the pointer to
the cont_pkt is not guaranteed to be continuous from previous one.
Actually, it is doable as you pointed out initially.
There is an example in the
~/drivers/scsi/qla2xxx/qla_iocb.c:qla2x00_build_scsi_iocb_32/64().
As long as the address is valid and get changed accordingly.
I will make the changes accordingly.

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