2016-10-12 13:08:21

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 00/16] Convert FibreChannel bsg code to use bsg-lib

This series converts the current bsg usage in the FibreChannel drivers over
to use bsg-lib. SAS will follow once FC is in a good enough shape.

I did take some inspiration from a similar patchset from Mike Christie
dating back to 2011 but it's not a 1:1 copy. Patch 15/16 is heavily based
on his series and attribution is given to him in the commit message.

It is currently regression tested on FCoE using the 'fcns' and
'fcrls' utilities. I'm still trying to figure out how to test the other
LLDDs. So any pointer from the respective maintainers are appreciated
although the LLDD changes are purely mechanical. All they do is change from
'struct fc_bsg_job' to 'struct bsg_job' and corresponding changes in order
to get the series bisectable.

The idea for this change arose when discussing racy sysfs handling the FC
bsg code with Christoph and is a next step in moving all bsg clients to
bsg-lib to eventually clean up the in kernel bsg API.

Changes to v1:
* Reduce the number of individual patches (44 -> 16)
* Fix s390 build failure (forgotten to kill fc_bsg_job from zfcp_ext.h)
* Fix build failure on configs without CONFIG_BLK_DEV_BSGLIB
* Make bsg_job_get() call kref_get_unless_zero() and use it in scsi_transport_fc.c

Johannes Thumshirn (16):
scsi: Get rid of struct fc_bsg_buffer
scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
scsi: fc: Export fc_bsg_jobdone and use it in FC drivers
scsi: Unify interfaces of fc_bsg_jobdone and bsg_job_done
scsi: fc: provide fc_bsg_to_shost() helper
scsi: fc: provide fc_bsg_to_rport() helper
scsi: libfc: don't set FC_RQST_STATE_DONE before calling
fc_bsg_jobdone()
scsi: fc: implement kref backed reference counting
block: add reference counting for struct bsg_job
scsi: change FC drivers to use 'struct bsg_job'
scsi: fc: Use bsg_destroy_job
scsi: fc: use bsg_softirq_done
scsi: fc: use bsg_job_done
block: add bsg_job_put() and bsg_job_get()
scsi: fc: move FC transport's bsg code to bsg-lib
block: unexport bsg_softirq_done() again

block/bsg-lib.c | 19 +-
drivers/s390/scsi/zfcp_ext.h | 4 +-
drivers/s390/scsi/zfcp_fc.c | 33 +--
drivers/scsi/Kconfig | 1 +
drivers/scsi/bfa/bfad_bsg.c | 62 +++---
drivers/scsi/bfa/bfad_im.h | 4 +-
drivers/scsi/ibmvscsi/ibmvfc.c | 40 ++--
drivers/scsi/libfc/fc_lport.c | 47 ++--
drivers/scsi/lpfc/lpfc_bsg.c | 375 +++++++++++++++++++-------------
drivers/scsi/lpfc/lpfc_crtn.h | 4 +-
drivers/scsi/qla2xxx/qla_bsg.c | 449 ++++++++++++++++++++++-----------------
drivers/scsi/qla2xxx/qla_def.h | 2 +-
drivers/scsi/qla2xxx/qla_gbl.h | 4 +-
drivers/scsi/qla2xxx/qla_iocb.c | 13 +-
drivers/scsi/qla2xxx/qla_isr.c | 52 +++--
drivers/scsi/qla2xxx/qla_mr.c | 15 +-
drivers/scsi/scsi_transport_fc.c | 409 ++++++-----------------------------
include/linux/bsg-lib.h | 4 +
include/scsi/libfc.h | 2 +-
include/scsi/scsi_transport_fc.h | 62 ++----
20 files changed, 745 insertions(+), 856 deletions(-)

--
1.8.5.6


2016-10-12 13:08:34

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 01/16] scsi: Get rid of struct fc_bsg_buffer

struct fc_bsg_buffer is just a clone of struct bsg_buffer from bsg-lib,
so use this one instead.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/scsi/lpfc/lpfc_bsg.c | 3 ++-
drivers/scsi/scsi_transport_fc.c | 2 +-
include/scsi/scsi_transport_fc.h | 12 +++---------
3 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 05dcc2a..1002627 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/list.h>
+#include <linux/bsg-lib.h>

#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
@@ -211,7 +212,7 @@ lpfc_alloc_bsg_buffers(struct lpfc_hba *phba, unsigned int size,

static unsigned int
lpfc_bsg_copy_data(struct lpfc_dmabuf *dma_buffers,
- struct fc_bsg_buffer *bsg_buffers,
+ struct bsg_buffer *bsg_buffers,
unsigned int bytes_to_transfer, int to_buffers)
{

diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 0f3a386..8ff2067 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3671,7 +3671,7 @@ fc_bsg_job_timeout(struct request *req)
}

static int
-fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req)
+fc_bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
{
size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);

diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index bf66ea6..921b097 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -28,6 +28,7 @@
#define SCSI_TRANSPORT_FC_H

#include <linux/sched.h>
+#include <linux/bsg-lib.h>
#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_netlink.h>
@@ -624,13 +625,6 @@ struct fc_host_attrs {
#define fc_host_dev_loss_tmo(x) \
(((struct fc_host_attrs *)(x)->shost_data)->dev_loss_tmo)

-
-struct fc_bsg_buffer {
- unsigned int payload_len;
- int sg_cnt;
- struct scatterlist *sg_list;
-};
-
/* Values for fc_bsg_job->state_flags (bitflags) */
#define FC_RQST_STATE_INPROGRESS 0
#define FC_RQST_STATE_DONE 1
@@ -659,8 +653,8 @@ struct fc_bsg_job {
*/

/* DMA payloads for the request/response */
- struct fc_bsg_buffer request_payload;
- struct fc_bsg_buffer reply_payload;
+ struct bsg_buffer request_payload;
+ struct bsg_buffer reply_payload;

void *dd_data; /* Used for driver-specific storage */
};
--
1.8.5.6

2016-10-12 13:08:47

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 15/16] scsi: fc: move FC transport's bsg code to bsg-lib

Now that all conversions are done, move the FibreChannel bsg code over to the
bsg library. Note that CONFIG_SCSI_FC_ATTRS now needs to select BLK_DEV_BSGLIB
in order to build correctly.

This patch is derived from work done by Mike Christie in 2011 [1] but only the
iscsi parts got merged back then.

[1] http://marc.info/?l=linux-scsi&m=131149780921009&w=2

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/scsi/Kconfig | 1 +
drivers/scsi/scsi_transport_fc.c | 287 ++++++---------------------------------
2 files changed, 44 insertions(+), 244 deletions(-)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 7d1b431..1a0338c 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -263,6 +263,7 @@ config SCSI_SPI_ATTRS
config SCSI_FC_ATTRS
tristate "FiberChannel Transport Attributes"
depends on SCSI && NET
+ select BLK_DEV_BSGLIB
select SCSI_NETLINK
help
If you wish to export transport-specific information about
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 7fae045..916d488 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3591,111 +3591,12 @@ fc_bsg_job_timeout(struct request *req)
return BLK_EH_HANDLED;
}

-static int
-fc_bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
-{
- size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);
-
- BUG_ON(!req->nr_phys_segments);
-
- buf->sg_list = kzalloc(sz, GFP_KERNEL);
- if (!buf->sg_list)
- return -ENOMEM;
- sg_init_table(buf->sg_list, req->nr_phys_segments);
- buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
- buf->payload_len = blk_rq_bytes(req);
- return 0;
-}
-
-
-/**
- * fc_req_to_bsgjob - Allocate/create the fc_bsg_job structure for the
- * bsg request
- * @shost: SCSI Host corresponding to the bsg object
- * @rport: (optional) FC Remote Port corresponding to the bsg object
- * @req: BSG request that needs a job structure
- */
-static int
-fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
- struct request *req)
-{
- struct fc_internal *i = to_fc_internal(shost->transportt);
- struct request *rsp = req->next_rq;
- struct bsg_job *job;
- struct fc_bsg_request *bsg_request;
- struct fc_bsg_reply *bsg_reply;
- int ret;
-
- BUG_ON(req->special);
-
- job = kzalloc(sizeof(struct bsg_job) + i->f->dd_bsg_size,
- GFP_KERNEL);
- if (!job)
- return -ENOMEM;
-
- /*
- * Note: this is a bit silly.
- * The request gets formatted as a SGIO v4 ioctl request, which
- * then gets reformatted as a blk request, which then gets
- * reformatted as a fc bsg request. And on completion, we have
- * to wrap return results such that SGIO v4 thinks it was a scsi
- * status. I hope this was all worth it.
- */
-
- req->special = job;
- job->req = req;
- if (i->f->dd_bsg_size)
- job->dd_data = (void *)&job[1];
- bsg_request = (struct fc_bsg_request *)req->cmd;
- job->request_len = req->cmd_len;
- bsg_reply = req->sense;
- job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
- * allocated */
- if (req->bio) {
- ret = fc_bsg_map_buffer(&job->request_payload, req);
- if (ret)
- goto failjob_rls_job;
- }
- if (rsp && rsp->bio) {
- ret = fc_bsg_map_buffer(&job->reply_payload, rsp);
- if (ret)
- goto failjob_rls_rqst_payload;
- }
- if (rport)
- job->dev = &rport->dev;
- else
- job->dev = &shost->shost_gendev;
- get_device(job->dev); /* take a reference for the request */
-
- kref_init(&job->kref);
-
- return 0;
-
-
-failjob_rls_rqst_payload:
- kfree(job->request_payload.sg_list);
-failjob_rls_job:
- kfree(job);
- return -ENOMEM;
-}
-
-
-enum fc_dispatch_result {
- FC_DISPATCH_BREAK, /* on return, q is locked, break from q loop */
- FC_DISPATCH_LOCKED, /* on return, q is locked, continue on */
- FC_DISPATCH_UNLOCKED, /* on return, q is unlocked, continue on */
-};
-
-
/**
* fc_bsg_host_dispatch - process fc host bsg requests and dispatch to LLDD
- * @q: fc host request queue
* @shost: scsi host rport attached to
* @job: bsg job to be processed
*/
-static enum fc_dispatch_result
-fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
- struct bsg_job *job)
+static int fc_bsg_host_dispatch(struct Scsi_Host *shost, struct bsg_job *job)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
struct fc_bsg_request *bsg_request = job->request;
@@ -3756,7 +3657,7 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,

ret = i->f->bsg_request(job);
if (!ret)
- return FC_DISPATCH_UNLOCKED;
+ return 0;

fail_host_msg:
/* return the errno failure code as the only status */
@@ -3766,7 +3667,7 @@ fail_host_msg:
job->reply_len = sizeof(uint32_t);
bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
- return FC_DISPATCH_UNLOCKED;
+ return 0;
}


@@ -3790,14 +3691,10 @@ fc_bsg_goose_queue(struct fc_rport *rport)

/**
* fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD
- * @q: rport request queue
* @shost: scsi host rport attached to
- * @rport: rport request destined to
* @job: bsg job to be processed
*/
-static enum fc_dispatch_result
-fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
- struct fc_rport *rport, struct bsg_job *job)
+static int fc_bsg_rport_dispatch(struct Scsi_Host *shost, struct bsg_job *job)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
struct fc_bsg_request *bsg_request = job->request;
@@ -3834,7 +3731,7 @@ check_bidi:

ret = i->f->bsg_request(job);
if (!ret)
- return FC_DISPATCH_UNLOCKED;
+ return 0;

fail_rport_msg:
/* return the errno failure code as the only status */
@@ -3844,119 +3741,19 @@ fail_rport_msg:
job->reply_len = sizeof(uint32_t);
bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
- return FC_DISPATCH_UNLOCKED;
-}
-
-
-/**
- * fc_bsg_request_handler - generic handler for bsg requests
- * @q: request queue to manage
- * @shost: Scsi_Host related to the bsg object
- * @rport: FC remote port related to the bsg object (optional)
- * @dev: device structure for bsg object
- */
-static void
-fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
- struct fc_rport *rport, struct device *dev)
-{
- struct request *req;
- struct bsg_job *job;
- enum fc_dispatch_result ret;
- struct fc_bsg_reply *bsg_reply;
-
- if (!get_device(dev))
- return;
-
- while (1) {
- if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
- !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
- break;
-
- req = blk_fetch_request(q);
- if (!req)
- break;
-
- if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
- req->errors = -ENXIO;
- spin_unlock_irq(q->queue_lock);
- blk_end_request_all(req, -ENXIO);
- spin_lock_irq(q->queue_lock);
- continue;
- }
-
- spin_unlock_irq(q->queue_lock);
-
- ret = fc_req_to_bsgjob(shost, rport, req);
- if (ret) {
- req->errors = ret;
- blk_end_request_all(req, ret);
- spin_lock_irq(q->queue_lock);
- continue;
- }
-
- job = req->special;
-
- /* check if we have the msgcode value at least */
- if (job->request_len < sizeof(uint32_t)) {
- BUG_ON(job->reply_len < sizeof(uint32_t));
- bsg_reply = job->reply;
- bsg_reply->reply_payload_rcv_len = 0;
- bsg_reply->result = -ENOMSG;
- job->reply_len = sizeof(uint32_t);
- bsg_job_done(job, bsg_reply->result,
- bsg_reply->reply_payload_rcv_len);
- spin_lock_irq(q->queue_lock);
- continue;
- }
-
- /* the dispatch routines will unlock the queue_lock */
- if (rport)
- ret = fc_bsg_rport_dispatch(q, shost, rport, job);
- else
- ret = fc_bsg_host_dispatch(q, shost, job);
-
- /* did dispatcher hit state that can't process any more */
- if (ret == FC_DISPATCH_BREAK)
- break;
-
- /* did dispatcher had released the lock */
- if (ret == FC_DISPATCH_UNLOCKED)
- spin_lock_irq(q->queue_lock);
- }
-
- spin_unlock_irq(q->queue_lock);
- put_device(dev);
- spin_lock_irq(q->queue_lock);
-}
-
-
-/**
- * fc_bsg_host_handler - handler for bsg requests for a fc host
- * @q: fc host request queue
- */
-static void
-fc_bsg_host_handler(struct request_queue *q)
-{
- struct Scsi_Host *shost = q->queuedata;
-
- fc_bsg_request_handler(q, shost, NULL, &shost->shost_gendev);
+ return 0;
}

-
-/**
- * fc_bsg_rport_handler - handler for bsg requests for a fc rport
- * @q: rport request queue
- */
-static void
-fc_bsg_rport_handler(struct request_queue *q)
+static int fc_bsg_dispatch(struct bsg_job *job)
{
- struct fc_rport *rport = q->queuedata;
- struct Scsi_Host *shost = rport_to_shost(rport);
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);

- fc_bsg_request_handler(q, shost, rport, &rport->dev);
+ if (scsi_is_fc_rport(job->dev))
+ return fc_bsg_rport_dispatch(shost, job);
+ else
+ return fc_bsg_host_dispatch(shost, job);
}

-
/**
* fc_bsg_hostadd - Create and add the bsg hooks so we can receive requests
* @shost: shost for fc_host
@@ -3979,33 +3776,42 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
snprintf(bsg_name, sizeof(bsg_name),
"fc_host%d", shost->host_no);

- q = __scsi_alloc_queue(shost, fc_bsg_host_handler);
+ q = __scsi_alloc_queue(shost, bsg_request_fn);
if (!q) {
- printk(KERN_ERR "fc_host%d: bsg interface failed to "
- "initialize - no request queue\n",
- shost->host_no);
+ dev_err(dev,
+ "fc_host%d: bsg interface failed to initialize - no request queue\n",
+ shost->host_no);
return -ENOMEM;
}

- q->queuedata = shost;
- queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
- blk_queue_softirq_done(q, bsg_softirq_done);
- blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
- blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
-
- err = bsg_register_queue(q, dev, bsg_name, NULL);
+ err = bsg_setup_queue(dev, q, bsg_name, fc_bsg_dispatch,
+ i->f->dd_bsg_size);
if (err) {
- printk(KERN_ERR "fc_host%d: bsg interface failed to "
- "initialize - register queue\n",
- shost->host_no);
+ dev_err(dev,
+ "fc_host%d: bsg interface failed to initialize - setup queue\n",
+ shost->host_no);
blk_cleanup_queue(q);
return err;
}
-
+ blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
+ blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
fc_host->rqst_q = q;
return 0;
}

+static int fc_bsg_rport_prep(struct request_queue *q, struct request *req)
+{
+ struct fc_rport *rport = dev_to_rport(q->queuedata);
+
+ if (rport->port_state == FC_PORTSTATE_BLOCKED &&
+ !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
+ return BLKPREP_DEFER;
+
+ if (rport->port_state != FC_PORTSTATE_ONLINE)
+ return BLKPREP_KILL;
+
+ return BLKPREP_OK;
+}

/**
* fc_bsg_rportadd - Create and add the bsg hooks so we can receive requests
@@ -4025,29 +3831,22 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
if (!i->f->bsg_request)
return -ENOTSUPP;

- q = __scsi_alloc_queue(shost, fc_bsg_rport_handler);
+ q = __scsi_alloc_queue(shost, bsg_request_fn);
if (!q) {
- printk(KERN_ERR "%s: bsg interface failed to "
- "initialize - no request queue\n",
- dev->kobj.name);
+ dev_err(dev, "bsg interface failed to initialize - no request queue\n");
return -ENOMEM;
}

- q->queuedata = rport;
- queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
- blk_queue_softirq_done(q, bsg_softirq_done);
- blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
- blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
-
- err = bsg_register_queue(q, dev, NULL, NULL);
+ err = bsg_setup_queue(dev, q, NULL, fc_bsg_dispatch, i->f->dd_bsg_size);
if (err) {
- printk(KERN_ERR "%s: bsg interface failed to "
- "initialize - register queue\n",
- dev->kobj.name);
+ dev_err(dev, "failed to setup bsg queue\n");
blk_cleanup_queue(q);
return err;
}

+ blk_queue_prep_rq(q, fc_bsg_rport_prep);
+ blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
+ blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
rport->rqst_q = q;
return 0;
}
--
1.8.5.6

2016-10-12 13:08:55

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 16/16] block: unexport bsg_softirq_done() again

Unexport bsg_softirq_done() again, we don't need it outside of bsg-lib.c
anymore now that scsi_transport_fc is a pure bsg-lib client.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
block/bsg-lib.c | 3 +--
include/linux/bsg-lib.h | 1 -
2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 46a4fee..4ac0ade 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -93,14 +93,13 @@ EXPORT_SYMBOL_GPL(bsg_job_done);
* bsg_softirq_done - softirq done routine for destroying the bsg requests
* @rq: BSG request that holds the job to be destroyed
*/
-void bsg_softirq_done(struct request *rq)
+static void bsg_softirq_done(struct request *rq)
{
struct bsg_job *job = rq->special;

blk_end_request_all(rq, rq->errors);
bsg_job_put(job);
}
-EXPORT_SYMBOL_GPL(bsg_softirq_done);

static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
{
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index b708db9..657a718 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -69,7 +69,6 @@ void bsg_job_done(struct bsg_job *job, int result,
int bsg_setup_queue(struct device *dev, struct request_queue *q, char *name,
bsg_job_fn *job_fn, int dd_job_size);
void bsg_request_fn(struct request_queue *q);
-void bsg_softirq_done(struct request *rq);
void bsg_job_put(struct bsg_job *job);
int __must_check bsg_job_get(struct bsg_job *job);

--
1.8.5.6

2016-10-12 13:09:31

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 14/16] block: add bsg_job_put() and bsg_job_get()

Add bsg_job_put() and bsg_job_get() so don't need to export
bsg_destroy_job() any more.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
block/bsg-lib.c | 17 ++++++++++++++---
drivers/scsi/scsi_transport_fc.c | 4 ++--
include/linux/bsg-lib.h | 3 ++-
3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 5d24d25..46a4fee 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -32,7 +32,7 @@
* bsg_destroy_job - routine to teardown/delete a bsg job
* @job: bsg_job that is to be torn down
*/
-void bsg_destroy_job(struct kref *kref)
+static void bsg_destroy_job(struct kref *kref)
{
struct bsg_job *job = container_of(kref, struct bsg_job, kref);

@@ -42,7 +42,18 @@ void bsg_destroy_job(struct kref *kref)
kfree(job->reply_payload.sg_list);
kfree(job);
}
-EXPORT_SYMBOL_GPL(bsg_destroy_job);
+
+void bsg_job_put(struct bsg_job *job)
+{
+ kref_put(&job->kref, bsg_destroy_job);
+}
+EXPORT_SYMBOL_GPL(bsg_job_put);
+
+int bsg_job_get(struct bsg_job *job)
+{
+ return kref_get_unless_zero(&job->kref);
+}
+EXPORT_SYMBOL_GPL(bsg_job_get);

/**
* bsg_job_done - completion routine for bsg requests
@@ -87,7 +98,7 @@ void bsg_softirq_done(struct request *rq)
struct bsg_job *job = rq->special;

blk_end_request_all(rq, rq->errors);
- kref_put(&job->kref, bsg_destroy_job);
+ bsg_job_put(job);
}
EXPORT_SYMBOL_GPL(bsg_softirq_done);

diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 720ddc9..7fae045 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3571,13 +3571,13 @@ fc_bsg_job_timeout(struct request *req)
if (rport && rport->port_state == FC_PORTSTATE_BLOCKED)
return BLK_EH_RESET_TIMER;

- inflight = kref_get_unless_zero(&job->kref);
+ inflight = bsg_job_get(job);

if (inflight && i->f->bsg_timeout) {
/* call LLDD to abort the i/o as it has timed out */
err = i->f->bsg_timeout(job);
if (err == -EAGAIN) {
- kref_put(&job->kref, bsg_destroy_job);
+ bsg_job_put(job);
return BLK_EH_RESET_TIMER;
} else if (err)
printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index 09f3044..b708db9 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -69,7 +69,8 @@ void bsg_job_done(struct bsg_job *job, int result,
int bsg_setup_queue(struct device *dev, struct request_queue *q, char *name,
bsg_job_fn *job_fn, int dd_job_size);
void bsg_request_fn(struct request_queue *q);
-void bsg_destroy_job(struct kref *kref);
void bsg_softirq_done(struct request *rq);
+void bsg_job_put(struct bsg_job *job);
+int __must_check bsg_job_get(struct bsg_job *job);

#endif
--
1.8.5.6

2016-10-12 13:09:42

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 13/16] scsi: fc: use bsg_job_done

fc_bsg_jobdone() and bsg_job_done() are 1:1 copies now so use the bsg-lib one
instead of the FC private implementation.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/s390/scsi/zfcp_fc.c | 2 +-
drivers/scsi/bfa/bfad_bsg.c | 4 ++--
drivers/scsi/ibmvscsi/ibmvfc.c | 2 +-
drivers/scsi/libfc/fc_lport.c | 4 ++--
drivers/scsi/lpfc/lpfc_bsg.c | 38 +++++++++++++++++-----------------
drivers/scsi/qla2xxx/qla_bsg.c | 44 ++++++++++++++++++++--------------------
drivers/scsi/scsi_transport_fc.c | 41 +++----------------------------------
include/scsi/scsi_transport_fc.h | 2 --
8 files changed, 50 insertions(+), 87 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index b1b4129..a0f9c82 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -893,7 +893,7 @@ static void zfcp_fc_ct_els_job_handler(void *data)
jr->reply_payload_rcv_len = job->reply_payload.payload_len;
jr->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
jr->result = zfcp_ct_els->status ? -EIO : 0;
- fc_bsg_jobdone(job, jr->result, jr->reply_payload_rcv_len);
+ bsg_job_done(job, jr->result, jr->reply_payload_rcv_len);
}

static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct bsg_job *job)
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index cdc25e6..a9a0016 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3179,7 +3179,7 @@ bfad_im_bsg_vendor_request(struct bsg_job *job)
bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len;
bsg_reply->result = rc;

- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
error:
@@ -3555,7 +3555,7 @@ out:
bsg_reply->result = rc;

if (rc == BFA_STATUS_OK)
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

return rc;
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 9fd8975..85aa8ab 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1940,7 +1940,7 @@ static int ibmvfc_bsg_request(struct bsg_job *job)
ibmvfc_free_event(evt);
spin_unlock_irqrestore(vhost->host->host_lock, flags);
bsg_reply->result = rc;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
rc = 0;
out:
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 58a3ccb..40d9038 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1911,7 +1911,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
-ECONNABORTED : -ETIMEDOUT;
job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
kfree(info);
return;
@@ -1946,7 +1946,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
bsg_reply->reply_payload_rcv_len =
job->reply_payload.payload_len;
bsg_reply->result = 0;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
kfree(info);
}
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index ca21f25..a862437 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -371,7 +371,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}
return;
@@ -645,7 +645,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}
return;
@@ -1138,7 +1138,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
job->dd_data = NULL;
/* complete the job back to userspace */
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
spin_lock_irqsave(&phba->ct_ev_lock, flags);
}
@@ -1364,7 +1364,7 @@ lpfc_bsg_hba_get_event(struct bsg_job *job)
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
job->dd_data = NULL;
bsg_reply->result = 0;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return 0;

@@ -1462,7 +1462,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}
return;
@@ -1891,7 +1891,7 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
}
@@ -2181,7 +2181,7 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
}
@@ -2296,7 +2296,7 @@ loopback_mode_end_exit:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
}
@@ -2449,7 +2449,7 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
}
@@ -3310,7 +3310,7 @@ loopback_test_exit:
job->dd_data = NULL;
/* complete the job back to userspace if no error */
if (rc == IOCB_SUCCESS)
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
}
@@ -3354,7 +3354,7 @@ lpfc_bsg_get_dfc_rev(struct bsg_job *job)
job_error:
bsg_reply->result = rc;
if (rc == 0)
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
}
@@ -3420,7 +3420,7 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)

if (job) {
bsg_reply->result = 0;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}
return;
@@ -3669,7 +3669,7 @@ lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
/* if the job is still active, call job done */
if (job) {
bsg_reply = job->reply;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}
return;
@@ -3707,7 +3707,7 @@ lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
/* if the job is still active, call job done */
if (job) {
bsg_reply = job->reply;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}

@@ -4150,7 +4150,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
/* wait for additoinal external buffers */

bsg_reply->result = 0;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return SLI_CONFIG_HANDLED;

@@ -4377,7 +4377,7 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct bsg_job *job)
}

bsg_reply->result = 0;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

return SLI_CONFIG_HANDLED;
@@ -4494,7 +4494,7 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job,

/* wait for additoinal external buffers */
bsg_reply->result = 0;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return SLI_CONFIG_HANDLED;

@@ -4963,7 +4963,7 @@ lpfc_bsg_mbox_cmd(struct bsg_job *job)
/* job done */
bsg_reply->result = 0;
job->dd_data = NULL;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
} else if (rc == 1)
/* job submitted, will complete later*/
@@ -5074,7 +5074,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 342e8a3..1bf8061 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -21,7 +21,7 @@ qla2x00_bsg_job_done(void *data, void *ptr, int res)
struct fc_bsg_reply *bsg_reply = bsg_job->reply;

bsg_reply->result = res;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
sp->free(vha, sp);
}
@@ -244,7 +244,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
}
exit_fcp_prio_cfg:
if (!ret)
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return ret;
}
@@ -942,7 +942,7 @@ done_unmap_req_sg:
bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
if (!rval)
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rval;
}
@@ -976,7 +976,7 @@ qla84xx_reset(struct bsg_job *bsg_job)
ql_dbg(ql_dbg_user, vha, 0x7031,
"Vendor request 84xx reset completed.\n");
bsg_reply->result = DID_OK;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}

@@ -1090,7 +1090,7 @@ done_unmap_sg:
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);

if (!rval)
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rval;
}
@@ -1288,7 +1288,7 @@ exit_mgmt:
dma_pool_free(ha->s_dma_pool, mn, mn_dma);

if (!rval)
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rval;
}
@@ -1375,7 +1375,7 @@ qla24xx_iidma(struct bsg_job *bsg_job)
}

bsg_reply->result = DID_OK;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
}

@@ -1484,7 +1484,7 @@ qla2x00_read_optrom(struct bsg_job *bsg_job)
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
mutex_unlock(&ha->optrom_mutex);
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rval;
}
@@ -1520,7 +1520,7 @@ qla2x00_update_optrom(struct bsg_job *bsg_job)
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
mutex_unlock(&ha->optrom_mutex);
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rval;
}
@@ -1571,7 +1571,7 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

return 0;
@@ -1621,7 +1621,7 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = sizeof(*sr);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

return 0;
@@ -1667,7 +1667,7 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

return 0;
@@ -1712,7 +1712,7 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

return 0;
@@ -1761,7 +1761,7 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

return 0;
@@ -1940,7 +1940,7 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = (DID_OK) << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
/* Always return success, vendor rsp carries correct status */
return 0;
@@ -2106,7 +2106,7 @@ qla26xx_serdes_op(struct bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return 0;
}
@@ -2148,7 +2148,7 @@ qla8044_serdes_op(struct bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return 0;
}
@@ -2180,7 +2180,7 @@ qla27xx_get_flash_upd_cap(struct bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return 0;
}
@@ -2226,7 +2226,7 @@ qla27xx_set_flash_upd_cap(struct bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return 0;
}
@@ -2285,7 +2285,7 @@ done:

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return 0;
}
@@ -2342,7 +2342,7 @@ qla2x00_get_priv_stats(struct bsg_job *bsg_job)

bsg_job->reply_len = sizeof(*bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
@@ -2386,7 +2386,7 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)

bsg_job->reply_len = sizeof(*bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_job_done(bsg_job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);

kfree(dd);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 1ae6d86..720ddc9 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3556,41 +3556,6 @@ fc_vport_sched_delete(struct work_struct *work)
*/

/**
- * fc_bsg_jobdone - completion routine for bsg requests that the LLD has
- * completed
- * @job: fc_bsg_job that is complete
- * @result: job reply result
- * @reply_payload_rcv_len: length of payload received
- */
-void fc_bsg_jobdone(struct bsg_job *job, int result,
- unsigned int reply_payload_rcv_len)
-{
- struct request *req = job->req;
- struct request *rsp = req->next_rq;
- int err;
-
- err = job->req->errors = result;
-
- if (err < 0)
- /* we're only returning the result field in the reply */
- job->req->sense_len = sizeof(uint32_t);
- else
- job->req->sense_len = job->reply_len;
-
- /* we assume all request payload was transferred, residual == 0 */
- req->resid_len = 0;
-
- if (rsp) {
- WARN_ON(reply_payload_rcv_len > rsp->resid_len);
-
- /* set reply (bidi) residual */
- rsp->resid_len -= min(reply_payload_rcv_len, rsp->resid_len);
- }
- blk_complete_request(req);
-}
-EXPORT_SYMBOL_GPL(fc_bsg_jobdone);
-
-/**
* fc_bsg_job_timeout - handler for when a bsg request timesout
* @req: request that timed out
*/
@@ -3799,7 +3764,7 @@ fail_host_msg:
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = ret;
job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return FC_DISPATCH_UNLOCKED;
}
@@ -3877,7 +3842,7 @@ fail_rport_msg:
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = ret;
job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return FC_DISPATCH_UNLOCKED;
}
@@ -3938,7 +3903,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = -ENOMSG;
job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
spin_lock_irq(q->queue_lock);
continue;
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 1da8b71..924c8e6 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -808,8 +808,6 @@ struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
struct fc_vport_identifiers *);
int fc_vport_terminate(struct fc_vport *vport);
int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
-void fc_bsg_jobdone(struct bsg_job *job, int result,
- unsigned int reply_payload_rcv_len);

static inline struct Scsi_Host *fc_bsg_to_shost(struct bsg_job *job)
{
--
1.8.5.6

2016-10-12 13:09:50

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 12/16] scsi: fc: use bsg_softirq_done

bsg_softirq_done() and fc_bsg_softirq_done() are copies of each other, so
ditch the fc specific one.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
block/bsg-lib.c | 3 ++-
drivers/scsi/scsi_transport_fc.c | 16 ++--------------
include/linux/bsg-lib.h | 1 +
3 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 6b99c7f..5d24d25 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -82,13 +82,14 @@ EXPORT_SYMBOL_GPL(bsg_job_done);
* bsg_softirq_done - softirq done routine for destroying the bsg requests
* @rq: BSG request that holds the job to be destroyed
*/
-static void bsg_softirq_done(struct request *rq)
+void bsg_softirq_done(struct request *rq)
{
struct bsg_job *job = rq->special;

blk_end_request_all(rq, rq->errors);
kref_put(&job->kref, bsg_destroy_job);
}
+EXPORT_SYMBOL_GPL(bsg_softirq_done);

static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
{
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 4b9324f..1ae6d86 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3591,18 +3591,6 @@ void fc_bsg_jobdone(struct bsg_job *job, int result,
EXPORT_SYMBOL_GPL(fc_bsg_jobdone);

/**
- * fc_bsg_softirq_done - softirq done routine for destroying the bsg requests
- * @rq: BSG request that holds the job to be destroyed
- */
-static void fc_bsg_softirq_done(struct request *rq)
-{
- struct bsg_job *job = rq->special;
-
- blk_end_request_all(rq, rq->errors);
- kref_put(&job->kref, fc_destroy_bsgjob);
-}
-
-/**
* fc_bsg_job_timeout - handler for when a bsg request timesout
* @req: request that timed out
*/
@@ -4036,7 +4024,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)

q->queuedata = shost;
queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
- blk_queue_softirq_done(q, fc_bsg_softirq_done);
+ blk_queue_softirq_done(q, bsg_softirq_done);
blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);

@@ -4082,7 +4070,7 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)

q->queuedata = rport;
queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
- blk_queue_softirq_done(q, fc_bsg_softirq_done);
+ blk_queue_softirq_done(q, bsg_softirq_done);
blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);

diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index 67f7de6..09f3044 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -70,5 +70,6 @@ int bsg_setup_queue(struct device *dev, struct request_queue *q, char *name,
bsg_job_fn *job_fn, int dd_job_size);
void bsg_request_fn(struct request_queue *q);
void bsg_destroy_job(struct kref *kref);
+void bsg_softirq_done(struct request *rq);

#endif
--
1.8.5.6

2016-10-12 13:10:01

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 11/16] scsi: fc: Use bsg_destroy_job

fc_destroy_bsgjob() and bsg_destroy_job() are now 1:1 copies, so use the
later.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
block/bsg-lib.c | 3 ++-
drivers/scsi/scsi_transport_fc.c | 20 ++------------------
include/linux/bsg-lib.h | 1 +
3 files changed, 5 insertions(+), 19 deletions(-)

diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 632fb40..6b99c7f 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -32,7 +32,7 @@
* bsg_destroy_job - routine to teardown/delete a bsg job
* @job: bsg_job that is to be torn down
*/
-static void bsg_destroy_job(struct kref *kref)
+void bsg_destroy_job(struct kref *kref)
{
struct bsg_job *job = container_of(kref, struct bsg_job, kref);

@@ -42,6 +42,7 @@ static void bsg_destroy_job(struct kref *kref)
kfree(job->reply_payload.sg_list);
kfree(job);
}
+EXPORT_SYMBOL_GPL(bsg_destroy_job);

/**
* bsg_job_done - completion routine for bsg requests
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index a0e150a..4b9324f 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/kernel.h>
+#include <linux/bsg-lib.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
@@ -3554,23 +3555,6 @@ fc_vport_sched_delete(struct work_struct *work)
* BSG support
*/

-
-/**
- * fc_destroy_bsgjob - routine to teardown/delete a fc bsg job
- * @job: fc_bsg_job that is to be torn down
- */
-static void
-fc_destroy_bsgjob(struct kref *kref)
-{
- struct bsg_job *job = container_of(kref, struct bsg_job, kref);
-
- put_device(job->dev); /* release reference for the request */
-
- kfree(job->request_payload.sg_list);
- kfree(job->reply_payload.sg_list);
- kfree(job);
-}
-
/**
* fc_bsg_jobdone - completion routine for bsg requests that the LLD has
* completed
@@ -3640,7 +3624,7 @@ fc_bsg_job_timeout(struct request *req)
/* call LLDD to abort the i/o as it has timed out */
err = i->f->bsg_timeout(job);
if (err == -EAGAIN) {
- kref_put(&job->kref, fc_destroy_bsgjob);
+ kref_put(&job->kref, bsg_destroy_job);
return BLK_EH_RESET_TIMER;
} else if (err)
printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index 58e0717..67f7de6 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -69,5 +69,6 @@ void bsg_job_done(struct bsg_job *job, int result,
int bsg_setup_queue(struct device *dev, struct request_queue *q, char *name,
bsg_job_fn *job_fn, int dd_job_size);
void bsg_request_fn(struct request_queue *q);
+void bsg_destroy_job(struct kref *kref);

#endif
--
1.8.5.6

2016-10-12 13:11:03

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 10/16] scsi: change FC drivers to use 'struct bsg_job'

Change FC drivers to use 'struct bsg_job' from bsg-lib.h instead of 'struct
fc_bsg_job' from scsi_transport_fc.h and remove 'struct fc_bsg_job'.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/s390/scsi/zfcp_ext.h | 4 +--
drivers/s390/scsi/zfcp_fc.c | 15 ++++----
drivers/scsi/bfa/bfad_bsg.c | 10 +++---
drivers/scsi/bfa/bfad_im.h | 4 +--
drivers/scsi/ibmvscsi/ibmvfc.c | 9 ++---
drivers/scsi/libfc/fc_lport.c | 10 +++---
drivers/scsi/lpfc/lpfc_bsg.c | 74 ++++++++++++++++++++--------------------
drivers/scsi/lpfc/lpfc_crtn.h | 4 +--
drivers/scsi/qla2xxx/qla_bsg.c | 61 +++++++++++++++++----------------
drivers/scsi/qla2xxx/qla_def.h | 2 +-
drivers/scsi/qla2xxx/qla_gbl.h | 4 +--
drivers/scsi/qla2xxx/qla_iocb.c | 8 ++---
drivers/scsi/qla2xxx/qla_isr.c | 6 ++--
drivers/scsi/qla2xxx/qla_mr.c | 5 +--
drivers/scsi/scsi_transport_fc.c | 20 +++++------
include/scsi/libfc.h | 2 +-
include/scsi/scsi_transport_fc.h | 63 ++++++++++------------------------
17 files changed, 138 insertions(+), 163 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 5b50065..ab163be 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -82,8 +82,8 @@ extern void zfcp_fc_link_test_work(struct work_struct *);
extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *);
extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
-extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
-extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
+extern int zfcp_fc_exec_bsg_job(struct bsg_job *);
+extern int zfcp_fc_timeout_bsg_job(struct bsg_job *);
extern void zfcp_fc_sym_name_update(struct work_struct *);
extern unsigned int zfcp_fc_port_scan_backoff(void);
extern void zfcp_fc_conditional_port_scan(struct zfcp_adapter *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 1977a66..b1b4129 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/utsname.h>
#include <linux/random.h>
+#include <linux/bsg-lib.h>
#include <scsi/fc/fc_els.h>
#include <scsi/libfc.h>
#include "zfcp_ext.h"
@@ -885,7 +886,7 @@ out_free:

static void zfcp_fc_ct_els_job_handler(void *data)
{
- struct fc_bsg_job *job = data;
+ struct bsg_job *job = data;
struct zfcp_fsf_ct_els *zfcp_ct_els = job->dd_data;
struct fc_bsg_reply *jr = job->reply;

@@ -895,7 +896,7 @@ static void zfcp_fc_ct_els_job_handler(void *data)
fc_bsg_jobdone(job, jr->result, jr->reply_payload_rcv_len);
}

-static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
+static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct bsg_job *job)
{
u32 preamble_word1;
u8 gs_type;
@@ -925,7 +926,7 @@ static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)

static void zfcp_fc_ct_job_handler(void *data)
{
- struct fc_bsg_job *job = data;
+ struct bsg_job *job = data;
struct zfcp_fc_wka_port *wka_port;

wka_port = zfcp_fc_job_wka_port(job);
@@ -934,7 +935,7 @@ static void zfcp_fc_ct_job_handler(void *data)
zfcp_fc_ct_els_job_handler(data);
}

-static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
+static int zfcp_fc_exec_els_job(struct bsg_job *job,
struct zfcp_adapter *adapter)
{
struct zfcp_fsf_ct_els *els = job->dd_data;
@@ -957,7 +958,7 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
}

-static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
+static int zfcp_fc_exec_ct_job(struct bsg_job *job,
struct zfcp_adapter *adapter)
{
int ret;
@@ -980,7 +981,7 @@ static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
return ret;
}

-int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
+int zfcp_fc_exec_bsg_job(struct bsg_job *job)
{
struct Scsi_Host *shost;
struct zfcp_adapter *adapter;
@@ -1010,7 +1011,7 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
}
}

-int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *job)
+int zfcp_fc_timeout_bsg_job(struct bsg_job *job)
{
/* hardware tracks timeout, reset bsg timeout to not interfere */
return -EAGAIN;
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index d3094270..cdc25e6 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3130,7 +3130,7 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
}

static int
-bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
+bfad_im_bsg_vendor_request(struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -3314,7 +3314,7 @@ bfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base,
}

int
-bfad_fcxp_bsg_send(struct fc_bsg_job *job, struct bfad_fcxp *drv_fcxp,
+bfad_fcxp_bsg_send(struct bsg_job *job, struct bfad_fcxp *drv_fcxp,
bfa_bsg_fcpt_t *bsg_fcpt)
{
struct bfa_fcxp_s *hal_fcxp;
@@ -3354,7 +3354,7 @@ bfad_fcxp_bsg_send(struct fc_bsg_job *job, struct bfad_fcxp *drv_fcxp,
}

int
-bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
+bfad_im_bsg_els_ct_request(struct bsg_job *job)
{
struct bfa_bsg_data *bsg_data;
struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job));
@@ -3562,7 +3562,7 @@ out:
}

int
-bfad_im_bsg_request(struct fc_bsg_job *job)
+bfad_im_bsg_request(struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -3590,7 +3590,7 @@ bfad_im_bsg_request(struct fc_bsg_job *job)
}

int
-bfad_im_bsg_timeout(struct fc_bsg_job *job)
+bfad_im_bsg_timeout(struct bsg_job *job)
{
/* Don't complete the BSG job request - return -EAGAIN
* to reset bsg job timeout : for ELS/CT pass thru we
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index 836fdc2..c81ec2a 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -166,8 +166,8 @@ extern struct device_attribute *bfad_im_vport_attrs[];

irqreturn_t bfad_intx(int irq, void *dev_id);

-int bfad_im_bsg_request(struct fc_bsg_job *job);
-int bfad_im_bsg_timeout(struct fc_bsg_job *job);
+int bfad_im_bsg_request(struct bsg_job *job);
+int bfad_im_bsg_timeout(struct bsg_job *job);

/*
* Macro to set the SCSI device sdev_bflags - sdev_bflags are used by the
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 35114d9..9fd8975 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -32,6 +32,7 @@
#include <linux/of.h>
#include <linux/pm.h>
#include <linux/stringify.h>
+#include <linux/bsg-lib.h>
#include <asm/firmware.h>
#include <asm/irq.h>
#include <asm/vio.h>
@@ -1695,12 +1696,12 @@ static void ibmvfc_bsg_timeout_done(struct ibmvfc_event *evt)

/**
* ibmvfc_bsg_timeout - Handle a BSG timeout
- * @job: struct fc_bsg_job that timed out
+ * @job: struct bsg_job that timed out
*
* Returns:
* 0 on success / other on failure
**/
-static int ibmvfc_bsg_timeout(struct fc_bsg_job *job)
+static int ibmvfc_bsg_timeout(struct bsg_job *job)
{
struct ibmvfc_host *vhost = shost_priv(fc_bsg_to_shost(job));
unsigned long port_id = (unsigned long)job->dd_data;
@@ -1808,12 +1809,12 @@ unlock_out:

/**
* ibmvfc_bsg_request - Handle a BSG request
- * @job: struct fc_bsg_job to be executed
+ * @job: struct bsg_job to be executed
*
* Returns:
* 0 on success / other on failure
**/
-static int ibmvfc_bsg_request(struct fc_bsg_job *job)
+static int ibmvfc_bsg_request(struct bsg_job *job)
{
struct ibmvfc_host *vhost = shost_priv(fc_bsg_to_shost(job));
struct fc_rport *rport = fc_bsg_to_rport(job);
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 53d13721..58a3ccb 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -149,7 +149,7 @@ static const char *fc_lport_state_names[] = {
* @offset: The offset into the response data
*/
struct fc_bsg_info {
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_lport *lport;
u16 rsp_code;
struct scatterlist *sg;
@@ -1900,7 +1900,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
void *info_arg)
{
struct fc_bsg_info *info = info_arg;
- struct fc_bsg_job *job = info->job;
+ struct bsg_job *job = info->job;
struct fc_bsg_reply *bsg_reply = job->reply;
struct fc_lport *lport = info->lport;
struct fc_frame_header *fh;
@@ -1963,7 +1963,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
* Locking Note: The lport lock is expected to be held before calling
* this routine.
*/
-static int fc_lport_els_request(struct fc_bsg_job *job,
+static int fc_lport_els_request(struct bsg_job *job,
struct fc_lport *lport,
u32 did, u32 tov)
{
@@ -2024,7 +2024,7 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
* Locking Note: The lport lock is expected to be held before calling
* this routine.
*/
-static int fc_lport_ct_request(struct fc_bsg_job *job,
+static int fc_lport_ct_request(struct bsg_job *job,
struct fc_lport *lport, u32 did, u32 tov)
{
struct fc_bsg_info *info;
@@ -2080,7 +2080,7 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
* FC Passthrough requests
* @job: The BSG passthrough job
*/
-int fc_lport_bsg_request(struct fc_bsg_job *job)
+int fc_lport_bsg_request(struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index dae7cc3..ca21f25 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -98,7 +98,7 @@ struct lpfc_bsg_menlo {
#define TYPE_MENLO 4
struct bsg_job_data {
uint32_t type;
- struct fc_bsg_job *set_job; /* job waiting for this iocb to finish */
+ struct bsg_job *set_job; /* job waiting for this iocb to finish */
union {
struct lpfc_bsg_event *evt;
struct lpfc_bsg_iocb iocb;
@@ -298,7 +298,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
struct lpfc_iocbq *rspiocbq)
{
struct bsg_job_data *dd_data;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp, *cmp, *rmp;
@@ -382,7 +382,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
* @job: fc_bsg_job to handle
**/
static int
-lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
+lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
@@ -575,7 +575,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
struct lpfc_iocbq *rspiocbq)
{
struct bsg_job_data *dd_data;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_nodelist *ndlp;
@@ -656,7 +656,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
* @job: fc_bsg_job to handle
**/
static int
-lpfc_bsg_rport_els(struct fc_bsg_job *job)
+lpfc_bsg_rport_els(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
@@ -927,7 +927,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_dmabuf *bdeBuf2 = piocbq->context3;
struct lpfc_hbq_entry *hbqe;
struct lpfc_sli_ct_request *ct_req;
- struct fc_bsg_job *job = NULL;
+ struct bsg_job *job = NULL;
struct fc_bsg_reply *bsg_reply;
struct bsg_job_data *dd_data = NULL;
unsigned long flags;
@@ -1200,7 +1200,7 @@ lpfc_bsg_ct_unsol_abort(struct lpfc_hba *phba, struct hbq_dmabuf *dmabuf)
* @job: SET_EVENT fc_bsg_job
**/
static int
-lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
+lpfc_bsg_hba_set_event(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
@@ -1285,7 +1285,7 @@ job_error:
* @job: GET_EVENT fc_bsg_job
**/
static int
-lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
+lpfc_bsg_hba_get_event(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
@@ -1397,7 +1397,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
struct lpfc_iocbq *rspiocbq)
{
struct bsg_job_data *dd_data;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp, *cmp;
@@ -1477,7 +1477,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
* @num_entry: Number of enties in the bde.
**/
static int
-lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
+lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,
struct lpfc_dmabuf *cmp, struct lpfc_dmabuf *bmp,
int num_entry)
{
@@ -1623,7 +1623,7 @@ no_dd_data:
* @job: SEND_MGMT_RESP fc_bsg_job
**/
static int
-lpfc_bsg_send_mgmt_rsp(struct fc_bsg_job *job)
+lpfc_bsg_send_mgmt_rsp(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
@@ -1782,7 +1782,7 @@ lpfc_bsg_diag_mode_exit(struct lpfc_hba *phba)
* All of this is done in-line.
*/
static int
-lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
+lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -2040,7 +2040,7 @@ lpfc_sli4_diag_fcport_reg_setup(struct lpfc_hba *phba)
* loopback mode in order to perform a diagnostic loopback test.
*/
static int
-lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
+lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -2194,7 +2194,7 @@ job_error:
* command from the user to proper driver action routines.
*/
static int
-lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job)
+lpfc_bsg_diag_loopback_mode(struct bsg_job *job)
{
struct Scsi_Host *shost;
struct lpfc_vport *vport;
@@ -2230,7 +2230,7 @@ lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job)
* command from the user to proper driver action routines.
*/
static int
-lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
+lpfc_sli4_bsg_diag_mode_end(struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -2309,7 +2309,7 @@ loopback_mode_end_exit:
* applicaiton.
*/
static int
-lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
+lpfc_sli4_bsg_link_diag_test(struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -3016,7 +3016,7 @@ err_post_rxbufs_exit:
* of loopback mode.
**/
static int
-lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
+lpfc_bsg_diag_loopback_run(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -3320,7 +3320,7 @@ loopback_test_exit:
* @job: GET_DFC_REV fc_bsg_job
**/
static int
-lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
+lpfc_bsg_get_dfc_rev(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -3375,7 +3375,7 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
struct bsg_job_data *dd_data;
struct fc_bsg_reply *bsg_reply;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
uint32_t size;
unsigned long flags;
uint8_t *pmb, *pmb_buf;
@@ -3551,11 +3551,11 @@ lpfc_bsg_mbox_ext_session_reset(struct lpfc_hba *phba)
* This is routine handles BSG job for mailbox commands completions with
* multiple external buffers.
**/
-static struct fc_bsg_job *
+static struct bsg_job *
lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
struct bsg_job_data *dd_data;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_reply *bsg_reply;
uint8_t *pmb, *pmb_buf;
unsigned long flags;
@@ -3646,7 +3646,7 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
static void
lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_reply *bsg_reply;

job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);
@@ -3686,7 +3686,7 @@ lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
static void
lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_reply *bsg_reply;

job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);
@@ -3818,7 +3818,7 @@ lpfc_bsg_sli_cfg_dma_desc_setup(struct lpfc_hba *phba, enum nemb_type nemb_tp,
* non-embedded external bufffers.
**/
static int
-lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
+lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
enum nemb_type nemb_tp,
struct lpfc_dmabuf *dmabuf)
{
@@ -4006,7 +4006,7 @@ job_error:
* non-embedded external bufffers.
**/
static int
-lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
+lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job,
enum nemb_type nemb_tp,
struct lpfc_dmabuf *dmabuf)
{
@@ -4173,7 +4173,7 @@ job_error:
* with embedded sussystem 0x1 and opcodes with external HBDs.
**/
static int
-lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
+lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct bsg_job *job,
struct lpfc_dmabuf *dmabuf)
{
struct lpfc_sli_config_mbox *sli_cfg_mbx;
@@ -4322,7 +4322,7 @@ lpfc_bsg_mbox_ext_abort(struct lpfc_hba *phba)
* user space through BSG.
**/
static int
-lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
+lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct bsg_job *job)
{
struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
@@ -4392,7 +4392,7 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
* from user space through BSG.
**/
static int
-lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
+lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job,
struct lpfc_dmabuf *dmabuf)
{
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -4515,7 +4515,7 @@ job_error:
* command with multiple non-embedded external buffers.
**/
static int
-lpfc_bsg_handle_sli_cfg_ebuf(struct lpfc_hba *phba, struct fc_bsg_job *job,
+lpfc_bsg_handle_sli_cfg_ebuf(struct lpfc_hba *phba, struct bsg_job *job,
struct lpfc_dmabuf *dmabuf)
{
int rc;
@@ -4560,7 +4560,7 @@ lpfc_bsg_handle_sli_cfg_ebuf(struct lpfc_hba *phba, struct fc_bsg_job *job,
* (0x9B) mailbox commands and external buffers.
**/
static int
-lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
+lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct bsg_job *job,
struct lpfc_dmabuf *dmabuf)
{
struct fc_bsg_request *bsg_request = job->request;
@@ -4638,7 +4638,7 @@ sli_cfg_ext_error:
* let our completion handler finish the command.
**/
static int
-lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
+lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct bsg_job *job,
struct lpfc_vport *vport)
{
struct fc_bsg_request *bsg_request = job->request;
@@ -4931,7 +4931,7 @@ job_cont:
* @job: MBOX fc_bsg_job for LPFC_BSG_VENDOR_MBOX.
**/
static int
-lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
+lpfc_bsg_mbox_cmd(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_request *bsg_request = job->request;
@@ -5000,7 +5000,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
struct lpfc_iocbq *rspiocbq)
{
struct bsg_job_data *dd_data;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp, *cmp, *rmp;
@@ -5091,7 +5091,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
* supplied in the menlo request header xri field.
**/
static int
-lpfc_menlo_cmd(struct fc_bsg_job *job)
+lpfc_menlo_cmd(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_request *bsg_request = job->request;
@@ -5259,7 +5259,7 @@ no_dd_data:
* @job: fc_bsg_job to handle
**/
static int
-lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
+lpfc_bsg_hst_vendor(struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -5314,7 +5314,7 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
* @job: fc_bsg_job to handle
**/
int
-lpfc_bsg_request(struct fc_bsg_job *job)
+lpfc_bsg_request(struct bsg_job *job)
{
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -5351,7 +5351,7 @@ lpfc_bsg_request(struct fc_bsg_job *job)
* the waiting function which will handle passing the error back to userspace
**/
int
-lpfc_bsg_timeout(struct fc_bsg_job *job)
+lpfc_bsg_timeout(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index bd7576d..d993c5a 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -431,8 +431,8 @@ struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t);
#define HBA_EVENT_LINK_DOWN 3

/* functions to support SGIOv4/bsg interface */
-int lpfc_bsg_request(struct fc_bsg_job *);
-int lpfc_bsg_timeout(struct fc_bsg_job *);
+int lpfc_bsg_request(struct bsg_job *);
+int lpfc_bsg_timeout(struct bsg_job *);
int lpfc_bsg_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *);
int lpfc_bsg_ct_unsol_abort(struct lpfc_hba *, struct hbq_dmabuf *);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 917eafe..342e8a3 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -9,6 +9,7 @@
#include <linux/kthread.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
+#include <linux/bsg-lib.h>

/* BSG support for ELS/CT pass through */
void
@@ -16,7 +17,7 @@ qla2x00_bsg_job_done(void *data, void *ptr, int res)
{
srb_t *sp = (srb_t *)ptr;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
- struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct bsg_job *bsg_job = sp->u.bsg_job;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;

bsg_reply->result = res;
@@ -30,7 +31,7 @@ qla2x00_bsg_sp_free(void *data, void *ptr)
{
srb_t *sp = (srb_t *)ptr;
struct scsi_qla_host *vha = sp->fcport->vha;
- struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct bsg_job *bsg_job = sp->u.bsg_job;
struct fc_bsg_request *bsg_request = bsg_job->request;

struct qla_hw_data *ha = vha->hw;
@@ -120,7 +121,7 @@ qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
}

static int
-qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
+qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
{
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
struct fc_bsg_request *bsg_request = bsg_job->request;
@@ -249,7 +250,7 @@ exit_fcp_prio_cfg:
}

static int
-qla2x00_process_els(struct fc_bsg_job *bsg_job)
+qla2x00_process_els(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_rport *rport;
@@ -428,7 +429,7 @@ qla24xx_calc_ct_iocbs(uint16_t dsds)
}

static int
-qla2x00_process_ct(struct fc_bsg_job *bsg_job)
+qla2x00_process_ct(struct bsg_job *bsg_job)
{
srb_t *sp;
struct fc_bsg_request *bsg_request = bsg_job->request;
@@ -706,7 +707,7 @@ done_set_internal:
}

static int
-qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
+qla2x00_process_loopback(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
@@ -947,7 +948,7 @@ done_unmap_req_sg:
}

static int
-qla84xx_reset(struct fc_bsg_job *bsg_job)
+qla84xx_reset(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -983,7 +984,7 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
}

static int
-qla84xx_updatefw(struct fc_bsg_job *bsg_job)
+qla84xx_updatefw(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
@@ -1095,7 +1096,7 @@ done_unmap_sg:
}

static int
-qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
+qla84xx_mgmt_cmd(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
@@ -1293,7 +1294,7 @@ exit_mgmt:
}

static int
-qla24xx_iidma(struct fc_bsg_job *bsg_job)
+qla24xx_iidma(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
@@ -1382,7 +1383,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
}

static int
-qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
+qla2x00_optrom_setup(struct bsg_job *bsg_job, scsi_qla_host_t *vha,
uint8_t is_update)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
@@ -1452,7 +1453,7 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
}

static int
-qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
+qla2x00_read_optrom(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1489,7 +1490,7 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
}

static int
-qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
+qla2x00_update_optrom(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1525,7 +1526,7 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
}

static int
-qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
+qla2x00_update_fru_versions(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1577,7 +1578,7 @@ done:
}

static int
-qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
+qla2x00_read_fru_status(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1627,7 +1628,7 @@ done:
}

static int
-qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
+qla2x00_write_fru_status(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1673,7 +1674,7 @@ done:
}

static int
-qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
+qla2x00_write_i2c(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1718,7 +1719,7 @@ done:
}

static int
-qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
+qla2x00_read_i2c(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1767,7 +1768,7 @@ done:
}

static int
-qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
+qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -1946,7 +1947,7 @@ done:
}

static int
-qlafx00_mgmt_cmd(struct fc_bsg_job *bsg_job)
+qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -2069,7 +2070,7 @@ done:
}

static int
-qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
+qla26xx_serdes_op(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -2111,7 +2112,7 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
}

static int
-qla8044_serdes_op(struct fc_bsg_job *bsg_job)
+qla8044_serdes_op(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -2153,7 +2154,7 @@ qla8044_serdes_op(struct fc_bsg_job *bsg_job)
}

static int
-qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
+qla27xx_get_flash_upd_cap(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -2185,7 +2186,7 @@ qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
}

static int
-qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
+qla27xx_set_flash_upd_cap(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -2231,7 +2232,7 @@ qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
}

static int
-qla27xx_get_bbcr_data(struct fc_bsg_job *bsg_job)
+qla27xx_get_bbcr_data(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -2290,7 +2291,7 @@ done:
}

static int
-qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
+qla2x00_get_priv_stats(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
@@ -2351,7 +2352,7 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
}

static int
-qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
+qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
@@ -2394,7 +2395,7 @@ qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
}

static int
-qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
+qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;

@@ -2472,7 +2473,7 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
}

int
-qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
+qla24xx_bsg_request(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
@@ -2525,7 +2526,7 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
}

int
-qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
+qla24xx_bsg_timeout(struct bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ae4a747..34b163f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -413,7 +413,7 @@ typedef struct srb {
int iocbs;
union {
struct srb_iocb iocb_cmd;
- struct fc_bsg_job *bsg_job;
+ struct bsg_job *bsg_job;
struct srb_cmd scmd;
} u;
void (*done)(void *, void *, int);
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 6ca0081..c51d9f3 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -733,8 +733,8 @@ extern int qla82xx_read_temperature(scsi_qla_host_t *);
extern int qla8044_read_temperature(scsi_qla_host_t *);

/* BSG related functions */
-extern int qla24xx_bsg_request(struct fc_bsg_job *);
-extern int qla24xx_bsg_timeout(struct fc_bsg_job *);
+extern int qla24xx_bsg_request(struct bsg_job *);
+extern int qla24xx_bsg_timeout(struct bsg_job *);
extern int qla84xx_reset_chip(scsi_qla_host_t *, uint16_t);
extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *,
dma_addr_t, size_t, uint32_t);
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 6929fda..221ad89 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2197,7 +2197,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
static void
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
{
- struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct bsg_job *bsg_job = sp->u.bsg_job;
struct fc_bsg_request *bsg_request = bsg_job->request;

els_iocb->entry_type = ELS_IOCB_TYPE;
@@ -2251,7 +2251,7 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
uint16_t tot_dsds;
scsi_qla_host_t *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw;
- struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct bsg_job *bsg_job = sp->u.bsg_job;
int loop_iterartion = 0;
int entry_count = 1;

@@ -2328,7 +2328,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
uint16_t tot_dsds;
scsi_qla_host_t *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw;
- struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct bsg_job *bsg_job = sp->u.bsg_job;
int loop_iterartion = 0;
int entry_count = 1;

@@ -2834,7 +2834,7 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha,
struct scatterlist *sg;
int index;
int entry_count = 1;
- struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct bsg_job *bsg_job = sp->u.bsg_job;

/*Update entry type to indicate bidir command */
*((uint32_t *)(&cmd_pkt->entry_type)) =
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 1adaad3..81e968c 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1356,7 +1356,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
const char func[] = "CT_IOCB";
const char *type;
srb_t *sp;
- struct fc_bsg_job *bsg_job;
+ struct bsg_job *bsg_job;
struct fc_bsg_reply *bsg_reply;
uint16_t comp_status;
int res;
@@ -1415,7 +1415,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
const char func[] = "ELS_CT_IOCB";
const char *type;
srb_t *sp;
- struct fc_bsg_job *bsg_job;
+ struct bsg_job *bsg_job;
struct fc_bsg_reply *bsg_reply;
uint16_t comp_status;
uint32_t fw_status[3];
@@ -1908,7 +1908,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
uint16_t scsi_status;
uint16_t thread_id;
uint32_t rval = EXT_STATUS_OK;
- struct fc_bsg_job *bsg_job = NULL;
+ struct bsg_job *bsg_job = NULL;
struct fc_bsg_request *bsg_request;
struct fc_bsg_reply *bsg_reply;
sts_entry_t *sts;
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index b597d04..02f1de1 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -10,6 +10,7 @@
#include <linux/pci.h>
#include <linux/ratelimit.h>
#include <linux/vmalloc.h>
+#include <linux/bsg-lib.h>
#include <scsi/scsi_tcq.h>
#include <linux/utsname.h>

@@ -2206,7 +2207,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
{
const char func[] = "IOSB_IOCB";
srb_t *sp;
- struct fc_bsg_job *bsg_job;
+ struct bsg_job *bsg_job;
struct fc_bsg_reply *bsg_reply;
struct srb_iocb *iocb_job;
int res;
@@ -3254,7 +3255,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
{
struct srb_iocb *fxio = &sp->u.iocb_cmd;
struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
- struct fc_bsg_job *bsg_job;
+ struct bsg_job *bsg_job;
struct fc_bsg_request *bsg_request;
struct fxdisc_entry_fx00 fx_iocb;
uint8_t entry_cnt = 1;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index b0e28af..a0e150a 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3562,7 +3562,7 @@ fc_vport_sched_delete(struct work_struct *work)
static void
fc_destroy_bsgjob(struct kref *kref)
{
- struct fc_bsg_job *job = container_of(kref, struct fc_bsg_job, kref);
+ struct bsg_job *job = container_of(kref, struct bsg_job, kref);

put_device(job->dev); /* release reference for the request */

@@ -3578,7 +3578,7 @@ fc_destroy_bsgjob(struct kref *kref)
* @result: job reply result
* @reply_payload_rcv_len: length of payload received
*/
-void fc_bsg_jobdone(struct fc_bsg_job *job, int result,
+void fc_bsg_jobdone(struct bsg_job *job, int result,
unsigned int reply_payload_rcv_len)
{
struct request *req = job->req;
@@ -3612,7 +3612,7 @@ EXPORT_SYMBOL_GPL(fc_bsg_jobdone);
*/
static void fc_bsg_softirq_done(struct request *rq)
{
- struct fc_bsg_job *job = rq->special;
+ struct bsg_job *job = rq->special;

blk_end_request_all(rq, rq->errors);
kref_put(&job->kref, fc_destroy_bsgjob);
@@ -3625,7 +3625,7 @@ static void fc_bsg_softirq_done(struct request *rq)
static enum blk_eh_timer_return
fc_bsg_job_timeout(struct request *req)
{
- struct fc_bsg_job *job = (void *) req->special;
+ struct bsg_job *job = (void *) req->special;
struct Scsi_Host *shost = fc_bsg_to_shost(job);
struct fc_rport *rport = fc_bsg_to_rport(job);
struct fc_internal *i = to_fc_internal(shost->transportt);
@@ -3684,14 +3684,14 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
{
struct fc_internal *i = to_fc_internal(shost->transportt);
struct request *rsp = req->next_rq;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
struct fc_bsg_request *bsg_request;
struct fc_bsg_reply *bsg_reply;
int ret;

BUG_ON(req->special);

- job = kzalloc(sizeof(struct fc_bsg_job) + i->f->dd_bsg_size,
+ job = kzalloc(sizeof(struct bsg_job) + i->f->dd_bsg_size,
GFP_KERNEL);
if (!job)
return -ENOMEM;
@@ -3706,8 +3706,6 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
*/

req->special = job;
- job->shost = shost;
- job->rport = rport;
job->req = req;
if (i->f->dd_bsg_size)
job->dd_data = (void *)&job[1];
@@ -3760,7 +3758,7 @@ enum fc_dispatch_result {
*/
static enum fc_dispatch_result
fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
- struct fc_bsg_job *job)
+ struct bsg_job *job)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
struct fc_bsg_request *bsg_request = job->request;
@@ -3862,7 +3860,7 @@ fc_bsg_goose_queue(struct fc_rport *rport)
*/
static enum fc_dispatch_result
fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
- struct fc_rport *rport, struct fc_bsg_job *job)
+ struct fc_rport *rport, struct bsg_job *job)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
struct fc_bsg_request *bsg_request = job->request;
@@ -3925,7 +3923,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
struct fc_rport *rport, struct device *dev)
{
struct request *req;
- struct fc_bsg_job *job;
+ struct bsg_job *job;
enum fc_dispatch_result ret;
struct fc_bsg_reply *bsg_reply;

diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 7428a53..2dd5cfc 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -1071,7 +1071,7 @@ int fc_lport_reset(struct fc_lport *);
int fc_set_mfs(struct fc_lport *, u32 mfs);
struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize);
struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id);
-int fc_lport_bsg_request(struct fc_bsg_job *);
+int fc_lport_bsg_request(struct bsg_job *);
void fc_lport_set_local_id(struct fc_lport *, u32 port_id);
void fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *);

diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 8ae5680..1da8b71 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -32,6 +32,7 @@
#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_netlink.h>
+#include <scsi/scsi_host.h>

struct scsi_transport_template;

@@ -625,38 +626,6 @@ struct fc_host_attrs {
#define fc_host_dev_loss_tmo(x) \
(((struct fc_host_attrs *)(x)->shost_data)->dev_loss_tmo)

-/* Values for fc_bsg_job->state_flags (bitflags) */
-#define FC_RQST_STATE_INPROGRESS 0
-#define FC_RQST_STATE_DONE 1
-
-struct fc_bsg_job {
- struct Scsi_Host *shost;
- struct fc_rport *rport;
- struct device *dev;
- struct request *req;
- struct kref kref;
-
- struct fc_bsg_request *request;
- struct fc_bsg_reply *reply;
- unsigned int request_len;
- unsigned int reply_len;
- /*
- * On entry : reply_len indicates the buffer size allocated for
- * the reply.
- *
- * Upon completion : the message handler must set reply_len
- * to indicates the size of the reply to be returned to the
- * caller.
- */
-
- /* DMA payloads for the request/response */
- struct bsg_buffer request_payload;
- struct bsg_buffer reply_payload;
-
- void *dd_data; /* Used for driver-specific storage */
-};
-
-
/* The functions by which the transport class and the driver communicate */
struct fc_function_template {
void (*get_rport_dev_loss_tmo)(struct fc_rport *);
@@ -693,8 +662,8 @@ struct fc_function_template {
int (* it_nexus_response)(struct Scsi_Host *, u64, int);

/* bsg support */
- int (*bsg_request)(struct fc_bsg_job *);
- int (*bsg_timeout)(struct fc_bsg_job *);
+ int (*bsg_request)(struct bsg_job *);
+ int (*bsg_timeout)(struct bsg_job *);

/* allocation lengths for host-specific data */
u32 dd_fcrport_size;
@@ -817,16 +786,6 @@ fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state)
vport->vport_state = new_state;
}

-static inline struct Scsi_Host *fc_bsg_to_shost(struct fc_bsg_job *job)
-{
- return job->shost;
-}
-
-static inline struct fc_rport *fc_bsg_to_rport(struct fc_bsg_job *job)
-{
- return job->rport;
-}
-
struct scsi_transport_template *fc_attach_transport(
struct fc_function_template *);
void fc_release_transport(struct scsi_transport_template *);
@@ -849,7 +808,21 @@ struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
struct fc_vport_identifiers *);
int fc_vport_terminate(struct fc_vport *vport);
int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
-void fc_bsg_jobdone(struct fc_bsg_job *job, int result,
+void fc_bsg_jobdone(struct bsg_job *job, int result,
unsigned int reply_payload_rcv_len);

+static inline struct Scsi_Host *fc_bsg_to_shost(struct bsg_job *job)
+{
+ if (scsi_is_host_device(job->dev))
+ return dev_to_shost(job->dev);
+ return rport_to_shost(dev_to_rport(job->dev));
+}
+
+static inline struct fc_rport *fc_bsg_to_rport(struct bsg_job *job)
+{
+ if (scsi_is_fc_rport(job->dev))
+ return dev_to_rport(job->dev);
+ return NULL;
+}
+
#endif /* SCSI_TRANSPORT_FC_H */
--
1.8.5.6

2016-10-12 13:11:14

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 09/16] block: add reference counting for struct bsg_job

Add reference counting to 'struct bsg_job' so we can implement a reuqest
timeout handler for bsg_jobs, which is needed for Fibre Channel.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
block/bsg-lib.c | 7 +++++--
include/linux/bsg-lib.h | 2 ++
2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 650f427..632fb40 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -32,8 +32,10 @@
* bsg_destroy_job - routine to teardown/delete a bsg job
* @job: bsg_job that is to be torn down
*/
-static void bsg_destroy_job(struct bsg_job *job)
+static void bsg_destroy_job(struct kref *kref)
{
+ struct bsg_job *job = container_of(kref, struct bsg_job, kref);
+
put_device(job->dev); /* release reference for the request */

kfree(job->request_payload.sg_list);
@@ -84,7 +86,7 @@ static void bsg_softirq_done(struct request *rq)
struct bsg_job *job = rq->special;

blk_end_request_all(rq, rq->errors);
- bsg_destroy_job(job);
+ kref_put(&job->kref, bsg_destroy_job);
}

static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
@@ -142,6 +144,7 @@ static int bsg_create_job(struct device *dev, struct request *req)
job->dev = dev;
/* take a reference for the request */
get_device(job->dev);
+ kref_init(&job->kref);
return 0;

failjob_rls_rqst_payload:
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index a226652..58e0717 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -40,6 +40,8 @@ struct bsg_job {
struct device *dev;
struct request *req;

+ struct kref kref;
+
/* Transport/driver specific request/reply structs */
void *request;
void *reply;
--
1.8.5.6

2016-10-12 13:11:27

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 08/16] scsi: fc: implement kref backed reference counting

Implement kref backed reference counting instead of rolling our own. This
elimnates the need of the following fields in 'struct fc_bsg_job':
* ref_cnt
* state_flags
* job_lock
bringing us close to unification of 'struct fc_bsg_job' and 'struct bsg_job'.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/scsi/scsi_transport_fc.c | 38 +++++++++-----------------------------
include/scsi/scsi_transport_fc.h | 4 +---
2 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 96b3a2e..b0e28af 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3560,16 +3560,9 @@ fc_vport_sched_delete(struct work_struct *work)
* @job: fc_bsg_job that is to be torn down
*/
static void
-fc_destroy_bsgjob(struct fc_bsg_job *job)
+fc_destroy_bsgjob(struct kref *kref)
{
- unsigned long flags;
-
- spin_lock_irqsave(&job->job_lock, flags);
- if (job->ref_cnt) {
- spin_unlock_irqrestore(&job->job_lock, flags);
- return;
- }
- spin_unlock_irqrestore(&job->job_lock, flags);
+ struct fc_bsg_job *job = container_of(kref, struct fc_bsg_job, kref);

put_device(job->dev); /* release reference for the request */

@@ -3620,15 +3613,9 @@ EXPORT_SYMBOL_GPL(fc_bsg_jobdone);
static void fc_bsg_softirq_done(struct request *rq)
{
struct fc_bsg_job *job = rq->special;
- unsigned long flags;
-
- spin_lock_irqsave(&job->job_lock, flags);
- job->state_flags |= FC_RQST_STATE_DONE;
- job->ref_cnt--;
- spin_unlock_irqrestore(&job->job_lock, flags);

blk_end_request_all(rq, rq->errors);
- fc_destroy_bsgjob(job);
+ kref_put(&job->kref, fc_destroy_bsgjob);
}

/**
@@ -3642,24 +3629,18 @@ fc_bsg_job_timeout(struct request *req)
struct Scsi_Host *shost = fc_bsg_to_shost(job);
struct fc_rport *rport = fc_bsg_to_rport(job);
struct fc_internal *i = to_fc_internal(shost->transportt);
- unsigned long flags;
- int err = 0, done = 0;
+ int err = 0, inflight = 0;

if (rport && rport->port_state == FC_PORTSTATE_BLOCKED)
return BLK_EH_RESET_TIMER;

- spin_lock_irqsave(&job->job_lock, flags);
- if (job->state_flags & FC_RQST_STATE_DONE)
- done = 1;
- else
- job->ref_cnt++;
- spin_unlock_irqrestore(&job->job_lock, flags);
+ inflight = kref_get_unless_zero(&job->kref);

- if (!done && i->f->bsg_timeout) {
+ if (inflight && i->f->bsg_timeout) {
/* call LLDD to abort the i/o as it has timed out */
err = i->f->bsg_timeout(job);
if (err == -EAGAIN) {
- job->ref_cnt--;
+ kref_put(&job->kref, fc_destroy_bsgjob);
return BLK_EH_RESET_TIMER;
} else if (err)
printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
@@ -3667,7 +3648,7 @@ fc_bsg_job_timeout(struct request *req)
}

/* the blk_end_sync_io() doesn't check the error */
- if (done)
+ if (!inflight)
return BLK_EH_NOT_HANDLED;
else
return BLK_EH_HANDLED;
@@ -3730,7 +3711,6 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
job->req = req;
if (i->f->dd_bsg_size)
job->dd_data = (void *)&job[1];
- spin_lock_init(&job->job_lock);
bsg_request = (struct fc_bsg_request *)req->cmd;
job->request_len = req->cmd_len;
bsg_reply = req->sense;
@@ -3752,7 +3732,7 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
job->dev = &shost->shost_gendev;
get_device(job->dev); /* take a reference for the request */

- job->ref_cnt = 1;
+ kref_init(&job->kref);

return 0;

diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 9f53fe3..8ae5680 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -634,9 +634,7 @@ struct fc_bsg_job {
struct fc_rport *rport;
struct device *dev;
struct request *req;
- spinlock_t job_lock;
- unsigned int state_flags;
- unsigned int ref_cnt;
+ struct kref kref;

struct fc_bsg_request *request;
struct fc_bsg_reply *reply;
--
1.8.5.6

2016-10-12 13:12:11

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 07/16] scsi: libfc: don't set FC_RQST_STATE_DONE before calling fc_bsg_jobdone()

Don't set FC_RQST_STATE_DONE before calling fc_bsg_jobdone() as
fc_bsg_jobdone() calls blk_complete_requeust() which raises a soft-IRQ that
ends up in fc_bsg_sofirq_done() and fc_bsg_softirq_done() sets the
FC_RQST_STATE_DONE flag.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/scsi/libfc/fc_lport.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 156708a..53d13721 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1911,7 +1911,6 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
-ECONNABORTED : -ETIMEDOUT;
job->reply_len = sizeof(uint32_t);
- job->state_flags |= FC_RQST_STATE_DONE;
fc_bsg_jobdone(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
kfree(info);
@@ -1947,7 +1946,6 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
bsg_reply->reply_payload_rcv_len =
job->reply_payload.payload_len;
bsg_reply->result = 0;
- job->state_flags |= FC_RQST_STATE_DONE;
fc_bsg_jobdone(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
kfree(info);
--
1.8.5.6

2016-10-12 13:12:23

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
helper variables bsg_request and bsg_reply. This will be helpfull when
transitioning to bsg-lib.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/s390/scsi/zfcp_fc.c | 9 +-
drivers/scsi/bfa/bfad_bsg.c | 40 +++---
drivers/scsi/ibmvscsi/ibmvfc.c | 22 ++--
drivers/scsi/libfc/fc_lport.c | 23 ++--
drivers/scsi/lpfc/lpfc_bsg.c | 194 +++++++++++++++++-----------
drivers/scsi/qla2xxx/qla_bsg.c | 264 ++++++++++++++++++++++-----------------
drivers/scsi/qla2xxx/qla_iocb.c | 5 +-
drivers/scsi/qla2xxx/qla_isr.c | 46 ++++---
drivers/scsi/qla2xxx/qla_mr.c | 10 +-
drivers/scsi/scsi_transport_fc.c | 37 +++---
10 files changed, 387 insertions(+), 263 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 237688a..4c4023f 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -900,8 +900,9 @@ static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
u32 preamble_word1;
u8 gs_type;
struct zfcp_adapter *adapter;
+ struct fc_bsg_request *bsg_request = job->request;

- preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
+ preamble_word1 = bsg_request->rqst_data.r_ct.preamble_word1;
gs_type = (preamble_word1 & 0xff000000) >> 24;

adapter = (struct zfcp_adapter *) job->shost->hostdata[0];
@@ -938,6 +939,7 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
{
struct zfcp_fsf_ct_els *els = job->dd_data;
struct fc_rport *rport = job->rport;
+ struct fc_bsg_request *bsg_request = job->request;
struct zfcp_port *port;
u32 d_id;

@@ -949,7 +951,7 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
d_id = port->d_id;
put_device(&port->dev);
} else
- d_id = ntoh24(job->request->rqst_data.h_els.port_id);
+ d_id = ntoh24(bsg_request->rqst_data.h_els.port_id);

els->handler = zfcp_fc_ct_els_job_handler;
return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
@@ -983,6 +985,7 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
struct Scsi_Host *shost;
struct zfcp_adapter *adapter;
struct zfcp_fsf_ct_els *ct_els = job->dd_data;
+ struct fc_bsg_request *bsg_request = job->request;

shost = job->rport ? rport_to_shost(job->rport) : job->shost;
adapter = (struct zfcp_adapter *)shost->hostdata[0];
@@ -994,7 +997,7 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
ct_els->resp = job->reply_payload.sg_list;
ct_els->handler_data = job;

- switch (job->request->msgcode) {
+ switch (bsg_request->msgcode) {
case FC_BSG_RPT_ELS:
case FC_BSG_HST_ELS_NOLOGIN:
return zfcp_fc_exec_els_job(job, adapter);
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index d1ad020..48366d8 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3132,7 +3132,9 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
static int
bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
{
- uint32_t vendor_cmd = job->request->rqst_data.h_vendor.vendor_cmd[0];
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
+ uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0];
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) job->shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
@@ -3175,8 +3177,8 @@ bfad_im_bsg_vendor_request(struct fc_bsg_job *job)

/* Fill the BSG job reply data */
job->reply_len = job->reply_payload.payload_len;
- job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
- job->reply->result = rc;
+ bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len;
+ bsg_reply->result = rc;

job->job_done(job);
return rc;
@@ -3184,9 +3186,9 @@ error:
/* free the command buffer */
kfree(payload_kbuf);
out:
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->reply_len = sizeof(uint32_t);
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
return rc;
}

@@ -3362,18 +3364,20 @@ bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
struct bfad_fcxp *drv_fcxp;
struct bfa_fcs_lport_s *fcs_port;
struct bfa_fcs_rport_s *fcs_rport;
- uint32_t command_type = job->request->msgcode;
+ struct fc_bsg_request *bsg_request = bsg_request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
+ uint32_t command_type = bsg_request->msgcode;
unsigned long flags;
struct bfad_buf_info *rsp_buf_info;
void *req_kbuf = NULL, *rsp_kbuf = NULL;
int rc = -EINVAL;

job->reply_len = sizeof(uint32_t); /* Atleast uint32_t reply_len */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

/* Get the payload passed in from userspace */
- bsg_data = (struct bfa_bsg_data *) (((char *)job->request) +
- sizeof(struct fc_bsg_request));
+ bsg_data = (struct bfa_bsg_data *) (((char *)bsg_request) +
+ sizeof(struct fc_bsg_request));
if (bsg_data == NULL)
goto out;

@@ -3517,13 +3521,13 @@ bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
/* fill the job->reply data */
if (drv_fcxp->req_status == BFA_STATUS_OK) {
job->reply_len = drv_fcxp->rsp_len;
- job->reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
- job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+ bsg_reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
+ bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
} else {
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sizeof(struct fc_bsg_ctels_reply);
job->reply_len = sizeof(uint32_t);
- job->reply->reply_data.ctels_reply.status =
+ bsg_reply->reply_data.ctels_reply.status =
FC_CTELS_STATUS_REJECT;
}

@@ -3549,7 +3553,7 @@ out_free_mem:
kfree(bsg_fcpt);
kfree(drv_fcxp);
out:
- job->reply->result = rc;
+ bsg_reply->result = rc;

if (rc == BFA_STATUS_OK)
job->job_done(job);
@@ -3560,9 +3564,11 @@ out:
int
bfad_im_bsg_request(struct fc_bsg_job *job)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
uint32_t rc = BFA_STATUS_OK;

- switch (job->request->msgcode) {
+ switch (bsg_request->msgcode) {
case FC_BSG_HST_VENDOR:
/* Process BSG HST Vendor requests */
rc = bfad_im_bsg_vendor_request(job);
@@ -3575,8 +3581,8 @@ bfad_im_bsg_request(struct fc_bsg_job *job)
rc = bfad_im_bsg_els_ct_request(job);
break;
default:
- job->reply->result = rc = -EINVAL;
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = rc = -EINVAL;
+ bsg_reply->reply_payload_rcv_len = 0;
break;
}

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index ab67ec4..8b55279 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1821,28 +1821,30 @@ static int ibmvfc_bsg_request(struct fc_bsg_job *job)
struct ibmvfc_event *evt;
union ibmvfc_iu rsp_iu;
unsigned long flags, port_id = -1;
- unsigned int code = job->request->msgcode;
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
+ unsigned int code = bsg_request->msgcode;
int rc = 0, req_seg, rsp_seg, issue_login = 0;
u32 fc_flags, rsp_len;

ENTER;
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
if (rport)
port_id = rport->port_id;

switch (code) {
case FC_BSG_HST_ELS_NOLOGIN:
- port_id = (job->request->rqst_data.h_els.port_id[0] << 16) |
- (job->request->rqst_data.h_els.port_id[1] << 8) |
- job->request->rqst_data.h_els.port_id[2];
+ port_id = (bsg_request->rqst_data.h_els.port_id[0] << 16) |
+ (bsg_request->rqst_data.h_els.port_id[1] << 8) |
+ bsg_request->rqst_data.h_els.port_id[2];
case FC_BSG_RPT_ELS:
fc_flags = IBMVFC_FC_ELS;
break;
case FC_BSG_HST_CT:
issue_login = 1;
- port_id = (job->request->rqst_data.h_ct.port_id[0] << 16) |
- (job->request->rqst_data.h_ct.port_id[1] << 8) |
- job->request->rqst_data.h_ct.port_id[2];
+ port_id = (bsg_request->rqst_data.h_ct.port_id[0] << 16) |
+ (bsg_request->rqst_data.h_ct.port_id[1] << 8) |
+ bsg_request->rqst_data.h_ct.port_id[2];
case FC_BSG_RPT_CT:
fc_flags = IBMVFC_FC_CT_IU;
break;
@@ -1931,12 +1933,12 @@ static int ibmvfc_bsg_request(struct fc_bsg_job *job)
if (rsp_iu.passthru.common.status)
rc = -EIO;
else
- job->reply->reply_payload_rcv_len = rsp_len;
+ bsg_reply->reply_payload_rcv_len = rsp_len;

spin_lock_irqsave(vhost->host->host_lock, flags);
ibmvfc_free_event(evt);
spin_unlock_irqrestore(vhost->host->host_lock, flags);
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->job_done(job);
rc = 0;
out:
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 04ce7cf..a1c12e7 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1901,13 +1901,14 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
{
struct fc_bsg_info *info = info_arg;
struct fc_bsg_job *job = info->job;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct fc_lport *lport = info->lport;
struct fc_frame_header *fh;
size_t len;
void *buf;

if (IS_ERR(fp)) {
- job->reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
+ bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
-ECONNABORTED : -ETIMEDOUT;
job->reply_len = sizeof(uint32_t);
job->state_flags |= FC_RQST_STATE_DONE;
@@ -1928,23 +1929,23 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
(unsigned short)fc_frame_payload_op(fp);

/* Save the reply status of the job */
- job->reply->reply_data.ctels_reply.status =
+ bsg_reply->reply_data.ctels_reply.status =
(cmd == info->rsp_code) ?
FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
}

- job->reply->reply_payload_rcv_len +=
+ bsg_reply->reply_payload_rcv_len +=
fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
&info->offset, NULL);

if (fr_eof(fp) == FC_EOF_T &&
(ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
(FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
- if (job->reply->reply_payload_rcv_len >
+ if (bsg_reply->reply_payload_rcv_len >
job->reply_payload.payload_len)
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
job->reply_payload.payload_len;
- job->reply->result = 0;
+ bsg_reply->result = 0;
job->state_flags |= FC_RQST_STATE_DONE;
job->job_done(job);
kfree(info);
@@ -2081,6 +2082,8 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
*/
int fc_lport_bsg_request(struct fc_bsg_job *job)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct request *rsp = job->req->next_rq;
struct Scsi_Host *shost = job->shost;
struct fc_lport *lport = shost_priv(shost);
@@ -2089,13 +2092,13 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
int rc = -EINVAL;
u32 did, tov;

- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
if (rsp)
rsp->resid_len = job->reply_payload.payload_len;

mutex_lock(&lport->lp_mutex);

- switch (job->request->msgcode) {
+ switch (bsg_request->msgcode) {
case FC_BSG_RPT_ELS:
rport = job->rport;
if (!rport)
@@ -2117,7 +2120,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
break;

case FC_BSG_HST_CT:
- did = ntoh24(job->request->rqst_data.h_ct.port_id);
+ did = ntoh24(bsg_request->rqst_data.h_ct.port_id);
if (did == FC_FID_DIR_SERV) {
rdata = lport->dns_rdata;
if (!rdata)
@@ -2135,7 +2138,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
break;

case FC_BSG_HST_ELS_NOLOGIN:
- did = ntoh24(job->request->rqst_data.h_els.port_id);
+ did = ntoh24(bsg_request->rqst_data.h_els.port_id);
rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
break;
}
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 1002627..27b5930 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -299,6 +299,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
{
struct bsg_job_data *dd_data;
struct fc_bsg_job *job;
+ struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp, *cmp, *rmp;
struct lpfc_nodelist *ndlp;
@@ -313,6 +314,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
spin_lock_irqsave(&phba->ct_ev_lock, flags);
job = dd_data->set_job;
if (job) {
+ bsg_reply = job->reply;
/* Prevent timeout handling from trying to abort job */
job->dd_data = NULL;
}
@@ -351,7 +353,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
}
} else {
rsp_size = rsp->un.genreq64.bdl.bdeSize;
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
lpfc_bsg_copy_data(rmp, &job->reply_payload,
rsp_size, 0);
}
@@ -368,7 +370,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
/* Complete the job if the job is still active */

if (job) {
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->job_done(job);
}
return;
@@ -385,6 +387,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
struct lpfc_hba *phba = vport->phba;
struct lpfc_rport_data *rdata = job->rport->dd_data;
struct lpfc_nodelist *ndlp = rdata->pnode;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct ulp_bde64 *bpl = NULL;
uint32_t timeout;
struct lpfc_iocbq *cmdiocbq = NULL;
@@ -399,7 +402,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
int iocb_stat;

/* in case no data is transferred */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

/* allocate our bsg tracking structure */
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
@@ -543,7 +546,7 @@ no_ndlp:
kfree(dd_data);
no_dd_data:
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->dd_data = NULL;
return rc;
}
@@ -572,6 +575,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
{
struct bsg_job_data *dd_data;
struct fc_bsg_job *job;
+ struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_nodelist *ndlp;
struct lpfc_dmabuf *pcmd = NULL, *prsp = NULL;
@@ -589,6 +593,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
spin_lock_irqsave(&phba->ct_ev_lock, flags);
job = dd_data->set_job;
if (job) {
+ bsg_reply = job->reply;
/* Prevent timeout handling from trying to abort job */
job->dd_data = NULL;
}
@@ -610,17 +615,17 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
if (job) {
if (rsp->ulpStatus == IOSTAT_SUCCESS) {
rsp_size = rsp->un.elsreq64.bdl.bdeSize;
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
prsp->virt,
rsp_size);
} else if (rsp->ulpStatus == IOSTAT_LS_RJT) {
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sizeof(struct fc_bsg_ctels_reply);
/* LS_RJT data returned in word 4 */
rjt_data = (uint8_t *)&rsp->un.ulpWord[4];
- els_reply = &job->reply->reply_data.ctels_reply;
+ els_reply = &bsg_reply->reply_data.ctels_reply;
els_reply->status = FC_CTELS_STATUS_REJECT;
els_reply->rjt_data.action = rjt_data[3];
els_reply->rjt_data.reason_code = rjt_data[2];
@@ -638,7 +643,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
/* Complete the job if the job is still active */

if (job) {
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->job_done(job);
}
return;
@@ -655,6 +660,8 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
struct lpfc_hba *phba = vport->phba;
struct lpfc_rport_data *rdata = job->rport->dd_data;
struct lpfc_nodelist *ndlp = rdata->pnode;
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
uint32_t elscmd;
uint32_t cmdsize;
struct lpfc_iocbq *cmdiocbq;
@@ -665,7 +672,7 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
int rc = 0;

/* in case no data is transferred */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

/* verify the els command is not greater than the
* maximum ELS transfer size.
@@ -685,7 +692,7 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
goto no_dd_data;
}

- elscmd = job->request->rqst_data.r_els.els_code;
+ elscmd = bsg_request->rqst_data.r_els.els_code;
cmdsize = job->request_payload.payload_len;

if (!lpfc_nlp_get(ndlp)) {
@@ -772,7 +779,7 @@ free_dd_data:

no_dd_data:
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->dd_data = NULL;
return rc;
}
@@ -919,6 +926,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_hbq_entry *hbqe;
struct lpfc_sli_ct_request *ct_req;
struct fc_bsg_job *job = NULL;
+ struct fc_bsg_reply *bsg_reply;
struct bsg_job_data *dd_data = NULL;
unsigned long flags;
int size = 0;
@@ -1121,9 +1129,10 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
dd_data->set_job = NULL;
lpfc_bsg_event_unref(evt);
if (job) {
- job->reply->reply_payload_rcv_len = size;
+ bsg_reply = job->reply;
+ bsg_reply->reply_payload_rcv_len = size;
/* make error code available to userspace */
- job->reply->result = 0;
+ bsg_reply->result = 0;
job->dd_data = NULL;
/* complete the job back to userspace */
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
@@ -1192,6 +1201,7 @@ lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
struct lpfc_hba *phba = vport->phba;
+ struct fc_bsg_request *bsg_request = job->request;
struct set_ct_event *event_req;
struct lpfc_bsg_event *evt;
int rc = 0;
@@ -1209,7 +1219,7 @@ lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
}

event_req = (struct set_ct_event *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;
ev_mask = ((uint32_t)(unsigned long)event_req->type_mask &
FC_REG_EVENT_MASK);
spin_lock_irqsave(&phba->ct_ev_lock, flags);
@@ -1276,6 +1286,8 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
struct lpfc_hba *phba = vport->phba;
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct get_ct_event *event_req;
struct get_ct_event_reply *event_reply;
struct lpfc_bsg_event *evt, *evt_next;
@@ -1293,10 +1305,10 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
}

event_req = (struct get_ct_event *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;

event_reply = (struct get_ct_event_reply *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp;
spin_lock_irqsave(&phba->ct_ev_lock, flags);
list_for_each_entry_safe(evt, evt_next, &phba->ct_ev_waiters, node) {
if (evt->reg_id == event_req->ev_reg_id) {
@@ -1316,7 +1328,7 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
* an error indicating that there isn't anymore
*/
if (evt_dat == NULL) {
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
rc = -ENOENT;
goto job_error;
}
@@ -1332,12 +1344,12 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
event_reply->type = evt_dat->type;
event_reply->immed_data = evt_dat->immed_dat;
if (evt_dat->len > 0)
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->request_payload.sg_list,
job->request_payload.sg_cnt,
evt_dat->data, evt_dat->len);
else
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

if (evt_dat) {
kfree(evt_dat->data);
@@ -1348,13 +1360,13 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
lpfc_bsg_event_unref(evt);
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
job->dd_data = NULL;
- job->reply->result = 0;
+ bsg_reply->result = 0;
job->job_done(job);
return 0;

job_error:
job->dd_data = NULL;
- job->reply->result = rc;
+ bsg_reply->result = rc;
return rc;
}

@@ -1382,6 +1394,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
{
struct bsg_job_data *dd_data;
struct fc_bsg_job *job;
+ struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp, *cmp;
struct lpfc_nodelist *ndlp;
@@ -1412,6 +1425,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
/* Copy the completed job data or set the error status */

if (job) {
+ bsg_reply = job->reply;
if (rsp->ulpStatus) {
if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
switch (rsp->un.ulpWord[4] & IOERR_PARAM_MASK) {
@@ -1429,7 +1443,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
rc = -EACCES;
}
} else {
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
}
}

@@ -1443,7 +1457,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
/* Complete the job if the job is still active */

if (job) {
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->job_done(job);
}
return;
@@ -1608,8 +1622,10 @@ lpfc_bsg_send_mgmt_rsp(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
struct lpfc_hba *phba = vport->phba;
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct send_mgmt_resp *mgmt_resp = (struct send_mgmt_resp *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;
struct ulp_bde64 *bpl;
struct lpfc_dmabuf *bmp = NULL, *cmp = NULL;
int bpl_entries;
@@ -1619,7 +1635,7 @@ lpfc_bsg_send_mgmt_rsp(struct fc_bsg_job *job)
int rc = 0;

/* in case no data is transferred */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

if (!reqbfrcnt || (reqbfrcnt > (80 * BUF_SZ_4K))) {
rc = -ERANGE;
@@ -1665,7 +1681,7 @@ send_mgmt_rsp_free_bmp:
kfree(bmp);
send_mgmt_rsp_exit:
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->dd_data = NULL;
return rc;
}
@@ -1763,6 +1779,8 @@ lpfc_bsg_diag_mode_exit(struct lpfc_hba *phba)
static int
lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct diag_mode_set *loopback_mode;
uint32_t link_flags;
uint32_t timeout;
@@ -1772,7 +1790,7 @@ lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
int rc = 0;

/* no data to return just the return code */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

if (job->request_len < sizeof(struct fc_bsg_request) +
sizeof(struct diag_mode_set)) {
@@ -1792,7 +1810,7 @@ lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)

/* bring the link to diagnostic mode */
loopback_mode = (struct diag_mode_set *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;
link_flags = loopback_mode->type;
timeout = loopback_mode->timeout * 100;

@@ -1865,7 +1883,7 @@ loopback_mode_exit:

job_error:
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
job->job_done(job);
@@ -2018,12 +2036,14 @@ lpfc_sli4_diag_fcport_reg_setup(struct lpfc_hba *phba)
static int
lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct diag_mode_set *loopback_mode;
uint32_t link_flags, timeout;
int i, rc = 0;

/* no data to return just the return code */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

if (job->request_len < sizeof(struct fc_bsg_request) +
sizeof(struct diag_mode_set)) {
@@ -2055,7 +2075,7 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
"3129 Bring link to diagnostic state.\n");
loopback_mode = (struct diag_mode_set *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;
link_flags = loopback_mode->type;
timeout = loopback_mode->timeout * 100;

@@ -2152,7 +2172,7 @@ loopback_mode_exit:

job_error:
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
job->job_done(job);
@@ -2205,6 +2225,8 @@ lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job)
static int
lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct Scsi_Host *shost;
struct lpfc_vport *vport;
struct lpfc_hba *phba;
@@ -2233,7 +2255,7 @@ lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
phba->link_flag &= ~LS_LOOPBACK_MODE;
spin_unlock_irq(&phba->hbalock);
loopback_mode_end_cmd = (struct diag_mode_set *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;
timeout = loopback_mode_end_cmd->timeout * 100;

rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0);
@@ -2264,7 +2286,7 @@ lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)

loopback_mode_end_exit:
/* make return code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
job->job_done(job);
@@ -2281,6 +2303,8 @@ loopback_mode_end_exit:
static int
lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct Scsi_Host *shost;
struct lpfc_vport *vport;
struct lpfc_hba *phba;
@@ -2336,7 +2360,7 @@ lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
goto job_error;

link_diag_test_cmd = (struct sli4_link_diag *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;

rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1);

@@ -2386,7 +2410,7 @@ lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
}

diag_status_reply = (struct diag_status *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp;

if (job->reply_len <
sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) {
@@ -2414,7 +2438,7 @@ link_diag_test_exit:

job_error:
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
job->job_done(job);
@@ -2986,6 +3010,7 @@ static int
lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
struct lpfc_bsg_event *evt;
struct event_data *evdat;
@@ -3013,7 +3038,7 @@ lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
uint32_t total_mem;

/* in case no data is returned return just the return code */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

if (job->request_len <
sizeof(struct fc_bsg_request) + sizeof(struct diag_mode_test)) {
@@ -3238,11 +3263,11 @@ lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
rc = IOCB_SUCCESS;
/* skip over elx loopback header */
rx_databuf += ELX_LOOPBACK_HEADER_SZ;
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
rx_databuf, size);
- job->reply->reply_payload_rcv_len = size;
+ bsg_reply->reply_payload_rcv_len = size;
}
}

@@ -3272,7 +3297,7 @@ err_loopback_test_exit:
loopback_test_exit:
kfree(dataout);
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->dd_data = NULL;
/* complete the job back to userspace if no error */
if (rc == IOCB_SUCCESS)
@@ -3288,6 +3313,7 @@ static int
lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
struct get_mgmt_rev_reply *event_reply;
int rc = 0;
@@ -3302,7 +3328,7 @@ lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
}

event_reply = (struct get_mgmt_rev_reply *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp;

if (job->reply_len <
sizeof(struct fc_bsg_request) + sizeof(struct get_mgmt_rev_reply)) {
@@ -3316,7 +3342,7 @@ lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
event_reply->info.a_Major = MANAGEMENT_MAJOR_REV;
event_reply->info.a_Minor = MANAGEMENT_MINOR_REV;
job_error:
- job->reply->result = rc;
+ bsg_reply->result = rc;
if (rc == 0)
job->job_done(job);
return rc;
@@ -3337,6 +3363,7 @@ static void
lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
struct bsg_job_data *dd_data;
+ struct fc_bsg_reply *bsg_reply;
struct fc_bsg_job *job;
uint32_t size;
unsigned long flags;
@@ -3365,8 +3392,9 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
/* Copy the mailbox data to the job if it is still active */

if (job) {
+ bsg_reply = job->reply;
size = job->reply_payload.payload_len;
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
pmb_buf, size);
@@ -3380,7 +3408,7 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
/* Complete the job if the job is still active */

if (job) {
- job->reply->result = 0;
+ bsg_reply->result = 0;
job->job_done(job);
}
return;
@@ -3516,6 +3544,7 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
struct bsg_job_data *dd_data;
struct fc_bsg_job *job;
+ struct fc_bsg_reply *bsg_reply;
uint8_t *pmb, *pmb_buf;
unsigned long flags;
uint32_t size;
@@ -3530,6 +3559,7 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
spin_lock_irqsave(&phba->ct_ev_lock, flags);
job = dd_data->set_job;
if (job) {
+ bsg_reply = job->reply;
/* Prevent timeout handling from trying to abort job */
job->dd_data = NULL;
}
@@ -3560,13 +3590,13 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)

if (job) {
size = job->reply_payload.payload_len;
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
pmb_buf, size);

/* result for successful */
- job->reply->result = 0;
+ bsg_reply->result = 0;

lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
"2937 SLI_CONFIG ext-buffer maibox command "
@@ -3773,6 +3803,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
enum nemb_type nemb_tp,
struct lpfc_dmabuf *dmabuf)
{
+ struct fc_bsg_request *bsg_request = job->request;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
struct dfc_mbox_req *mbox_req;
struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf;
@@ -3785,7 +3816,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
int rc, i;

mbox_req =
- (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+ (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;

/* pointer to the start of mailbox command */
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
@@ -3960,6 +3991,8 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
enum nemb_type nemb_tp,
struct lpfc_dmabuf *dmabuf)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct dfc_mbox_req *mbox_req;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
uint32_t ext_buf_cnt;
@@ -3970,7 +4003,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
int rc = SLI_CONFIG_NOT_HANDLED, i;

mbox_req =
- (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+ (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;

/* pointer to the start of mailbox command */
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
@@ -4097,7 +4130,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,

/* wait for additoinal external buffers */

- job->reply->result = 0;
+ bsg_reply->result = 0;
job->job_done(job);
return SLI_CONFIG_HANDLED;

@@ -4271,6 +4304,7 @@ lpfc_bsg_mbox_ext_abort(struct lpfc_hba *phba)
static int
lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
{
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
struct lpfc_dmabuf *dmabuf;
uint8_t *pbuf;
@@ -4308,7 +4342,7 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
dmabuf, index);

pbuf = (uint8_t *)dmabuf->virt;
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
pbuf, size);
@@ -4322,7 +4356,7 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
lpfc_bsg_mbox_ext_session_reset(phba);
}

- job->reply->result = 0;
+ bsg_reply->result = 0;
job->job_done(job);

return SLI_CONFIG_HANDLED;
@@ -4340,6 +4374,7 @@ static int
lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
struct lpfc_dmabuf *dmabuf)
{
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct bsg_job_data *dd_data = NULL;
LPFC_MBOXQ_t *pmboxq = NULL;
MAILBOX_t *pmb;
@@ -4437,7 +4472,7 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
}

/* wait for additoinal external buffers */
- job->reply->result = 0;
+ bsg_reply->result = 0;
job->job_done(job);
return SLI_CONFIG_HANDLED;

@@ -4506,11 +4541,12 @@ static int
lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
struct lpfc_dmabuf *dmabuf)
{
+ struct fc_bsg_request *bsg_request = job->request;
struct dfc_mbox_req *mbox_req;
int rc = SLI_CONFIG_NOT_HANDLED;

mbox_req =
- (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+ (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;

/* mbox command with/without single external buffer */
if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0)
@@ -4583,6 +4619,8 @@ static int
lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
struct lpfc_vport *vport)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
LPFC_MBOXQ_t *pmboxq = NULL; /* internal mailbox queue */
MAILBOX_t *pmb; /* shortcut to the pmboxq mailbox */
/* a 4k buffer to hold the mb and extended data from/to the bsg */
@@ -4601,7 +4639,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
uint32_t size;

/* in case no data is transferred */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

/* sanity check to protect driver */
if (job->reply_payload.payload_len > BSG_MBOX_SIZE ||
@@ -4620,7 +4658,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
}

mbox_req =
- (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+ (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;

/* check if requested extended data lengths are valid */
if ((mbox_req->inExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t)) ||
@@ -4842,7 +4880,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,

/* job finished, copy the data */
memcpy(pmbx, pmb, sizeof(*pmb));
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
pmbx, size);
@@ -4874,12 +4912,14 @@ static int
lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
struct dfc_mbox_req *mbox_req;
int rc = 0;

/* mix-and-match backward compatibility */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
if (job->request_len <
sizeof(struct fc_bsg_request) + sizeof(struct dfc_mbox_req)) {
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
@@ -4890,7 +4930,7 @@ lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
sizeof(struct fc_bsg_request)),
(int)sizeof(struct dfc_mbox_req));
mbox_req = (struct dfc_mbox_req *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;
mbox_req->extMboxTag = 0;
mbox_req->extSeqNum = 0;
}
@@ -4899,7 +4939,7 @@ lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)

if (rc == 0) {
/* job done */
- job->reply->result = 0;
+ bsg_reply->result = 0;
job->dd_data = NULL;
job->job_done(job);
} else if (rc == 1)
@@ -4907,7 +4947,7 @@ lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
rc = 0; /* return zero, no error */
else {
/* some error occurred */
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->dd_data = NULL;
}

@@ -4938,6 +4978,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
{
struct bsg_job_data *dd_data;
struct fc_bsg_job *job;
+ struct fc_bsg_reply *bsg_reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp, *cmp, *rmp;
struct lpfc_bsg_menlo *menlo;
@@ -4957,6 +4998,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
spin_lock_irqsave(&phba->ct_ev_lock, flags);
job = dd_data->set_job;
if (job) {
+ bsg_reply = job->reply;
/* Prevent timeout handling from trying to abort job */
job->dd_data = NULL;
}
@@ -4971,7 +5013,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
*/

menlo_resp = (struct menlo_response *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp;
menlo_resp->xri = rsp->ulpContext;
if (rsp->ulpStatus) {
if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
@@ -4991,7 +5033,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
}
} else {
rsp_size = rsp->un.genreq64.bdl.bdeSize;
- job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
lpfc_bsg_copy_data(rmp, &job->reply_payload,
rsp_size, 0);
}
@@ -5008,7 +5050,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
/* Complete the job if active */

if (job) {
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->job_done(job);
}

@@ -5028,6 +5070,8 @@ static int
lpfc_menlo_cmd(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
struct lpfc_iocbq *cmdiocbq;
IOCB_t *cmd;
@@ -5040,7 +5084,7 @@ lpfc_menlo_cmd(struct fc_bsg_job *job)
struct ulp_bde64 *bpl = NULL;

/* in case no data is returned return just the return code */
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

if (job->request_len <
sizeof(struct fc_bsg_request) +
@@ -5070,7 +5114,7 @@ lpfc_menlo_cmd(struct fc_bsg_job *job)
}

menlo_cmd = (struct menlo_command *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ bsg_request->rqst_data.h_vendor.vendor_cmd;

/* allocate our bsg tracking structure */
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
@@ -5181,7 +5225,7 @@ free_dd:
kfree(dd_data);
no_dd_data:
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
job->dd_data = NULL;
return rc;
}
@@ -5193,7 +5237,9 @@ no_dd_data:
static int
lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
{
- int command = job->request->rqst_data.h_vendor.vendor_cmd[0];
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
+ int command = bsg_request->rqst_data.h_vendor.vendor_cmd[0];
int rc;

switch (command) {
@@ -5230,9 +5276,9 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
break;
default:
rc = -EINVAL;
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
break;
}

@@ -5246,10 +5292,12 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
int
lpfc_bsg_request(struct fc_bsg_job *job)
{
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
uint32_t msgcode;
int rc;

- msgcode = job->request->msgcode;
+ msgcode = bsg_request->msgcode;
switch (msgcode) {
case FC_BSG_HST_VENDOR:
rc = lpfc_bsg_hst_vendor(job);
@@ -5262,9 +5310,9 @@ lpfc_bsg_request(struct fc_bsg_job *job)
break;
default:
rc = -EINVAL;
- job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
/* make error code available to userspace */
- job->reply->result = rc;
+ bsg_reply->result = rc;
break;
}

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 643014f..40f7c10 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -17,8 +17,9 @@ qla2x00_bsg_job_done(void *data, void *ptr, int res)
srb_t *sp = (srb_t *)ptr;
struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;

- bsg_job->reply->result = res;
+ bsg_reply->result = res;
bsg_job->job_done(bsg_job);
sp->free(vha, sp);
}
@@ -29,12 +30,14 @@ qla2x00_bsg_sp_free(void *data, void *ptr)
srb_t *sp = (srb_t *)ptr;
struct scsi_qla_host *vha = sp->fcport->vha;
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+
struct qla_hw_data *ha = vha->hw;
struct qla_mt_iocb_rqst_fx00 *piocb_rqst;

if (sp->type == SRB_FXIOCB_BCMD) {
piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
- &bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ &bsg_request->rqst_data.h_vendor.vendor_cmd[1];

if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
dma_unmap_sg(&ha->pdev->dev,
@@ -119,6 +122,8 @@ static int
qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
{
struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int ret = 0;
@@ -131,7 +136,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
}

/* Get the sub command */
- oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];

/* Only set config is allowed if config memory is not allocated */
if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
@@ -145,10 +150,10 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
ha->fcp_prio_cfg->attributes &=
~FCP_PRIO_ATTR_ENABLE;
qla24xx_update_all_fcp_prio(vha);
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
} else {
ret = -EINVAL;
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->result = (DID_ERROR << 16);
goto exit_fcp_prio_cfg;
}
break;
@@ -160,10 +165,10 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
ha->fcp_prio_cfg->attributes |=
FCP_PRIO_ATTR_ENABLE;
qla24xx_update_all_fcp_prio(vha);
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
} else {
ret = -EINVAL;
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->result = (DID_ERROR << 16);
goto exit_fcp_prio_cfg;
}
}
@@ -173,12 +178,12 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
len = bsg_job->reply_payload.payload_len;
if (!len || len > FCP_PRIO_CFG_SIZE) {
ret = -EINVAL;
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->result = (DID_ERROR << 16);
goto exit_fcp_prio_cfg;
}

- bsg_job->reply->result = DID_OK;
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->result = DID_OK;
+ bsg_reply->reply_payload_rcv_len =
sg_copy_from_buffer(
bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
@@ -189,7 +194,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
case QLFC_FCP_PRIO_SET_CONFIG:
len = bsg_job->request_payload.payload_len;
if (!len || len > FCP_PRIO_CFG_SIZE) {
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->result = (DID_ERROR << 16);
ret = -EINVAL;
goto exit_fcp_prio_cfg;
}
@@ -200,7 +205,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
ql_log(ql_log_warn, vha, 0x7050,
"Unable to allocate memory for fcp prio "
"config data (%x).\n", FCP_PRIO_CFG_SIZE);
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->result = (DID_ERROR << 16);
ret = -ENOMEM;
goto exit_fcp_prio_cfg;
}
@@ -215,7 +220,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)

if (!qla24xx_fcp_prio_cfg_valid(vha,
(struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) {
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->result = (DID_ERROR << 16);
ret = -EINVAL;
/* If buffer was invalidatic int
* fcp_prio_cfg is of no use
@@ -229,7 +234,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
ha->flags.fcp_prio_enabled = 1;
qla24xx_update_all_fcp_prio(vha);
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
break;
default:
ret = -EINVAL;
@@ -244,6 +249,7 @@ exit_fcp_prio_cfg:
static int
qla2x00_process_els(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_rport *rport;
fc_port_t *fcport = NULL;
struct Scsi_Host *host;
@@ -255,7 +261,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
int rval = (DRIVER_ERROR << 16);
uint16_t nextlid = 0;

- if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
+ if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
rport = bsg_job->rport;
fcport = *(fc_port_t **) rport->dd_data;
host = rport_to_shost(rport);
@@ -296,7 +302,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
}

/* ELS request for rport */
- if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
+ if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
/* make sure the rport is logged in,
* if not perform fabric login
*/
@@ -322,11 +328,11 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
/* Initialize all required fields of fcport */
fcport->vha = vha;
fcport->d_id.b.al_pa =
- bsg_job->request->rqst_data.h_els.port_id[0];
+ bsg_request->rqst_data.h_els.port_id[0];
fcport->d_id.b.area =
- bsg_job->request->rqst_data.h_els.port_id[1];
+ bsg_request->rqst_data.h_els.port_id[1];
fcport->d_id.b.domain =
- bsg_job->request->rqst_data.h_els.port_id[2];
+ bsg_request->rqst_data.h_els.port_id[2];
fcport->loop_id =
(fcport->d_id.b.al_pa == 0xFD) ?
NPH_FABRIC_CONTROLLER : NPH_F_PORT;
@@ -366,11 +372,11 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
}

sp->type =
- (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
- SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
+ (bsg_request->msgcode == FC_BSG_RPT_ELS ?
+ SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
sp->name =
- (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
- "bsg_els_rpt" : "bsg_els_hst");
+ (bsg_request->msgcode == FC_BSG_RPT_ELS ?
+ "bsg_els_rpt" : "bsg_els_hst");
sp->u.bsg_job = bsg_job;
sp->free = qla2x00_bsg_sp_free;
sp->done = qla2x00_bsg_job_done;
@@ -378,7 +384,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
ql_dbg(ql_dbg_user, vha, 0x700a,
"bsg rqst type: %s els type: %x - loop-id=%x "
"portid=%-2x%02x%02x.\n", type,
- bsg_job->request->rqst_data.h_els.command_code, fcport->loop_id,
+ bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);

rval = qla2x00_start_sp(sp);
@@ -399,7 +405,7 @@ done_unmap_sg:
goto done_free_fcport;

done_free_fcport:
- if (bsg_job->request->msgcode == FC_BSG_RPT_ELS)
+ if (bsg_request->msgcode == FC_BSG_RPT_ELS)
kfree(fcport);
done:
return rval;
@@ -423,6 +429,7 @@ static int
qla2x00_process_ct(struct fc_bsg_job *bsg_job)
{
srb_t *sp;
+ struct fc_bsg_request *bsg_request = bsg_job->request;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -469,7 +476,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
}

loop_id =
- (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
+ (bsg_request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
>> 24;
switch (loop_id) {
case 0xFC:
@@ -500,9 +507,9 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)

/* Initialize all required fields of fcport */
fcport->vha = vha;
- fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0];
- fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1];
- fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2];
+ fcport->d_id.b.al_pa = bsg_request->rqst_data.h_ct.port_id[0];
+ fcport->d_id.b.area = bsg_request->rqst_data.h_ct.port_id[1];
+ fcport->d_id.b.domain = bsg_request->rqst_data.h_ct.port_id[2];
fcport->loop_id = loop_id;

/* Alloc SRB structure */
@@ -524,7 +531,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
ql_dbg(ql_dbg_user, vha, 0x7016,
"bsg rqst type: %s else type: %x - "
"loop-id=%x portid=%02x%02x%02x.\n", type,
- (bsg_job->request->rqst_data.h_ct.preamble_word2 >> 16),
+ (bsg_request->rqst_data.h_ct.preamble_word2 >> 16),
fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);

@@ -699,6 +706,8 @@ done_set_internal:
static int
qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -780,9 +789,9 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
elreq.rcv_dma = rsp_data_dma;
elreq.transfer_size = req_data_len;

- elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ elreq.options = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
elreq.iteration_count =
- bsg_job->request->rqst_data.h_vendor.vendor_cmd[2];
+ bsg_request->rqst_data.h_vendor.vendor_cmd[2];

if (atomic_read(&vha->loop_state) == LOOP_READY &&
(ha->current_topology == ISP_CFG_F ||
@@ -896,12 +905,12 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
"Vendor request %s failed.\n", type);

rval = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
+ bsg_reply->reply_payload_rcv_len = 0;
} else {
ql_dbg(ql_dbg_user, vha, 0x702d,
"Vendor request %s completed.\n", type);
- bsg_job->reply->result = (DID_OK << 16);
+ bsg_reply->result = (DID_OK << 16);
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, rsp_data,
rsp_data_len);
@@ -937,7 +946,9 @@ done_unmap_req_sg:
static int
qla84xx_reset(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -948,7 +959,7 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
return -EINVAL;
}

- flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];

rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);

@@ -960,7 +971,7 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
} else {
ql_dbg(ql_dbg_user, vha, 0x7031,
"Vendor request 84xx reset completed.\n");
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
bsg_job->job_done(bsg_job);
}

@@ -970,6 +981,8 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
static int
qla84xx_updatefw(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1027,7 +1040,7 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job)
goto done_free_fw_buf;
}

- flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2)));

memset(mn, 0, sizeof(struct access_chip_84xx));
@@ -1059,7 +1072,7 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job)
"Vendor request 84xx updatefw completed.\n");

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
}

dma_pool_free(ha->s_dma_pool, mn, mn_dma);
@@ -1079,6 +1092,8 @@ done_unmap_sg:
static int
qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1107,7 +1122,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
memset(mn, 0, sizeof(struct access_chip_84xx));
mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
mn->entry_count = 1;
- ql84_mgmt = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
+ ql84_mgmt = (void *)bsg_request + sizeof(struct fc_bsg_request);
switch (ql84_mgmt->mgmt.cmd) {
case QLA84_MGMT_READ_MEM:
case QLA84_MGMT_GET_INFO:
@@ -1239,11 +1254,11 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
"Vendor request 84xx mgmt completed.\n");

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;

if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) ||
(ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) {
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
bsg_job->reply_payload.payload_len;

sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
@@ -1274,6 +1289,8 @@ exit_mgmt:
static int
qla24xx_iidma(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
int rval = 0;
@@ -1288,7 +1305,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
return -EINVAL;
}

- port_param = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
+ port_param = (void *)bsg_request + sizeof(struct fc_bsg_request);
if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
ql_log(ql_log_warn, vha, 0x7048,
"Invalid destination type.\n");
@@ -1343,14 +1360,14 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
sizeof(struct qla_port_param);

- rsp_ptr = ((uint8_t *)bsg_job->reply) +
+ rsp_ptr = ((uint8_t *)bsg_reply) +
sizeof(struct fc_bsg_reply);

memcpy(rsp_ptr, port_param,
sizeof(struct qla_port_param));
}

- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
bsg_job->job_done(bsg_job);
}

@@ -1361,6 +1378,7 @@ static int
qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
uint8_t is_update)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
uint32_t start = 0;
int valid = 0;
struct qla_hw_data *ha = vha->hw;
@@ -1368,7 +1386,7 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
if (unlikely(pci_channel_offline(ha->pdev)))
return -EINVAL;

- start = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ start = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
if (start > ha->optrom_size) {
ql_log(ql_log_warn, vha, 0x7055,
"start %d > optrom_size %d.\n", start, ha->optrom_size);
@@ -1429,6 +1447,7 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
static int
qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1451,8 +1470,8 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
ha->optrom_region_size);

- bsg_job->reply->reply_payload_rcv_len = ha->optrom_region_size;
- bsg_job->reply->result = DID_OK;
+ bsg_reply->reply_payload_rcv_len = ha->optrom_region_size;
+ bsg_reply->result = DID_OK;
vfree(ha->optrom_buffer);
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
@@ -1464,6 +1483,7 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
static int
qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1486,7 +1506,7 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
ha->optrom_region_start, ha->optrom_region_size);

- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
vfree(ha->optrom_buffer);
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
@@ -1498,6 +1518,7 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
static int
qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1509,7 +1530,7 @@ qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
dma_addr_t sfp_dma;
void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
if (!sfp) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
goto done;
}
@@ -1525,21 +1546,21 @@ qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
image->field_address.device, image->field_address.offset,
sizeof(image->field_info), image->field_address.option);
if (rval) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_MAILBOX;
goto dealloc;
}
image++;
}

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;

dealloc:
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);

done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);

return 0;
@@ -1548,6 +1569,7 @@ done:
static int
qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1557,7 +1579,7 @@ qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
if (!sfp) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
goto done;
}
@@ -1571,7 +1593,7 @@ qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
sr->status_reg = *sfp;

if (rval) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_MAILBOX;
goto dealloc;
}
@@ -1579,15 +1601,15 @@ qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;

dealloc:
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);

done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->reply_payload_rcv_len = sizeof(*sr);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->reply_payload_rcv_len = sizeof(*sr);
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);

return 0;
@@ -1596,6 +1618,7 @@ done:
static int
qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1605,7 +1628,7 @@ qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
if (!sfp) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
goto done;
}
@@ -1619,19 +1642,19 @@ qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
sizeof(sr->status_reg), sr->field_address.option);

if (rval) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_MAILBOX;
goto dealloc;
}

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;

dealloc:
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);

done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);

return 0;
@@ -1640,6 +1663,7 @@ done:
static int
qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1649,7 +1673,7 @@ qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
if (!sfp) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
goto done;
}
@@ -1662,19 +1686,19 @@ qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
i2c->device, i2c->offset, i2c->length, i2c->option);

if (rval) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_MAILBOX;
goto dealloc;
}

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;

dealloc:
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);

done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);

return 0;
@@ -1683,6 +1707,7 @@ done:
static int
qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1692,7 +1717,7 @@ qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
if (!sfp) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
goto done;
}
@@ -1704,7 +1729,7 @@ qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
i2c->device, i2c->offset, i2c->length, i2c->option);

if (rval) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_MAILBOX;
goto dealloc;
}
@@ -1713,15 +1738,15 @@ qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;

dealloc:
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);

done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->reply_payload_rcv_len = sizeof(*i2c);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);

return 0;
@@ -1730,6 +1755,7 @@ done:
static int
qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1895,10 +1921,10 @@ done:
/* Return an error vendor specific response
* and complete the bsg request
*/
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->reply_payload_rcv_len = 0;
- bsg_job->reply->result = (DID_OK) << 16;
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_OK) << 16;
bsg_job->job_done(bsg_job);
/* Always return success, vendor rsp carries correct status */
return 0;
@@ -1907,6 +1933,7 @@ done:
static int
qlafx00_mgmt_cmd(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -1919,7 +1946,7 @@ qlafx00_mgmt_cmd(struct fc_bsg_job *bsg_job)

/* Copy the IOCB specific information */
piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
- &bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ &bsg_request->rqst_data.h_vendor.vendor_cmd[1];

/* Dump the vendor information */
ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf,
@@ -2029,6 +2056,7 @@ done:
static int
qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
int rval = 0;
@@ -2042,13 +2070,13 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
switch (sr.cmd) {
case INT_SC_SERDES_WRITE_REG:
rval = qla2x00_write_serdes_word(vha, sr.addr, sr.val);
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
break;
case INT_SC_SERDES_READ_REG:
rval = qla2x00_read_serdes_word(vha, sr.addr, &sr.val);
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
- bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
+ bsg_reply->reply_payload_rcv_len = sizeof(sr);
break;
default:
ql_dbg(ql_dbg_user, vha, 0x708c,
@@ -2057,11 +2085,11 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
break;
}

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
rval ? EXT_STATUS_MAILBOX : 0;

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);
return 0;
}
@@ -2069,6 +2097,7 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
static int
qla8044_serdes_op(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
int rval = 0;
@@ -2082,13 +2111,13 @@ qla8044_serdes_op(struct fc_bsg_job *bsg_job)
switch (sr.cmd) {
case INT_SC_SERDES_WRITE_REG:
rval = qla8044_write_serdes_word(vha, sr.addr, sr.val);
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
break;
case INT_SC_SERDES_READ_REG:
rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val);
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
- bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
+ bsg_reply->reply_payload_rcv_len = sizeof(sr);
break;
default:
ql_dbg(ql_dbg_user, vha, 0x70cf,
@@ -2097,11 +2126,11 @@ qla8044_serdes_op(struct fc_bsg_job *bsg_job)
break;
}

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
rval ? EXT_STATUS_MAILBOX : 0;

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);
return 0;
}
@@ -2109,6 +2138,7 @@ qla8044_serdes_op(struct fc_bsg_job *bsg_job)
static int
qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -2125,13 +2155,13 @@ qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)

sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, &cap, sizeof(cap));
- bsg_job->reply->reply_payload_rcv_len = sizeof(cap);
+ bsg_reply->reply_payload_rcv_len = sizeof(cap);

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_OK;

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);
return 0;
}
@@ -2139,6 +2169,7 @@ qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
static int
qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -2158,24 +2189,24 @@ qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
(uint64_t)ha->fw_attributes;

if (online_fw_attr != cap.capabilities) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_INVALID_PARAM;
return -EINVAL;
}

if (cap.outage_duration < MAX_LOOP_TIMEOUT) {
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_INVALID_PARAM;
return -EINVAL;
}

- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_OK;

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);
return 0;
}
@@ -2183,6 +2214,7 @@ qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
static int
qla27xx_get_bbcr_data(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -2227,12 +2259,12 @@ qla27xx_get_bbcr_data(struct fc_bsg_job *bsg_job)
done:
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, &bbcr, sizeof(bbcr));
- bsg_job->reply->reply_payload_rcv_len = sizeof(bbcr);
+ bsg_reply->reply_payload_rcv_len = sizeof(bbcr);

- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);
return 0;
}
@@ -2240,6 +2272,8 @@ done:
static int
qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -2247,7 +2281,7 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
struct link_statistics *stats = NULL;
dma_addr_t stats_dma;
int rval;
- uint32_t *cmd = bsg_job->request->rqst_data.h_vendor.vendor_cmd;
+ uint32_t *cmd = bsg_request->rqst_data.h_vendor.vendor_cmd;
uint options = cmd[0] == QL_VND_GET_PRIV_STATS_EX ? cmd[1] : 0;

if (test_bit(UNLOADING, &vha->dpc_flags))
@@ -2281,12 +2315,12 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats));
}

- bsg_job->reply->reply_payload_rcv_len = sizeof(*stats);
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_payload_rcv_len = sizeof(*stats);
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;

- bsg_job->reply_len = sizeof(*bsg_job->reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_job->reply_len = sizeof(*bsg_reply);
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);

dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
@@ -2298,6 +2332,7 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
static int
qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
struct Scsi_Host *host = bsg_job->shost;
scsi_qla_host_t *vha = shost_priv(host);
int rval;
@@ -2323,12 +2358,12 @@ qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
}

- bsg_job->reply->reply_payload_rcv_len = sizeof(*dd);
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ bsg_reply->reply_payload_rcv_len = sizeof(*dd);
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;

- bsg_job->reply_len = sizeof(*bsg_job->reply);
- bsg_job->reply->result = DID_OK << 16;
+ bsg_job->reply_len = sizeof(*bsg_reply);
+ bsg_reply->result = DID_OK << 16;
bsg_job->job_done(bsg_job);

kfree(dd);
@@ -2339,7 +2374,9 @@ qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
static int
qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
{
- switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+
+ switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
case QL_VND_LOOPBACK:
return qla2x00_process_loopback(bsg_job);

@@ -2415,15 +2452,17 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
int
qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_request = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
int ret = -EINVAL;
struct fc_rport *rport;
struct Scsi_Host *host;
scsi_qla_host_t *vha;

/* In case no data transferred. */
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

- if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
+ if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
rport = bsg_job->rport;
host = rport_to_shost(rport);
vha = shost_priv(host);
@@ -2435,14 +2474,14 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
if (qla2x00_reset_active(vha)) {
ql_dbg(ql_dbg_user, vha, 0x709f,
"BSG: ISP abort active/needed -- cmd=%d.\n",
- bsg_job->request->msgcode);
+ bsg_request->msgcode);
return -EBUSY;
}

ql_dbg(ql_dbg_user, vha, 0x7000,
- "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode);
+ "Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);

- switch (bsg_job->request->msgcode) {
+ switch (bsg_request->msgcode) {
case FC_BSG_RPT_ELS:
case FC_BSG_HST_ELS_NOLOGIN:
ret = qla2x00_process_els(bsg_job);
@@ -2466,6 +2505,7 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
int
qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
{
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
struct qla_hw_data *ha = vha->hw;
srb_t *sp;
@@ -2494,13 +2534,13 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
"mbx abort_command "
"failed.\n");
bsg_job->req->errors =
- bsg_job->reply->result = -EIO;
+ bsg_reply->result = -EIO;
} else {
ql_dbg(ql_dbg_user, vha, 0x708a,
"mbx abort_command "
"success.\n");
bsg_job->req->errors =
- bsg_job->reply->result = 0;
+ bsg_reply->result = 0;
}
spin_lock_irqsave(&ha->hardware_lock, flags);
goto done;
@@ -2510,7 +2550,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
- bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
+ bsg_job->req->errors = bsg_reply->result = -ENXIO;
return 0;

done:
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index b41265a..6929fda 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2198,6 +2198,7 @@ static void
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
{
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+ struct fc_bsg_request *bsg_request = bsg_job->request;

els_iocb->entry_type = ELS_IOCB_TYPE;
els_iocb->entry_count = 1;
@@ -2212,8 +2213,8 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)

els_iocb->opcode =
sp->type == SRB_ELS_CMD_RPT ?
- bsg_job->request->rqst_data.r_els.els_code :
- bsg_job->request->rqst_data.h_els.command_code;
+ bsg_request->rqst_data.r_els.els_code :
+ bsg_request->rqst_data.h_els.command_code;
els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
els_iocb->port_id[1] = sp->fcport->d_id.b.area;
els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 987f1c7..1adaad3 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1357,6 +1357,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
const char *type;
srb_t *sp;
struct fc_bsg_job *bsg_job;
+ struct fc_bsg_reply *bsg_reply;
uint16_t comp_status;
int res;

@@ -1365,6 +1366,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
return;

bsg_job = sp->u.bsg_job;
+ bsg_reply = bsg_job->reply;

type = "ct pass-through";

@@ -1373,32 +1375,32 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
* fc payload to the caller
*/
- bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+ bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
bsg_job->reply_len = sizeof(struct fc_bsg_reply);

if (comp_status != CS_COMPLETE) {
if (comp_status == CS_DATA_UNDERRUN) {
res = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);

ql_log(ql_log_warn, vha, 0x5048,
"CT pass-through-%s error "
"comp_status-status=0x%x total_byte = 0x%x.\n",
type, comp_status,
- bsg_job->reply->reply_payload_rcv_len);
+ bsg_reply->reply_payload_rcv_len);
} else {
ql_log(ql_log_warn, vha, 0x5049,
"CT pass-through-%s error "
"comp_status-status=0x%x.\n", type, comp_status);
res = DID_ERROR << 16;
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
}
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035,
(uint8_t *)pkt, sizeof(*pkt));
} else {
res = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0;
}
@@ -1414,6 +1416,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
const char *type;
srb_t *sp;
struct fc_bsg_job *bsg_job;
+ struct fc_bsg_reply *bsg_reply;
uint16_t comp_status;
uint32_t fw_status[3];
uint8_t* fw_sts_ptr;
@@ -1423,6 +1426,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
if (!sp)
return;
bsg_job = sp->u.bsg_job;
+ bsg_reply = bsg_job->reply;

type = NULL;
switch (sp->type) {
@@ -1452,13 +1456,13 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
* fc payload to the caller
*/
- bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+ bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status);

if (comp_status != CS_COMPLETE) {
if (comp_status == CS_DATA_UNDERRUN) {
res = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->total_byte_count);

ql_dbg(ql_dbg_user, vha, 0x503f,
@@ -1480,7 +1484,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
le16_to_cpu(((struct els_sts_entry_24xx *)
pkt)->error_subcode_2));
res = DID_ERROR << 16;
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
}
@@ -1489,7 +1493,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
}
else {
res = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
+ bsg_reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0;
}

@@ -1905,6 +1909,8 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
uint16_t thread_id;
uint32_t rval = EXT_STATUS_OK;
struct fc_bsg_job *bsg_job = NULL;
+ struct fc_bsg_request *bsg_request;
+ struct fc_bsg_reply *bsg_reply;
sts_entry_t *sts;
struct sts_entry_24xx *sts24;
sts = (sts_entry_t *) pkt;
@@ -1919,11 +1925,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
}

sp = req->outstanding_cmds[index];
- if (sp) {
- /* Free outstanding command slot. */
- req->outstanding_cmds[index] = NULL;
- bsg_job = sp->u.bsg_job;
- } else {
+ if (!sp) {
ql_log(ql_log_warn, vha, 0x70b0,
"Req:%d: Invalid ISP SCSI completion handle(0x%x)\n",
req->id, index);
@@ -1932,6 +1934,12 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
return;
}

+ /* Free outstanding command slot. */
+ req->outstanding_cmds[index] = NULL;
+ bsg_job = sp->u.bsg_job;
+ bsg_request = bsg_job->request;
+ bsg_reply = bsg_job->reply;
+
if (IS_FWI2_CAPABLE(ha)) {
comp_status = le16_to_cpu(sts24->comp_status);
scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
@@ -1940,14 +1948,14 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
}

- thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ thread_id = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
switch (comp_status) {
case CS_COMPLETE:
if (scsi_status == 0) {
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
bsg_job->reply_payload.payload_len;
vha->qla_stats.input_bytes +=
- bsg_job->reply->reply_payload_rcv_len;
+ bsg_reply->reply_payload_rcv_len;
vha->qla_stats.input_requests++;
rval = EXT_STATUS_OK;
}
@@ -2028,11 +2036,11 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
rval = EXT_STATUS_ERR;
break;
}
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;

done:
/* Return the vendor specific reply to API */
- bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
/* Always return DID_OK, bsg will send the vendor specific response
* in this case only */
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 15dff70..b597d04 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -2207,6 +2207,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
const char func[] = "IOSB_IOCB";
srb_t *sp;
struct fc_bsg_job *bsg_job;
+ struct fc_bsg_reply *bsg_reply;
struct srb_iocb *iocb_job;
int res;
struct qla_mt_iocb_rsp_fx00 fstatus;
@@ -2226,6 +2227,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
pkt->dataword_r;
} else {
bsg_job = sp->u.bsg_job;
+ bsg_reply = bsg_job->reply;

memset(&fstatus, 0, sizeof(struct qla_mt_iocb_rsp_fx00));

@@ -2257,8 +2259,8 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
sp->fcport->vha, 0x5074,
(uint8_t *)fw_sts_ptr, sizeof(struct qla_mt_iocb_rsp_fx00));

- res = bsg_job->reply->result = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len =
+ res = bsg_reply->result = DID_OK << 16;
+ bsg_reply->reply_payload_rcv_len =
bsg_job->reply_payload.payload_len;
}
sp->done(vha, sp, res);
@@ -3253,6 +3255,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
struct srb_iocb *fxio = &sp->u.iocb_cmd;
struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
struct fc_bsg_job *bsg_job;
+ struct fc_bsg_request *bsg_request;
struct fxdisc_entry_fx00 fx_iocb;
uint8_t entry_cnt = 1;

@@ -3301,8 +3304,9 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
} else {
struct scatterlist *sg;
bsg_job = sp->u.bsg_job;
+ bsg_request = bsg_job->request;
piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
- &bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ &bsg_request->rqst_data.h_vendor.vendor_cmd[1];

fx_iocb.func_num = piocb_rqst->func_type;
fx_iocb.adapid = piocb_rqst->adapid;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 8ff2067..eafc7555 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3588,9 +3588,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
{
struct request *req = job->req;
struct request *rsp = req->next_rq;
+ struct fc_bsg_reply *bsg_reply = job->reply;
int err;

- err = job->req->errors = job->reply->result;
+ err = job->req->errors = bsg_reply->result;

if (err < 0)
/* we're only returning the result field in the reply */
@@ -3602,10 +3603,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
req->resid_len = 0;

if (rsp) {
- WARN_ON(job->reply->reply_payload_rcv_len > rsp->resid_len);
+ WARN_ON(bsg_reply->reply_payload_rcv_len > rsp->resid_len);

/* set reply (bidi) residual */
- rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
+ rsp->resid_len -= min(bsg_reply->reply_payload_rcv_len,
rsp->resid_len);
}
blk_complete_request(req);
@@ -3701,6 +3702,8 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
struct fc_internal *i = to_fc_internal(shost->transportt);
struct request *rsp = req->next_rq;
struct fc_bsg_job *job;
+ struct fc_bsg_request *bsg_request;
+ struct fc_bsg_reply *bsg_reply;
int ret;

BUG_ON(req->special);
@@ -3726,9 +3729,9 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
if (i->f->dd_bsg_size)
job->dd_data = (void *)&job[1];
spin_lock_init(&job->job_lock);
- job->request = (struct fc_bsg_request *)req->cmd;
+ bsg_request = (struct fc_bsg_request *)req->cmd;
job->request_len = req->cmd_len;
- job->reply = req->sense;
+ bsg_reply = req->sense;
job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
* allocated */
if (req->bio) {
@@ -3779,11 +3782,13 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
struct fc_bsg_job *job)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
int ret;

/* Validate the host command */
- switch (job->request->msgcode) {
+ switch (bsg_request->msgcode) {
case FC_BSG_HST_ADD_RPORT:
cmdlen += sizeof(struct fc_bsg_host_add_rport);
break;
@@ -3815,7 +3820,7 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
case FC_BSG_HST_VENDOR:
cmdlen += sizeof(struct fc_bsg_host_vendor);
if ((shost->hostt->vendor_id == 0L) ||
- (job->request->rqst_data.h_vendor.vendor_id !=
+ (bsg_request->rqst_data.h_vendor.vendor_id !=
shost->hostt->vendor_id)) {
ret = -ESRCH;
goto fail_host_msg;
@@ -3840,8 +3845,8 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
fail_host_msg:
/* return the errno failure code as the only status */
BUG_ON(job->reply_len < sizeof(uint32_t));
- job->reply->reply_payload_rcv_len = 0;
- job->reply->result = ret;
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = ret;
job->reply_len = sizeof(uint32_t);
fc_bsg_jobdone(job);
return FC_DISPATCH_UNLOCKED;
@@ -3878,11 +3883,13 @@ fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
struct fc_rport *rport, struct fc_bsg_job *job)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct fc_bsg_request *bsg_request = job->request;
+ struct fc_bsg_reply *bsg_reply = job->reply;
int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
int ret;

/* Validate the rport command */
- switch (job->request->msgcode) {
+ switch (bsg_request->msgcode) {
case FC_BSG_RPT_ELS:
cmdlen += sizeof(struct fc_bsg_rport_els);
goto check_bidi;
@@ -3915,8 +3922,8 @@ check_bidi:
fail_rport_msg:
/* return the errno failure code as the only status */
BUG_ON(job->reply_len < sizeof(uint32_t));
- job->reply->reply_payload_rcv_len = 0;
- job->reply->result = ret;
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = ret;
job->reply_len = sizeof(uint32_t);
fc_bsg_jobdone(job);
return FC_DISPATCH_UNLOCKED;
@@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
struct request *req;
struct fc_bsg_job *job;
enum fc_dispatch_result ret;
+ struct fc_bsg_reply *bsg_reply;

if (!get_device(dev))
return;
@@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
/* check if we have the msgcode value at least */
if (job->request_len < sizeof(uint32_t)) {
BUG_ON(job->reply_len < sizeof(uint32_t));
- job->reply->reply_payload_rcv_len = 0;
- job->reply->result = -ENOMSG;
+ bsg_reply = job->reply;
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = -ENOMSG;
job->reply_len = sizeof(uint32_t);
fc_bsg_jobdone(job);
spin_lock_irq(q->queue_lock);
--
1.8.5.6

2016-10-12 13:12:38

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 06/16] scsi: fc: provide fc_bsg_to_rport() helper

Provide fc_bsg_to_rport() helper that will become handy when we're moving
from struct fc_bsg_job to a plain struct bsg_job. Also move all LLDDs to use
the new helper.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/s390/scsi/zfcp_fc.c | 5 +++--
drivers/scsi/ibmvscsi/ibmvfc.c | 2 +-
drivers/scsi/libfc/fc_lport.c | 4 ++--
drivers/scsi/lpfc/lpfc_bsg.c | 4 ++--
drivers/scsi/qla2xxx/qla_bsg.c | 4 ++--
drivers/scsi/scsi_transport_fc.c | 3 ++-
include/scsi/scsi_transport_fc.h | 5 +++++
7 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 813c286..1977a66 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -938,7 +938,7 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
struct zfcp_adapter *adapter)
{
struct zfcp_fsf_ct_els *els = job->dd_data;
- struct fc_rport *rport = job->rport;
+ struct fc_rport *rport = fc_bsg_to_rport(job);
struct fc_bsg_request *bsg_request = job->request;
struct zfcp_port *port;
u32 d_id;
@@ -986,8 +986,9 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
struct zfcp_adapter *adapter;
struct zfcp_fsf_ct_els *ct_els = job->dd_data;
struct fc_bsg_request *bsg_request = job->request;
+ struct fc_rport *rport = fc_bsg_to_rport(job);

- shost = job->rport ? rport_to_shost(job->rport) : fc_bsg_to_shost(job);
+ shost = rport ? rport_to_shost(rport) : fc_bsg_to_shost(job);
adapter = (struct zfcp_adapter *)shost->hostdata[0];

if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index f7b50af..35114d9 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1816,7 +1816,7 @@ unlock_out:
static int ibmvfc_bsg_request(struct fc_bsg_job *job)
{
struct ibmvfc_host *vhost = shost_priv(fc_bsg_to_shost(job));
- struct fc_rport *rport = job->rport;
+ struct fc_rport *rport = fc_bsg_to_rport(job);
struct ibmvfc_passthru_mad *mad;
struct ibmvfc_event *evt;
union ibmvfc_iu rsp_iu;
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index c60fdb9..156708a 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -2102,7 +2102,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)

switch (bsg_request->msgcode) {
case FC_BSG_RPT_ELS:
- rport = job->rport;
+ rport = fc_bsg_to_rport(job);
if (!rport)
break;

@@ -2112,7 +2112,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
break;

case FC_BSG_RPT_CT:
- rport = job->rport;
+ rport = fc_bsg_to_rport(job);
if (!rport)
break;

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index bfcc37d..dae7cc3 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -386,7 +386,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
- struct lpfc_rport_data *rdata = job->rport->dd_data;
+ struct lpfc_rport_data *rdata = fc_bsg_to_rport(job)->dd_data;
struct lpfc_nodelist *ndlp = rdata->pnode;
struct fc_bsg_reply *bsg_reply = job->reply;
struct ulp_bde64 *bpl = NULL;
@@ -660,7 +660,7 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
- struct lpfc_rport_data *rdata = job->rport->dd_data;
+ struct lpfc_rport_data *rdata = fc_bsg_to_rport(job)->dd_data;
struct lpfc_nodelist *ndlp = rdata->pnode;
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 109b852..917eafe 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -264,7 +264,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
uint16_t nextlid = 0;

if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
- rport = bsg_job->rport;
+ rport = fc_bsg_to_rport(bsg_job);
fcport = *(fc_port_t **) rport->dd_data;
host = rport_to_shost(rport);
vha = shost_priv(host);
@@ -2485,7 +2485,7 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
bsg_reply->reply_payload_rcv_len = 0;

if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
- rport = bsg_job->rport;
+ rport = fc_bsg_to_rport(bsg_job);
host = rport_to_shost(rport);
vha = shost_priv(host);
} else {
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index d6d18ce..96b3a2e 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3640,11 +3640,12 @@ fc_bsg_job_timeout(struct request *req)
{
struct fc_bsg_job *job = (void *) req->special;
struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct fc_rport *rport = fc_bsg_to_rport(job);
struct fc_internal *i = to_fc_internal(shost->transportt);
unsigned long flags;
int err = 0, done = 0;

- if (job->rport && job->rport->port_state == FC_PORTSTATE_BLOCKED)
+ if (rport && rport->port_state == FC_PORTSTATE_BLOCKED)
return BLK_EH_RESET_TIMER;

spin_lock_irqsave(&job->job_lock, flags);
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index efb9488..9f53fe3 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -824,6 +824,11 @@ static inline struct Scsi_Host *fc_bsg_to_shost(struct fc_bsg_job *job)
return job->shost;
}

+static inline struct fc_rport *fc_bsg_to_rport(struct fc_bsg_job *job)
+{
+ return job->rport;
+}
+
struct scsi_transport_template *fc_attach_transport(
struct fc_function_template *);
void fc_release_transport(struct scsi_transport_template *);
--
1.8.5.6

2016-10-12 13:13:10

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 04/16] scsi: Unify interfaces of fc_bsg_jobdone and bsg_job_done

Unify the interfaces of fc_bsg_jobdone and bsg_job_done. This will reduce the
diff when moving from 'struct fc_bsg_job' to a plain 'struct bsg_job' later
on.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/s390/scsi/zfcp_fc.c | 2 +-
drivers/scsi/bfa/bfad_bsg.c | 6 ++--
drivers/scsi/ibmvscsi/ibmvfc.c | 3 +-
drivers/scsi/libfc/fc_lport.c | 6 ++--
drivers/scsi/lpfc/lpfc_bsg.c | 68 +++++++++++++++++++++++++++-------------
drivers/scsi/qla2xxx/qla_bsg.c | 66 +++++++++++++++++++++++++-------------
drivers/scsi/scsi_transport_fc.c | 22 +++++++------
include/scsi/scsi_transport_fc.h | 3 +-
8 files changed, 116 insertions(+), 60 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 40d8f06..87f6330 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -892,7 +892,7 @@ static void zfcp_fc_ct_els_job_handler(void *data)
jr->reply_payload_rcv_len = job->reply_payload.payload_len;
jr->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
jr->result = zfcp_ct_els->status ? -EIO : 0;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, jr->result, jr->reply_payload_rcv_len);
}

static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 25889b9..e49a6c8 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3180,7 +3180,8 @@ bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len;
bsg_reply->result = rc;

- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rc;
error:
/* free the command buffer */
@@ -3556,7 +3557,8 @@ out:
bsg_reply->result = rc;

if (rc == BFA_STATUS_OK)
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

return rc;
}
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 21c9d28..1001d4a 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1939,7 +1939,8 @@ static int ibmvfc_bsg_request(struct fc_bsg_job *job)
ibmvfc_free_event(evt);
spin_unlock_irqrestore(vhost->host->host_lock, flags);
bsg_reply->result = rc;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
rc = 0;
out:
dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 8811fe0..4bed7ec 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1912,7 +1912,8 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
-ECONNABORTED : -ETIMEDOUT;
job->reply_len = sizeof(uint32_t);
job->state_flags |= FC_RQST_STATE_DONE;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
kfree(info);
return;
}
@@ -1947,7 +1948,8 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
job->reply_payload.payload_len;
bsg_reply->result = 0;
job->state_flags |= FC_RQST_STATE_DONE;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
kfree(info);
}
fc_frame_free(fp);
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 1db9cca..447a7af 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -371,7 +371,8 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}
return;
}
@@ -644,7 +645,8 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}
return;
}
@@ -1136,7 +1138,8 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
job->dd_data = NULL;
/* complete the job back to userspace */
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
spin_lock_irqsave(&phba->ct_ev_lock, flags);
}
}
@@ -1361,7 +1364,8 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
job->dd_data = NULL;
bsg_reply->result = 0;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return 0;

job_error:
@@ -1458,7 +1462,8 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}
return;
}
@@ -1886,7 +1891,8 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rc;
}

@@ -2175,7 +2181,8 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rc;
}

@@ -2289,7 +2296,8 @@ loopback_mode_end_exit:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rc;
}

@@ -2441,7 +2449,8 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rc;
}

@@ -3301,7 +3310,8 @@ loopback_test_exit:
job->dd_data = NULL;
/* complete the job back to userspace if no error */
if (rc == IOCB_SUCCESS)
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rc;
}

@@ -3344,7 +3354,8 @@ lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
job_error:
bsg_reply->result = rc;
if (rc == 0)
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rc;
}

@@ -3409,7 +3420,8 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)

if (job) {
bsg_reply->result = 0;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}
return;
}
@@ -3635,6 +3647,7 @@ static void
lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
struct fc_bsg_job *job;
+ struct fc_bsg_reply *bsg_reply;

job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);

@@ -3654,9 +3667,11 @@ lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
mempool_free(pmboxq, phba->mbox_mem_pool);

/* if the job is still active, call job done */
- if (job)
- fc_bsg_jobdone(job);
-
+ if (job) {
+ bsg_reply = job->reply;
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
+ }
return;
}

@@ -3672,6 +3687,7 @@ static void
lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
struct fc_bsg_job *job;
+ struct fc_bsg_reply *bsg_reply;

job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);

@@ -3689,8 +3705,11 @@ lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
lpfc_bsg_mbox_ext_session_reset(phba);

/* if the job is still active, call job done */
- if (job)
- fc_bsg_jobdone(job);
+ if (job) {
+ bsg_reply = job->reply;
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
+ }

return;
}
@@ -4131,7 +4150,8 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
/* wait for additoinal external buffers */

bsg_reply->result = 0;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return SLI_CONFIG_HANDLED;

job_error:
@@ -4357,7 +4377,8 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
}

bsg_reply->result = 0;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

return SLI_CONFIG_HANDLED;
}
@@ -4473,7 +4494,8 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,

/* wait for additoinal external buffers */
bsg_reply->result = 0;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return SLI_CONFIG_HANDLED;

job_error:
@@ -4941,7 +4963,8 @@ lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
/* job done */
bsg_reply->result = 0;
job->dd_data = NULL;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
} else if (rc == 1)
/* job submitted, will complete later*/
rc = 0; /* return zero, no error */
@@ -5051,7 +5074,8 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}

return;
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 1bca77b..9293d5a 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -20,7 +20,8 @@ qla2x00_bsg_job_done(void *data, void *ptr, int res)
struct fc_bsg_reply *bsg_reply = bsg_job->reply;

bsg_reply->result = res;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
sp->free(vha, sp);
}

@@ -242,7 +243,8 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
}
exit_fcp_prio_cfg:
if (!ret)
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return ret;
}

@@ -939,7 +941,8 @@ done_unmap_req_sg:
bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
if (!rval)
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}

@@ -972,7 +975,8 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
ql_dbg(ql_dbg_user, vha, 0x7031,
"Vendor request 84xx reset completed.\n");
bsg_reply->result = DID_OK;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}

return rval;
@@ -1085,7 +1089,8 @@ done_unmap_sg:
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);

if (!rval)
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}

@@ -1282,7 +1287,8 @@ exit_mgmt:
dma_pool_free(ha->s_dma_pool, mn, mn_dma);

if (!rval)
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}

@@ -1368,7 +1374,8 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
}

bsg_reply->result = DID_OK;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}

return rval;
@@ -1476,7 +1483,8 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
mutex_unlock(&ha->optrom_mutex);
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}

@@ -1511,7 +1519,8 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
mutex_unlock(&ha->optrom_mutex);
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}

@@ -1561,7 +1570,8 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

return 0;
}
@@ -1610,7 +1620,8 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = sizeof(*sr);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

return 0;
}
@@ -1655,7 +1666,8 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

return 0;
}
@@ -1699,7 +1711,8 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

return 0;
}
@@ -1747,7 +1760,8 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

return 0;
}
@@ -1925,7 +1939,8 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = (DID_OK) << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
/* Always return success, vendor rsp carries correct status */
return 0;
}
@@ -2090,7 +2105,8 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return 0;
}

@@ -2131,7 +2147,8 @@ qla8044_serdes_op(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return 0;
}

@@ -2162,7 +2179,8 @@ qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return 0;
}

@@ -2207,7 +2225,8 @@ qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return 0;
}

@@ -2265,7 +2284,8 @@ done:

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return 0;
}

@@ -2321,7 +2341,8 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(*bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
stats, stats_dma);
@@ -2364,7 +2385,8 @@ qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(*bsg_reply);
bsg_reply->result = DID_OK << 16;
- fc_bsg_jobdone(bsg_job);
+ fc_bsg_jobdone(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);

kfree(dd);

diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 4149dac..9744476 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3582,15 +3582,17 @@ fc_destroy_bsgjob(struct fc_bsg_job *job)
* fc_bsg_jobdone - completion routine for bsg requests that the LLD has
* completed
* @job: fc_bsg_job that is complete
+ * @result: job reply result
+ * @reply_payload_rcv_len: length of payload received
*/
-void fc_bsg_jobdone(struct fc_bsg_job *job)
+void fc_bsg_jobdone(struct fc_bsg_job *job, int result,
+ unsigned int reply_payload_rcv_len)
{
struct request *req = job->req;
struct request *rsp = req->next_rq;
- struct fc_bsg_reply *bsg_reply = job->reply;
int err;

- err = job->req->errors = bsg_reply->result;
+ err = job->req->errors = result;

if (err < 0)
/* we're only returning the result field in the reply */
@@ -3602,11 +3604,10 @@ void fc_bsg_jobdone(struct fc_bsg_job *job)
req->resid_len = 0;

if (rsp) {
- WARN_ON(bsg_reply->reply_payload_rcv_len > rsp->resid_len);
+ WARN_ON(reply_payload_rcv_len > rsp->resid_len);

/* set reply (bidi) residual */
- rsp->resid_len -= min(bsg_reply->reply_payload_rcv_len,
- rsp->resid_len);
+ rsp->resid_len -= min(reply_payload_rcv_len, rsp->resid_len);
}
blk_complete_request(req);
}
@@ -3847,7 +3848,8 @@ fail_host_msg:
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = ret;
job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return FC_DISPATCH_UNLOCKED;
}

@@ -3924,7 +3926,8 @@ fail_rport_msg:
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = ret;
job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return FC_DISPATCH_UNLOCKED;
}

@@ -3984,7 +3987,8 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = -ENOMSG;
job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job);
+ fc_bsg_jobdone(job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
spin_lock_irq(q->queue_lock);
continue;
}
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 9ef583f..eca8ed7 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -841,6 +841,7 @@ struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
struct fc_vport_identifiers *);
int fc_vport_terminate(struct fc_vport *vport);
int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
-void fc_bsg_jobdone(struct fc_bsg_job *job);
+void fc_bsg_jobdone(struct fc_bsg_job *job, int result,
+ unsigned int reply_payload_rcv_len);

#endif /* SCSI_TRANSPORT_FC_H */
--
1.8.5.6

2016-10-12 13:13:23

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 05/16] scsi: fc: provide fc_bsg_to_shost() helper

Provide fc_bsg_to_shost() helper that will become handy when we're moving from
struct fc_bsg_job to a plain struct bsg_job. Also use this little helper in
the LLDDs.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/s390/scsi/zfcp_fc.c | 4 +--
drivers/scsi/bfa/bfad_bsg.c | 6 ++---
drivers/scsi/ibmvscsi/ibmvfc.c | 4 +--
drivers/scsi/libfc/fc_lport.c | 2 +-
drivers/scsi/lpfc/lpfc_bsg.c | 32 ++++++++++++------------
drivers/scsi/qla2xxx/qla_bsg.c | 54 ++++++++++++++++++++--------------------
drivers/scsi/scsi_transport_fc.c | 2 +-
include/scsi/scsi_transport_fc.h | 5 ++++
8 files changed, 56 insertions(+), 53 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 87f6330..813c286 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -905,7 +905,7 @@ static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
preamble_word1 = bsg_request->rqst_data.r_ct.preamble_word1;
gs_type = (preamble_word1 & 0xff000000) >> 24;

- adapter = (struct zfcp_adapter *) job->shost->hostdata[0];
+ adapter = shost_priv(fc_bsg_to_shost(job));

switch (gs_type) {
case FC_FST_ALIAS:
@@ -987,7 +987,7 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
struct zfcp_fsf_ct_els *ct_els = job->dd_data;
struct fc_bsg_request *bsg_request = job->request;

- shost = job->rport ? rport_to_shost(job->rport) : job->shost;
+ shost = job->rport ? rport_to_shost(job->rport) : fc_bsg_to_shost(job);
adapter = (struct zfcp_adapter *)shost->hostdata[0];

if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index e49a6c8..d3094270 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3135,8 +3135,7 @@ bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0];
- struct bfad_im_port_s *im_port =
- (struct bfad_im_port_s *) job->shost->hostdata[0];
+ struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job));
struct bfad_s *bfad = im_port->bfad;
struct request_queue *request_q = job->req->q;
void *payload_kbuf;
@@ -3358,8 +3357,7 @@ int
bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
{
struct bfa_bsg_data *bsg_data;
- struct bfad_im_port_s *im_port =
- (struct bfad_im_port_s *) job->shost->hostdata[0];
+ struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job));
struct bfad_s *bfad = im_port->bfad;
bfa_bsg_fcpt_t *bsg_fcpt;
struct bfad_fcxp *drv_fcxp;
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 1001d4a..f7b50af 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1702,7 +1702,7 @@ static void ibmvfc_bsg_timeout_done(struct ibmvfc_event *evt)
**/
static int ibmvfc_bsg_timeout(struct fc_bsg_job *job)
{
- struct ibmvfc_host *vhost = shost_priv(job->shost);
+ struct ibmvfc_host *vhost = shost_priv(fc_bsg_to_shost(job));
unsigned long port_id = (unsigned long)job->dd_data;
struct ibmvfc_event *evt;
struct ibmvfc_tmf *tmf;
@@ -1815,7 +1815,7 @@ unlock_out:
**/
static int ibmvfc_bsg_request(struct fc_bsg_job *job)
{
- struct ibmvfc_host *vhost = shost_priv(job->shost);
+ struct ibmvfc_host *vhost = shost_priv(fc_bsg_to_shost(job));
struct fc_rport *rport = job->rport;
struct ibmvfc_passthru_mad *mad;
struct ibmvfc_event *evt;
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 4bed7ec..c60fdb9 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -2087,7 +2087,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
struct request *rsp = job->req->next_rq;
- struct Scsi_Host *shost = job->shost;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
struct fc_lport *lport = shost_priv(shost);
struct fc_rport *rport;
struct fc_rport_priv *rdata;
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 447a7af..bfcc37d 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -384,7 +384,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
static int
lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct lpfc_rport_data *rdata = job->rport->dd_data;
struct lpfc_nodelist *ndlp = rdata->pnode;
@@ -658,7 +658,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
static int
lpfc_bsg_rport_els(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct lpfc_rport_data *rdata = job->rport->dd_data;
struct lpfc_nodelist *ndlp = rdata->pnode;
@@ -1202,7 +1202,7 @@ lpfc_bsg_ct_unsol_abort(struct lpfc_hba *phba, struct hbq_dmabuf *dmabuf)
static int
lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct fc_bsg_request *bsg_request = job->request;
struct set_ct_event *event_req;
@@ -1287,7 +1287,7 @@ job_error:
static int
lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -1625,7 +1625,7 @@ no_dd_data:
static int
lpfc_bsg_send_mgmt_rsp(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
@@ -2201,10 +2201,10 @@ lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job)
struct lpfc_hba *phba;
int rc;

- shost = job->shost;
+ shost = fc_bsg_to_shost(job);
if (!shost)
return -ENODEV;
- vport = (struct lpfc_vport *)job->shost->hostdata;
+ vport = shost_priv(shost);
if (!vport)
return -ENODEV;
phba = vport->phba;
@@ -2241,10 +2241,10 @@ lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
uint32_t timeout;
int rc, i;

- shost = job->shost;
+ shost = fc_bsg_to_shost(job);
if (!shost)
return -ENODEV;
- vport = (struct lpfc_vport *)job->shost->hostdata;
+ vport = shost_priv(shost);
if (!vport)
return -ENODEV;
phba = vport->phba;
@@ -2325,12 +2325,12 @@ lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
struct diag_status *diag_status_reply;
int mbxstatus, rc = 0;

- shost = job->shost;
+ shost = fc_bsg_to_shost(job);
if (!shost) {
rc = -ENODEV;
goto job_error;
}
- vport = (struct lpfc_vport *)job->shost->hostdata;
+ vport = shost_priv(shost);
if (!vport) {
rc = -ENODEV;
goto job_error;
@@ -3018,7 +3018,7 @@ err_post_rxbufs_exit:
static int
lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
struct lpfc_bsg_event *evt;
@@ -3322,7 +3322,7 @@ loopback_test_exit:
static int
lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
struct get_mgmt_rev_reply *event_reply;
@@ -4933,7 +4933,7 @@ job_cont:
static int
lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
@@ -5093,7 +5093,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
static int
lpfc_menlo_cmd(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct fc_bsg_request *bsg_request = job->request;
struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_hba *phba = vport->phba;
@@ -5353,7 +5353,7 @@ lpfc_bsg_request(struct fc_bsg_job *job)
int
lpfc_bsg_timeout(struct fc_bsg_job *job)
{
- struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct lpfc_iocbq *cmdiocb;
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 9293d5a..109b852 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1,4 +1,4 @@
-/*
+ /*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
@@ -122,7 +122,7 @@ qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
static int
qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
{
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
scsi_qla_host_t *vha = shost_priv(host);
@@ -271,7 +271,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
ha = vha->hw;
type = "FC_BSG_RPT_ELS";
} else {
- host = bsg_job->shost;
+ host = fc_bsg_to_shost(bsg_job);
vha = shost_priv(host);
ha = vha->hw;
type = "FC_BSG_HST_ELS_NOLOGIN";
@@ -432,7 +432,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
{
srb_t *sp;
struct fc_bsg_request *bsg_request = bsg_job->request;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = (DRIVER_ERROR << 16);
@@ -710,7 +710,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval;
@@ -950,7 +950,7 @@ static int
qla84xx_reset(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
@@ -987,7 +987,7 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
struct verify_chip_entry_84xx *mn = NULL;
@@ -1099,7 +1099,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
struct access_chip_84xx *mn = NULL;
@@ -1297,7 +1297,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
int rval = 0;
struct qla_port_param *port_param = NULL;
@@ -1455,7 +1455,7 @@ static int
qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1492,7 +1492,7 @@ static int
qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1528,7 +1528,7 @@ static int
qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1580,7 +1580,7 @@ static int
qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1630,7 +1630,7 @@ static int
qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1676,7 +1676,7 @@ static int
qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1721,7 +1721,7 @@ static int
qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1770,7 +1770,7 @@ static int
qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
uint32_t rval = EXT_STATUS_OK;
@@ -1949,7 +1949,7 @@ static int
qlafx00_mgmt_cmd(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int rval = (DRIVER_ERROR << 16);
@@ -2072,7 +2072,7 @@ static int
qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
int rval = 0;
struct qla_serdes_reg sr;
@@ -2114,7 +2114,7 @@ static int
qla8044_serdes_op(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
int rval = 0;
struct qla_serdes_reg_ex sr;
@@ -2156,7 +2156,7 @@ static int
qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
struct qla_flash_update_caps cap;
@@ -2188,7 +2188,7 @@ static int
qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
uint64_t online_fw_attr = 0;
@@ -2234,7 +2234,7 @@ static int
qla27xx_get_bbcr_data(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
struct qla_bbcr_data bbcr;
@@ -2294,7 +2294,7 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
@@ -2354,7 +2354,7 @@ static int
qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- struct Scsi_Host *host = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
scsi_qla_host_t *vha = shost_priv(host);
int rval;
struct qla_dport_diag *dd;
@@ -2489,7 +2489,7 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
host = rport_to_shost(rport);
vha = shost_priv(host);
} else {
- host = bsg_job->shost;
+ host = fc_bsg_to_shost(bsg_job);
vha = shost_priv(host);
}

@@ -2528,7 +2528,7 @@ int
qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
{
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
- scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
+ scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
struct qla_hw_data *ha = vha->hw;
srb_t *sp;
int cnt, que;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 9744476..d6d18ce 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3639,7 +3639,7 @@ static enum blk_eh_timer_return
fc_bsg_job_timeout(struct request *req)
{
struct fc_bsg_job *job = (void *) req->special;
- struct Scsi_Host *shost = job->shost;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
struct fc_internal *i = to_fc_internal(shost->transportt);
unsigned long flags;
int err = 0, done = 0;
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index eca8ed7..efb9488 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -819,6 +819,11 @@ fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state)
vport->vport_state = new_state;
}

+static inline struct Scsi_Host *fc_bsg_to_shost(struct fc_bsg_job *job)
+{
+ return job->shost;
+}
+
struct scsi_transport_template *fc_attach_transport(
struct fc_function_template *);
void fc_release_transport(struct scsi_transport_template *);
--
1.8.5.6

2016-10-12 13:13:32

by Johannes Thumshirn

[permalink] [raw]
Subject: [PATCH v2 03/16] scsi: fc: Export fc_bsg_jobdone and use it in FC drivers

Export fc_bsg_jobdone so drivers can use it directly instead of doing
the round-trip via struct fc_bsg_job::job_done() and use it in the LLDDs.

As we've converted all LLDDs over to use fc_bsg_jobdone() directly,
we can remove the function pointer from struct fc_bsg_job as well.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
drivers/s390/scsi/zfcp_fc.c | 2 +-
drivers/scsi/bfa/bfad_bsg.c | 4 ++--
drivers/scsi/ibmvscsi/ibmvfc.c | 2 +-
drivers/scsi/libfc/fc_lport.c | 4 ++--
drivers/scsi/lpfc/lpfc_bsg.c | 38 +++++++++++++++++-----------------
drivers/scsi/qla2xxx/qla_bsg.c | 44 ++++++++++++++++++++--------------------
drivers/scsi/scsi_transport_fc.c | 5 ++---
include/scsi/scsi_transport_fc.h | 2 +-
8 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 4c4023f..40d8f06 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -892,7 +892,7 @@ static void zfcp_fc_ct_els_job_handler(void *data)
jr->reply_payload_rcv_len = job->reply_payload.payload_len;
jr->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
jr->result = zfcp_ct_els->status ? -EIO : 0;
- job->job_done(job);
+ fc_bsg_jobdone(job);
}

static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 48366d8..25889b9 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3180,7 +3180,7 @@ bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len;
bsg_reply->result = rc;

- job->job_done(job);
+ fc_bsg_jobdone(job);
return rc;
error:
/* free the command buffer */
@@ -3556,7 +3556,7 @@ out:
bsg_reply->result = rc;

if (rc == BFA_STATUS_OK)
- job->job_done(job);
+ fc_bsg_jobdone(job);

return rc;
}
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 8b55279..21c9d28 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1939,7 +1939,7 @@ static int ibmvfc_bsg_request(struct fc_bsg_job *job)
ibmvfc_free_event(evt);
spin_unlock_irqrestore(vhost->host->host_lock, flags);
bsg_reply->result = rc;
- job->job_done(job);
+ fc_bsg_jobdone(job);
rc = 0;
out:
dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index a1c12e7..8811fe0 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1912,7 +1912,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
-ECONNABORTED : -ETIMEDOUT;
job->reply_len = sizeof(uint32_t);
job->state_flags |= FC_RQST_STATE_DONE;
- job->job_done(job);
+ fc_bsg_jobdone(job);
kfree(info);
return;
}
@@ -1947,7 +1947,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
job->reply_payload.payload_len;
bsg_reply->result = 0;
job->state_flags |= FC_RQST_STATE_DONE;
- job->job_done(job);
+ fc_bsg_jobdone(job);
kfree(info);
}
fc_frame_free(fp);
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 27b5930..1db9cca 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -371,7 +371,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- job->job_done(job);
+ fc_bsg_jobdone(job);
}
return;
}
@@ -644,7 +644,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- job->job_done(job);
+ fc_bsg_jobdone(job);
}
return;
}
@@ -1136,7 +1136,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
job->dd_data = NULL;
/* complete the job back to userspace */
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
- job->job_done(job);
+ fc_bsg_jobdone(job);
spin_lock_irqsave(&phba->ct_ev_lock, flags);
}
}
@@ -1361,7 +1361,7 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
job->dd_data = NULL;
bsg_reply->result = 0;
- job->job_done(job);
+ fc_bsg_jobdone(job);
return 0;

job_error:
@@ -1458,7 +1458,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- job->job_done(job);
+ fc_bsg_jobdone(job);
}
return;
}
@@ -1886,7 +1886,7 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ fc_bsg_jobdone(job);
return rc;
}

@@ -2175,7 +2175,7 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ fc_bsg_jobdone(job);
return rc;
}

@@ -2289,7 +2289,7 @@ loopback_mode_end_exit:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ fc_bsg_jobdone(job);
return rc;
}

@@ -2441,7 +2441,7 @@ job_error:
bsg_reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ fc_bsg_jobdone(job);
return rc;
}

@@ -3301,7 +3301,7 @@ loopback_test_exit:
job->dd_data = NULL;
/* complete the job back to userspace if no error */
if (rc == IOCB_SUCCESS)
- job->job_done(job);
+ fc_bsg_jobdone(job);
return rc;
}

@@ -3344,7 +3344,7 @@ lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
job_error:
bsg_reply->result = rc;
if (rc == 0)
- job->job_done(job);
+ fc_bsg_jobdone(job);
return rc;
}

@@ -3409,7 +3409,7 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)

if (job) {
bsg_reply->result = 0;
- job->job_done(job);
+ fc_bsg_jobdone(job);
}
return;
}
@@ -3655,7 +3655,7 @@ lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)

/* if the job is still active, call job done */
if (job)
- job->job_done(job);
+ fc_bsg_jobdone(job);

return;
}
@@ -3690,7 +3690,7 @@ lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)

/* if the job is still active, call job done */
if (job)
- job->job_done(job);
+ fc_bsg_jobdone(job);

return;
}
@@ -4131,7 +4131,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
/* wait for additoinal external buffers */

bsg_reply->result = 0;
- job->job_done(job);
+ fc_bsg_jobdone(job);
return SLI_CONFIG_HANDLED;

job_error:
@@ -4357,7 +4357,7 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
}

bsg_reply->result = 0;
- job->job_done(job);
+ fc_bsg_jobdone(job);

return SLI_CONFIG_HANDLED;
}
@@ -4473,7 +4473,7 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,

/* wait for additoinal external buffers */
bsg_reply->result = 0;
- job->job_done(job);
+ fc_bsg_jobdone(job);
return SLI_CONFIG_HANDLED;

job_error:
@@ -4941,7 +4941,7 @@ lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
/* job done */
bsg_reply->result = 0;
job->dd_data = NULL;
- job->job_done(job);
+ fc_bsg_jobdone(job);
} else if (rc == 1)
/* job submitted, will complete later*/
rc = 0; /* return zero, no error */
@@ -5051,7 +5051,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,

if (job) {
bsg_reply->result = rc;
- job->job_done(job);
+ fc_bsg_jobdone(job);
}

return;
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 40f7c10..1bca77b 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -20,7 +20,7 @@ qla2x00_bsg_job_done(void *data, void *ptr, int res)
struct fc_bsg_reply *bsg_reply = bsg_job->reply;

bsg_reply->result = res;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
sp->free(vha, sp);
}

@@ -242,7 +242,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
}
exit_fcp_prio_cfg:
if (!ret)
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return ret;
}

@@ -939,7 +939,7 @@ done_unmap_req_sg:
bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
if (!rval)
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return rval;
}

@@ -972,7 +972,7 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
ql_dbg(ql_dbg_user, vha, 0x7031,
"Vendor request 84xx reset completed.\n");
bsg_reply->result = DID_OK;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
}

return rval;
@@ -1085,7 +1085,7 @@ done_unmap_sg:
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);

if (!rval)
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return rval;
}

@@ -1282,7 +1282,7 @@ exit_mgmt:
dma_pool_free(ha->s_dma_pool, mn, mn_dma);

if (!rval)
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return rval;
}

@@ -1368,7 +1368,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
}

bsg_reply->result = DID_OK;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
}

return rval;
@@ -1476,7 +1476,7 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
mutex_unlock(&ha->optrom_mutex);
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return rval;
}

@@ -1511,7 +1511,7 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
mutex_unlock(&ha->optrom_mutex);
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return rval;
}

@@ -1561,7 +1561,7 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);

return 0;
}
@@ -1610,7 +1610,7 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = sizeof(*sr);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);

return 0;
}
@@ -1655,7 +1655,7 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);

return 0;
}
@@ -1699,7 +1699,7 @@ dealloc:
done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);

return 0;
}
@@ -1747,7 +1747,7 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);

return 0;
}
@@ -1925,7 +1925,7 @@ done:
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->reply_payload_rcv_len = 0;
bsg_reply->result = (DID_OK) << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
/* Always return success, vendor rsp carries correct status */
return 0;
}
@@ -2090,7 +2090,7 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return 0;
}

@@ -2131,7 +2131,7 @@ qla8044_serdes_op(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return 0;
}

@@ -2162,7 +2162,7 @@ qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return 0;
}

@@ -2207,7 +2207,7 @@ qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return 0;
}

@@ -2265,7 +2265,7 @@ done:

bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);
return 0;
}

@@ -2321,7 +2321,7 @@ qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(*bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);

dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
stats, stats_dma);
@@ -2364,7 +2364,7 @@ qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)

bsg_job->reply_len = sizeof(*bsg_reply);
bsg_reply->result = DID_OK << 16;
- bsg_job->job_done(bsg_job);
+ fc_bsg_jobdone(bsg_job);

kfree(dd);

diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index eafc7555..4149dac 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3583,8 +3583,7 @@ fc_destroy_bsgjob(struct fc_bsg_job *job)
* completed
* @job: fc_bsg_job that is complete
*/
-static void
-fc_bsg_jobdone(struct fc_bsg_job *job)
+void fc_bsg_jobdone(struct fc_bsg_job *job)
{
struct request *req = job->req;
struct request *rsp = req->next_rq;
@@ -3611,6 +3610,7 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
}
blk_complete_request(req);
}
+EXPORT_SYMBOL_GPL(fc_bsg_jobdone);

/**
* fc_bsg_softirq_done - softirq done routine for destroying the bsg requests
@@ -3744,7 +3744,6 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
if (ret)
goto failjob_rls_rqst_payload;
}
- job->job_done = fc_bsg_jobdone;
if (rport)
job->dev = &rport->dev;
else
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 921b097..9ef583f 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -637,7 +637,6 @@ struct fc_bsg_job {
spinlock_t job_lock;
unsigned int state_flags;
unsigned int ref_cnt;
- void (*job_done)(struct fc_bsg_job *);

struct fc_bsg_request *request;
struct fc_bsg_reply *reply;
@@ -842,5 +841,6 @@ struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
struct fc_vport_identifiers *);
int fc_vport_terminate(struct fc_vport *vport);
int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
+void fc_bsg_jobdone(struct fc_bsg_job *job);

#endif /* SCSI_TRANSPORT_FC_H */
--
1.8.5.6

2016-10-12 19:41:56

by Steffen Maier

[permalink] [raw]
Subject: Re: [PATCH v2 00/16] Convert FibreChannel bsg code to use bsg-lib

Hi Johannes,

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> This series converts the current bsg usage in the FibreChannel drivers over
> to use bsg-lib. SAS will follow once FC is in a good enough shape.
>
> I did take some inspiration from a similar patchset from Mike Christie
> dating back to 2011 but it's not a 1:1 copy. Patch 15/16 is heavily based
> on his series and attribution is given to him in the commit message.
>
> It is currently regression tested on FCoE using the 'fcns' and
> 'fcrls' utilities. I'm still trying to figure out how to test the other
> LLDDs. So any pointer from the respective maintainers are appreciated

The first thing that comes to mind for zfcp is libzfcphbaapi and simply
run its tools for starters. They issue a few different CT GLS requests.
http://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.lhdd/lhdd_t_fcp_api_runappl.html
or
http://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.lgdd/lgdd_t_fcp_api_runappl.html
(upstream:
http://www.ibm.com/developerworks/linux/linux390/zfcp-hbaapi.html)

Theoretically above tools could be built against libHBAAPI on other
architectures.
Currently I don't have anything handy for ELS requests.

Maybe there is some common code tool (possibly building directly on BSG
IOCTL) to exercise more code paths?

Just as a heads up the result of my example run (need to dig deeper why
it crashed):

# zfcp_show -n

Local Port List:
<<<end of ssh output, Linux console following...>>>
> [ 799.640378] Oops: 0038 ilc:3 [#1] [ 799.640387] PREEMPT SMP [ 799.640393]
> [ 799.640399] Modules linked in: nf_log_ipv6 xt_pkttype nf_log_ipv4 nf_log_common xt_LOG xt_limit ip6t_REJECT nf_reject_ipv6 xt_tcpudp nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw ipt_REJECT nf_reject_ipv4 iptable_raw xt_CT iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables ghash_s390 prng ecb aes_s390 des_s390 dm_mod des_generic sha512_s390 sha256_s390 qeth_l2 sha1_s390 qeth zfcp sha_common ccwgroup qdio autofs4
> [ 799.640542] CPU: 1 PID: 2210 Comm: zfcp_show Not tainted 4.8.0fcbsg+ #6
> [ 799.640550] Hardware name: IBM 2964 N96 702 (z/VM)
> [ 799.640558] task: 0000000047b60008 task.stack: 0000000062428000
> [ 799.640567] Krnl PSW : 0404e00180000000 00000000001b125c[ 799.640581] (__lock_acquire+0x104/0x7d8)
> [ 799.640590]
> [ 799.640599] R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0[ 799.640618] RI:0 EA:3
> [ 799.640621]
> [ 799.640621] Krnl GPRS: 0000000000000000 0000000000000008 07f40707c0040000 0000000000000000
> [ 799.640624] 0000000000000000 0000000000000000 0000000000000001 0000000000000000
> [ 799.640627] 0000000000000000 0000000000355cb4 0000000000000000 0000000047b60008
> [ 799.640630] 0300000000000000 00000000009b17b0 000000006242b800 000000006242b778
> [ 799.640643] Krnl Code: 00000000001b124c: b9040029 lgr %r2,%r9
> [ 799.640648] 00000000001b1250: c0e5ffffd6a4 brasl %r14,1abf98
> #00000000001b1256: ec28ffad007c cgij %r2,0,8,1b11b0
> [ 799.640659] >00000000001b125c: eb012198006a asi 408(%r2,1
> 00000000001b1262: 5830ba10 l %r3,2576(%r11)
> [ 799.640669] 00000000001b1266: 5030f0a4 st %r3,164(%r15)
> 00000000001b126a: c01000e3f9db larl %r1,1e30620
> [ 799.640678] 00000000001b1270: e31010000012 lt %r1,0(%r1)
> [ 799.640682]
> [ 799.640684] Call Trace:
> [ 799.640687] ([<ffffffffffffffff>] 0xffffffffffffffff)
> [ 799.640691] ([<00000000001b21f4>] lock_acquire+0x30c/0x358)
> [ 799.640699] ([<000000000099fdae>] mutex_lock_interruptible_nested+0x7e/0x4f8)
> [ 799.640717] ([<000003ff8047a090>] zfcp_fc_wka_port_get+0x40/0x128 [zfcp])
> [ 799.640724] ([<000003ff8047bd54>] zfcp_fc_exec_bsg_job+0x244/0x2d8 [zfcp])
> [ 799.640732] ([<00000000007c8b1e>] fc_bsg_dispatch+0x20e/0x280)
> [ 799.640739] ([<00000000006dea1a>] bsg_request_fn+0x132/0x1e0)
> [ 799.640746] ([<00000000006b8e0a>] __blk_run_queue+0x52/0x68)
> [ 799.640751] ([<00000000006c549a>] blk_execute_rq_nowait+0xf2/0x110)
> [ 799.640754] ([<00000000006c557a>] blk_execute_rq+0xa2/0x110)
> [ 799.640757] ([<00000000006de0ee>] bsg_ioctl+0x1f6/0x268)
> [ 799.640763] ([<000000000036ca20>] do_vfs_ioctl+0x680/0x6d8)
> [ 799.640767] ([<000000000036caf4>] SyS_ioctl+0x7c/0xb0)
> [ 799.640771] ([<00000000009a50de>] system_call+0xd6/0x270)
> [ 799.640774] INFO: lockdep is turned off.
> [ 799.640776] Last Breaking-Event-Address:
> [ 799.640779] [<00000000001b1244>] __lock_acquire+0xec/0x7d8
> [ 799.640782] [ 799.640785] Kernel panic - not syncing: Fatal exception: panic_on_oops


> although the LLDD changes are purely mechanical. All they do is change from
> 'struct fc_bsg_job' to 'struct bsg_job' and corresponding changes in order
> to get the series bisectable.
>
> The idea for this change arose when discussing racy sysfs handling the FC
> bsg code with Christoph and is a next step in moving all bsg clients to
> bsg-lib to eventually clean up the in kernel bsg API.
>
> Changes to v1:
> * Reduce the number of individual patches (44 -> 16)

nice

> * Fix s390 build failure (forgotten to kill fc_bsg_job from zfcp_ext.h)

I pushed your patches on today's linux.git, i.e. post v4.8 with zfcp
fixes of v4.9 merge window already included and it did build with our
default_defconfig but qdio and zfcp as modules rather than built-in.

> * Make bsg_job_get() call kref_get_unless_zero() and use it in scsi_transport_fc.c

Perfect, I had planned to suggest this based on v1 of the patch set.

> Johannes Thumshirn (16):
> scsi: Get rid of struct fc_bsg_buffer
> scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
> scsi: fc: Export fc_bsg_jobdone and use it in FC drivers
> scsi: Unify interfaces of fc_bsg_jobdone and bsg_job_done
> scsi: fc: provide fc_bsg_to_shost() helper
> scsi: fc: provide fc_bsg_to_rport() helper
> scsi: libfc: don't set FC_RQST_STATE_DONE before calling
> fc_bsg_jobdone()
> scsi: fc: implement kref backed reference counting
> block: add reference counting for struct bsg_job
> scsi: change FC drivers to use 'struct bsg_job'
> scsi: fc: Use bsg_destroy_job
> scsi: fc: use bsg_softirq_done
> scsi: fc: use bsg_job_done
> block: add bsg_job_put() and bsg_job_get()
> scsi: fc: move FC transport's bsg code to bsg-lib
> block: unexport bsg_softirq_done() again
>
> block/bsg-lib.c | 19 +-
> drivers/s390/scsi/zfcp_ext.h | 4 +-
> drivers/s390/scsi/zfcp_fc.c | 33 +--
> drivers/scsi/Kconfig | 1 +
> drivers/scsi/bfa/bfad_bsg.c | 62 +++---
> drivers/scsi/bfa/bfad_im.h | 4 +-
> drivers/scsi/ibmvscsi/ibmvfc.c | 40 ++--
> drivers/scsi/libfc/fc_lport.c | 47 ++--
> drivers/scsi/lpfc/lpfc_bsg.c | 375 +++++++++++++++++++-------------
> drivers/scsi/lpfc/lpfc_crtn.h | 4 +-
> drivers/scsi/qla2xxx/qla_bsg.c | 449 ++++++++++++++++++++++-----------------
> drivers/scsi/qla2xxx/qla_def.h | 2 +-
> drivers/scsi/qla2xxx/qla_gbl.h | 4 +-
> drivers/scsi/qla2xxx/qla_iocb.c | 13 +-
> drivers/scsi/qla2xxx/qla_isr.c | 52 +++--
> drivers/scsi/qla2xxx/qla_mr.c | 15 +-
> drivers/scsi/scsi_transport_fc.c | 409 ++++++-----------------------------
> include/linux/bsg-lib.h | 4 +
> include/scsi/libfc.h | 2 +-
> include/scsi/scsi_transport_fc.h | 62 ++----
> 20 files changed, 745 insertions(+), 856 deletions(-)
>

--
Mit freundlichen Gr??en / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

2016-10-13 08:23:52

by Johannes Thumshirn

[permalink] [raw]
Subject: Re: [PATCH v2 00/16] Convert FibreChannel bsg code to use bsg-lib

On Wed, Oct 12, 2016 at 05:54:45PM +0200, Steffen Maier wrote:
> Hi Johannes,
>
> On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> > This series converts the current bsg usage in the FibreChannel drivers over
> > to use bsg-lib. SAS will follow once FC is in a good enough shape.
> >
> > I did take some inspiration from a similar patchset from Mike Christie
> > dating back to 2011 but it's not a 1:1 copy. Patch 15/16 is heavily based
> > on his series and attribution is given to him in the commit message.
> >
> > It is currently regression tested on FCoE using the 'fcns' and
> > 'fcrls' utilities. I'm still trying to figure out how to test the other
> > LLDDs. So any pointer from the respective maintainers are appreciated
>
> The first thing that comes to mind for zfcp is libzfcphbaapi and simply run
> its tools for starters. They issue a few different CT GLS requests.
> http://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.lhdd/lhdd_t_fcp_api_runappl.html
> or
> http://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.lgdd/lgdd_t_fcp_api_runappl.html
> (upstream:
> http://www.ibm.com/developerworks/linux/linux390/zfcp-hbaapi.html)

I'll give it a try, thanks. zfcp_show was the 1st hit on Google as well, when
I was looking for a way to test it.

>
> Theoretically above tools could be built against libHBAAPI on other
> architectures.
> Currently I don't have anything handy for ELS requests.
>
> Maybe there is some common code tool (possibly building directly on BSG
> IOCTL) to exercise more code paths?

Yes this is something I had in mind as well and it could become handy later on
anyways.

>
> Just as a heads up the result of my example run (need to dig deeper why it
> crashed):
>
> # zfcp_show -n
>
> Local Port List:
> <<<end of ssh output, Linux console following...>>>
> > [ 799.640378] Oops: 0038 ilc:3 [#1] [ 799.640387] PREEMPT SMP [ 799.640393]
> > [ 799.640399] Modules linked in: nf_log_ipv6 xt_pkttype nf_log_ipv4 nf_log_common xt_LOG xt_limit ip6t_REJECT nf_reject_ipv6 xt_tcpudp nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw ipt_REJECT nf_reject_ipv4 iptable_raw xt_CT iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables ghash_s390 prng ecb aes_s390 des_s390 dm_mod des_generic sha512_s390 sha256_s390 qeth_l2 sha1_s390 qeth zfcp sha_common ccwgroup qdio autofs4
> > [ 799.640542] CPU: 1 PID: 2210 Comm: zfcp_show Not tainted 4.8.0fcbsg+ #6
> > [ 799.640550] Hardware name: IBM 2964 N96 702 (z/VM)
> > [ 799.640558] task: 0000000047b60008 task.stack: 0000000062428000
> > [ 799.640567] Krnl PSW : 0404e00180000000 00000000001b125c[ 799.640581] (__lock_acquire+0x104/0x7d8)
> > [ 799.640590]
> > [ 799.640599] R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0[ 799.640618] RI:0 EA:3
> > [ 799.640621]
> > [ 799.640621] Krnl GPRS: 0000000000000000 0000000000000008 07f40707c0040000 0000000000000000
> > [ 799.640624] 0000000000000000 0000000000000000 0000000000000001 0000000000000000
> > [ 799.640627] 0000000000000000 0000000000355cb4 0000000000000000 0000000047b60008
> > [ 799.640630] 0300000000000000 00000000009b17b0 000000006242b800 000000006242b778
> > [ 799.640643] Krnl Code: 00000000001b124c: b9040029 lgr %r2,%r9
> > [ 799.640648] 00000000001b1250: c0e5ffffd6a4 brasl %r14,1abf98
> > #00000000001b1256: ec28ffad007c cgij %r2,0,8,1b11b0
> > [ 799.640659] >00000000001b125c: eb012198006a asi 408(%r2,1
> > 00000000001b1262: 5830ba10 l %r3,2576(%r11)
> > [ 799.640669] 00000000001b1266: 5030f0a4 st %r3,164(%r15)
> > 00000000001b126a: c01000e3f9db larl %r1,1e30620
> > [ 799.640678] 00000000001b1270: e31010000012 lt %r1,0(%r1)
> > [ 799.640682]
> > [ 799.640684] Call Trace:
> > [ 799.640687] ([<ffffffffffffffff>] 0xffffffffffffffff)
> > [ 799.640691] ([<00000000001b21f4>] lock_acquire+0x30c/0x358)
> > [ 799.640699] ([<000000000099fdae>] mutex_lock_interruptible_nested+0x7e/0x4f8)
> > [ 799.640717] ([<000003ff8047a090>] zfcp_fc_wka_port_get+0x40/0x128 [zfcp])
> > [ 799.640724] ([<000003ff8047bd54>] zfcp_fc_exec_bsg_job+0x244/0x2d8 [zfcp])
> > [ 799.640732] ([<00000000007c8b1e>] fc_bsg_dispatch+0x20e/0x280)
> > [ 799.640739] ([<00000000006dea1a>] bsg_request_fn+0x132/0x1e0)
> > [ 799.640746] ([<00000000006b8e0a>] __blk_run_queue+0x52/0x68)
> > [ 799.640751] ([<00000000006c549a>] blk_execute_rq_nowait+0xf2/0x110)
> > [ 799.640754] ([<00000000006c557a>] blk_execute_rq+0xa2/0x110)
> > [ 799.640757] ([<00000000006de0ee>] bsg_ioctl+0x1f6/0x268)
> > [ 799.640763] ([<000000000036ca20>] do_vfs_ioctl+0x680/0x6d8)
> > [ 799.640767] ([<000000000036caf4>] SyS_ioctl+0x7c/0xb0)
> > [ 799.640771] ([<00000000009a50de>] system_call+0xd6/0x270)
> > [ 799.640774] INFO: lockdep is turned off.
> > [ 799.640776] Last Breaking-Event-Address:
> > [ 799.640779] [<00000000001b1244>] __lock_acquire+0xec/0x7d8
> > [ 799.640782] [ 799.640785] Kernel panic - not syncing: Fatal exception: panic_on_oops

I'll have a look into it. But from a first quick glance over it I must admit I
don't see the problem yet. I could imagine two reasons for it though. One
being the change in the refcounting and one being the patches changing over to
the fc_bsg_to{shost,rport}() helpers. I think a git bisect will help here.

>
>
> > although the LLDD changes are purely mechanical. All they do is change from
> > 'struct fc_bsg_job' to 'struct bsg_job' and corresponding changes in order
> > to get the series bisectable.
> >
> > The idea for this change arose when discussing racy sysfs handling the FC
> > bsg code with Christoph and is a next step in moving all bsg clients to
> > bsg-lib to eventually clean up the in kernel bsg API.
> >
> > Changes to v1:
> > * Reduce the number of individual patches (44 -> 16)
>
> nice
>
> > * Fix s390 build failure (forgotten to kill fc_bsg_job from zfcp_ext.h)
>
> I pushed your patches on today's linux.git, i.e. post v4.8 with zfcp fixes
> of v4.9 merge window already included and it did build with our
> default_defconfig but qdio and zfcp as modules rather than built-in.

Thanks for the feedback.

Johannes

--
Johannes Thumshirn Storage
[email protected] +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

2016-10-13 09:14:27

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 01/16] scsi: Get rid of struct fc_bsg_buffer

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> struct fc_bsg_buffer is just a clone of struct bsg_buffer from bsg-lib,
> so use this one instead.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/scsi/lpfc/lpfc_bsg.c | 3 ++-
> drivers/scsi/scsi_transport_fc.c | 2 +-
> include/scsi/scsi_transport_fc.h | 12 +++---------
> 3 files changed, 6 insertions(+), 11 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:26:34

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
> helper variables bsg_request and bsg_reply. This will be helpfull when
> transitioning to bsg-lib.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_fc.c | 9 +-
> drivers/scsi/bfa/bfad_bsg.c | 40 +++---
> drivers/scsi/ibmvscsi/ibmvfc.c | 22 ++--
> drivers/scsi/libfc/fc_lport.c | 23 ++--
> drivers/scsi/lpfc/lpfc_bsg.c | 194 +++++++++++++++++-----------
> drivers/scsi/qla2xxx/qla_bsg.c | 264 ++++++++++++++++++++++-----------------
> drivers/scsi/qla2xxx/qla_iocb.c | 5 +-
> drivers/scsi/qla2xxx/qla_isr.c | 46 ++++---
> drivers/scsi/qla2xxx/qla_mr.c | 10 +-
> drivers/scsi/scsi_transport_fc.c | 37 +++---
> 10 files changed, 387 insertions(+), 263 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:28:15

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 03/16] scsi: fc: Export fc_bsg_jobdone and use it in FC drivers

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Export fc_bsg_jobdone so drivers can use it directly instead of doing
> the round-trip via struct fc_bsg_job::job_done() and use it in the LLDDs.
>
> As we've converted all LLDDs over to use fc_bsg_jobdone() directly,
> we can remove the function pointer from struct fc_bsg_job as well.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_fc.c | 2 +-
> drivers/scsi/bfa/bfad_bsg.c | 4 ++--
> drivers/scsi/ibmvscsi/ibmvfc.c | 2 +-
> drivers/scsi/libfc/fc_lport.c | 4 ++--
> drivers/scsi/lpfc/lpfc_bsg.c | 38 +++++++++++++++++-----------------
> drivers/scsi/qla2xxx/qla_bsg.c | 44 ++++++++++++++++++++--------------------
> drivers/scsi/scsi_transport_fc.c | 5 ++---
> include/scsi/scsi_transport_fc.h | 2 +-
> 8 files changed, 50 insertions(+), 51 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:36:04

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 06/16] scsi: fc: provide fc_bsg_to_rport() helper

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Provide fc_bsg_to_rport() helper that will become handy when we're moving
> from struct fc_bsg_job to a plain struct bsg_job. Also move all LLDDs to use
> the new helper.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_fc.c | 5 +++--
> drivers/scsi/ibmvscsi/ibmvfc.c | 2 +-
> drivers/scsi/libfc/fc_lport.c | 4 ++--
> drivers/scsi/lpfc/lpfc_bsg.c | 4 ++--
> drivers/scsi/qla2xxx/qla_bsg.c | 4 ++--
> drivers/scsi/scsi_transport_fc.c | 3 ++-
> include/scsi/scsi_transport_fc.h | 5 +++++
> 7 files changed, 17 insertions(+), 10 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:40:02

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 07/16] scsi: libfc: don't set FC_RQST_STATE_DONE before calling fc_bsg_jobdone()

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Don't set FC_RQST_STATE_DONE before calling fc_bsg_jobdone() as
> fc_bsg_jobdone() calls blk_complete_requeust() which raises a soft-IRQ that
> ends up in fc_bsg_sofirq_done() and fc_bsg_softirq_done() sets the
> FC_RQST_STATE_DONE flag.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/scsi/libfc/fc_lport.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
> index 156708a..53d13721 100644
> --- a/drivers/scsi/libfc/fc_lport.c
> +++ b/drivers/scsi/libfc/fc_lport.c
> @@ -1911,7 +1911,6 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
> bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
> -ECONNABORTED : -ETIMEDOUT;
> job->reply_len = sizeof(uint32_t);
> - job->state_flags |= FC_RQST_STATE_DONE;
> fc_bsg_jobdone(job, bsg_reply->result,
> bsg_reply->reply_payload_rcv_len);
> kfree(info);
> @@ -1947,7 +1946,6 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
> bsg_reply->reply_payload_rcv_len =
> job->reply_payload.payload_len;
> bsg_reply->result = 0;
> - job->state_flags |= FC_RQST_STATE_DONE;
> fc_bsg_jobdone(job, bsg_reply->result,
> bsg_reply->reply_payload_rcv_len);
> kfree(info);
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:43:48

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 08/16] scsi: fc: implement kref backed reference counting

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Implement kref backed reference counting instead of rolling our own. This
> elimnates the need of the following fields in 'struct fc_bsg_job':
> * ref_cnt
> * state_flags
> * job_lock
> bringing us close to unification of 'struct fc_bsg_job' and 'struct bsg_job'.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/scsi/scsi_transport_fc.c | 38 +++++++++-----------------------------
> include/scsi/scsi_transport_fc.h | 4 +---
> 2 files changed, 10 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
> index 96b3a2e..b0e28af 100644
> --- a/drivers/scsi/scsi_transport_fc.c
> +++ b/drivers/scsi/scsi_transport_fc.c
> @@ -3560,16 +3560,9 @@ fc_vport_sched_delete(struct work_struct *work)
> * @job: fc_bsg_job that is to be torn down
> */
> static void
> -fc_destroy_bsgjob(struct fc_bsg_job *job)
> +fc_destroy_bsgjob(struct kref *kref)
> {
> - unsigned long flags;
> -
> - spin_lock_irqsave(&job->job_lock, flags);
> - if (job->ref_cnt) {
> - spin_unlock_irqrestore(&job->job_lock, flags);
> - return;
> - }
> - spin_unlock_irqrestore(&job->job_lock, flags);
> + struct fc_bsg_job *job = container_of(kref, struct fc_bsg_job, kref);
>
> put_device(job->dev); /* release reference for the request */
>
> @@ -3620,15 +3613,9 @@ EXPORT_SYMBOL_GPL(fc_bsg_jobdone);
> static void fc_bsg_softirq_done(struct request *rq)
> {
> struct fc_bsg_job *job = rq->special;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&job->job_lock, flags);
> - job->state_flags |= FC_RQST_STATE_DONE;
> - job->ref_cnt--;
> - spin_unlock_irqrestore(&job->job_lock, flags);
>
> blk_end_request_all(rq, rq->errors);
> - fc_destroy_bsgjob(job);
> + kref_put(&job->kref, fc_destroy_bsgjob);
> }
>
> /**
Hmm. blk_end_request_all() (potentially) triggers a recursion into all
.end_io callbacks, which might end up doing god-knows-what.
With some delays in doing so
During that time we have no idea that bsg_softirq_done() is actually
running, and we might clash with eg. timeouts or somesuch.

Maybe it's an idea to move blk_end_request_all into the kref destroy
callback; that way we're guaranteed to call it only once and would avoid
this situation.

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:44:00

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 09/16] block: add reference counting for struct bsg_job

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Add reference counting to 'struct bsg_job' so we can implement a reuqest
> timeout handler for bsg_jobs, which is needed for Fibre Channel.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> block/bsg-lib.c | 7 +++++--
> include/linux/bsg-lib.h | 2 ++
> 2 files changed, 7 insertions(+), 2 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:46:38

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 10/16] scsi: change FC drivers to use 'struct bsg_job'

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Change FC drivers to use 'struct bsg_job' from bsg-lib.h instead of 'struct
> fc_bsg_job' from scsi_transport_fc.h and remove 'struct fc_bsg_job'.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_ext.h | 4 +--
> drivers/s390/scsi/zfcp_fc.c | 15 ++++----
> drivers/scsi/bfa/bfad_bsg.c | 10 +++---
> drivers/scsi/bfa/bfad_im.h | 4 +--
> drivers/scsi/ibmvscsi/ibmvfc.c | 9 ++---
> drivers/scsi/libfc/fc_lport.c | 10 +++---
> drivers/scsi/lpfc/lpfc_bsg.c | 74 ++++++++++++++++++++--------------------
> drivers/scsi/lpfc/lpfc_crtn.h | 4 +--
> drivers/scsi/qla2xxx/qla_bsg.c | 61 +++++++++++++++++----------------
> drivers/scsi/qla2xxx/qla_def.h | 2 +-
> drivers/scsi/qla2xxx/qla_gbl.h | 4 +--
> drivers/scsi/qla2xxx/qla_iocb.c | 8 ++---
> drivers/scsi/qla2xxx/qla_isr.c | 6 ++--
> drivers/scsi/qla2xxx/qla_mr.c | 5 +--
> drivers/scsi/scsi_transport_fc.c | 20 +++++------
> include/scsi/libfc.h | 2 +-
> include/scsi/scsi_transport_fc.h | 63 ++++++++++------------------------
> 17 files changed, 138 insertions(+), 163 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:47:23

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 11/16] scsi: fc: Use bsg_destroy_job

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> fc_destroy_bsgjob() and bsg_destroy_job() are now 1:1 copies, so use the
> later.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> block/bsg-lib.c | 3 ++-
> drivers/scsi/scsi_transport_fc.c | 20 ++------------------
> include/linux/bsg-lib.h | 1 +
> 3 files changed, 5 insertions(+), 19 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:48:08

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 14/16] block: add bsg_job_put() and bsg_job_get()

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Add bsg_job_put() and bsg_job_get() so don't need to export
> bsg_destroy_job() any more.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> block/bsg-lib.c | 17 ++++++++++++++---
> drivers/scsi/scsi_transport_fc.c | 4 ++--
> include/linux/bsg-lib.h | 3 ++-
> 3 files changed, 18 insertions(+), 6 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 11:48:15

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 13/16] scsi: fc: use bsg_job_done

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> fc_bsg_jobdone() and bsg_job_done() are 1:1 copies now so use the bsg-lib one
> instead of the FC private implementation.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_fc.c | 2 +-
> drivers/scsi/bfa/bfad_bsg.c | 4 ++--
> drivers/scsi/ibmvscsi/ibmvfc.c | 2 +-
> drivers/scsi/libfc/fc_lport.c | 4 ++--
> drivers/scsi/lpfc/lpfc_bsg.c | 38 +++++++++++++++++-----------------
> drivers/scsi/qla2xxx/qla_bsg.c | 44 ++++++++++++++++++++--------------------
> drivers/scsi/scsi_transport_fc.c | 41 +++----------------------------------
> include/scsi/scsi_transport_fc.h | 2 --
> 8 files changed, 50 insertions(+), 87 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 12:33:47

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 12/16] scsi: fc: use bsg_softirq_done

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> bsg_softirq_done() and fc_bsg_softirq_done() are copies of each other, so
> ditch the fc specific one.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> block/bsg-lib.c | 3 ++-
> drivers/scsi/scsi_transport_fc.c | 16 ++--------------
> include/linux/bsg-lib.h | 1 +
> 3 files changed, 5 insertions(+), 15 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 13:03:53

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 15/16] scsi: fc: move FC transport's bsg code to bsg-lib

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Now that all conversions are done, move the FibreChannel bsg code over to the
> bsg library. Note that CONFIG_SCSI_FC_ATTRS now needs to select BLK_DEV_BSGLIB
> in order to build correctly.
>
> This patch is derived from work done by Mike Christie in 2011 [1] but only the
> iscsi parts got merged back then.
>
> [1] http://marc.info/?l=linux-scsi&m=131149780921009&w=2
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/scsi/Kconfig | 1 +
> drivers/scsi/scsi_transport_fc.c | 287 ++++++---------------------------------
> 2 files changed, 44 insertions(+), 244 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 13:03:55

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 16/16] block: unexport bsg_softirq_done() again

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Unexport bsg_softirq_done() again, we don't need it outside of bsg-lib.c
> anymore now that scsi_transport_fc is a pure bsg-lib client.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> block/bsg-lib.c | 3 +--
> include/linux/bsg-lib.h | 1 -
> 2 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/block/bsg-lib.c b/block/bsg-lib.c
> index 46a4fee..4ac0ade 100644
> --- a/block/bsg-lib.c
> +++ b/block/bsg-lib.c
> @@ -93,14 +93,13 @@ EXPORT_SYMBOL_GPL(bsg_job_done);
> * bsg_softirq_done - softirq done routine for destroying the bsg requests
> * @rq: BSG request that holds the job to be destroyed
> */
> -void bsg_softirq_done(struct request *rq)
> +static void bsg_softirq_done(struct request *rq)
> {
> struct bsg_job *job = rq->special;
>
> blk_end_request_all(rq, rq->errors);
> bsg_job_put(job);
> }
> -EXPORT_SYMBOL_GPL(bsg_softirq_done);
>
> static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
> {
> diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
> index b708db9..657a718 100644
> --- a/include/linux/bsg-lib.h
> +++ b/include/linux/bsg-lib.h
> @@ -69,7 +69,6 @@ void bsg_job_done(struct bsg_job *job, int result,
> int bsg_setup_queue(struct device *dev, struct request_queue *q, char *name,
> bsg_job_fn *job_fn, int dd_job_size);
> void bsg_request_fn(struct request_queue *q);
> -void bsg_softirq_done(struct request *rq);
> void bsg_job_put(struct bsg_job *job);
> int __must_check bsg_job_get(struct bsg_job *job);
>
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 13:23:57

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 04/16] scsi: Unify interfaces of fc_bsg_jobdone and bsg_job_done

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Unify the interfaces of fc_bsg_jobdone and bsg_job_done. This will reduce the
> diff when moving from 'struct fc_bsg_job' to a plain 'struct bsg_job' later
> on.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_fc.c | 2 +-
> drivers/scsi/bfa/bfad_bsg.c | 6 ++--
> drivers/scsi/ibmvscsi/ibmvfc.c | 3 +-
> drivers/scsi/libfc/fc_lport.c | 6 ++--
> drivers/scsi/lpfc/lpfc_bsg.c | 68 +++++++++++++++++++++++++++-------------
> drivers/scsi/qla2xxx/qla_bsg.c | 66 +++++++++++++++++++++++++-------------
> drivers/scsi/scsi_transport_fc.c | 22 +++++++------
> include/scsi/scsi_transport_fc.h | 3 +-
> 8 files changed, 116 insertions(+), 60 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 13:24:07

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 05/16] scsi: fc: provide fc_bsg_to_shost() helper

On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Provide fc_bsg_to_shost() helper that will become handy when we're moving from
> struct fc_bsg_job to a plain struct bsg_job. Also use this little helper in
> the LLDDs.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_fc.c | 4 +--
> drivers/scsi/bfa/bfad_bsg.c | 6 ++---
> drivers/scsi/ibmvscsi/ibmvfc.c | 4 +--
> drivers/scsi/libfc/fc_lport.c | 2 +-
> drivers/scsi/lpfc/lpfc_bsg.c | 32 ++++++++++++------------
> drivers/scsi/qla2xxx/qla_bsg.c | 54 ++++++++++++++++++++--------------------
> drivers/scsi/scsi_transport_fc.c | 2 +-
> include/scsi/scsi_transport_fc.h | 5 ++++
> 8 files changed, 56 insertions(+), 53 deletions(-)
>
Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-13 14:40:55

by Johannes Thumshirn

[permalink] [raw]
Subject: Re: [PATCH v2 08/16] scsi: fc: implement kref backed reference counting

On Thu, Oct 13, 2016 at 01:42:06PM +0200, Hannes Reinecke wrote:
> On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> > Implement kref backed reference counting instead of rolling our own. This
> > elimnates the need of the following fields in 'struct fc_bsg_job':
> > * ref_cnt
> > * state_flags
> > * job_lock
> > bringing us close to unification of 'struct fc_bsg_job' and 'struct bsg_job'.
> >
> > Signed-off-by: Johannes Thumshirn <[email protected]>
> > ---
> > drivers/scsi/scsi_transport_fc.c | 38 +++++++++-----------------------------
> > include/scsi/scsi_transport_fc.h | 4 +---
> > 2 files changed, 10 insertions(+), 32 deletions(-)
> >
> > diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
> > index 96b3a2e..b0e28af 100644
> > --- a/drivers/scsi/scsi_transport_fc.c
> > +++ b/drivers/scsi/scsi_transport_fc.c
> > @@ -3560,16 +3560,9 @@ fc_vport_sched_delete(struct work_struct *work)
> > * @job: fc_bsg_job that is to be torn down
> > */
> > static void
> > -fc_destroy_bsgjob(struct fc_bsg_job *job)
> > +fc_destroy_bsgjob(struct kref *kref)
> > {
> > - unsigned long flags;
> > -
> > - spin_lock_irqsave(&job->job_lock, flags);
> > - if (job->ref_cnt) {
> > - spin_unlock_irqrestore(&job->job_lock, flags);
> > - return;
> > - }
> > - spin_unlock_irqrestore(&job->job_lock, flags);
> > + struct fc_bsg_job *job = container_of(kref, struct fc_bsg_job, kref);
> >
> > put_device(job->dev); /* release reference for the request */
> >
> > @@ -3620,15 +3613,9 @@ EXPORT_SYMBOL_GPL(fc_bsg_jobdone);
> > static void fc_bsg_softirq_done(struct request *rq)
> > {
> > struct fc_bsg_job *job = rq->special;
> > - unsigned long flags;
> > -
> > - spin_lock_irqsave(&job->job_lock, flags);
> > - job->state_flags |= FC_RQST_STATE_DONE;
> > - job->ref_cnt--;
> > - spin_unlock_irqrestore(&job->job_lock, flags);
> >
> > blk_end_request_all(rq, rq->errors);
> > - fc_destroy_bsgjob(job);
> > + kref_put(&job->kref, fc_destroy_bsgjob);
> > }
> >
> > /**
> Hmm. blk_end_request_all() (potentially) triggers a recursion into all
> .end_io callbacks, which might end up doing god-knows-what.
> With some delays in doing so
> During that time we have no idea that bsg_softirq_done() is actually
> running, and we might clash with eg. timeouts or somesuch.
>
> Maybe it's an idea to move blk_end_request_all into the kref destroy
> callback; that way we're guaranteed to call it only once and would avoid
> this situation.

This _could_ explain the panic with zfcp. Fixed that for v3.

--
Johannes Thumshirn Storage
[email protected] +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

2016-10-13 15:16:20

by Steffen Maier

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

I'm puzzled.

$ git bisect start fc_bsg master
Bisecting: 8 revisions left to test after this (roughly 3 steps)
[005d51510eee6102636d5dbb06310531c5d46151] scsi: fc: implement kref
backed reference counting
$ git bisect bad
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[bef6da201de1bb81bb4d9511f9a155862efc251f] scsi: Unify interfaces of
fc_bsg_jobdone and bsg_job_done
$ git bisect bad
Bisecting: 1 revision left to test after this (roughly 1 step)
[3087864ce3d7282f59021245d8a5f83ef1caef18] scsi: don't use
fc_bsg_job::request and fc_bsg_job::reply directly
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[81aea44720d22d2e0c4a2613ae8b1c256ef6b0cb] scsi: Get rid of struct
fc_bsg_buffer
> $ git bisect good
> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
> Author: Johannes Thumshirn <[email protected]>
> Date: Wed Oct 12 15:06:28 2016 +0200
>
> scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>
> Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
> helper variables bsg_request and bsg_reply. This will be helpfull when
> transitioning to bsg-lib.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
>
> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2 0d9fe225615679550be91fbd9f84c09ab1e280fc M drivers

From there (on the reverse bisect path) I get the following Oops,
except for the full patch set having another stack trace as in my
previous mail (dying in zfcp code).

> [ 46.942452] Oops: 0004 ilc:2 [#1] [ 46.942460] PREEMPT SMP [ 46.942465]
> [ 46.942470] Modules linked in: nf_log_ipv6 xt_pkttype nf_log_ipv4 nf_log_common xt_LOG xt_limit ip6t_REJECT nf_reject_ipv6 xt_tcpudp nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw ipt_REJECT nf_reject_ipv4 iptable_raw xt_CT iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables qeth_l2 ghash_s390 prng ecb aes_s390 des_s390 des_generic sha512_s390 sha256_s390 sha1_s390 sha_common dm_mod qeth ccwgroup zfcp qdio autofs4
> [ 46.942547] CPU: 1 PID: 1714 Comm: zfcp_ping Not tainted 4.8.0fcbsg+ #9
> [ 46.942550] Hardware name: IBM 2964 N96 702 (z/VM)
> [ 46.942556] task: 000000005c988008 task.stack: 000000005d2ec000
> [ 46.942560] Krnl PSW : 0704e00180000000 00000000007c91ec[ 46.942574] (fc_bsg_request_handler+0x404/0x4b0)
> [ 46.942579]
> [ 46.942583] R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:000:
> [ 46.942598] RI:0 EA:3
> [ 46.942601]
> [ 46.942601] Krnl GPRS: 0000000000000000 00000000ffffffcb 0000000000000000 0000000080000001
> [ 46.942603] 00000000007c8fe8 0000000064398c68 0000000069f967e8 000000006a3d8008
> [ 46.942605] 000000006a5e02c8 00000000698b5490 0000000000000000 0000000000000000
> [ 46.942607] 000000006a9ef5f8 0000000000a36840 00000000007c8fe8 000000005d2efa00
> [ 46.942619] Krnl Code: 00000000007c91de: e55dc08c0003 clfhsi 140(%r12),3[ 46.942622]
> [ 46.942622] 00000000007c91e4: a7240004 brc 2,7c91ec
> #00000000007c91e8: a7f40001 brc 15,7c91ea[ 46.942629]
> [ 46.942629] >00000000007c91ec: 5010b000 st %r1,0(%r11)
> 00000000007c91f0: e54cb0040000 mvhi 4(%r11),0[ 46.942635]
> [ 46.942635] 00000000007c91f6: e54cc08c0004 mvhi 140(%r12),4
> 00000000007c91fc: b904002c lgr %r2,%r12[ 46.942643]
> [ 46.942643] 00000000007c9200: c0e5ffffe2c0 brasl %r14,7c5780
> [ 46.942646]
> [ 46.942647] Call Trace:
> [ 46.942650] ([<00000000007c8fe8>] fc_bsg_request_handler+0x200/0x4b0)
> [ 46.942656] ([<00000000006b8e0a>] __blk_run_queue+0x52/0x68)
> [ 46.942661] ([<00000000006c549a>] blk_execute_rq_nowait+0xf2/0x110)
> [ 46.942664] ([<00000000006c557a>] blk_execute_rq+0xa2/0x110)
> [ 46.942668] ([<00000000006de0ee>] bsg_ioctl+0x1f6/0x268)
> [ 46.942675] ([<000000000036ca20>] do_vfs_ioctl+0x680/0x6d8)
> [ 46.942677] ([<000000000036caf4>] SyS_ioctl+0x7c/0xb0)
> [ 46.942685] ([<00000000009a541e>] system_call+0xd6/0x270)
> [ 46.942687] INFO: lockdep is turned off.
> [ 46.942688] Last Breaking-Event-Address:
> [ 46.942692] [<00000000007c91e4>] fc_bsg_request_handler+0x3fc/0x4b0
> [ 46.942696] [ 46.942698] Kernel panic - not syncing: Fatal exception: panic_on_oops



On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
> helper variables bsg_request and bsg_reply. This will be helpfull when
> transitioning to bsg-lib.
>
> Signed-off-by: Johannes Thumshirn <[email protected]>
> ---
> drivers/s390/scsi/zfcp_fc.c | 9 +-
> drivers/scsi/bfa/bfad_bsg.c | 40 +++---
> drivers/scsi/ibmvscsi/ibmvfc.c | 22 ++--
> drivers/scsi/libfc/fc_lport.c | 23 ++--
> drivers/scsi/lpfc/lpfc_bsg.c | 194 +++++++++++++++++-----------
> drivers/scsi/qla2xxx/qla_bsg.c | 264 ++++++++++++++++++++++-----------------
> drivers/scsi/qla2xxx/qla_iocb.c | 5 +-
> drivers/scsi/qla2xxx/qla_isr.c | 46 ++++---
> drivers/scsi/qla2xxx/qla_mr.c | 10 +-
> drivers/scsi/scsi_transport_fc.c | 37 +++---
> 10 files changed, 387 insertions(+), 263 deletions(-)


> diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
> index 8ff2067..eafc7555 100644
> --- a/drivers/scsi/scsi_transport_fc.c
> +++ b/drivers/scsi/scsi_transport_fc.c
> @@ -3588,9 +3588,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
> {
> struct request *req = job->req;
> struct request *rsp = req->next_rq;
> + struct fc_bsg_reply *bsg_reply = job->reply;
> int err;
>
> - err = job->req->errors = job->reply->result;
> + err = job->req->errors = bsg_reply->result;
>
> if (err < 0)
> /* we're only returning the result field in the reply */
> @@ -3602,10 +3603,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
> req->resid_len = 0;
>
> if (rsp) {
> - WARN_ON(job->reply->reply_payload_rcv_len > rsp->resid_len);
> + WARN_ON(bsg_reply->reply_payload_rcv_len > rsp->resid_len);
>
> /* set reply (bidi) residual */
> - rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
> + rsp->resid_len -= min(bsg_reply->reply_payload_rcv_len,
> rsp->resid_len);
> }
> blk_complete_request(req);
> @@ -3701,6 +3702,8 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
> struct fc_internal *i = to_fc_internal(shost->transportt);
> struct request *rsp = req->next_rq;
> struct fc_bsg_job *job;
> + struct fc_bsg_request *bsg_request;
> + struct fc_bsg_reply *bsg_reply;
> int ret;
>
> BUG_ON(req->special);
> @@ -3726,9 +3729,9 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
> if (i->f->dd_bsg_size)
> job->dd_data = (void *)&job[1];
> spin_lock_init(&job->job_lock);
> - job->request = (struct fc_bsg_request *)req->cmd;
> + bsg_request = (struct fc_bsg_request *)req->cmd;
> job->request_len = req->cmd_len;
> - job->reply = req->sense;
> + bsg_reply = req->sense;
> job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
> * allocated */
> if (req->bio) {
> @@ -3779,11 +3782,13 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
> struct fc_bsg_job *job)
> {
> struct fc_internal *i = to_fc_internal(shost->transportt);
> + struct fc_bsg_request *bsg_request = job->request;
> + struct fc_bsg_reply *bsg_reply = job->reply;
> int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
> int ret;
>
> /* Validate the host command */
> - switch (job->request->msgcode) {
> + switch (bsg_request->msgcode) {
> case FC_BSG_HST_ADD_RPORT:
> cmdlen += sizeof(struct fc_bsg_host_add_rport);
> break;
> @@ -3815,7 +3820,7 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
> case FC_BSG_HST_VENDOR:
> cmdlen += sizeof(struct fc_bsg_host_vendor);
> if ((shost->hostt->vendor_id == 0L) ||
> - (job->request->rqst_data.h_vendor.vendor_id !=
> + (bsg_request->rqst_data.h_vendor.vendor_id !=
> shost->hostt->vendor_id)) {
> ret = -ESRCH;
> goto fail_host_msg;
> @@ -3840,8 +3845,8 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
> fail_host_msg:
> /* return the errno failure code as the only status */
> BUG_ON(job->reply_len < sizeof(uint32_t));
> - job->reply->reply_payload_rcv_len = 0;
> - job->reply->result = ret;
> + bsg_reply->reply_payload_rcv_len = 0;
> + bsg_reply->result = ret;
> job->reply_len = sizeof(uint32_t);
> fc_bsg_jobdone(job);
> return FC_DISPATCH_UNLOCKED;
> @@ -3878,11 +3883,13 @@ fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
> struct fc_rport *rport, struct fc_bsg_job *job)
> {
> struct fc_internal *i = to_fc_internal(shost->transportt);
> + struct fc_bsg_request *bsg_request = job->request;
> + struct fc_bsg_reply *bsg_reply = job->reply;
> int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
> int ret;
>
> /* Validate the rport command */
> - switch (job->request->msgcode) {
> + switch (bsg_request->msgcode) {
> case FC_BSG_RPT_ELS:
> cmdlen += sizeof(struct fc_bsg_rport_els);
> goto check_bidi;
> @@ -3915,8 +3922,8 @@ check_bidi:
> fail_rport_msg:
> /* return the errno failure code as the only status */
> BUG_ON(job->reply_len < sizeof(uint32_t));
> - job->reply->reply_payload_rcv_len = 0;
> - job->reply->result = ret;
> + bsg_reply->reply_payload_rcv_len = 0;
> + bsg_reply->result = ret;
> job->reply_len = sizeof(uint32_t);
> fc_bsg_jobdone(job);
> return FC_DISPATCH_UNLOCKED;


> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> struct request *req;
> struct fc_bsg_job *job;
> enum fc_dispatch_result ret;
> + struct fc_bsg_reply *bsg_reply;
>
> if (!get_device(dev))
> return;
> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> /* check if we have the msgcode value at least */
> if (job->request_len < sizeof(uint32_t)) {
> BUG_ON(job->reply_len < sizeof(uint32_t));
> - job->reply->reply_payload_rcv_len = 0;
> - job->reply->result = -ENOMSG;
> + bsg_reply = job->reply;
> + bsg_reply->reply_payload_rcv_len = 0;
> + bsg_reply->result = -ENOMSG;
> job->reply_len = sizeof(uint32_t);
> fc_bsg_jobdone(job);
> spin_lock_irq(q->queue_lock);
>


--
Mit freundlichen Gr??en / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

2016-10-13 16:25:20

by Johannes Thumshirn

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
> I'm puzzled.
>
> $ git bisect start fc_bsg master
> Bisecting: 8 revisions left to test after this (roughly 3 steps)
> [005d51510eee6102636d5dbb06310531c5d46151] scsi: fc: implement kref backed
> reference counting
> $ git bisect bad
> Bisecting: 3 revisions left to test after this (roughly 2 steps)
> [bef6da201de1bb81bb4d9511f9a155862efc251f] scsi: Unify interfaces of
> fc_bsg_jobdone and bsg_job_done
> $ git bisect bad
> Bisecting: 1 revision left to test after this (roughly 1 step)
> [3087864ce3d7282f59021245d8a5f83ef1caef18] scsi: don't use
> fc_bsg_job::request and fc_bsg_job::reply directly
> $ git bisect bad
> Bisecting: 0 revisions left to test after this (roughly 0 steps)
> [81aea44720d22d2e0c4a2613ae8b1c256ef6b0cb] scsi: Get rid of struct
> fc_bsg_buffer
> > $ git bisect good
> > 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
> > commit 3087864ce3d7282f59021245d8a5f83ef1caef18
> > Author: Johannes Thumshirn <[email protected]>
> > Date: Wed Oct 12 15:06:28 2016 +0200
> >
> > scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
> >
> > Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
> > helper variables bsg_request and bsg_reply. This will be helpfull when
> > transitioning to bsg-lib.
> >
> > Signed-off-by: Johannes Thumshirn <[email protected]>
> >
> > :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2 0d9fe225615679550be91fbd9f84c09ab1e280fc M drivers
>
> From there (on the reverse bisect path) I get the following Oops,
> except for the full patch set having another stack trace as in my previous
> mail (dying in zfcp code).
>

[...]

>
> > @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> > struct request *req;
> > struct fc_bsg_job *job;
> > enum fc_dispatch_result ret;
> > + struct fc_bsg_reply *bsg_reply;
> >
> > if (!get_device(dev))
> > return;
> > @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> > /* check if we have the msgcode value at least */
> > if (job->request_len < sizeof(uint32_t)) {
> > BUG_ON(job->reply_len < sizeof(uint32_t));
> > - job->reply->reply_payload_rcv_len = 0;
> > - job->reply->result = -ENOMSG;
> > + bsg_reply = job->reply;
> > + bsg_reply->reply_payload_rcv_len = 0;
> > + bsg_reply->result = -ENOMSG;
> > job->reply_len = sizeof(uint32_t);
> > fc_bsg_jobdone(job);
> > spin_lock_irq(q->queue_lock);
> >

Ahm and what exactly can break here? It's just assigning variables. Now
I'm puzzled too.

I'll have to look into it tomorrow.

Byte,
Johannes

--
Johannes Thumshirn Storage
[email protected] +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

2016-10-28 09:55:03

by Steffen Maier

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly



On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
>> I'm puzzled.
>>
>> $ git bisect start fc_bsg master

>>> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
>>> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
>>> Author: Johannes Thumshirn <[email protected]>
>>> Date: Wed Oct 12 15:06:28 2016 +0200
>>>
>>> scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>>>
>>> Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
>>> helper variables bsg_request and bsg_reply. This will be helpfull when
>>> transitioning to bsg-lib.
>>>
>>> Signed-off-by: Johannes Thumshirn <[email protected]>
>>>
>>> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2 0d9fe225615679550be91fbd9f84c09ab1e280fc M drivers
>>
>> From there (on the reverse bisect path) I get the following Oops,
>> except for the full patch set having another stack trace as in my previous
>> mail (dying in zfcp code).
>>
>
> [...]
>
>>
>>> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
>>> struct request *req;
>>> struct fc_bsg_job *job;
>>> enum fc_dispatch_result ret;
>>> + struct fc_bsg_reply *bsg_reply;
>>>
>>> if (!get_device(dev))
>>> return;
>>> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
>>> /* check if we have the msgcode value at least */
>>> if (job->request_len < sizeof(uint32_t)) {
>>> BUG_ON(job->reply_len < sizeof(uint32_t));
>>> - job->reply->reply_payload_rcv_len = 0;
>>> - job->reply->result = -ENOMSG;
>>> + bsg_reply = job->reply;
>>> + bsg_reply->reply_payload_rcv_len = 0;
>>> + bsg_reply->result = -ENOMSG;

Compiler optimization re-ordered above two lines and the first pointer
derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
The assignment tries to write to memory at address NULL causing the
kernel page fault.

Does your suggested change for [PATCH v3 02/16], shuffling the
job->request_len checks, address above kernel page fault?

>>> job->reply_len = sizeof(uint32_t);
>>> fc_bsg_jobdone(job);
>>> spin_lock_irq(q->queue_lock);
>>>
>
> Ahm and what exactly can break here? It's just assigning variables. Now
> I'm puzzled too.


--
Mit freundlichen Gr??en / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

2016-10-28 11:31:24

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

On 10/28/2016 11:53 AM, Steffen Maier wrote:
>
>
> On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
>> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
>>> I'm puzzled.
>>>
>>> $ git bisect start fc_bsg master
>
>>>> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
>>>> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
>>>> Author: Johannes Thumshirn <[email protected]>
>>>> Date: Wed Oct 12 15:06:28 2016 +0200
>>>>
>>>> scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>>>>
>>>> Don't use fc_bsg_job::request and fc_bsg_job::reply directly,
>>>> but use
>>>> helper variables bsg_request and bsg_reply. This will be
>>>> helpfull when
>>>> transitioning to bsg-lib.
>>>>
>>>> Signed-off-by: Johannes Thumshirn <[email protected]>
>>>>
>>>> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2
>>>> 0d9fe225615679550be91fbd9f84c09ab1e280fc M drivers
>>>
>>> From there (on the reverse bisect path) I get the following Oops,
>>> except for the full patch set having another stack trace as in my
>>> previous
>>> mail (dying in zfcp code).
>>>
>>
>> [...]
>>
>>>
>>>> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue
>>>> *q, struct Scsi_Host *shost,
>>>> struct request *req;
>>>> struct fc_bsg_job *job;
>>>> enum fc_dispatch_result ret;
>>>> + struct fc_bsg_reply *bsg_reply;
>>>>
>>>> if (!get_device(dev))
>>>> return;
>>>> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue
>>>> *q, struct Scsi_Host *shost,
>>>> /* check if we have the msgcode value at least */
>>>> if (job->request_len < sizeof(uint32_t)) {
>>>> BUG_ON(job->reply_len < sizeof(uint32_t));
>>>> - job->reply->reply_payload_rcv_len = 0;
>>>> - job->reply->result = -ENOMSG;
>>>> + bsg_reply = job->reply;
>>>> + bsg_reply->reply_payload_rcv_len = 0;
>>>> + bsg_reply->result = -ENOMSG;
>
> Compiler optimization re-ordered above two lines and the first pointer
> derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
> The assignment tries to write to memory at address NULL causing the
> kernel page fault.
>
I spoke to our compiler people, and they strongly believed this not to
be the case. Or, put it the other way round, if such a thing would
happen it would be a compiler issue.

Have you checked the compiler output?

Cheers,

Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
[email protected] +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

2016-10-28 13:53:49

by Steffen Maier

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly



On 10/28/2016 01:31 PM, Hannes Reinecke wrote:
> On 10/28/2016 11:53 AM, Steffen Maier wrote:
>> On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
>>> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
>>>> I'm puzzled.
>>>>
>>>> $ git bisect start fc_bsg master
>>
>>>>> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
>>>>> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
>>>>> Author: Johannes Thumshirn <[email protected]>
>>>>> Date: Wed Oct 12 15:06:28 2016 +0200
>>>>>
>>>>> scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>>>>>
>>>>> Don't use fc_bsg_job::request and fc_bsg_job::reply directly,
>>>>> but use
>>>>> helper variables bsg_request and bsg_reply. This will be
>>>>> helpfull when
>>>>> transitioning to bsg-lib.
>>>>>
>>>>> Signed-off-by: Johannes Thumshirn <[email protected]>
>>>>>
>>>>> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2
>>>>> 0d9fe225615679550be91fbd9f84c09ab1e280fc M drivers
>>>>
>>>> From there (on the reverse bisect path) I get the following Oops,
>>>> except for the full patch set having another stack trace as in my
>>>> previous
>>>> mail (dying in zfcp code).
>>>
>>> [...]
>>>
>>>>> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue
>>>>> *q, struct Scsi_Host *shost,
>>>>> struct request *req;
>>>>> struct fc_bsg_job *job;
>>>>> enum fc_dispatch_result ret;
>>>>> + struct fc_bsg_reply *bsg_reply;
>>>>>
>>>>> if (!get_device(dev))
>>>>> return;
>>>>> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue
>>>>> *q, struct Scsi_Host *shost,
>>>>> /* check if we have the msgcode value at least */
>>>>> if (job->request_len < sizeof(uint32_t)) {
>>>>> BUG_ON(job->reply_len < sizeof(uint32_t));
>>>>> - job->reply->reply_payload_rcv_len = 0;
>>>>> - job->reply->result = -ENOMSG;
>>>>> + bsg_reply = job->reply;
>>>>> + bsg_reply->reply_payload_rcv_len = 0;
>>>>> + bsg_reply->result = -ENOMSG;
>>
>> Compiler optimization re-ordered above two lines and the first pointer
>> derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
>> The assignment tries to write to memory at address NULL causing the
>> kernel page fault.
>>
> I spoke to our compiler people, and they strongly believed this not to
> be the case. Or, put it the other way round, if such a thing would
> happen it would be a compiler issue.
>
> Have you checked the compiler output?

I just mentioned the compiler optimization to explain why the assembler
code visible in the panic dies at bsg_reply->result = -ENOMSG and not at
bsg_reply->reply_payload_rcv_len = 0. I don't think it makes a
difference regarding the issue, which remains a NULL pointer dereference
with bsg_reply either way, which I doubt is caused by compiler output.
But then again, see further down below.

> [ 46.942560] Krnl PSW : 0704e00180000000 00000000007c91ec[ 46.942574] (fc_bsg_request_handler+0x404/0x4b0)
> [ 46.942579]
> [ 46.942583] R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:000:
> [ 46.942598] RI:0 EA:3
> [ 46.942601]
> [ 46.942601] Krnl GPRS: 0000000000000000 00000000ffffffcb 0000000000000000 0000000080000001
> [ 46.942603] 00000000007c8fe8 0000000064398c68 0000000069f967e8 000000006a3d8008
> [ 46.942605] 000000006a5e02c8 00000000698b5490 0000000000000000 0000000000000000


%r11 is NULL

> [ 46.942607] 000000006a9ef5f8 0000000000a36840 00000000007c8fe8 000000005d2efa00
> [ 46.942619] Krnl Code: 00000000007c91de: e55dc08c0003 clfhsi 140(%r12),3[ 46.942622]
> [ 46.942622] 00000000007c91e4: a7240004 brc 2,7c91ec
> #00000000007c91e8: a7f40001 brc 15,7c91ea[ 46.942629]
> [ 46.942629] >00000000007c91ec: 5010b000 st %r1,0(%r11)
> 00000000007c91f0: e54cb0040000 mvhi 4(%r11),0[ 46.942635]
> [ 46.942635] 00000000007c91f6: e54cc08c0004 mvhi 140(%r12),4
> 00000000007c91fc: b904002c lgr %r2,%r12[ 46.942643]
> [ 46.942643] 00000000007c9200: c0e5ffffe2c0 brasl %r14,7c5780
> [ 46.942646]
> [ 46.942647] Call Trace:
> [ 46.942650] ([<00000000007c8fe8>] fc_bsg_request_handler+0x200/0x4b0)
> [ 46.942656] ([<00000000006b8e0a>] __blk_run_queue+0x52/0x68)
> [ 46.942661] ([<00000000006c549a>] blk_execute_rq_nowait+0xf2/0x110)
> [ 46.942664] ([<00000000006c557a>] blk_execute_rq+0xa2/0x110)
> [ 46.942668] ([<00000000006de0ee>] bsg_ioctl+0x1f6/0x268)
> [ 46.942675] ([<000000000036ca20>] do_vfs_ioctl+0x680/0x6d8)
> [ 46.942677] ([<000000000036caf4>] SyS_ioctl+0x7c/0xb0)
> [ 46.942685] ([<00000000009a541e>] system_call+0xd6/0x270)
> [ 46.942687] INFO: lockdep is turned off.
> [ 46.942688] Last Breaking-Event-Address:
> [ 46.942692] [<00000000007c91e4>] fc_bsg_request_handler+0x3fc/0x4b0
> [ 46.942696] [ 46.942698] Kernel panic - not syncing: Fatal exception: panic_on_oops

all the following was written from bottom to top:

> crash> dis -l fc_bsg_request_handler
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3943

static void
fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
struct fc_rport *rport, struct device *dev)
{

> 0x7c8de8 <fc_bsg_request_handler>: brcl 0,0x7c8de8 <fc_bsg_request_handler>
> 0x7c8dee <fc_bsg_request_handler+0x6>: stmg %r6,%r15,72(%r15)
> 0x7c8df4 <fc_bsg_request_handler+0xc>: larl %r13,0xa36840
> 0x7c8dfa <fc_bsg_request_handler+0x12>: tmll %r15,16256
> 0x7c8dfe <fc_bsg_request_handler+0x16>: lgr %r14,%r15
> 0x7c8e02 <fc_bsg_request_handler+0x1a>: je 0x7c8e04 <fc_bsg_request_handler+0x1c>
> 0x7c8e06 <fc_bsg_request_handler+0x1e>: lay %r15,-112(%r15)
> 0x7c8e0c <fc_bsg_request_handler+0x24>: stg %r14,152(%r15)
> 0x7c8e12 <fc_bsg_request_handler+0x2a>: lgr %r9,%r2
> 0x7c8e16 <fc_bsg_request_handler+0x2e>: stg %r5,176(%r15)
> 0x7c8e1c <fc_bsg_request_handler+0x34>: lgr %r2,%r5
> 0x7c8e20 <fc_bsg_request_handler+0x38>: lgr %r6,%r3
> 0x7c8e24 <fc_bsg_request_handler+0x3c>: lgr %r10,%r4
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3949
> 0x7c8e28 <fc_bsg_request_handler+0x40>: brasl %r14,0x787968 <get_device>
> 0x7c8e2e <fc_bsg_request_handler+0x46>: cgij %r2,0,8,0x7c9288 <fc_bsg_request_handler+0x4a0>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3751

there is some confusing inlining of part of fc_req_to_bsgjob

> 0x7c8e34 <fc_bsg_request_handler+0x4c>: la %r1,960(%r6)
> 0x7c8e38 <fc_bsg_request_handler+0x50>: stg %r1,168(%r15)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3749
> 0x7c8e3e <fc_bsg_request_handler+0x56>: la %r1,96(%r10)
> 0x7c8e42 <fc_bsg_request_handler+0x5a>: stg %r1,160(%r15)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3953
> 0x7c8e48 <fc_bsg_request_handler+0x60>: cgij %r10,0,8,0x7c9270 <fc_bsg_request_handler+0x488>
> 0x7c8e4e <fc_bsg_request_handler+0x66>: clc 4(4,%r13),40(%r10)
> 0x7c8e54 <fc_bsg_request_handler+0x6c>: jne 0x7c9258 <fc_bsg_request_handler+0x470>
> 0x7c8e58 <fc_bsg_request_handler+0x70>: tm 72(%r10),4
> 0x7c8e5c <fc_bsg_request_handler+0x74>: jne 0x7c9258 <fc_bsg_request_handler+0x470>
> 0x7c8e60 <fc_bsg_request_handler+0x78>: j 0x7c920a <fc_bsg_request_handler+0x422>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3961
> 0x7c8e64 <fc_bsg_request_handler+0x7c>: clc 0(4,%r13),40(%r10)
> 0x7c8e6a <fc_bsg_request_handler+0x82>: je 0x7c8e9e <fc_bsg_request_handler+0xb6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3962

fc_bsg_request_handler()
req->errors = -ENXIO;

> 0x7c8e6e <fc_bsg_request_handler+0x86>: mvhi 260(%r12),-6

crash> struct -od request.errors
struct request {
[260] int errors;
}

********************************************************************

BUT this seems the first time %r12 is used in fc_bsg_request_handler(),
especially I seem to miss %r12 being initalized with anything.
But then again I'm not at all well versed in disassembly.
Maybe fc_bsg_request_handler() is itself in turn inlined and I would
need to start disassembling even earlier to get to %r12 init?
s390x ELF ABI says %r12:
usage: Local variable, commonly used as GOT pointer;
call effect: saved.
Even if it wasn't initialized and remained NULL below why did it not
already page fault at above instruction? Silly me, we did not execute
this instruction as it's "if" conditional. This makes me wonder even
more where the content of %r12 comes from.

Ulli, Andreas, could you please shed some light on this?

********************************************************************

> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 357
> 0x7c8e74 <fc_bsg_request_handler+0x8c>: lg %r2,2600(%r9)
> 0x7c8e7a <fc_bsg_request_handler+0x92>: brasl %r14,0x9a46d0 <_raw_spin_unlock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3964
> 0x7c8e80 <fc_bsg_request_handler+0x98>: lgr %r2,%r12
> 0x7c8e84 <fc_bsg_request_handler+0x9c>: lghi %r3,-6
> 0x7c8e88 <fc_bsg_request_handler+0xa0>: brasl %r14,0x6be2f0 <blk_end_request_all>
> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 332
> 0x7c8e8e <fc_bsg_request_handler+0xa6>: lg %r2,2600(%r9)
> 0x7c8e94 <fc_bsg_request_handler+0xac>: brasl %r14,0x9a4280 <_raw_spin_lock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3966
> 0x7c8e9a <fc_bsg_request_handler+0xb2>: j 0x7c8e48 <fc_bsg_request_handler+0x60>
> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 357
> 0x7c8e9e <fc_bsg_request_handler+0xb6>: lg %r2,2600(%r9)
> 0x7c8ea4 <fc_bsg_request_handler+0xbc>: brasl %r14,0x9a46d0 <_raw_spin_unlock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3709
> 0x7c8eaa <fc_bsg_request_handler+0xc2>: ltg %r1,248(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3702
> 0x7c8eb0 <fc_bsg_request_handler+0xc8>: lg %r7,512(%r6)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3703
> 0x7c8eb6 <fc_bsg_request_handler+0xce>: lg %r8,360(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3709
> 0x7c8ebc <fc_bsg_request_handler+0xd4>: je 0x7c8ec4 <fc_bsg_request_handler+0xdc>
> 0x7c8ec0 <fc_bsg_request_handler+0xd8>: j 0x7c8ec2 <fc_bsg_request_handler+0xda>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3711
> 0x7c8ec4 <fc_bsg_request_handler+0xdc>: lg %r1,568(%r7)
> 0x7c8eca <fc_bsg_request_handler+0xe2>: llgf %r1,216(%r1)
> /home/maier/kernel/linux-vanilla/./include/linux/slab.h: 495
> 0x7c8ed0 <fc_bsg_request_handler+0xe8>: lgfi %r3,37781696
> 0x7c8ed6 <fc_bsg_request_handler+0xee>: la %r2,184(%r1)
> 0x7c8eda <fc_bsg_request_handler+0xf2>: brasl %r14,0x325e38 <__kmalloc>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3713
> 0x7c8ee0 <fc_bsg_request_handler+0xf8>: lgr %r11,%r2
> 0x7c8ee4 <fc_bsg_request_handler+0xfc>: cgij %r2,0,8,0x7c9234 <fc_bsg_request_handler+0x44c>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3725

fc_req_to_bsgjob()
req->special = job;

> 0x7c8eea <fc_bsg_request_handler+0x102>: stg %r2,248(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3726
> 0x7c8ef0 <fc_bsg_request_handler+0x108>: stg %r6,0(%r2)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3727
> 0x7c8ef6 <fc_bsg_request_handler+0x10e>: stg %r10,8(%r2)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3728

fc_req_to_bsgjob()
job->req = req;

> 0x7c8efc <fc_bsg_request_handler+0x114>: stg %r12,24(%r2)

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3729
> 0x7c8f02 <fc_bsg_request_handler+0x11a>: lg %r1,568(%r7)
> 0x7c8f08 <fc_bsg_request_handler+0x120>: lt %r1,216(%r1)
> 0x7c8f0e <fc_bsg_request_handler+0x126>: je 0x7c8f1c <fc_bsg_request_handler+0x134>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3730
> 0x7c8f12 <fc_bsg_request_handler+0x12a>: la %r1,184(%r2)
> 0x7c8f16 <fc_bsg_request_handler+0x12e>: stg %r1,176(%r2)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3731
> 0x7c8f1c <fc_bsg_request_handler+0x134>: larl %r4,0x2054808 <proc_scsi+0x48>
> 0x7c8f22 <fc_bsg_request_handler+0x13a>: larl %r3,0xbddbd8
> 0x7c8f28 <fc_bsg_request_handler+0x140>: la %r2,32(%r11)
> 0x7c8f2c <fc_bsg_request_handler+0x144>: brasl %r14,0x1b7ac8 <__raw_spin_lock_init>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3733
> 0x7c8f32 <fc_bsg_request_handler+0x14a>: llh %r1,288(%r12)
> 0x7c8f38 <fc_bsg_request_handler+0x150>: st %r1,136(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3735
> 0x7c8f3c <fc_bsg_request_handler+0x154>: mvhi 140(%r11),96
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3737
> 0x7c8f42 <fc_bsg_request_handler+0x15a>: ltg %r1,104(%r12)
> 0x7c8f48 <fc_bsg_request_handler+0x160>: jne 0x7c8f56 <fc_bsg_request_handler+0x16e>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3742
> 0x7c8f4c <fc_bsg_request_handler+0x164>: cgij %r8,0,6,0x7c8f84 <fc_bsg_request_handler+0x19c>
> 0x7c8f52 <fc_bsg_request_handler+0x16a>: j 0x7c8f6e <fc_bsg_request_handler+0x186>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3738
> 0x7c8f56 <fc_bsg_request_handler+0x16e>: lgr %r3,%r12
> 0x7c8f5a <fc_bsg_request_handler+0x172>: la %r2,144(%r11)
> 0x7c8f5e <fc_bsg_request_handler+0x176>: brasl %r14,0x7c56c8 <fc_bsg_map_buffer>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3739
> 0x7c8f64 <fc_bsg_request_handler+0x17c>: cij %r2,0,8,0x7c8f4c <fc_bsg_request_handler+0x164>
> 0x7c8f6a <fc_bsg_request_handler+0x182>: j 0x7c900e <fc_bsg_request_handler+0x226>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3747
> 0x7c8f6e <fc_bsg_request_handler+0x186>: larl %r1,0x7c5780 <fc_bsg_jobdone>
> 0x7c8f74 <fc_bsg_request_handler+0x18c>: stg %r1,112(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3748
> 0x7c8f7a <fc_bsg_request_handler+0x192>: cgij %r10,0,6,0x7c8fa6 <fc_bsg_request_handler+0x1be>
> 0x7c8f80 <fc_bsg_request_handler+0x198>: j 0x7c8fd2 <fc_bsg_request_handler+0x1ea>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3742
> 0x7c8f84 <fc_bsg_request_handler+0x19c>: ltg %r1,104(%r8)
> 0x7c8f8a <fc_bsg_request_handler+0x1a2>: je 0x7c8f6e <fc_bsg_request_handler+0x186>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3743
> 0x7c8f8e <fc_bsg_request_handler+0x1a6>: lgr %r3,%r8
> 0x7c8f92 <fc_bsg_request_handler+0x1aa>: la %r2,160(%r11)
> 0x7c8f96 <fc_bsg_request_handler+0x1ae>: brasl %r14,0x7c56c8 <fc_bsg_map_buffer>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3744
> 0x7c8f9c <fc_bsg_request_handler+0x1b4>: cij %r2,0,8,0x7c8f6e <fc_bsg_request_handler+0x186>
> 0x7c8fa2 <fc_bsg_request_handler+0x1ba>: j 0x7c9002 <fc_bsg_request_handler+0x21a>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3749
> 0x7c8fa6 <fc_bsg_request_handler+0x1be>: lg %r2,160(%r15)
> 0x7c8fac <fc_bsg_request_handler+0x1c4>: stg %r2,16(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3752
> 0x7c8fb2 <fc_bsg_request_handler+0x1ca>: brasl %r14,0x787968 <get_device>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3754
> 0x7c8fb8 <fc_bsg_request_handler+0x1d0>: mvhi 108(%r11),1
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3979

fc_bsg_request_handler()
job = req->special;

> 0x7c8fbe <fc_bsg_request_handler+0x1d6>: lg %r12,248(%r12)

crash> struct -od request.special
struct request {
[248] void *special;
}

********************************************************************

so above %r12 did contain req, below it contains job.
since we could deref req further up it must have been non-NULL and
pointing to a mapped page, but req->special is NULL here?
well, req could even have been NULL and we read from address 248 in low
core here which does not trigger a page fault (only on write to low core).

crash> x/g 248
0xf8 <_text+248>: 0x0

********************************************************************

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3982
> 0x7c8fc4 <fc_bsg_request_handler+0x1dc>: l %r1,136(%r12)
> 0x7c8fc8 <fc_bsg_request_handler+0x1e0>: clij %r1,3,12,0x7c901c <fc_bsg_request_handler+0x234>
> 0x7c8fce <fc_bsg_request_handler+0x1e6>: j 0x7c905c <fc_bsg_request_handler+0x274>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3751
> 0x7c8fd2 <fc_bsg_request_handler+0x1ea>: lg %r1,168(%r15)
> 0x7c8fd8 <fc_bsg_request_handler+0x1f0>: stg %r1,16(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3752
> 0x7c8fde <fc_bsg_request_handler+0x1f6>: lgr %r2,%r1
> 0x7c8fe2 <fc_bsg_request_handler+0x1fa>: brasl %r14,0x787968 <get_device>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3754
> 0x7c8fe8 <fc_bsg_request_handler+0x200>: mvhi 108(%r11),1
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3979
> 0x7c8fee <fc_bsg_request_handler+0x206>: lg %r12,248(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3982
> 0x7c8ff4 <fc_bsg_request_handler+0x20c>: l %r1,136(%r12)
> 0x7c8ff8 <fc_bsg_request_handler+0x210>: clij %r1,3,12,0x7c901c <fc_bsg_request_handler+0x234>
> 0x7c8ffe <fc_bsg_request_handler+0x216>: j 0x7c90f4 <fc_bsg_request_handler+0x30c>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3760
> 0x7c9002 <fc_bsg_request_handler+0x21a>: lg %r2,152(%r11)
> 0x7c9008 <fc_bsg_request_handler+0x220>: brasl %r14,0x328ff0 <kfree>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3762
> 0x7c900e <fc_bsg_request_handler+0x226>: lgr %r2,%r11
> 0x7c9012 <fc_bsg_request_handler+0x22a>: brasl %r14,0x328ff0 <kfree>
> 0x7c9018 <fc_bsg_request_handler+0x230>: j 0x7c9234 <fc_bsg_request_handler+0x44c>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3983
> 0x7c901c <fc_bsg_request_handler+0x234>: clfhsi 140(%r12),3
> 0x7c9022 <fc_bsg_request_handler+0x23a>: jh 0x7c902a <fc_bsg_request_handler+0x242>
> 0x7c9026 <fc_bsg_request_handler+0x23e>: j 0x7c9028 <fc_bsg_request_handler+0x240>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3984
> 0x7c902a <fc_bsg_request_handler+0x242>: lg %r1,128(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3985
> 0x7c9030 <fc_bsg_request_handler+0x248>: mvhi 4(%r1),0
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3986
> 0x7c9036 <fc_bsg_request_handler+0x24e>: mvhi 0(%r1),-42
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3988
> 0x7c903c <fc_bsg_request_handler+0x254>: lgr %r2,%r12
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3987
> 0x7c9040 <fc_bsg_request_handler+0x258>: mvhi 140(%r12),4
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3988
> 0x7c9046 <fc_bsg_request_handler+0x25e>: brasl %r14,0x7c5780 <fc_bsg_jobdone>
> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 332
> 0x7c904c <fc_bsg_request_handler+0x264>: lg %r2,2600(%r9)
> 0x7c9052 <fc_bsg_request_handler+0x26a>: brasl %r14,0x9a4280 <_raw_spin_lock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3990
> 0x7c9058 <fc_bsg_request_handler+0x270>: j 0x7c8e48 <fc_bsg_request_handler+0x60>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3892
> 0x7c905c <fc_bsg_request_handler+0x274>: lg %r2,120(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3887
> 0x7c9062 <fc_bsg_request_handler+0x27a>: lg %r11,128(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3892
> 0x7c9068 <fc_bsg_request_handler+0x280>: l %r2,0(%r2)
> 0x7c906c <fc_bsg_request_handler+0x284>: iilf %r3,1073741825
> 0x7c9072 <fc_bsg_request_handler+0x28a>: crj %r2,%r3,8,0x7c9088 <fc_bsg_request_handler+0x2a0>
> 0x7c9078 <fc_bsg_request_handler+0x290>: iilf %r3,1073741826
> 0x7c907e <fc_bsg_request_handler+0x296>: crj %r2,%r3,8,0x7c9090 <fc_bsg_request_handler+0x2a8>
> 0x7c9084 <fc_bsg_request_handler+0x29c>: j 0x7c90d2 <fc_bsg_request_handler+0x2ea>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3894
> 0x7c9088 <fc_bsg_request_handler+0x2a0>: lhi %r2,5
> 0x7c908c <fc_bsg_request_handler+0x2a4>: j 0x7c9094 <fc_bsg_request_handler+0x2ac>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3898
> 0x7c9090 <fc_bsg_request_handler+0x2a8>: lhi %r2,16
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3901
> 0x7c9094 <fc_bsg_request_handler+0x2ac>: lt %r3,144(%r12)
> 0x7c909a <fc_bsg_request_handler+0x2b2>: je 0x7c90da <fc_bsg_request_handler+0x2f2>
> 0x7c909e <fc_bsg_request_handler+0x2b6>: lt %r3,160(%r12)
> 0x7c90a4 <fc_bsg_request_handler+0x2bc>: je 0x7c90da <fc_bsg_request_handler+0x2f2>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3913
> 0x7c90a8 <fc_bsg_request_handler+0x2c0>: clrj %r2,%r1,2,0x7c90e2 <fc_bsg_request_handler+0x2fa>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3918
> 0x7c90ae <fc_bsg_request_handler+0x2c6>: lg %r1,512(%r6)
> 0x7c90b4 <fc_bsg_request_handler+0x2cc>: lg %r1,568(%r1)
> 0x7c90ba <fc_bsg_request_handler+0x2d2>: lg %r1,192(%r1)
> 0x7c90c0 <fc_bsg_request_handler+0x2d8>: lgr %r2,%r12
> 0x7c90c4 <fc_bsg_request_handler+0x2dc>: basr %r14,%r1
> 0x7c90c6 <fc_bsg_request_handler+0x2de>: lr %r1,%r2
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3919
> 0x7c90c8 <fc_bsg_request_handler+0x2e0>: cij %r2,0,6,0x7c90e6 <fc_bsg_request_handler+0x2fe>
> 0x7c90ce <fc_bsg_request_handler+0x2e6>: j 0x7c9248 <fc_bsg_request_handler+0x460>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3908
> 0x7c90d2 <fc_bsg_request_handler+0x2ea>: lhi %r1,-53
> 0x7c90d6 <fc_bsg_request_handler+0x2ee>: j 0x7c90e6 <fc_bsg_request_handler+0x2fe>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3903
> 0x7c90da <fc_bsg_request_handler+0x2f2>: lhi %r1,-22
> 0x7c90de <fc_bsg_request_handler+0x2f6>: j 0x7c90e6 <fc_bsg_request_handler+0x2fe>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3914
> 0x7c90e2 <fc_bsg_request_handler+0x2fa>: lhi %r1,-42
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3924
> 0x7c90e6 <fc_bsg_request_handler+0x2fe>: clfhsi 140(%r12),3
> 0x7c90ec <fc_bsg_request_handler+0x304>: jh 0x7c91ec <fc_bsg_request_handler+0x404>
> 0x7c90f0 <fc_bsg_request_handler+0x308>: j 0x7c90f2 <fc_bsg_request_handler+0x30a>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3785

fc_bsg_host_dispatch()
struct fc_bsg_request *bsg_request = job->request;

> 0x7c90f4 <fc_bsg_request_handler+0x30c>: lg %r3,120(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3786

fc_bsg_host_dispatch()
struct fc_bsg_reply *bsg_reply = job->reply;

> 0x7c90fa <fc_bsg_request_handler+0x312>: lg %r11,128(%r12)

load content of address in %r12 with displacement 128 into %r11.
so presumably job->reply is NULL.
due to funny inlining incl. fc_bsg_host_dispatch(), it's tricky to
backtrack where job in %r12 came from and what happened to it on the way.
%r11 is not clobbered until used below where the page fault happens.
displacement is consistent:
crash> struct -od fc_bsg_job
struct fc_bsg_job {
[0] struct Scsi_Host *shost;
[8] struct fc_rport *rport;
[16] struct device *dev;
[24] struct request *req;
[32] spinlock_t job_lock;
[104] unsigned int state_flags;
[108] unsigned int ref_cnt;
[112] void (*job_done)(struct fc_bsg_job *);
[120] struct fc_bsg_request *request;
[128] struct fc_bsg_reply *reply;
[136] unsigned int request_len;
[140] unsigned int reply_len;
[144] struct bsg_buffer request_payload;
[160] struct bsg_buffer reply_payload;
[176] void *dd_data;
}
SIZE: 184

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3791
> 0x7c9100 <fc_bsg_request_handler+0x318>: l %r2,0(%r3)
> 0x7c9104 <fc_bsg_request_handler+0x31c>: clfi %r2,2147483651
> 0x7c910a <fc_bsg_request_handler+0x322>: je 0x7c913e <fc_bsg_request_handler+0x356>
> 0x7c910e <fc_bsg_request_handler+0x326>: jh 0x7c9122 <fc_bsg_request_handler+0x33a>
> 0x7c9112 <fc_bsg_request_handler+0x32a>: iilf %r3,2147483649
> 0x7c9118 <fc_bsg_request_handler+0x330>: clrj %r2,%r3,10,0x7c9194 <fc_bsg_request_handler+0x3ac>
> 0x7c911e <fc_bsg_request_handler+0x336>: j 0x7c91c2 <fc_bsg_request_handler+0x3da>
> 0x7c9122 <fc_bsg_request_handler+0x33a>: iilf %r4,2147483652
> 0x7c9128 <fc_bsg_request_handler+0x340>: crj %r2,%r4,8,0x7c9156 <fc_bsg_request_handler+0x36e>
> 0x7c912e <fc_bsg_request_handler+0x346>: iilf %r4,2147483903
> 0x7c9134 <fc_bsg_request_handler+0x34c>: crj %r2,%r4,8,0x7c9172 <fc_bsg_request_handler+0x38a>
> 0x7c913a <fc_bsg_request_handler+0x352>: j 0x7c91c2 <fc_bsg_request_handler+0x3da>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3803
> 0x7c913e <fc_bsg_request_handler+0x356>: lt %r2,144(%r12)
> 0x7c9144 <fc_bsg_request_handler+0x35c>: je 0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c9148 <fc_bsg_request_handler+0x360>: lt %r2,160(%r12)
> 0x7c914e <fc_bsg_request_handler+0x366>: je 0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c9152 <fc_bsg_request_handler+0x36a>: j 0x7c9194 <fc_bsg_request_handler+0x3ac>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3813
> 0x7c9156 <fc_bsg_request_handler+0x36e>: lt %r2,144(%r12)
> 0x7c915c <fc_bsg_request_handler+0x374>: je 0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c9160 <fc_bsg_request_handler+0x378>: lt %r2,160(%r12)
> 0x7c9166 <fc_bsg_request_handler+0x37e>: je 0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c916a <fc_bsg_request_handler+0x382>: lhi %r2,20
> 0x7c916e <fc_bsg_request_handler+0x386>: j 0x7c9198 <fc_bsg_request_handler+0x3b0>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3822
> 0x7c9172 <fc_bsg_request_handler+0x38a>: lg %r2,504(%r6)
> 0x7c9178 <fc_bsg_request_handler+0x390>: ltg %r2,304(%r2)
> 0x7c917e <fc_bsg_request_handler+0x396>: je 0x7c91d2 <fc_bsg_request_handler+0x3ea>
> 0x7c9182 <fc_bsg_request_handler+0x39a>: cg %r2,4(%r3)
> 0x7c9188 <fc_bsg_request_handler+0x3a0>: jne 0x7c91d2 <fc_bsg_request_handler+0x3ea>
> 0x7c918c <fc_bsg_request_handler+0x3a4>: lhi %r2,12
> 0x7c9190 <fc_bsg_request_handler+0x3a8>: j 0x7c9198 <fc_bsg_request_handler+0x3b0>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3791
> 0x7c9194 <fc_bsg_request_handler+0x3ac>: lhi %r2,8
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3836
> 0x7c9198 <fc_bsg_request_handler+0x3b0>: clrj %r2,%r1,2,0x7c91da <fc_bsg_request_handler+0x3f2>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3841
> 0x7c919e <fc_bsg_request_handler+0x3b6>: lg %r1,512(%r6)
> 0x7c91a4 <fc_bsg_request_handler+0x3bc>: lg %r1,568(%r1)
> 0x7c91aa <fc_bsg_request_handler+0x3c2>: lg %r1,192(%r1)
> 0x7c91b0 <fc_bsg_request_handler+0x3c8>: lgr %r2,%r12
> 0x7c91b4 <fc_bsg_request_handler+0x3cc>: basr %r14,%r1
> 0x7c91b6 <fc_bsg_request_handler+0x3ce>: lr %r1,%r2
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3842
> 0x7c91b8 <fc_bsg_request_handler+0x3d0>: cij %r2,0,6,0x7c91de <fc_bsg_request_handler+0x3f6>
> 0x7c91be <fc_bsg_request_handler+0x3d6>: j 0x7c9248 <fc_bsg_request_handler+0x460>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3831
> 0x7c91c2 <fc_bsg_request_handler+0x3da>: lhi %r1,-53
> 0x7c91c6 <fc_bsg_request_handler+0x3de>: j 0x7c91de <fc_bsg_request_handler+0x3f6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3805
> 0x7c91ca <fc_bsg_request_handler+0x3e2>: lhi %r1,-22
> 0x7c91ce <fc_bsg_request_handler+0x3e6>: j 0x7c91de <fc_bsg_request_handler+0x3f6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3825
> 0x7c91d2 <fc_bsg_request_handler+0x3ea>: lhi %r1,-3
> 0x7c91d6 <fc_bsg_request_handler+0x3ee>: j 0x7c91de <fc_bsg_request_handler+0x3f6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3837
> 0x7c91da <fc_bsg_request_handler+0x3f2>: lhi %r1,-42
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3847

fc_bsg_host_dispatch()

fail_host_msg:
/* return the errno failure code as the only status */
BUG_ON(job->reply_len < sizeof(uint32_t));

> 0x7c91de <fc_bsg_request_handler+0x3f6>: clfhsi 140(%r12),3
> 0x7c91e4 <fc_bsg_request_handler+0x3fc>: jh 0x7c91ec <fc_bsg_request_handler+0x404>
> 0x7c91e8 <fc_bsg_request_handler+0x400>: j 0x7c91ea <fc_bsg_request_handler+0x402>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3849

bsg_reply->result = ret;

> 0x7c91ec <fc_bsg_request_handler+0x404>: st %r1,0(%r11)

that store causes the kernel page fault because %r11 is NULL and with
displacement 0 it still is NULL.

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3848

bsg_reply->reply_payload_rcv_len = 0;

> 0x7c91f0 <fc_bsg_request_handler+0x408>: mvhi 4(%r11),0

if we would have gotten this far:
16-bit signed immediate 0 is extended to 4-bytes and stored to where
%r11 with displacement 4 points to.
displacements nicely match structure fields:
crash> struct -od fc_bsg_reply
struct fc_bsg_reply {
[0] uint32_t result;
[4] uint32_t reply_payload_rcv_len;
union {
struct fc_bsg_host_vendor_reply vendor_reply;
struct fc_bsg_ctels_reply ctels_reply;
[8] } reply_data;
}
SIZE: 16

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3850

job->reply_len = sizeof(uint32_t);

> 0x7c91f6 <fc_bsg_request_handler+0x40e>: mvhi 140(%r12),4
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3851
> 0x7c91fc <fc_bsg_request_handler+0x414>: lgr %r2,%r12
> 0x7c9200 <fc_bsg_request_handler+0x418>: brasl %r14,0x7c5780 <fc_bsg_jobdone>

source code is based on
> $ git log --graph --oneline
> * 271c1723d9c8 scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
> * a3c95a6c69e4 scsi: Get rid of struct fc_bsg_buffer
> * 1573d2caf713 Merge branch 'parisc-4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux




--
Mit freundlichen Gr??en / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

2016-10-28 16:30:01

by Andreas Krebbel1

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

> On 10/28/2016 01:31 PM, Hannes Reinecke wrote:
> > On 10/28/2016 11:53 AM, Steffen Maier wrote:
> >> On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
> >>> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
...
> fc_bsg_request_handler()
> req->errors = -ENXIO;
>
> > 0x7c8e6e <fc_bsg_request_handler+0x86>: mvhi 260(%r12),-6
>
> crash> struct -od request.errors
> struct request {
> [260] int errors;
> }
>
> ********************************************************************
>
> BUT this seems the first time %r12 is used in fc_bsg_request_handler(),
> especially I seem to miss %r12 being initalized with anything.
> But then again I'm not at all well versed in disassembly.
> Maybe fc_bsg_request_handler() is itself in turn inlined and I would
> need to start disassembling even earlier to get to %r12 init?
> s390x ELF ABI says %r12:
> usage: Local variable, commonly used as GOT pointer;
> call effect: saved.
> Even if it wasn't initialized and remained NULL below why did it not
> already page fault at above instruction? Silly me, we did not execute
> this instruction as it's "if" conditional. This makes me wonder even
> more where the content of %r12 comes from.
>
> Ulli, Andreas, could you please shed some light on this?
>
> ********************************************************************

r12 holds variable req for that access. It is initialized here:

req = blk_fetch_request(q);
if (!req)
break;

The asm code ends up down below in the function and loads the return value
into r12. The code
invoking blk_fetch_request got duplicated and there are three jumps before
the r12 access to these
locations.

7c8e48: ec a8 02 14 00 7c cgije %r10,0,7c9270
<fc_bsg_request_handler+0x488> <--- x
7c8e4e: d5 03 d0 04 a0 28 clc 4(4,%r13),40(%r10)
7c8e54: a7 74 02 02 jne 7c9258
<fc_bsg_request_handler+0x470> <--- y
7c8e58: 91 04 a0 48 tm 72(%r10),4
7c8e5c: a7 74 01 fe jne 7c9258
<fc_bsg_request_handler+0x470> <--- y
7c8e60: a7 f4 01 d5 j 7c920a
<fc_bsg_request_handler+0x422>
7c8e64: d5 03 d0 00 a0 28 clc 0(4,%r13),40(%r10)
7c8e6a: a7 84 00 1a je 7c8e9e
<fc_bsg_request_handler+0xb6>
7c8e6e: e5 4c c1 04 ff fa mvhi 260(%r12),-6
...

7c9258: b9 04 00 29 lgr %r2,%r9
7c925c: c0 e5 ff f7 b3 a6 brasl %r14,6bf9a8
<blk_fetch_request>
7c9262: b9 04 00 c2 lgr %r12,%r2
7c9266: ec 26 fd ff 00 7c cgijne %r2,0,7c8e64
<fc_bsg_request_handler+0x7c>
7c926c: a7 f4 ff cf j 7c920a
<fc_bsg_request_handler+0x422>

7c9270: b9 04 00 29 lgr %r2,%r9
7c9274: c0 e5 ff f7 b3 9a brasl %r14,6bf9a8
<blk_fetch_request>
7c927a: b9 04 00 c2 lgr %r12,%r2
7c927e: ec 26 fe 10 00 7c cgijne %r2,0,7c8e9e
<fc_bsg_request_handler+0xb6>

-Andreas-


2016-10-30 17:57:26

by Johannes Thumshirn

[permalink] [raw]
Subject: Re: [PATCH v2 02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

On Fri, Oct 28, 2016 at 11:53:46AM +0200, Steffen Maier wrote:

[...]

> > >
> > > > @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> > > > struct request *req;
> > > > struct fc_bsg_job *job;
> > > > enum fc_dispatch_result ret;
> > > > + struct fc_bsg_reply *bsg_reply;
> > > >
> > > > if (!get_device(dev))
> > > > return;
> > > > @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> > > > /* check if we have the msgcode value at least */
> > > > if (job->request_len < sizeof(uint32_t)) {
> > > > BUG_ON(job->reply_len < sizeof(uint32_t));
> > > > - job->reply->reply_payload_rcv_len = 0;
> > > > - job->reply->result = -ENOMSG;
> > > > + bsg_reply = job->reply;
> > > > + bsg_reply->reply_payload_rcv_len = 0;
> > > > + bsg_reply->result = -ENOMSG;
>
> Compiler optimization re-ordered above two lines and the first pointer
> derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
> The assignment tries to write to memory at address NULL causing the kernel
> page fault.
>
> Does your suggested change for [PATCH v3 02/16], shuffling the
> job->request_len checks, address above kernel page fault?

This is what I hope at least. I'm sorry but I don't have any experience with s390
and zfcp at all. I still need to get a test environment set up, but all the
people knowing how to do are rather busy at the moment. All my tests on x86_64
with FCoE and lpfc haven't had a problem so far.

Thanks,
Johannes
--
Johannes Thumshirn Storage
[email protected] +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850