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

Commit ad1331a7 authored by Bastian Blank's avatar Bastian Blank Committed by James Bottomley
Browse files

[SCSI] tgt: fix rdma transfer bugs



- ibmstgt hits the max rdma transfer size (128k).
- libsrp returns a rdma transfer error properly.

Signed-off-by: default avatarBastian Blank <bastian@waldi.eu.org>
Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 4def7fa1
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
#include "ibmvscsi.h"

#define	INITIAL_SRP_LIMIT	16
#define	DEFAULT_MAX_SECTORS	512
#define	DEFAULT_MAX_SECTORS	256

#define	TGT_NAME	"ibmvstgt"

@@ -248,8 +248,8 @@ static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg,
						  md[i].va + mdone);

			if (err != H_SUCCESS) {
				eprintk("rdma error %d %d\n", dir, slen);
				goto out;
				eprintk("rdma error %d %d %ld\n", dir, slen, err);
				return -EIO;
			}

			mlen -= slen;
@@ -265,14 +265,13 @@ static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg,
				if (sidx > nsg) {
					eprintk("out of sg %p %d %d\n",
						iue, sidx, nsg);
					goto out;
					return -EIO;
				}
			}
		};

		rest -= mlen;
	}
out:
	return 0;
}

@@ -282,18 +281,19 @@ static int ibmvstgt_cmd_done(struct scsi_cmnd *sc,
	unsigned long flags;
	struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
	struct srp_target *target = iue->target;
	int err = 0;

	dprintk("%p %p %x %u\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0],
		cmd->usg_sg);

	if (sc->use_sg)
		srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1);
		err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1);

	spin_lock_irqsave(&target->lock, flags);
	list_del(&iue->ilist);
	spin_unlock_irqrestore(&target->lock, flags);

	if (sc->result != SAM_STAT_GOOD) {
	if (err|| sc->result != SAM_STAT_GOOD) {
		eprintk("operation failed %p %d %x\n",
			iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]);
		send_rsp(iue, sc, HARDWARE_ERROR, 0x00);
@@ -493,7 +493,8 @@ static void process_iu(struct viosrp_crq *crq, struct srp_target *target)
{
	struct vio_port *vport = target_to_port(target);
	struct iu_entry *iue;
	long err, done;
	long err;
	int done = 1;

	iue = srp_iu_get(target);
	if (!iue) {
@@ -508,7 +509,6 @@ static void process_iu(struct viosrp_crq *crq, struct srp_target *target)

	if (err != H_SUCCESS) {
		eprintk("%ld transferring data error %p\n", err, iue);
		done = 1;
		goto out;
	}

+6 −6
Original line number Diff line number Diff line
@@ -225,8 +225,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
	struct srp_direct_buf *md = NULL;
	struct scatterlist dummy, *sg = NULL;
	dma_addr_t token = 0;
	long err;
	unsigned int done = 0;
	int err = 0;
	int nmd, nsg = 0, len;

	if (dma_map || ext_desc) {
@@ -258,8 +257,8 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
		sg_dma_address(&dummy) = token;
		err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
			      id->table_desc.len);
		if (err < 0) {
			eprintk("Error copying indirect table %ld\n", err);
		if (err) {
			eprintk("Error copying indirect table %d\n", err);
			goto free_mem;
		}
	} else {
@@ -272,6 +271,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
		nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, DMA_BIDIRECTIONAL);
		if (!nsg) {
			eprintk("fail to map %p %d\n", iue, sc->use_sg);
			err = -EIO;
			goto free_mem;
		}
		len = min(sc->request_bufflen, id->len);
@@ -287,7 +287,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
	if (token && dma_map)
		dma_free_coherent(iue->target->dev, id->table_desc.len, md, token);

	return done;
	return err;
}

static int data_out_desc_size(struct srp_cmd *cmd)
@@ -352,7 +352,7 @@ int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
		break;
	default:
		eprintk("Unknown format %d %x\n", dir, format);
		break;
		err = -EINVAL;
	}

	return err;