From bc7e380a6a4c94f79a49c36bdb28062a750b3c2b Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 3 Mar 2007 09:55:54 +0900 Subject: [SCSI] tgt: fix sesnse buffer problems This patch simplify the way to notify LLDs of the command completion and addresses the following sense buffer problems: - can't handle both data and sense. - forces user-space to use aligned sense buffer tgt copies sense_data from userspace to cmnd->sense_buffer (if necessary), maps user-space pages (if necessary) and then calls host->transfer_response (host->transfer_data is removed). Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvstgt.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'drivers/scsi/ibmvscsi') diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 4368ca0e8270..a7fbd10817a0 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -273,23 +273,9 @@ static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, rest -= mlen; } out: - return 0; } -static int ibmvstgt_transfer_data(struct scsi_cmnd *sc, - void (*done)(struct scsi_cmnd *)) -{ - struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; - int err; - - err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); - - done(sc); - - return err; -} - static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) { @@ -297,7 +283,11 @@ static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; struct srp_target *target = iue->target; - dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[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); spin_lock_irqsave(&target->lock, flags); list_del(&iue->ilist); @@ -794,7 +784,6 @@ static struct scsi_host_template ibmvstgt_sht = { .use_clustering = DISABLE_CLUSTERING, .max_sectors = DEFAULT_MAX_SECTORS, .transfer_response = ibmvstgt_cmd_done, - .transfer_data = ibmvstgt_transfer_data, .eh_abort_handler = ibmvstgt_eh_abort_handler, .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, .shost_attrs = ibmvstgt_attrs, -- cgit v1.2.3 From a897ff2a6386ac4368ba41db18b626afd903f9d8 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Wed, 28 Mar 2007 12:45:46 -0500 Subject: [SCSI] ibmvscsi: allow for dynamic adjustment of server request_limit The request limit calculations used previously on the client failed to mirror the state of the server. Additionally, when a value < 3 was provided there could be problems setting can_queue and handling abort and reset commands. Signed-off-by: "Robert Jennings" Signed-off-by: Santiago Leon Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.c | 58 ++++++++++++++++++++++++++-------------- drivers/scsi/ibmvscsi/ibmvscsi.h | 2 ++ 2 files changed, 40 insertions(+), 20 deletions(-) (limited to 'drivers/scsi/ibmvscsi') diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index fbc1d5c3b0a7..383f5948ba06 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -85,7 +85,7 @@ static int max_id = 64; static int max_channel = 3; static int init_timeout = 5; -static int max_requests = 50; +static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; #define IBMVSCSI_VERSION "1.5.8" @@ -538,7 +538,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, int request_status; int rc; - /* If we have exhausted our request limit, just fail this request. + /* If we have exhausted our request limit, just fail this request, + * unless it is for a reset or abort. * Note that there are rare cases involving driver generated requests * (such as task management requests) that the mid layer may think we * can handle more requests (can_queue) when we actually can't @@ -551,9 +552,30 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, */ if (request_status < -1) goto send_error; - /* Otherwise, if we have run out of requests */ - else if (request_status < 0) - goto send_busy; + /* Otherwise, we may have run out of requests. */ + /* Abort and reset calls should make it through. + * Nothing except abort and reset should use the last two + * slots unless we had two or less to begin with. + */ + else if (request_status < 2 && + evt_struct->iu.srp.cmd.opcode != SRP_TSK_MGMT) { + /* In the case that we have less than two requests + * available, check the server limit as a combination + * of the request limit and the number of requests + * in-flight (the size of the send list). If the + * server limit is greater than 2, return busy so + * that the last two are reserved for reset and abort. + */ + int server_limit = request_status; + struct srp_event_struct *tmp_evt; + + list_for_each_entry(tmp_evt, &hostdata->sent, list) { + server_limit++; + } + + if (server_limit > 2) + goto send_busy; + } } /* Copy the IU into the transfer area */ @@ -572,6 +594,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, printk(KERN_ERR "ibmvscsi: send error %d\n", rc); + atomic_inc(&hostdata->request_limit); goto send_error; } @@ -581,7 +604,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); free_event_struct(&hostdata->pool, evt_struct); - return SCSI_MLQUEUE_HOST_BUSY; + atomic_inc(&hostdata->request_limit); + return SCSI_MLQUEUE_HOST_BUSY; send_error: unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); @@ -831,23 +855,16 @@ static void login_rsp(struct srp_event_struct *evt_struct) printk(KERN_INFO "ibmvscsi: SRP_LOGIN succeeded\n"); - if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta > - (max_requests - 2)) - evt_struct->xfer_iu->srp.login_rsp.req_lim_delta = - max_requests - 2; + if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta < 0) + printk(KERN_ERR "ibmvscsi: Invalid request_limit.\n"); - /* Now we know what the real request-limit is */ + /* Now we know what the real request-limit is. + * This value is set rather than added to request_limit because + * request_limit could have been set to -1 by this client. + */ atomic_set(&hostdata->request_limit, evt_struct->xfer_iu->srp.login_rsp.req_lim_delta); - hostdata->host->can_queue = - evt_struct->xfer_iu->srp.login_rsp.req_lim_delta - 2; - - if (hostdata->host->can_queue < 1) { - printk(KERN_ERR "ibmvscsi: Invalid request_limit_delta\n"); - return; - } - /* If we had any pending I/Os, kick them */ scsi_unblock_requests(hostdata->host); @@ -1483,7 +1500,7 @@ static struct scsi_host_template driver_template = { .eh_abort_handler = ibmvscsi_eh_abort_handler, .eh_device_reset_handler = ibmvscsi_eh_device_reset_handler, .cmd_per_lun = 16, - .can_queue = 1, /* Updated after SRP_LOGIN */ + .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, .this_id = -1, .sg_tablesize = SG_ALL, .use_clustering = ENABLE_CLUSTERING, @@ -1503,6 +1520,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) vdev->dev.driver_data = NULL; + driver_template.can_queue = max_requests; host = scsi_host_alloc(&driver_template, sizeof(*hostdata)); if (!host) { printk(KERN_ERR "ibmvscsi: couldn't allocate host data\n"); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 5c6d93582929..77cc1d40f5bb 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -44,6 +44,8 @@ struct Scsi_Host; */ #define MAX_INDIRECT_BUFS 10 +#define IBMVSCSI_MAX_REQUESTS_DEFAULT 100 + /* ------------------------------------------------------------ * Data Structures */ -- cgit v1.2.3 From 0979c84b4affaf924a894380dd0069638b64de03 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Thu, 29 Mar 2007 12:30:40 -0500 Subject: [SCSI] ibmvscsi: add slave_configure to allow device restart Fixed the kernel-doc comment for ibmvscsi_slave_configure. Thanks to Randy Dunlap for pointing this out. Adding a slave_configure function for the driver. Now the disks can be restarted by the scsi mid-layer when the are disconnected and reconnected. Signed-off-by: "Robert Jennings" Signed-off-by: "Santiago Leon" Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/scsi/ibmvscsi') diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 383f5948ba06..b10eefe735c5 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1354,6 +1354,27 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, return rc; } +/** + * ibmvscsi_slave_configure: Set the "allow_restart" flag for each disk. + * @sdev: struct scsi_device device to configure + * + * Enable allow_restart for a device if it is a disk. Adjust the + * queue_depth here also as is required by the documentation for + * struct scsi_host_template. + */ +static int ibmvscsi_slave_configure(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + unsigned long lock_flags = 0; + + spin_lock_irqsave(shost->host_lock, lock_flags); + if (sdev->type == TYPE_DISK) + sdev->allow_restart = 1; + scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun); + spin_unlock_irqrestore(shost->host_lock, lock_flags); + return 0; +} + /* ------------------------------------------------------------ * sysfs attributes */ @@ -1499,6 +1520,7 @@ static struct scsi_host_template driver_template = { .queuecommand = ibmvscsi_queuecommand, .eh_abort_handler = ibmvscsi_eh_abort_handler, .eh_device_reset_handler = ibmvscsi_eh_device_reset_handler, + .slave_configure = ibmvscsi_slave_configure, .cmd_per_lun = 16, .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, .this_id = -1, -- cgit v1.2.3 From ad1331a792f9f253bef362de9b6872c6b8f88c0c Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sat, 7 Apr 2007 18:10:00 +0900 Subject: [SCSI] tgt: fix rdma transfer bugs - ibmstgt hits the max rdma transfer size (128k). - libsrp returns a rdma transfer error properly. Signed-off-by: Bastian Blank Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvstgt.c | 18 +++++++++--------- drivers/scsi/libsrp.c | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/scsi/ibmvscsi') diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index a7fbd10817a0..84363c181620 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -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; } diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 89403b00e042..37a0f4dd6186 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -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 @@ rdma: 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 @@ free_mem: 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; -- cgit v1.2.3