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

Commit 2f4cf91c authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by James Bottomley
Browse files

[SCSI] ips: convert to use the data buffer accessors



- remove the unnecessary map_single path.

- convert to use the new accessors for the sg lists and the
parameters.

Jens Axboe <jens.axboe@oracle.com> did the for_each_sg cleanup.

TODO: use scsi_for_each_sg() in the breakup handling.

Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: default avatar"Salyzyn, Mark" <mark_salyzyn@adaptec.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent bb350d1d
Loading
Loading
Loading
Loading
+99 −157
Original line number Diff line number Diff line
@@ -1104,7 +1104,7 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
		/* A Reset IOCTL is only sent by the boot CD in extreme cases.           */
		/* There can never be any system activity ( network or disk ), but check */
		/* anyway just as a good practice.                                       */
		pt = (ips_passthru_t *) SC->request_buffer;
		pt = (ips_passthru_t *) scsi_sglist(SC);
		if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
		    (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
			if (ha->scb_activelist.count != 0) {
@@ -1507,15 +1507,8 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
	if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
	    (SC->device->channel == 0) &&
	    (SC->device->id == IPS_ADAPTER_ID) &&
	    (SC->device->lun == 0) && SC->request_buffer) {
		if ((!SC->use_sg) && SC->request_bufflen &&
		    (((char *) SC->request_buffer)[0] == 'C') &&
		    (((char *) SC->request_buffer)[1] == 'O') &&
		    (((char *) SC->request_buffer)[2] == 'P') &&
		    (((char *) SC->request_buffer)[3] == 'P'))
			return 1;
		else if (SC->use_sg) {
			struct scatterlist *sg = SC->request_buffer;
	    (SC->device->lun == 0) && scsi_sglist(SC)) {
                struct scatterlist *sg = scsi_sglist(SC);
                char  *buffer;

                /* kmap_atomic() ensures addressability of the user buffer.*/
@@ -1531,7 +1524,6 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                kunmap_atomic(buffer - sg->offset, KM_IRQ0);
                local_irq_restore(flags);
	}
	}
	return 0;
}

@@ -1581,18 +1573,14 @@ ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
{
	ips_passthru_t *pt;
	int length = 0;
	int ret;
	int i, ret;
        struct scatterlist *sg = scsi_sglist(SC);

	METHOD_TRACE("ips_make_passthru", 1);

	if (!SC->use_sg) {
		length = SC->request_bufflen;
	} else {
		struct scatterlist *sg = SC->request_buffer;
		int i;
		for (i = 0; i < SC->use_sg; i++)
        scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
                length += sg[i].length;
	}

	if (length < sizeof (ips_passthru_t)) {
		/* wrong size */
		DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
@@ -2016,7 +2004,7 @@ ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)

	METHOD_TRACE("ips_cleanup_passthru", 1);

	if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
	if ((!scb) || (!scb->scsi_cmd) || (!scsi_sglist(scb->scsi_cmd))) {
		DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
			  ips_name, ha->host_num);

@@ -2766,34 +2754,21 @@ ips_next(ips_ha_t * ha, int intr)
		/* copy in the CDB */
		memcpy(scb->cdb, SC->cmnd, SC->cmd_len);

		/* Now handle the data buffer */
		if (SC->use_sg) {
                scb->sg_count = scsi_dma_map(SC);
                BUG_ON(scb->sg_count < 0);
		if (scb->sg_count) {
			struct scatterlist *sg;
			int i;

			sg = SC->request_buffer;
			scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
						   SC->sc_data_direction);
			scb->flags |= IPS_SCB_MAP_SG;
			for (i = 0; i < scb->sg_count; i++) {

                        scsi_for_each_sg(SC, sg, scb->sg_count, i) {
				if (ips_fill_scb_sg_single
				    (ha, sg_dma_address(&sg[i]), scb, i,
				     sg_dma_len(&sg[i])) < 0)
				    (ha, sg_dma_address(sg), scb, i,
				     sg_dma_len(sg)) < 0)
					break;
			}
			scb->dcdb.transfer_length = scb->data_len;
		} else {
			if (SC->request_bufflen) {
				scb->data_busaddr =
				    pci_map_single(ha->pcidev,
						   SC->request_buffer,
						   SC->request_bufflen,
						   SC->sc_data_direction);
				scb->flags |= IPS_SCB_MAP_SINGLE;
				ips_fill_scb_sg_single(ha, scb->data_busaddr,
						       scb, 0,
						       SC->request_bufflen);
				scb->dcdb.transfer_length = scb->data_len;
		} else {
                        scb->data_busaddr = 0L;
                        scb->sg_len = 0;
@@ -2801,8 +2776,6 @@ ips_next(ips_ha_t * ha, int intr)
                        scb->dcdb.transfer_length = 0;
		}

		}

		scb->dcdb.cmd_attribute =
		    ips_command_direction[scb->scsi_cmd->cmnd[0]];

@@ -3277,29 +3250,24 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
		 * the rest of the data and continue.
		 */
		if ((scb->breakup) || (scb->sg_break)) {
                        struct scatterlist *sg;
                        int sg_dma_index, ips_sg_index = 0;

			/* we had a data breakup */
			scb->data_len = 0;

			if (scb->sg_count) {
				/* S/G request */
				struct scatterlist *sg;
				int ips_sg_index = 0;
				int sg_dma_index;

				sg = scb->scsi_cmd->request_buffer;
                        sg = scsi_sglist(scb->scsi_cmd);

                        /* Spin forward to last dma chunk */
                        sg_dma_index = scb->breakup;

			/* Take care of possible partial on last chunk */
                        ips_fill_scb_sg_single(ha,
						       sg_dma_address(&sg
								      [sg_dma_index]),
                                               sg_dma_address(&sg[sg_dma_index]),
                                               scb, ips_sg_index++,
						       sg_dma_len(&sg
								  [sg_dma_index]));
                                               sg_dma_len(&sg[sg_dma_index]));

				for (; sg_dma_index < scb->sg_count;
                        for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
                             sg_dma_index++) {
                                if (ips_fill_scb_sg_single
                                    (ha,
@@ -3307,21 +3275,6 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
                                     scb, ips_sg_index++,
                                     sg_dma_len(&sg[sg_dma_index])) < 0)
                                        break;

				}

			} else {
				/* Non S/G Request */
				(void) ips_fill_scb_sg_single(ha,
							      scb->
							      data_busaddr +
							      (scb->sg_break *
							       ha->max_xfer),
							      scb, 0,
							      scb->scsi_cmd->
							      request_bufflen -
							      (scb->sg_break *
							       ha->max_xfer));
                        }

			scb->dcdb.transfer_length = scb->data_len;
@@ -3553,15 +3506,15 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
static void
ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
{
	if (scmd->use_sg) {
        int i;
        unsigned int min_cnt, xfer_cnt;
        char *cdata = (char *) data;
        unsigned char *buffer;
        unsigned long flags;
		struct scatterlist *sg = scmd->request_buffer;
        struct scatterlist *sg = scsi_sglist(scmd);

        for (i = 0, xfer_cnt = 0;
		     (i < scmd->use_sg) && (xfer_cnt < count); i++) {
             (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
                min_cnt = min(count - xfer_cnt, sg[i].length);

                /* kmap_atomic() ensures addressability of the data buffer.*/
@@ -3574,11 +3527,6 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)

                xfer_cnt += min_cnt;
        }

	} else {
		unsigned int min_cnt = min(count, scmd->request_bufflen);
		memcpy(scmd->request_buffer, data, min_cnt);
	}
}

/****************************************************************************/
@@ -3591,15 +3539,15 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
static void
ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
{
	if (scmd->use_sg) {
        int i;
        unsigned int min_cnt, xfer_cnt;
        char *cdata = (char *) data;
        unsigned char *buffer;
        unsigned long flags;
		struct scatterlist *sg = scmd->request_buffer;
        struct scatterlist *sg = scsi_sglist(scmd);

        for (i = 0, xfer_cnt = 0;
		     (i < scmd->use_sg) && (xfer_cnt < count); i++) {
             (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
                min_cnt = min(count - xfer_cnt, sg[i].length);

                /* kmap_atomic() ensures addressability of the data buffer.*/
@@ -3612,11 +3560,6 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)

                xfer_cnt += min_cnt;
        }

	} else {
		unsigned int min_cnt = min(count, scmd->request_bufflen);
		memcpy(data, scmd->request_buffer, min_cnt);
	}
}

/****************************************************************************/
@@ -4250,7 +4193,7 @@ ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)

	METHOD_TRACE("ips_rdcap", 1);

	if (scb->scsi_cmd->request_bufflen < 8)
	if (scsi_bufflen(scb->scsi_cmd) < 8)
		return (0);

	cap.lba =
@@ -4635,8 +4578,7 @@ ips_freescb(ips_ha_t * ha, ips_scb_t * scb)

	METHOD_TRACE("ips_freescb", 1);
	if (scb->flags & IPS_SCB_MAP_SG)
		pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer,
			     scb->scsi_cmd->use_sg, IPS_DMA_DIR(scb));
                scsi_dma_unmap(scb->scsi_cmd);
	else if (scb->flags & IPS_SCB_MAP_SINGLE)
		pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
				 IPS_DMA_DIR(scb));