Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0441891 authored by Jens Axboe's avatar Jens Axboe
Browse files

qla1280: sg chaining support



Interesting hardware setup...

Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent b0f655d0
Loading
Loading
Loading
Loading
+37 −29
Original line number Original line Diff line number Diff line
@@ -2775,7 +2775,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
	struct device_reg __iomem *reg = ha->iobase;
	struct device_reg __iomem *reg = ha->iobase;
	struct scsi_cmnd *cmd = sp->cmd;
	struct scsi_cmnd *cmd = sp->cmd;
	cmd_a64_entry_t *pkt;
	cmd_a64_entry_t *pkt;
	struct scatterlist *sg = NULL;
	struct scatterlist *sg = NULL, *s;
	__le32 *dword_ptr;
	__le32 *dword_ptr;
	dma_addr_t dma_handle;
	dma_addr_t dma_handle;
	int status = 0;
	int status = 0;
@@ -2889,13 +2889,16 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
	 * Load data segments.
	 * Load data segments.
	 */
	 */
	if (seg_cnt) {	/* If data transfer. */
	if (seg_cnt) {	/* If data transfer. */
		int remseg = seg_cnt;
		/* Setup packet address segment pointer. */
		/* Setup packet address segment pointer. */
		dword_ptr = (u32 *)&pkt->dseg_0_address;
		dword_ptr = (u32 *)&pkt->dseg_0_address;


		if (cmd->use_sg) {	/* If scatter gather */
		if (cmd->use_sg) {	/* If scatter gather */
			/* Load command entry data segments. */
			/* Load command entry data segments. */
			for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) {
			for_each_sg(sg, s, seg_cnt, cnt) {
				dma_handle = sg_dma_address(sg);
				if (cnt == 2)
					break;
				dma_handle = sg_dma_address(s);
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
				if (ha->flags.use_pci_vchannel)
				if (ha->flags.use_pci_vchannel)
					sn_pci_set_vchan(ha->pdev,
					sn_pci_set_vchan(ha->pdev,
@@ -2906,12 +2909,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
					cpu_to_le32(pci_dma_lo32(dma_handle));
					cpu_to_le32(pci_dma_lo32(dma_handle));
				*dword_ptr++ =
				*dword_ptr++ =
					cpu_to_le32(pci_dma_hi32(dma_handle));
					cpu_to_le32(pci_dma_hi32(dma_handle));
				*dword_ptr++ = cpu_to_le32(sg_dma_len(sg));
				*dword_ptr++ = cpu_to_le32(sg_dma_len(s));
				sg++;
				dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
				dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
					cpu_to_le32(pci_dma_hi32(dma_handle)),
					cpu_to_le32(pci_dma_hi32(dma_handle)),
					cpu_to_le32(pci_dma_lo32(dma_handle)),
					cpu_to_le32(pci_dma_lo32(dma_handle)),
					cpu_to_le32(sg_dma_len(sg)));
					cpu_to_le32(sg_dma_len(sg_next(s))));
				remseg--;
			}
			}
			dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
			dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
				"command packet data - b %i, t %i, l %i \n",
				"command packet data - b %i, t %i, l %i \n",
@@ -2926,7 +2929,9 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
			dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
			dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
				"remains\n", seg_cnt);
				"remains\n", seg_cnt);


			while (seg_cnt > 0) {
			while (remseg > 0) {
				/* Update sg start */
				sg = s;
				/* Adjust ring index. */
				/* Adjust ring index. */
				ha->req_ring_index++;
				ha->req_ring_index++;
				if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
				if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@@ -2952,9 +2957,10 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
					(u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;
					(u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;


				/* Load continuation entry data segments. */
				/* Load continuation entry data segments. */
				for (cnt = 0; cnt < 5 && seg_cnt;
				for_each_sg(sg, s, remseg, cnt) {
				     cnt++, seg_cnt--) {
					if (cnt == 5)
					dma_handle = sg_dma_address(sg);
						break;
					dma_handle = sg_dma_address(s);
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
				if (ha->flags.use_pci_vchannel)
				if (ha->flags.use_pci_vchannel)
					sn_pci_set_vchan(ha->pdev, 
					sn_pci_set_vchan(ha->pdev, 
@@ -2966,12 +2972,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
					*dword_ptr++ =
					*dword_ptr++ =
						cpu_to_le32(pci_dma_hi32(dma_handle));
						cpu_to_le32(pci_dma_hi32(dma_handle));
					*dword_ptr++ =
					*dword_ptr++ =
						cpu_to_le32(sg_dma_len(sg));
						cpu_to_le32(sg_dma_len(s));
					dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
					dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
						cpu_to_le32(pci_dma_hi32(dma_handle)),
						cpu_to_le32(pci_dma_hi32(dma_handle)),
						cpu_to_le32(pci_dma_lo32(dma_handle)),
						cpu_to_le32(pci_dma_lo32(dma_handle)),
						cpu_to_le32(sg_dma_len(sg)));
						cpu_to_le32(sg_dma_len(s)));
					sg++;
					remseg--;
				}
				}
				dprintk(5, "qla1280_64bit_start_scsi: "
				dprintk(5, "qla1280_64bit_start_scsi: "
					"continuation packet data - b %i, t "
					"continuation packet data - b %i, t "
@@ -3062,7 +3068,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
	struct device_reg __iomem *reg = ha->iobase;
	struct device_reg __iomem *reg = ha->iobase;
	struct scsi_cmnd *cmd = sp->cmd;
	struct scsi_cmnd *cmd = sp->cmd;
	struct cmd_entry *pkt;
	struct cmd_entry *pkt;
	struct scatterlist *sg = NULL;
	struct scatterlist *sg = NULL, *s;
	__le32 *dword_ptr;
	__le32 *dword_ptr;
	int status = 0;
	int status = 0;
	int cnt;
	int cnt;
@@ -3188,6 +3194,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
	 * Load data segments.
	 * Load data segments.
	 */
	 */
	if (seg_cnt) {
	if (seg_cnt) {
		int remseg = seg_cnt;
		/* Setup packet address segment pointer. */
		/* Setup packet address segment pointer. */
		dword_ptr = &pkt->dseg_0_address;
		dword_ptr = &pkt->dseg_0_address;


@@ -3196,22 +3203,25 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
			qla1280_dump_buffer(1, (char *)sg, 4 * 16);
			qla1280_dump_buffer(1, (char *)sg, 4 * 16);


			/* Load command entry data segments. */
			/* Load command entry data segments. */
			for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) {
			for_each_sg(sg, s, seg_cnt, cnt) {
				*dword_ptr++ =
				if (cnt == 4)
					cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
					break;
				*dword_ptr++ =
				*dword_ptr++ =
					cpu_to_le32(sg_dma_len(sg));
					cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
				*dword_ptr++ = cpu_to_le32(sg_dma_len(s));
				dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
				dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
					(pci_dma_lo32(sg_dma_address(sg))),
					(pci_dma_lo32(sg_dma_address(s))),
					(sg_dma_len(sg)));
					(sg_dma_len(s)));
				sg++;
				remseg--;
			}
			}
			/*
			/*
			 * Build continuation packets.
			 * Build continuation packets.
			 */
			 */
			dprintk(3, "S/G Building Continuation"
			dprintk(3, "S/G Building Continuation"
				"...seg_cnt=0x%x remains\n", seg_cnt);
				"...seg_cnt=0x%x remains\n", seg_cnt);
			while (seg_cnt > 0) {
			while (remseg > 0) {
				/* Continue from end point */
				sg = s;
				/* Adjust ring index. */
				/* Adjust ring index. */
				ha->req_ring_index++;
				ha->req_ring_index++;
				if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
				if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@@ -3239,18 +3249,16 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
					&((struct cont_entry *) pkt)->dseg_0_address;
					&((struct cont_entry *) pkt)->dseg_0_address;


				/* Load continuation entry data segments. */
				/* Load continuation entry data segments. */
				for (cnt = 0; cnt < 7 && seg_cnt;
				for_each_sg(sg, s, remseg, cnt) {
				     cnt++, seg_cnt--) {
					*dword_ptr++ =
					*dword_ptr++ =
						cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
						cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
					*dword_ptr++ =
					*dword_ptr++ =
						cpu_to_le32(sg_dma_len(sg));
						cpu_to_le32(sg_dma_len(s));
					dprintk(1,
					dprintk(1,
						"S/G Segment Cont. phys_addr=0x%x, "
						"S/G Segment Cont. phys_addr=0x%x, "
						"len=0x%x\n",
						"len=0x%x\n",
						cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
						cpu_to_le32(pci_dma_lo32(sg_dma_address(s))),
						cpu_to_le32(sg_dma_len(sg)));
						cpu_to_le32(sg_dma_len(s)));
					sg++;
				}
				}
				dprintk(5, "qla1280_32bit_start_scsi: "
				dprintk(5, "qla1280_32bit_start_scsi: "
					"continuation packet data - "
					"continuation packet data - "