* [PATCH RFC/RFT 00/10] add block layer bsg helper lib
@ 2011-07-24 8:59 michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 01/10] block: add bsg heler library michaelc
` (9 more replies)
0 siblings, 10 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi
The following patches move the FC bsg code to the block
dir, and make them more generic so other classes and
drivers can use them. I added bsg support to iscsi and
I converted the FC class and FC drivers (they were
a lot more complicated than SAS so I did them first to
make sure it would work).
I have tested the iscsi code but have not been able to
test any of the FC code.
Patches were made over scsi-misc.
v2:
- Move FC bsg code to block layer.
v1:
- Moved FC bsg code to scsi layer.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 01/10] block: add bsg heler library
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 18:32 ` Jens Axboe
2011-07-24 8:59 ` [PATCH RFC/RFT 02/10] iscsi class: add bsg support to iscsi class michaelc
` (8 subsequent siblings)
9 siblings, 1 reply; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Jens Axboe
From: Mike Christie <michaelc@cs.wisc.edu>
This moves the FC classes bsg code to the block layer and
makes it a lib so that other classes like iscsi and SAS can use it.
It is helpful because working with the request queue, bios,
creating scatterlists, etc are a pain that the LLD does not
have to worry about with normal IOs and should not have to
worry about for bsg requests.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Jens Axboe <jaxboe@fusionio.com>
---
block/Kconfig | 10 ++
block/Makefile | 1 +
block/bsg-lib.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/blkdev.h | 4 +
include/linux/bsg-lib.h | 73 ++++++++++++
5 files changed, 385 insertions(+), 0 deletions(-)
create mode 100644 block/bsg-lib.c
create mode 100644 include/linux/bsg-lib.h
diff --git a/block/Kconfig b/block/Kconfig
index 60be1e0..e97934e 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -65,6 +65,16 @@ config BLK_DEV_BSG
If unsure, say Y.
+config BLK_DEV_BSGLIB
+ bool "Block layer SG support v4 helper lib"
+ default n
+ select BLK_DEV_BSG
+ help
+ Subsystems will normally enable this if needed. Users will not
+ normally need to manually enable this.
+
+ If unsure, say N.
+
config BLK_DEV_INTEGRITY
bool "Block layer data integrity support"
---help---
diff --git a/block/Makefile b/block/Makefile
index 0fec4b3..514c6e4 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
blk-iopoll.o blk-lib.o ioctl.o genhd.o scsi_ioctl.o
obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
+obj-$(CONFIG_BLK_DEV_BSGLIB) += bsg-lib.o
obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o
obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
diff --git a/block/bsg-lib.c b/block/bsg-lib.c
new file mode 100644
index 0000000..f8c0a61
--- /dev/null
+++ b/block/bsg-lib.c
@@ -0,0 +1,297 @@
+/*
+ * BSG helper library
+ *
+ * Copyright (C) 2008 James Smart, Emulex Corporation
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2011 Mike Christie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/scatterlist.h>
+#include <linux/bsg-lib.h>
+#include <scsi/scsi_cmnd.h>
+
+/**
+ * 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)
+{
+ put_device(job->dev); /* release reference for the request */
+
+ kfree(job->request_payload.sg_list);
+ kfree(job->reply_payload.sg_list);
+ kfree(job);
+}
+
+/**
+ * bsg_job_done - completion routine for bsg requests
+ * @job: bsg_job that is complete
+ * @result: job reply result
+ * @reply_payload_rcv_len: length of payload recvd
+ *
+ * The LLD should call this when the bsg job has completed.
+ */
+void bsg_job_done(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(u32);
+ 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(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)
+{
+ struct bsg_job *job = rq->special;
+
+ blk_end_request_all(rq, rq->errors);
+ bsg_destroy_job(job);
+}
+
+static int 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;
+}
+
+/**
+ * bsg_create_job - create the bsg_job structure for the bsg request
+ * @dev: device that is being sent the bsg request
+ * @req: BSG request that needs a job structure
+ */
+static int bsg_create_job(struct device *dev, struct request *req)
+{
+ struct request *rsp = req->next_rq;
+ struct request_queue *q = req->q;
+ struct bsg_job *job;
+ int ret;
+
+ BUG_ON(req->special);
+
+ job = kzalloc(sizeof(struct bsg_job) + q->bsg_job_size, GFP_KERNEL);
+ if (!job)
+ return -ENOMEM;
+
+ req->special = job;
+ job->req = req;
+ if (q->bsg_job_size)
+ job->dd_data = (void *)&job[1];
+ job->request = req->cmd;
+ job->request_len = req->cmd_len;
+ job->reply = req->sense;
+ job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
+ * allocated */
+ if (req->bio) {
+ ret = bsg_map_buffer(&job->request_payload, req);
+ if (ret)
+ goto failjob_rls_job;
+ }
+ if (rsp && rsp->bio) {
+ ret = bsg_map_buffer(&job->reply_payload, rsp);
+ if (ret)
+ goto failjob_rls_rqst_payload;
+ }
+ job->dev = dev;
+ /* take a reference for the request */
+ get_device(job->dev);
+ return 0;
+
+failjob_rls_rqst_payload:
+ kfree(job->request_payload.sg_list);
+failjob_rls_job:
+ kfree(job);
+ return -ENOMEM;
+}
+
+/*
+ * bsg_goose_queue - restart queue in case it was stopped
+ * @q: request q to be restarted
+ */
+void bsg_goose_queue(struct request_queue *q)
+{
+ if (!q)
+ return;
+
+ blk_run_queue_async(q);
+}
+EXPORT_SYMBOL_GPL(bsg_goose_queue);
+
+/**
+ * bsg_request_fn - generic handler for bsg requests
+ * @q: request queue to manage
+ *
+ * On error the create_bsg_job function should return a -Exyz error value
+ * that will be set to the req->errors.
+ *
+ * Drivers/subsys should pass this to the queue init function.
+ */
+void bsg_request_fn(struct request_queue *q)
+{
+ struct device *dev = q->queuedata;
+ struct request *req;
+ struct bsg_job *job;
+ int ret;
+
+ if (!get_device(dev))
+ return;
+
+ while (1) {
+ req = blk_fetch_request(q);
+ if (!req)
+ break;
+ spin_unlock_irq(q->queue_lock);
+
+ ret = bsg_create_job(dev, req);
+ if (ret) {
+ req->errors = ret;
+ blk_end_request_all(req, ret);
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
+ job = req->special;
+ ret = q->bsg_job_fn(job);
+ spin_lock_irq(q->queue_lock);
+ if (ret)
+ break;
+ }
+
+ spin_unlock_irq(q->queue_lock);
+ put_device(dev);
+ spin_lock_irq(q->queue_lock);
+}
+EXPORT_SYMBOL_GPL(bsg_request_fn);
+
+/**
+ * bsg_setup_queue - Create and add the bsg hooks so we can receive requests
+ * @dev: device to attach bsg device to
+ * @q: request queue setup by caller
+ * @name: device to give bsg device
+ * @job_fn: bsg job handler
+ * @dd_job_size: size of LLD data needed for each job
+ *
+ * The caller should have setup the reuqest queue with bsg_request_fn
+ * as the request_fn.
+ */
+int bsg_setup_queue(struct device *dev, struct request_queue *q,
+ char *name, bsg_job_fn *job_fn, int dd_job_size)
+{
+ int ret;
+
+ q->queuedata = dev;
+ q->bsg_job_size = dd_job_size;
+ q->bsg_job_fn = job_fn;
+ queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
+ blk_queue_softirq_done(q, bsg_softirq_done);
+ blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
+
+ ret = bsg_register_queue(q, dev, name, NULL);
+ if (ret) {
+ printk(KERN_ERR "%s: bsg interface failed to "
+ "initialize - register queue\n", dev->kobj.name);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bsg_setup_queue);
+
+/**
+ * bsg_remove_queue - Deletes the bsg dev from the q
+ * @q: the request_queue that is to be torn down.
+ *
+ * Notes:
+ * Before unregistering the queue empty any requests that are blocked
+ */
+void bsg_remove_queue(struct request_queue *q)
+{
+ struct request *req; /* block request */
+ int counts; /* totals for request_list count and starved */
+
+ if (!q)
+ return;
+
+ /* Stop taking in new requests */
+ spin_lock_irq(q->queue_lock);
+ blk_stop_queue(q);
+
+ /* drain all requests in the queue */
+ while (1) {
+ /* need the lock to fetch a request
+ * this may fetch the same reqeust as the previous pass
+ */
+ req = blk_fetch_request(q);
+ /* save requests in use and starved */
+ counts = q->rq.count[0] + q->rq.count[1] +
+ q->rq.starved[0] + q->rq.starved[1];
+ spin_unlock_irq(q->queue_lock);
+ /* any requests still outstanding? */
+ if (counts == 0)
+ break;
+
+ /* This may be the same req as the previous iteration,
+ * always send the blk_end_request_all after a prefetch.
+ * It is not okay to not end the request because the
+ * prefetch started the request.
+ */
+ if (req) {
+ /* return -ENXIO to indicate that this queue is
+ * going away
+ */
+ req->errors = -ENXIO;
+ blk_end_request_all(req, -ENXIO);
+ }
+
+ msleep(200); /* allow bsg to possibly finish */
+ spin_lock_irq(q->queue_lock);
+ }
+ bsg_unregister_queue(q);
+}
+EXPORT_SYMBOL_GPL(bsg_remove_queue);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 1a23722..6434d66 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -30,6 +30,7 @@ struct request_pm_state;
struct blk_trace;
struct request;
struct sg_io_hdr;
+struct bsg_job;
#define BLKDEV_MIN_RQ 4
#define BLKDEV_MAX_RQ 128 /* Default maximum */
@@ -209,6 +210,7 @@ typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *,
typedef void (softirq_done_fn)(struct request *);
typedef int (dma_drain_needed_fn)(struct request *);
typedef int (lld_busy_fn) (struct request_queue *q);
+typedef int (bsg_job_fn) (struct bsg_job *);
enum blk_eh_timer_return {
BLK_EH_NOT_HANDLED,
@@ -376,6 +378,8 @@ struct request_queue
struct mutex sysfs_lock;
#if defined(CONFIG_BLK_DEV_BSG)
+ bsg_job_fn *bsg_job_fn;
+ int bsg_job_size;
struct bsg_class_device bsg_dev;
#endif
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
new file mode 100644
index 0000000..f55ab8c
--- /dev/null
+++ b/include/linux/bsg-lib.h
@@ -0,0 +1,73 @@
+/*
+ * BSG helper library
+ *
+ * Copyright (C) 2008 James Smart, Emulex Corporation
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2011 Mike Christie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _BLK_BSG_
+#define _BLK_BSG_
+
+#include <linux/blkdev.h>
+
+struct request;
+struct device;
+struct scatterlist;
+struct request_queue;
+
+struct bsg_buffer {
+ unsigned int payload_len;
+ int sg_cnt;
+ struct scatterlist *sg_list;
+};
+
+struct bsg_job {
+ struct device *dev;
+ struct request *req;
+
+ /* Transport/driver specific request/reply structs */
+ void *request;
+ void *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 */
+};
+
+void bsg_job_done(struct bsg_job *job, int result,
+ unsigned int reply_payload_rcv_len);
+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_remove_queue(struct request_queue *q);
+void bsg_goose_queue(struct request_queue *q);
+
+#endif
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 02/10] iscsi class: add bsg support to iscsi class
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 01/10] block: add bsg heler library michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 03/10] be2iscsi: add bsg support michaelc
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie
From: Mike Christie <michaelc@cs.wisc.edu>
This patch adds bsg support to the iscsi class. There is only
1 request, the host vendor one, supported. It is expected that
this would be used for things like flash updates.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/Kconfig | 1 +
drivers/scsi/scsi_transport_iscsi.c | 114 ++++++++++++++++++++++++++++++++++-
include/scsi/scsi_bsg_iscsi.h | 110 +++++++++++++++++++++++++++++++++
include/scsi/scsi_transport_iscsi.h | 6 ++
4 files changed, 230 insertions(+), 1 deletions(-)
create mode 100644 include/scsi/scsi_bsg_iscsi.h
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 8d9dae8..4a79b9d 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -309,6 +309,7 @@ config SCSI_FC_TGT_ATTRS
config SCSI_ISCSI_ATTRS
tristate "iSCSI Transport Attributes"
depends on SCSI && NET
+ select BLK_DEV_BSGLIB
help
If you wish to export transport-specific information about
each attached iSCSI device to sysfs, say Y.
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 3fd16d7..4b80fbd 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/bsg-lib.h>
#include <net/tcp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
@@ -31,6 +32,7 @@
#include <scsi/scsi_transport_iscsi.h>
#include <scsi/iscsi_if.h>
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_bsg_iscsi.h>
#define ISCSI_SESSION_ATTRS 23
#define ISCSI_CONN_ATTRS 13
@@ -270,6 +272,99 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
}
EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
+/*
+ * BSG support
+ */
+/**
+ * iscsi_bsg_host_dispatch - Dispatch command to LLD.
+ * @job: bsg job to be processed
+ */
+static int iscsi_bsg_host_dispatch(struct bsg_job *job)
+{
+ struct Scsi_Host *shost = iscsi_job_to_shost(job);
+ struct iscsi_bsg_request *req = job->request;
+ struct iscsi_bsg_reply *reply = job->reply;
+ struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+ int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
+ int ret;
+
+ /* check if we have the msgcode value at least */
+ if (job->request_len < sizeof(uint32_t)) {
+ ret = -ENOMSG;
+ goto fail_host_msg;
+ }
+
+ /* Validate the host command */
+ switch (req->msgcode) {
+ case ISCSI_BSG_HST_VENDOR:
+ cmdlen += sizeof(struct iscsi_bsg_host_vendor);
+ if ((shost->hostt->vendor_id == 0L) ||
+ (req->rqst_data.h_vendor.vendor_id !=
+ shost->hostt->vendor_id)) {
+ ret = -ESRCH;
+ goto fail_host_msg;
+ }
+ break;
+ default:
+ ret = -EBADR;
+ goto fail_host_msg;
+ }
+
+ /* check if we really have all the request data needed */
+ if (job->request_len < cmdlen) {
+ ret = -ENOMSG;
+ goto fail_host_msg;
+ }
+
+ ret = i->iscsi_transport->bsg_request(job);
+ if (!ret)
+ return 0;
+
+fail_host_msg:
+ /* return the errno failure code as the only status */
+ BUG_ON(job->reply_len < sizeof(uint32_t));
+ reply->reply_payload_rcv_len = 0;
+ reply->result = ret;
+ job->reply_len = sizeof(uint32_t);
+ bsg_job_done(job, ret, 0);
+ return 0;
+}
+
+/**
+ * iscsi_bsg_host_add - Create and add the bsg hooks to receive requests
+ * @shost: shost for iscsi_host
+ * @cls_host: iscsi_cls_host adding the structures to
+ */
+static int
+iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost)
+{
+ struct device *dev = &shost->shost_gendev;
+ struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+ struct request_queue *q;
+ char bsg_name[20];
+ int ret;
+
+ if (!i->iscsi_transport->bsg_request)
+ return -ENOTSUPP;
+
+ snprintf(bsg_name, sizeof(bsg_name), "iscsi_host%d", shost->host_no);
+
+ q = __scsi_alloc_queue(shost, bsg_request_fn);
+ if (!q)
+ return -ENOMEM;
+
+ ret = bsg_setup_queue(dev, q, bsg_name, iscsi_bsg_host_dispatch, 0);
+ if (ret) {
+ shost_printk(KERN_ERR, shost, "bsg interface failed to "
+ "initialize - no request queue\n");
+ blk_cleanup_queue(q);
+ return ret;
+ }
+
+ ihost->bsg_q = q;
+ return 0;
+}
+
static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
struct device *cdev)
{
@@ -279,13 +374,30 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
memset(ihost, 0, sizeof(*ihost));
atomic_set(&ihost->nr_scans, 0);
mutex_init(&ihost->mutex);
+
+ iscsi_bsg_host_add(shost, ihost);
+ /* ignore any bsg add error - we just can't do sgio */
+
+ return 0;
+}
+
+static int iscsi_remove_host(struct transport_container *tc,
+ struct device *dev, struct device *cdev)
+{
+ struct Scsi_Host *shost = dev_to_shost(dev);
+ struct iscsi_cls_host *ihost = shost->shost_data;
+
+ if (ihost->bsg_q) {
+ bsg_remove_queue(ihost->bsg_q);
+ blk_cleanup_queue(ihost->bsg_q);
+ }
return 0;
}
static DECLARE_TRANSPORT_CLASS(iscsi_host_class,
"iscsi_host",
iscsi_setup_host,
- NULL,
+ iscsi_remove_host,
NULL);
static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
diff --git a/include/scsi/scsi_bsg_iscsi.h b/include/scsi/scsi_bsg_iscsi.h
new file mode 100644
index 0000000..fd5689d
--- /dev/null
+++ b/include/scsi/scsi_bsg_iscsi.h
@@ -0,0 +1,110 @@
+/*
+ * iSCSI Transport BSG Interface
+ *
+ * Copyright (C) 2009 James Smart, Emulex Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef SCSI_BSG_ISCSI_H
+#define SCSI_BSG_ISCSI_H
+
+/*
+ * This file intended to be included by both kernel and user space
+ */
+
+#include <scsi/scsi.h>
+
+/*
+ * iSCSI Transport SGIO v4 BSG Message Support
+ */
+
+/* Default BSG request timeout (in seconds) */
+#define ISCSI_DEFAULT_BSG_TIMEOUT (10 * HZ)
+
+
+/*
+ * Request Message Codes supported by the iSCSI Transport
+ */
+
+/* define the class masks for the message codes */
+#define ISCSI_BSG_CLS_MASK 0xF0000000 /* find object class */
+#define ISCSI_BSG_HST_MASK 0x80000000 /* iscsi host class */
+
+/* iscsi host Message Codes */
+#define ISCSI_BSG_HST_VENDOR (ISCSI_BSG_HST_MASK | 0x000000FF)
+
+
+/*
+ * iSCSI Host Messages
+ */
+
+/* ISCSI_BSG_HST_VENDOR : */
+
+/* Request:
+ * Note: When specifying vendor_id, be sure to read the Vendor Type and ID
+ * formatting requirements specified in scsi_netlink.h
+ */
+struct iscsi_bsg_host_vendor {
+ /*
+ * Identifies the vendor that the message is formatted for. This
+ * should be the recipient of the message.
+ */
+ uint64_t vendor_id;
+
+ /* start of vendor command area */
+ uint32_t vendor_cmd[0];
+};
+
+/* Response:
+ */
+struct iscsi_bsg_host_vendor_reply {
+ /* start of vendor response area */
+ uint32_t vendor_rsp[0];
+};
+
+
+/* request (CDB) structure of the sg_io_v4 */
+struct iscsi_bsg_request {
+ uint32_t msgcode;
+ union {
+ struct iscsi_bsg_host_vendor h_vendor;
+ } rqst_data;
+} __attribute__((packed));
+
+
+/* response (request sense data) structure of the sg_io_v4 */
+struct iscsi_bsg_reply {
+ /*
+ * The completion result. Result exists in two forms:
+ * if negative, it is an -Exxx system errno value. There will
+ * be no further reply information supplied.
+ * else, it's the 4-byte scsi error result, with driver, host,
+ * msg and status fields. The per-msgcode reply structure
+ * will contain valid data.
+ */
+ uint32_t result;
+
+ /* If there was reply_payload, how much was recevied ? */
+ uint32_t reply_payload_rcv_len;
+
+ union {
+ struct iscsi_bsg_host_vendor_reply vendor_reply;
+ } reply_data;
+};
+
+
+#endif /* SCSI_BSG_ISCSI_H */
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index bf8f529..60f1a25 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -37,6 +37,7 @@ struct iscsi_cls_conn;
struct iscsi_conn;
struct iscsi_task;
struct sockaddr;
+struct bsg_job;
/**
* struct iscsi_transport - iSCSI Transport template
@@ -137,6 +138,7 @@ struct iscsi_transport {
int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
uint32_t enable, struct sockaddr *dst_addr);
int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params);
+ int (*bsg_request)(struct bsg_job *job);
};
/*
@@ -216,8 +218,12 @@ struct iscsi_cls_session {
struct iscsi_cls_host {
atomic_t nr_scans;
struct mutex mutex;
+ struct request_queue *bsg_q;
};
+#define iscsi_job_to_shost(_job) \
+ dev_to_shost(_job->dev)
+
extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
void (*fn)(struct iscsi_cls_session *));
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 03/10] be2iscsi: add bsg support
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 01/10] block: add bsg heler library michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 02/10] iscsi class: add bsg support to iscsi class michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 04/10] FC class: convert to scsi bsg lib michaelc
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie
From: Mike Christie <michaelc@cs.wisc.edu>
This patch adds bsg support to be2iscsi. It is completely
untested. This patch is based on Jay's
[PATCH 2_2] be2iscsi: Adding bsg Interface
patch from Nov 3, 2009.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/be2iscsi/be_main.c | 25 +++++++++++++++
drivers/scsi/be2iscsi/be_mgmt.c | 66 ++++++++++++++++++++++++++++++++++++++-
drivers/scsi/be2iscsi/be_mgmt.h | 3 ++
3 files changed, 93 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 0a9bdfa..fb946a8 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -27,9 +27,11 @@
#include <linux/kernel.h>
#include <linux/semaphore.h>
#include <linux/iscsi_boot_sysfs.h>
+#include <linux/bsg-lib.h>
#include <scsi/libiscsi.h>
#include <scsi/scsi_transport_iscsi.h>
+#include <scsi/scsi_bsg_iscsi.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
@@ -4102,6 +4104,28 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
}
+/**
+* beiscsi_bsg_request - handle bsg request from ISCSI transport
+ * @job: iscsi_bsg_job to handle
+ */
+static int beiscsi_bsg_request(struct bsg_job *job)
+{
+ struct iscsi_bsg_request *req = job->request;
+ struct Scsi_Host *shost = iscsi_job_to_shost(job);
+ struct beiscsi_hba *phba = iscsi_host_priv(shost);
+ int rc = -ENOSYS;
+
+ switch (req->msgcode) {
+ case ISCSI_BSG_HST_VENDOR:
+ rc = mgmt_bsg_fw_cmd(&phba->ctrl, phba, job);
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
+
static void beiscsi_remove(struct pci_dev *pcidev)
{
struct beiscsi_hba *phba = NULL;
@@ -4412,6 +4436,7 @@ struct iscsi_transport beiscsi_iscsi_transport = {
.ep_poll = beiscsi_ep_poll,
.ep_disconnect = beiscsi_ep_disconnect,
.session_recovery_timedout = iscsi_session_recovery_timedout,
+ .bsg_request = beiscsi_bsg_request,
};
static struct pci_driver beiscsi_pci_driver = {
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 44762cf..bb819a9 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -17,9 +17,12 @@
* Costa Mesa, CA 92626
*/
+#include <linux/bsg-lib.h>
+#include <scsi/scsi_transport_iscsi.h>
+#include <scsi/scsi_bsg_iscsi.h>
+
#include "be_mgmt.h"
#include "be_iscsi.h"
-#include <scsi/scsi_transport_iscsi.h>
unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba)
{
@@ -447,3 +450,64 @@ unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba)
return tag;
}
+int mgmt_bsg_fw_cmd(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba,
+ struct bsg_job *job)
+{
+ struct iscsi_bsg_reply *reply = job->reply;
+ struct be_dma_mem nonemb_cmd;
+ unsigned char *pdata;
+ int num, tot_len, status = -EIO;
+ struct scatterlist *sge = NULL;
+ struct be_cmd_resp_hdr *resp;
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_sge *mcc_sge = nonembedded_sgl(wrb);
+
+ tot_len = 0;
+ for_each_sg(job->request_payload.sg_list, sge,
+ job->request_payload.sg_cnt, num)
+ tot_len += sg_dma_len(sge);
+
+ nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, tot_len,
+ &nonemb_cmd.dma);
+ if (nonemb_cmd.va == NULL) {
+ SE_DEBUG(DBG_LVL_1,
+ "Failed to allocate memory for mgmt_fw_cmd \n");
+ return -EIO;
+ }
+
+ pdata = nonemb_cmd.va;
+ resp = nonemb_cmd.va;
+ nonemb_cmd.size = tot_len;
+ for_each_sg(job->request_payload.sg_list, sge,
+ job->request_payload.sg_cnt, num) {
+ memcpy(pdata, sg_virt(sge), sg_dma_len(sge));
+ pdata += sg_dma_len(sge);
+ }
+
+ spin_lock(&ctrl->mbox_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, tot_len, false, job->request_payload.sg_cnt);
+ mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
+ mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
+ mcc_sge->len = cpu_to_le32(nonemb_cmd.size);
+ status = be_mbox_notify(ctrl);
+ if (status)
+ SE_DEBUG(DBG_LVL_1, " Failed in mgmt_fw_cmd\n");
+
+ pdata = nonemb_cmd.va;
+ for_each_sg(job->reply_payload.sg_list, sge,
+ job->request_payload.sg_cnt, num) {
+ memcpy(sg_virt(sge), pdata, sg_dma_len(sge));
+ pdata += sg_dma_len(sge);
+ }
+
+ pci_free_consistent(ctrl->pdev, nonemb_cmd.size, nonemb_cmd.va,
+ nonemb_cmd.dma);
+
+ spin_unlock(&ctrl->mbox_lock);
+ reply->reply_payload_rcv_len = resp->response_length;
+ reply->result = status;
+ bsg_job_done(job, reply->result, reply->reply_payload_rcv_len);
+ return 0;
+}
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 0842882..3a9526e 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -248,4 +248,7 @@ unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
unsigned short issue_reset,
unsigned short savecfg_flag);
+int mgmt_bsg_fw_cmd(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba,
+ struct bsg_job *job);
+
#endif
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 04/10] FC class: convert to scsi bsg lib
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
` (2 preceding siblings ...)
2011-07-24 8:59 ` [PATCH RFC/RFT 03/10] be2iscsi: add bsg support michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 05/10] libfc: convert to blk " michaelc
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie
From: Mike Christie <michaelc@cs.wisc.edu>
This patch just converts the FC class to use the bsg
lib.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/scsi_transport_fc.c | 572 ++++++++------------------------------
include/scsi/scsi_transport_fc.h | 50 +---
2 files changed, 129 insertions(+), 493 deletions(-)
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 1b21491..9448442 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>
@@ -49,8 +50,6 @@ static int fc_vport_setup(struct Scsi_Host *shost, int channel,
struct fc_vport **vport);
static int fc_bsg_hostadd(struct Scsi_Host *, struct fc_host_attrs *);
static int fc_bsg_rportadd(struct Scsi_Host *, struct fc_rport *);
-static void fc_bsg_remove(struct request_queue *);
-static void fc_bsg_goose_queue(struct fc_rport *);
/*
* Module Parameters
@@ -450,7 +449,10 @@ static int fc_host_remove(struct transport_container *tc, struct device *dev,
struct Scsi_Host *shost = dev_to_shost(dev);
struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
- fc_bsg_remove(fc_host->rqst_q);
+ if (fc_host->rqst_q) {
+ bsg_remove_queue(fc_host->rqst_q);
+ blk_cleanup_queue(fc_host->rqst_q);
+ }
return 0;
}
@@ -2536,7 +2538,10 @@ fc_rport_final_delete(struct work_struct *work)
if (do_callback)
i->f->dev_loss_tmo_callbk(rport);
- fc_bsg_remove(rport->rqst_q);
+ if (rport->rqst_q) {
+ bsg_remove_queue(rport->rqst_q);
+ blk_cleanup_queue(rport->rqst_q);
+ }
transport_remove_device(dev);
device_del(dev);
@@ -2792,7 +2797,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
spin_unlock_irqrestore(shost->host_lock,
flags);
- fc_bsg_goose_queue(rport);
+ bsg_goose_queue(rport->rqst_q);
return rport;
}
@@ -3514,236 +3519,38 @@ 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 fc_bsg_job *job)
-{
- 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);
-
- 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
- * @job: fc_bsg_job that is complete
- */
-static void
-fc_bsg_jobdone(struct fc_bsg_job *job)
-{
- struct request *req = job->req;
- struct request *rsp = req->next_rq;
- int err;
-
- err = job->req->errors = job->reply->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(job->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);
- }
- blk_complete_request(req);
-}
-
-/**
- * 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 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);
-}
-
-/**
- * fc_bsg_job_timeout - handler for when a bsg request timesout
- * @req: request that timed out
- */
-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 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)
- 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);
-
- if (!done && 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--;
- return BLK_EH_RESET_TIMER;
- } else if (err)
- printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
- "abort failed with status %d\n", err);
- }
-
- /* the blk_end_sync_io() doesn't check the error */
- if (done)
- return BLK_EH_NOT_HANDLED;
- else
- return BLK_EH_HANDLED;
-}
-
-static int
-fc_bsg_map_buffer(struct fc_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)
+static void fc_bsg_fail_job(struct bsg_job *job, int ret)
{
- struct fc_internal *i = to_fc_internal(shost->transportt);
- struct request *rsp = req->next_rq;
- struct fc_bsg_job *job;
- int ret;
-
- BUG_ON(req->special);
-
- job = kzalloc(sizeof(struct fc_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->shost = shost;
- job->rport = rport;
- job->req = req;
- 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;
- job->request_len = req->cmd_len;
- job->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;
- }
- job->job_done = fc_bsg_jobdone;
- if (rport)
- job->dev = &rport->dev;
- else
- job->dev = &shost->shost_gendev;
- get_device(job->dev); /* take a reference for the request */
-
- job->ref_cnt = 1;
-
- return 0;
-
-
-failjob_rls_rqst_payload:
- kfree(job->request_payload.sg_list);
-failjob_rls_job:
- kfree(job);
- return -ENOMEM;
+ struct fc_bsg_reply *bsg_reply = job->reply;
+ BUG_ON(job->reply_len < sizeof(uint32_t));
+ bsg_reply->reply_payload_rcv_len = 0;
+ /* return the errno failure code as the only status */
+ bsg_reply->result = ret;
+ job->reply_len = sizeof(uint32_t);
+ bsg_job_done(job, ret, 0);
}
-
-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
+ * @shost: scsi host
* @job: bsg job to be processed
*/
-static enum fc_dispatch_result
-fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
- struct fc_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);
int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
+ struct fc_bsg_request *bsg_req = job->request;
int ret;
+ /* check if we have the msgcode value at least */
+ if (job->request_len < sizeof(uint32_t)) {
+ ret = -ENOMSG;
+ goto fail_host_msg;
+ }
+
/* Validate the host command */
- switch (job->request->msgcode) {
+ switch (bsg_req->msgcode) {
case FC_BSG_HST_ADD_RPORT:
cmdlen += sizeof(struct fc_bsg_host_add_rport);
break;
@@ -3775,8 +3582,8 @@ 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 !=
- shost->hostt->vendor_id)) {
+ (bsg_req->rqst_data.h_vendor.vendor_id !=
+ shost->hostt->vendor_id)) {
ret = -ESRCH;
goto fail_host_msg;
}
@@ -3795,54 +3602,34 @@ 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 */
- BUG_ON(job->reply_len < sizeof(uint32_t));
- job->reply->reply_payload_rcv_len = 0;
- job->reply->result = ret;
- job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job);
- return FC_DISPATCH_UNLOCKED;
-}
-
-
-/*
- * fc_bsg_goose_queue - restart rport queue in case it was stopped
- * @rport: rport to be restarted
- */
-static void
-fc_bsg_goose_queue(struct fc_rport *rport)
-{
- if (!rport->rqst_q)
- return;
-
- /*
- * This get/put dance makes no sense
- */
- get_device(&rport->dev);
- blk_run_queue_async(rport->rqst_q);
- put_device(&rport->dev);
+ fc_bsg_fail_job(job, ret);
+ return 0;
}
/**
* 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 fc_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);
int cmdlen = sizeof(uint32_t); /* start with length of msgcode */
+ struct fc_bsg_request *bsg_req = job->request;
int ret;
+ /* check if we have the msgcode value at least */
+ if (job->request_len < sizeof(uint32_t)) {
+ ret = -ENOMSG;
+ goto fail_rport_msg;
+ }
+
/* Validate the rport command */
- switch (job->request->msgcode) {
+ switch (bsg_req->msgcode) {
case FC_BSG_RPT_ELS:
cmdlen += sizeof(struct fc_bsg_rport_els);
goto check_bidi;
@@ -3870,124 +3657,86 @@ 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 */
- BUG_ON(job->reply_len < sizeof(uint32_t));
- job->reply->reply_payload_rcv_len = 0;
- job->reply->result = ret;
- job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job);
- return FC_DISPATCH_UNLOCKED;
+ fc_bsg_fail_job(job, ret);
+ return 0;
}
-
/**
- * 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
+ * fc_bsg_dispatch - process fc bsg requests and dispatch to LLDD
+ * @job: bsg job to be processed
*/
-static void
-fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
- struct fc_rport *rport, struct device *dev)
+static int fc_bsg_dispatch(struct bsg_job *job)
{
- struct request *req;
- struct fc_bsg_job *job;
- enum fc_dispatch_result ret;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
- 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;
+ if (scsi_is_fc_rport(job->dev))
+ return fc_bsg_rport_dispatch(shost, job);
+ else
+ return fc_bsg_host_dispatch(shost, job);
+}
- /* 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;
- job->reply_len = sizeof(uint32_t);
- fc_bsg_jobdone(job);
- spin_lock_irq(q->queue_lock);
- continue;
- }
+/**
+ * fc_bsg_timed_out - handler for when a bsg request timesout
+ * @req: request that timed out
+ */
+static enum blk_eh_timer_return fc_bsg_timed_out(struct request *req)
+{
+ struct bsg_job *job = req->special;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct fc_rport *rport = fc_bsg_to_rport(job);
+ int ret;
- /* the dispatch routines will unlock the queue_lock */
- if (rport)
- ret = fc_bsg_rport_dispatch(q, shost, rport, job);
+ if (rport && rport->port_state == FC_PORTSTATE_BLOCKED)
+ return BLK_EH_RESET_TIMER;
+ if (i->f->bsg_timeout) {
+ ret = i->f->bsg_timeout(job);
+ if (ret == -EAGAIN)
+ return BLK_EH_RESET_TIMER;
+ else if (!ret)
+ return BLK_EH_HANDLED;
else
- ret = fc_bsg_host_dispatch(q, shost, job);
+ dev_printk(KERN_ERR, job->dev, "ERROR: FC BSG request "
+ "timeout - LLD abort failed with status "
+ "%d\n", ret);
+ }
+ return BLK_EH_NOT_HANDLED;
+}
- /* did dispatcher hit state that can't process any more */
- if (ret == FC_DISPATCH_BREAK)
- break;
+static int fc_bsg_rport_prep(struct request_queue *q, struct request *req)
+{
+ struct fc_rport *rport = dev_to_rport(q->queuedata);
- /* did dispatcher had released the lock */
- if (ret == FC_DISPATCH_UNLOCKED)
- spin_lock_irq(q->queue_lock);
- }
+ if (rport->port_state == FC_PORTSTATE_BLOCKED &&
+ !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
+ return BLKPREP_DEFER;
- spin_unlock_irq(q->queue_lock);
- put_device(dev);
- spin_lock_irq(q->queue_lock);
-}
+ if (rport->port_state != FC_PORTSTATE_ONLINE)
+ return BLKPREP_KILL;
+ return BLKPREP_OK;
+}
-/**
- * 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 fc_rport *fc_bsg_to_rport(struct bsg_job *job)
{
- struct Scsi_Host *shost = q->queuedata;
+ if (!scsi_is_fc_rport(job->dev))
+ return NULL;
- fc_bsg_request_handler(q, shost, NULL, &shost->shost_gendev);
+ return dev_to_rport(job->dev);
}
+EXPORT_SYMBOL_GPL(fc_bsg_to_rport);
-
-/**
- * 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)
+struct Scsi_Host *fc_bsg_to_shost(struct bsg_job *job)
{
- struct fc_rport *rport = q->queuedata;
- struct Scsi_Host *shost = rport_to_shost(rport);
+ if (scsi_is_host_device(job->dev))
+ return dev_to_shost(job->dev);
- fc_bsg_request_handler(q, shost, rport, &rport->dev);
+ return rport_to_shost(dev_to_rport(job->dev));
}
-
+EXPORT_SYMBOL_GPL(fc_bsg_to_shost);
/**
* fc_bsg_hostadd - Create and add the bsg hooks so we can receive requests
@@ -4000,40 +3749,31 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
struct device *dev = &shost->shost_gendev;
struct fc_internal *i = to_fc_internal(shost->transportt);
struct request_queue *q;
- int err;
char bsg_name[20];
+ int ret;
fc_host->rqst_q = NULL;
if (!i->f->bsg_request)
return -ENOTSUPP;
- snprintf(bsg_name, sizeof(bsg_name),
- "fc_host%d", shost->host_no);
+ snprintf(bsg_name, sizeof(bsg_name), "fc_host%d", shost->host_no);
- q = __scsi_alloc_queue(shost, fc_bsg_host_handler);
- if (!q) {
- printk(KERN_ERR "fc_host%d: bsg interface failed to "
- "initialize - no request queue\n",
- shost->host_no);
+ q = __scsi_alloc_queue(shost, bsg_request_fn);
+ if (!q)
return -ENOMEM;
- }
-
- q->queuedata = shost;
- queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
- blk_queue_softirq_done(q, fc_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);
- if (err) {
+ ret = bsg_setup_queue(dev, q, bsg_name, fc_bsg_dispatch,
+ i->f->dd_bsg_size);
+ if (ret) {
printk(KERN_ERR "fc_host%d: bsg interface failed to "
- "initialize - register queue\n",
- shost->host_no);
+ "initialize - no request queue\n", shost->host_no);
blk_cleanup_queue(q);
- return err;
+ return ret;
}
+ blk_queue_rq_timed_out(q, fc_bsg_timed_out);
+ blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
fc_host->rqst_q = q;
return 0;
}
@@ -4050,98 +3790,32 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
struct device *dev = &rport->dev;
struct fc_internal *i = to_fc_internal(shost->transportt);
struct request_queue *q;
- int err;
+ int ret;
rport->rqst_q = NULL;
if (!i->f->bsg_request)
return -ENOTSUPP;
- q = __scsi_alloc_queue(shost, fc_bsg_rport_handler);
- if (!q) {
- printk(KERN_ERR "%s: bsg interface failed to "
- "initialize - no request queue\n",
- dev->kobj.name);
+ q = __scsi_alloc_queue(shost, bsg_request_fn);
+ if (!q)
return -ENOMEM;
- }
-
- q->queuedata = rport;
- queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
- blk_queue_softirq_done(q, fc_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);
- if (err) {
- printk(KERN_ERR "%s: bsg interface failed to "
- "initialize - register queue\n",
- dev->kobj.name);
+ ret = bsg_setup_queue(dev, q, NULL, fc_bsg_dispatch, i->f->dd_bsg_size);
+ if (ret) {
+ printk(KERN_ERR "%s: bsg interface failed to initialize - "
+ "no request queue\n", dev->kobj.name);
blk_cleanup_queue(q);
- return err;
+ return ret;
}
+ blk_queue_prep_rq(q, fc_bsg_rport_prep);
+ blk_queue_rq_timed_out(q, fc_bsg_timed_out);
+ blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
rport->rqst_q = q;
return 0;
}
-
-/**
- * fc_bsg_remove - Deletes the bsg hooks on fchosts/rports
- * @q: the request_queue that is to be torn down.
- *
- * Notes:
- * Before unregistering the queue empty any requests that are blocked
- *
- *
- */
-static void
-fc_bsg_remove(struct request_queue *q)
-{
- struct request *req; /* block request */
- int counts; /* totals for request_list count and starved */
-
- if (q) {
- /* Stop taking in new requests */
- spin_lock_irq(q->queue_lock);
- blk_stop_queue(q);
-
- /* drain all requests in the queue */
- while (1) {
- /* need the lock to fetch a request
- * this may fetch the same reqeust as the previous pass
- */
- req = blk_fetch_request(q);
- /* save requests in use and starved */
- counts = q->rq.count[0] + q->rq.count[1] +
- q->rq.starved[0] + q->rq.starved[1];
- spin_unlock_irq(q->queue_lock);
- /* any requests still outstanding? */
- if (counts == 0)
- break;
-
- /* This may be the same req as the previous iteration,
- * always send the blk_end_request_all after a prefetch.
- * It is not okay to not end the request because the
- * prefetch started the request.
- */
- if (req) {
- /* return -ENXIO to indicate that this queue is
- * going away
- */
- req->errors = -ENXIO;
- blk_end_request_all(req, -ENXIO);
- }
-
- msleep(200); /* allow bsg to possibly finish */
- spin_lock_irq(q->queue_lock);
- }
-
- bsg_unregister_queue(q);
- blk_cleanup_queue(q);
- }
-}
-
-
/* Original Author: Martin Hicks */
MODULE_AUTHOR("James Smart");
MODULE_DESCRIPTION("FC Transport Attributes");
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 2a65167..55650c6 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -28,8 +28,10 @@
#define SCSI_TRANSPORT_FC_H
#include <linux/sched.h>
+#include <linux/bsg-lib.h>
#include <scsi/scsi.h>
#include <scsi/scsi_netlink.h>
+#include <scsi/scsi_host.h>
struct scsi_transport_template;
@@ -584,48 +586,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
-
-struct fc_bsg_job {
- struct Scsi_Host *shost;
- struct fc_rport *rport;
- struct device *dev;
- struct request *req;
- 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;
- 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 fc_bsg_buffer request_payload;
- struct fc_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 *);
@@ -662,8 +622,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;
@@ -798,6 +758,8 @@ struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost,
void fc_remote_port_delete(struct fc_rport *rport);
void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles);
int scsi_is_fc_rport(const struct device *);
+struct fc_rport *fc_bsg_to_rport(struct bsg_job *job);
+struct Scsi_Host *fc_bsg_to_shost(struct bsg_job *job);
u32 fc_get_event_number(void);
void fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
enum fc_host_event_code event_code, u32 event_data);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 05/10] libfc: convert to blk bsg lib
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
` (3 preceding siblings ...)
2011-07-24 8:59 ` [PATCH RFC/RFT 04/10] FC class: convert to scsi bsg lib michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-28 1:13 ` Love, Robert W
2011-07-24 8:59 ` [PATCH RFC/RFT 06/10] qla2xxx: convert qla2xxx " michaelc
` (4 subsequent siblings)
9 siblings, 1 reply; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Robert Love
From: Mike Christie <michaelc@cs.wisc.edu>
This patch converts libfc to the blk bsg lib. The differences
visible to the driver are:
- fc_bsg_job is now named bsg_job.
- no rport pointer. Can access it through the device pointer.
- the request and reply pointers on the blk_bsg_job struct
are now void pointers, so you cannot do bsg_job->request->some_field.
Patch is only quickly tested with fcping and made over scsi-misc.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_lport.c | 51 ++++++++++++++++++----------------------
include/scsi/libfc.h | 3 +-
2 files changed, 25 insertions(+), 29 deletions(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index e008b16..6043173 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -140,7 +140,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;
@@ -1653,18 +1653,18 @@ 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 *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) ?
+ reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
-ECONNABORTED : -ETIMEDOUT;
job->reply_len = sizeof(uint32_t);
- job->state_flags |= FC_RQST_STATE_DONE;
- job->job_done(job);
+ bsg_job_done(job, reply->result, reply->reply_payload_rcv_len);
kfree(info);
return;
}
@@ -1681,25 +1681,24 @@ 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 =
+ reply->reply_data.ctels_reply.status =
(cmd == info->rsp_code) ?
FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
}
- job->reply->reply_payload_rcv_len +=
+ reply->reply_payload_rcv_len +=
fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
&info->offset, KM_BIO_SRC_IRQ, 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 (reply->reply_payload_rcv_len >
job->reply_payload.payload_len)
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
job->reply_payload.payload_len;
- job->reply->result = 0;
- job->state_flags |= FC_RQST_STATE_DONE;
- job->job_done(job);
+ reply->result = 0;
+ bsg_job_done(job, reply->result, reply->reply_payload_rcv_len);
kfree(info);
}
fc_frame_free(fp);
@@ -1715,7 +1714,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)
{
@@ -1776,7 +1775,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;
@@ -1832,45 +1831,41 @@ 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 request *rsp = job->req->next_rq;
- struct Scsi_Host *shost = job->shost;
+ struct fc_bsg_request *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
+ 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;
int rc = -EINVAL;
u32 did;
- job->reply->reply_payload_rcv_len = 0;
+ 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 (req->msgcode) {
case FC_BSG_RPT_ELS:
- rport = job->rport;
- if (!rport)
- break;
-
+ rport = dev_to_rport(job->dev);
rdata = rport->dd_data;
rc = fc_lport_els_request(job, lport, rport->port_id,
rdata->e_d_tov);
break;
case FC_BSG_RPT_CT:
- rport = job->rport;
- if (!rport)
- break;
-
+ rport = dev_to_rport(job->dev);
rdata = rport->dd_data;
rc = fc_lport_ct_request(job, lport, rport->port_id,
rdata->e_d_tov);
break;
case FC_BSG_HST_CT:
- did = ntoh24(job->request->rqst_data.h_ct.port_id);
+ did = ntoh24(req->rqst_data.h_ct.port_id);
if (did == FC_FID_DIR_SERV)
rdata = lport->dns_rdata;
else
@@ -1883,7 +1878,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(req->rqst_data.h_els.port_id);
rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
break;
}
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 7d96829..eb7fc9f 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -23,6 +23,7 @@
#include <linux/timer.h>
#include <linux/if.h>
#include <linux/percpu.h>
+#include <linux/bsg-lib.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
@@ -1055,7 +1056,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 *);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 06/10] qla2xxx: convert qla2xxx to blk bsg lib
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
` (4 preceding siblings ...)
2011-07-24 8:59 ` [PATCH RFC/RFT 05/10] libfc: convert to blk " michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 07/10] lpfc: convert lpfc " michaelc
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Giridhar Malavali
From: Mike Christie <michaelc@cs.wisc.edu>
This patch converts qla2xxx to the blk bsg lib. The differences
visible to the driver are:
- fc_bsg_job is now named bsg_job.
- no rport pointer. Can access it through the device pointer.
- the request and reply pointers on the bsg_job struct
are now void pointers, so you cannot do bsg_job->request->some_field.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
---
drivers/scsi/qla2xxx/qla_bsg.c | 241 ++++++++++++++++++++++-----------------
drivers/scsi/qla2xxx/qla_def.h | 3 +-
drivers/scsi/qla2xxx/qla_gbl.h | 4 +-
drivers/scsi/qla2xxx/qla_iocb.c | 11 +-
drivers/scsi/qla2xxx/qla_isr.c | 44 ++++---
drivers/scsi/qla2xxx/qla_os.c | 32 +++--
6 files changed, 189 insertions(+), 146 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 8c10e2c..3031a12 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -92,16 +92,18 @@ qla24xx_fcp_prio_cfg_valid(struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
}
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 = bsg_job->shost;
+ struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ struct fc_bsg_request *bsg_req = bsg_job->request;
scsi_qla_host_t *vha = shost_priv(host);
struct qla_hw_data *ha = vha->hw;
int ret = 0;
uint32_t len;
uint32_t oper;
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))) {
ret = -EINVAL;
@@ -116,7 +118,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_req->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)) {
@@ -130,10 +132,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;
@@ -145,10 +147,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;
}
}
@@ -158,12 +160,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,
@@ -174,7 +176,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;
}
@@ -186,7 +188,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
"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;
}
@@ -201,7 +203,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
if (!qla24xx_fcp_prio_cfg_valid(
(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
@@ -215,19 +217,21 @@ 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;
break;
}
exit_fcp_prio_cfg:
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return ret;
}
static int
-qla2x00_process_els(struct fc_bsg_job *bsg_job)
+qla2x00_process_els(struct bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_req = bsg_job->request;
struct fc_rport *rport;
fc_port_t *fcport = NULL;
struct Scsi_Host *host;
@@ -240,15 +244,15 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
uint16_t nextlid = 0;
struct srb_ctx *els;
- if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
- rport = bsg_job->rport;
+ if (bsg_req->msgcode == FC_BSG_RPT_ELS) {
+ rport = dev_to_rport(bsg_job->dev);
fcport = *(fc_port_t **) rport->dd_data;
host = rport_to_shost(rport);
vha = shost_priv(host);
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";
@@ -276,7 +280,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_req->msgcode == FC_BSG_RPT_ELS) {
/* make sure the rport is logged in,
* if not perform fabric login
*/
@@ -303,11 +307,11 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
fcport->vha = vha;
fcport->vp_idx = vha->vp_idx;
fcport->d_id.b.al_pa =
- bsg_job->request->rqst_data.h_els.port_id[0];
+ bsg_req->rqst_data.h_els.port_id[0];
fcport->d_id.b.area =
- bsg_job->request->rqst_data.h_els.port_id[1];
+ bsg_req->rqst_data.h_els.port_id[1];
fcport->d_id.b.domain =
- bsg_job->request->rqst_data.h_els.port_id[2];
+ bsg_req->rqst_data.h_els.port_id[2];
fcport->loop_id =
(fcport->d_id.b.al_pa == 0xFD) ?
NPH_FABRIC_CONTROLLER : NPH_F_PORT;
@@ -356,17 +360,17 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
els = sp->ctx;
els->type =
- (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
+ (bsg_req->msgcode == FC_BSG_RPT_ELS ?
SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
els->name =
- (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
+ (bsg_req->msgcode == FC_BSG_RPT_ELS ?
"bsg_els_rpt" : "bsg_els_hst");
els->u.bsg_job = bsg_job;
DEBUG2(qla_printk(KERN_INFO, ha,
"scsi(%ld:%x): bsg rqst type: %s els type: %x - loop-id=%x "
"portid=%02x%02x%02x.\n", vha->host_no, sp->handle, type,
- bsg_job->request->rqst_data.h_els.command_code,
+ bsg_req->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));
@@ -387,17 +391,18 @@ done_unmap_sg:
goto done_free_fcport;
done_free_fcport:
- if (bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN)
+ if (bsg_req->msgcode == FC_BSG_HST_ELS_NOLOGIN)
kfree(fcport);
done:
return rval;
}
static int
-qla2x00_process_ct(struct fc_bsg_job *bsg_job)
+qla2x00_process_ct(struct bsg_job *bsg_job)
{
srb_t *sp;
- struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ 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);
@@ -441,7 +446,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
}
loop_id =
- (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
+ (bsg_req->rqst_data.h_ct.preamble_word1 & 0xFF000000)
>> 24;
switch (loop_id) {
case 0xFC:
@@ -471,9 +476,9 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
/* Initialize all required fields of fcport */
fcport->vha = vha;
fcport->vp_idx = vha->vp_idx;
- 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_req->rqst_data.h_ct.port_id[0];
+ fcport->d_id.b.area = bsg_req->rqst_data.h_ct.port_id[1];
+ fcport->d_id.b.domain = bsg_req->rqst_data.h_ct.port_id[2];
fcport->loop_id = loop_id;
/* Alloc SRB structure */
@@ -491,7 +496,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
DEBUG2(qla_printk(KERN_INFO, ha,
"scsi(%ld:%x): bsg rqst type: %s els type: %x - loop-id=%x "
"portid=%02x%02x%02x.\n", vha->host_no, sp->handle, type,
- (bsg_job->request->rqst_data.h_ct.preamble_word2 >> 16),
+ (bsg_req->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));
@@ -608,9 +613,11 @@ done_reset_internal:
}
static int
-qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
+qla2x00_process_loopback(struct bsg_job *bsg_job)
{
- struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ 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;
@@ -691,7 +698,7 @@ 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_req->rqst_data.h_vendor.vendor_cmd[1];
if ((ha->current_topology == ISP_CFG_F ||
(IS_QLA81XX(ha) &&
@@ -711,8 +718,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
DEBUG2(printk(KERN_ERR
"%s(%lu): Get port config failed\n",
__func__, vha->host_no));
- bsg_job->reply->reply_payload_rcv_len = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
rval = -EPERM;
goto done_free_dma_req;
}
@@ -723,10 +730,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
config[0]));
if (qla81xx_set_internal_loopback(vha, config,
new_config)) {
- bsg_job->reply->reply_payload_rcv_len =
- 0;
- bsg_job->reply->result =
- (DID_ERROR << 16);
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
rval = -EPERM;
goto done_free_dma_req;
}
@@ -736,10 +741,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
*/
if (qla81xx_reset_internal_loopback(vha,
config, 1)) {
- bsg_job->reply->reply_payload_rcv_len =
- 0;
- bsg_job->reply->result =
- (DID_ERROR << 16);
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
rval = -EPERM;
goto done_free_dma_req;
}
@@ -776,8 +779,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
vha->host_no);
}
- bsg_job->reply->reply_payload_rcv_len = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
rval = -EIO;
goto done_free_dma_req;
}
@@ -802,27 +805,28 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
fw_sts_ptr += sizeof(response);
*fw_sts_ptr = command_sent;
rval = 0;
- bsg_job->reply->reply_payload_rcv_len = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
} else {
DEBUG2(qla_printk(KERN_WARNING, ha, "scsi(%ld) Vendor "
"request %s completed\n", vha->host_no, type));
bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
sizeof(response) + sizeof(uint8_t);
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->reply_payload_rcv_len =
bsg_job->reply_payload.payload_len;
fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
sizeof(struct fc_bsg_reply);
memcpy(fw_sts_ptr, response, sizeof(response));
fw_sts_ptr += sizeof(response);
*fw_sts_ptr = command_sent;
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, rsp_data,
rsp_data_len);
}
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
dma_free_coherent(&ha->pdev->dev, rsp_data_len,
rsp_data, rsp_data_dma);
@@ -841,9 +845,11 @@ done_unmap_req_sg:
}
static int
-qla84xx_reset(struct fc_bsg_job *bsg_job)
+qla84xx_reset(struct bsg_job *bsg_job)
{
- struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ 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;
@@ -860,30 +866,33 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
return -EINVAL;
}
- flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ flag = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
if (rval) {
DEBUG2(qla_printk(KERN_WARNING, ha, "scsi(%ld) Vendor "
"request 84xx reset failed\n", vha->host_no));
- rval = bsg_job->reply->reply_payload_rcv_len = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
+ rval = bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
} else {
DEBUG2(qla_printk(KERN_WARNING, ha, "scsi(%ld) Vendor "
"request 84xx reset completed\n", vha->host_no));
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
}
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}
static int
-qla84xx_updatefw(struct fc_bsg_job *bsg_job)
+qla84xx_updatefw(struct bsg_job *bsg_job)
{
- struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ 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;
@@ -942,7 +951,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_req->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));
@@ -968,18 +977,19 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job)
DEBUG2(qla_printk(KERN_WARNING, ha, "scsi(%ld) Vendor "
"request 84xx updatefw failed\n", vha->host_no));
- rval = bsg_job->reply->reply_payload_rcv_len = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
+ rval = bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
} else {
DEBUG2(qla_printk(KERN_WARNING, ha, "scsi(%ld) Vendor "
"request 84xx updatefw completed\n", vha->host_no));
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
}
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
dma_pool_free(ha->s_dma_pool, mn, mn_dma);
done_free_fw_buf:
@@ -993,9 +1003,10 @@ done_unmap_sg:
}
static int
-qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
+qla84xx_mgmt_cmd(struct bsg_job *bsg_job)
{
- struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ 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;
@@ -1159,19 +1170,19 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
DEBUG2(qla_printk(KERN_WARNING, ha, "scsi(%ld) Vendor "
"request 84xx mgmt failed\n", vha->host_no));
- rval = bsg_job->reply->reply_payload_rcv_len = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
+ rval = bsg_reply->reply_payload_rcv_len = 0;
+ bsg_reply->result = (DID_ERROR << 16);
} else {
DEBUG2(qla_printk(KERN_WARNING, ha, "scsi(%ld) Vendor "
"request 84xx mgmt completed\n", vha->host_no));
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,
@@ -1180,7 +1191,8 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
}
}
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
done_unmap_sg:
if (mgmt_b)
@@ -1200,9 +1212,10 @@ exit_mgmt:
}
static int
-qla24xx_iidma(struct fc_bsg_job *bsg_job)
+qla24xx_iidma(struct bsg_job *bsg_job)
{
- struct Scsi_Host *host = bsg_job->shost;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ 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;
@@ -1211,7 +1224,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
uint16_t mb[MAILBOX_REGISTER_COUNT];
uint8_t *rsp_ptr = NULL;
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
@@ -1285,7 +1298,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
fcport->port_name[6], fcport->port_name[7], rval,
fcport->fp_speed, mb[0], mb[1]));
rval = 0;
- bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_reply->result = (DID_ERROR << 16);
} else {
if (!port_param->mode) {
@@ -1299,26 +1312,29 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
sizeof(struct qla_port_param));
}
- bsg_job->reply->result = DID_OK;
+ bsg_reply->result = DID_OK;
}
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}
static int
-qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, struct qla_hw_data *ha,
+qla2x00_optrom_setup(struct bsg_job *bsg_job, struct qla_hw_data *ha,
uint8_t is_update)
{
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
uint32_t start = 0;
int valid = 0;
- bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_reply->reply_payload_rcv_len = 0;
if (unlikely(pci_channel_offline(ha->pdev)))
return -EINVAL;
- start = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ start = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
if (start > ha->optrom_size)
return -EINVAL;
@@ -1371,10 +1387,11 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, struct qla_hw_data *ha,
}
static int
-qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
+qla2x00_read_optrom(struct bsg_job *bsg_job)
{
- 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 fc_bsg_reply *bsg_reply = bsg_job->reply;
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1389,20 +1406,22 @@ 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;
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}
static int
-qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
+qla2x00_update_optrom(struct bsg_job *bsg_job)
{
- 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 fc_bsg_reply *bsg_reply = bsg_job->reply;
struct qla_hw_data *ha = vha->hw;
int rval = 0;
@@ -1417,18 +1436,23 @@ 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;
+ bsg_reply->reply_payload_rcv_len = 0;
vfree(ha->optrom_buffer);
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return rval;
}
static int
-qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
+qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
{
- switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+
+ switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
case QL_VND_LOOPBACK:
return qla2x00_process_loopback(bsg_job);
@@ -1454,18 +1478,21 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
return qla2x00_update_optrom(bsg_job);
default:
- bsg_job->reply->result = (DID_ERROR << 16);
- bsg_job->job_done(bsg_job);
+ bsg_reply->result = (DID_ERROR << 16);
+ bsg_reply->reply_payload_rcv_len = 0;
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
return -ENOSYS;
}
}
int
-qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
+qla24xx_bsg_request(struct bsg_job *bsg_job)
{
+ struct fc_bsg_request *bsg_req = bsg_job->request;
int ret = -EINVAL;
- switch (bsg_job->request->msgcode) {
+ switch (bsg_req->msgcode) {
case FC_BSG_RPT_ELS:
case FC_BSG_HST_ELS_NOLOGIN:
ret = qla2x00_process_els(bsg_job);
@@ -1487,9 +1514,11 @@ 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)
{
- scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ 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;
@@ -1519,14 +1548,14 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
"abort_command failed\n",
vha->host_no));
bsg_job->req->errors =
- bsg_job->reply->result = -EIO;
+ bsg_reply->result = -EIO;
} else {
DEBUG2(qla_printk(KERN_INFO, ha,
"scsi(%ld): mbx "
"abort_command success\n",
vha->host_no));
bsg_job->req->errors =
- bsg_job->reply->result = 0;
+ bsg_reply->result = 0;
}
spin_lock_irqsave(&ha->hardware_lock, flags);
goto done;
@@ -1537,12 +1566,12 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
DEBUG2(qla_printk(KERN_INFO, ha,
"scsi(%ld) SRB not found to abort\n", vha->host_no));
- bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
+ bsg_job->req->errors = bsg_reply->result = -ENXIO;
return 0;
done:
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (bsg_job->request->msgcode == FC_BSG_HST_CT)
+ if (bsg_req->msgcode == FC_BSG_HST_CT)
kfree(sp->fcport);
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index cc5a792..f7f6f0b 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -25,6 +25,7 @@
#include <linux/firmware.h>
#include <linux/aer.h>
#include <linux/mutex.h>
+#include <linux/bsg-lib.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
@@ -273,7 +274,7 @@ struct srb_ctx {
char *name;
union {
struct srb_iocb *iocb_cmd;
- struct fc_bsg_job *bsg_job;
+ struct bsg_job *bsg_job;
} u;
};
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 0b38122..71f59c4 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -568,8 +568,8 @@ extern int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *);
extern void qla82xx_chip_reset_cleanup(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 7bac3cd..e05c0ec 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1799,7 +1799,8 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
static void
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
{
- struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
+ struct bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
+ struct fc_bsg_request *bsg_req = bsg_job->request;
els_iocb->entry_type = ELS_IOCB_TYPE;
els_iocb->entry_count = 1;
@@ -1814,8 +1815,8 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->opcode =
(((struct srb_ctx *)sp->ctx)->type == SRB_ELS_CMD_RPT) ?
- bsg_job->request->rqst_data.r_els.els_code :
- bsg_job->request->rqst_data.h_els.command_code;
+ bsg_req->rqst_data.r_els.els_code :
+ bsg_req->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;
@@ -1850,7 +1851,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 = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
+ struct bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
int loop_iterartion = 0;
int cont_iocb_prsnt = 0;
int entry_count = 1;
@@ -1925,7 +1926,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
int index;
uint16_t tot_dsds;
scsi_qla_host_t *vha = sp->fcport->vha;
- struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
+ struct bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
int loop_iterartion = 0;
int cont_iocb_prsnt = 0;
int entry_count = 1;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 1b60a95..bf50009 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1009,7 +1009,8 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
struct qla_hw_data *ha = vha->hw;
srb_t *sp;
struct srb_ctx *sp_bsg;
- struct fc_bsg_job *bsg_job;
+ struct bsg_job *bsg_job;
+ struct fc_bsg_reply *bsg_reply;
uint16_t comp_status;
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
@@ -1018,6 +1019,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
sp_bsg = sp->ctx;
bsg_job = sp_bsg->u.bsg_job;
+ bsg_reply = bsg_job->reply;
type = NULL;
switch (sp_bsg->type) {
@@ -1036,32 +1038,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) {
- bsg_job->reply->result = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->result = DID_OK << 16;
+ bsg_reply->reply_payload_rcv_len =
le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
DEBUG2(qla_printk(KERN_WARNING, ha,
"scsi(%ld): CT pass-through-%s error "
"comp_status-status=0x%x total_byte = 0x%x.\n",
vha->host_no, type, comp_status,
- bsg_job->reply->reply_payload_rcv_len));
+ bsg_reply->reply_payload_rcv_len));
} else {
DEBUG2(qla_printk(KERN_WARNING, ha,
"scsi(%ld): CT pass-through-%s error "
"comp_status-status=0x%x.\n",
vha->host_no, type, comp_status));
- 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;
}
DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
} else {
- bsg_job->reply->result = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->result = DID_OK << 16;;
+ bsg_reply->reply_payload_rcv_len =
bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0;
}
@@ -1077,7 +1079,8 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}
static void
@@ -1089,7 +1092,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
struct qla_hw_data *ha = vha->hw;
srb_t *sp;
struct srb_ctx *sp_bsg;
- 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];
uint8_t* fw_sts_ptr;
@@ -1099,6 +1103,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
return;
sp_bsg = sp->ctx;
bsg_job = sp_bsg->u.bsg_job;
+ bsg_reply = bsg_job->reply;
type = NULL;
switch (sp_bsg->type) {
@@ -1123,13 +1128,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) {
- bsg_job->reply->result = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len =
+ bsg_reply->result = DID_OK << 16;
+ bsg_reply->reply_payload_rcv_len =
le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
DEBUG2(qla_printk(KERN_WARNING, ha,
@@ -1147,16 +1152,16 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
vha->host_no, sp->handle, type, comp_status,
le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1),
le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2)));
- 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;
fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
}
DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
}
else {
- bsg_job->reply->result = DID_OK << 16;
- bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
+ bsg_reply->result = DID_OK << 16;;
+ bsg_reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0;
}
@@ -1171,7 +1176,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
kfree(sp->fcport);
kfree(sp->ctx);
mempool_free(sp, ha->srb_mempool);
- bsg_job->job_done(bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
}
static void
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f461925..59958fd 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1214,6 +1214,22 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
return QLA_SUCCESS;
}
+static void qla2x00_abort_bsg_job(struct qla_hw_data *ha, srb_t *sp, int res)
+{
+ struct srb_ctx *ctx = sp->ctx;
+ struct bsg_job *bsg_job = ctx->u.bsg_job;
+ struct fc_bsg_request *bsg_req = bsg_job->request;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+
+ if (bsg_req->msgcode == FC_BSG_HST_CT)
+ kfree(sp->fcport);
+ bsg_job->req->errors = 0;
+ bsg_reply->result = res;
+ bsg_job_done(bsg_job, res, bsg_reply->reply_payload_rcv_len);
+ kfree(sp->ctx);
+ mempool_free(sp, ha->srb_mempool);
+}
+
void
qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
{
@@ -1243,19 +1259,9 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
if (ctx->type == SRB_LOGIN_CMD ||
ctx->type == SRB_LOGOUT_CMD) {
ctx->u.iocb_cmd->free(sp);
- } else {
- struct fc_bsg_job *bsg_job =
- ctx->u.bsg_job;
- if (bsg_job->request->msgcode
- == FC_BSG_HST_CT)
- kfree(sp->fcport);
- bsg_job->req->errors = 0;
- bsg_job->reply->result = res;
- bsg_job->job_done(bsg_job);
- kfree(sp->ctx);
- mempool_free(sp,
- ha->srb_mempool);
- }
+ } else
+ qla2x00_abort_bsg_job(ha, sp,
+ res);
}
}
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 07/10] lpfc: convert lpfc to blk bsg lib
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
` (5 preceding siblings ...)
2011-07-24 8:59 ` [PATCH RFC/RFT 06/10] qla2xxx: convert qla2xxx " michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 08/10] bfa: convert bfa " michaelc
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, James Smart
From: Mike Christie <michaelc@cs.wisc.edu>
This patch converts lpfc to the blk bsg lib. The differences
visible to the driver are:
- fc_bsg_job is now named bsg_job.
- no rport pointer. Can access it through the device pointer.
- the request and reply pointers on the scsi_bsg_job struct
are now void pointers, so you cannot do bsg_job->request->some_field.
Patch is only compile tested and made over scsi-misc.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: James Smart <james.smart@emulex.com>
---
drivers/scsi/lpfc/lpfc_bsg.c | 428 ++++++++++++++++++++++++-----------------
drivers/scsi/lpfc/lpfc_crtn.h | 4 +-
2 files changed, 252 insertions(+), 180 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 7fb0ba4..2a5ee63 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -64,7 +64,7 @@ struct lpfc_bsg_event {
struct list_head events_to_see;
/* job waiting for this event to finish */
- struct fc_bsg_job *set_job;
+ struct bsg_job *set_job;
};
struct lpfc_bsg_iocb {
@@ -74,7 +74,7 @@ struct lpfc_bsg_iocb {
struct lpfc_nodelist *ndlp;
/* job waiting for this iocb to finish */
- struct fc_bsg_job *set_job;
+ struct bsg_job *set_job;
};
struct lpfc_bsg_mbox {
@@ -87,7 +87,7 @@ struct lpfc_bsg_mbox {
uint32_t outExtWLen; /* from app */
/* job waiting for this mbox command to finish */
- struct fc_bsg_job *set_job;
+ struct bsg_job *set_job;
};
#define MENLO_DID 0x0000FC0E
@@ -98,7 +98,7 @@ struct lpfc_bsg_menlo {
struct lpfc_dmabuf *bmp;
/* job waiting for this iocb to finish */
- struct fc_bsg_job *set_job;
+ struct bsg_job *set_job;
};
#define TYPE_EVT 1
@@ -163,7 +163,8 @@ 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 *reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp;
struct lpfc_nodelist *ndlp;
@@ -182,6 +183,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
iocb = &dd_data->context_un.iocb;
job = iocb->set_job;
job->dd_data = NULL; /* so timeout handler does not reply */
+ reply = job->reply;
bmp = iocb->bmp;
rsp = &rspiocbq->iocb;
@@ -208,7 +210,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
} else
rc = -EACCES;
} else
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
rsp->un.genreq64.bdl.bdeSize;
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
@@ -217,23 +219,26 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
kfree(bmp);
kfree(dd_data);
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
/* complete the job back to userspace */
- job->job_done(job);
+ bsg_job_done(job, rc, reply->reply_payload_rcv_len);
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
return;
}
/**
* lpfc_bsg_send_mgmt_cmd - send a CT command from a bsg request
- * @job: fc_bsg_job to handle
+ * @job: 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
- struct lpfc_rport_data *rdata = job->rport->dd_data;
+ struct fc_rport *rport = fc_bsg_to_rport(job);
+ struct lpfc_rport_data *rdata = rport->dd_data;
+ struct fc_bsg_reply *reply = job->reply;
struct lpfc_nodelist *ndlp = rdata->pnode;
struct ulp_bde64 *bpl = NULL;
uint32_t timeout;
@@ -251,7 +256,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;
+ reply->reply_payload_rcv_len = 0;
/* allocate our bsg tracking structure */
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
@@ -386,7 +391,7 @@ no_ndlp:
kfree(dd_data);
no_dd_data:
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
return rc;
}
@@ -414,7 +419,8 @@ 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 *reply;
IOCB_t *rsp;
struct lpfc_nodelist *ndlp;
struct lpfc_dmabuf *pbuflist = NULL;
@@ -437,6 +443,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
&rspiocbq->iocb, sizeof(IOCB_t));
job = dd_data->context_un.iocb.set_job;
+ reply = job->reply;
cmdiocbq = dd_data->context_un.iocb.cmdiocbq;
rspiocbq = dd_data->context_un.iocb.rspiocbq;
rsp = &rspiocbq->iocb;
@@ -447,17 +454,17 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
- if (job->reply->result == -EAGAIN)
+ if (reply->result == -EAGAIN)
rc = -EAGAIN;
else if (rsp->ulpStatus == IOSTAT_SUCCESS)
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
rsp->un.elsreq64.bdl.bdeSize;
else if (rsp->ulpStatus == IOSTAT_LS_RJT) {
- job->reply->reply_payload_rcv_len =
+ 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 = &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];
@@ -473,24 +480,26 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
lpfc_nlp_put(ndlp);
kfree(dd_data);
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
/* complete the job back to userspace */
- job->job_done(job);
+ bsg_job_done(job, rc, reply->reply_payload_rcv_len);
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
return;
}
/**
* lpfc_bsg_rport_els - send an ELS command from a bsg request
- * @job: fc_bsg_job to handle
+ * @job: 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
- struct lpfc_rport_data *rdata = job->rport->dd_data;
+ struct fc_rport *rport = fc_bsg_to_rport(job);
+ struct lpfc_rport_data *rdata = rport->dd_data;
struct lpfc_nodelist *ndlp = rdata->pnode;
uint32_t elscmd;
uint32_t cmdsize;
@@ -509,11 +518,13 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
int numbde;
dma_addr_t busaddr;
struct bsg_job_data *dd_data;
+ struct fc_bsg_request *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
uint32_t creg_val;
int rc = 0;
/* in case no data is transferred */
- job->reply->reply_payload_rcv_len = 0;
+ reply->reply_payload_rcv_len = 0;
/* allocate our bsg tracking structure */
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
@@ -529,7 +540,7 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
goto free_dd_data;
}
- elscmd = job->request->rqst_data.r_els.els_code;
+ elscmd = req->rqst_data.r_els.els_code;
cmdsize = job->request_payload.payload_len;
rspsize = job->reply_payload.payload_len;
rspiocbq = lpfc_sli_get_iocbq(phba);
@@ -639,7 +650,7 @@ free_dd_data:
no_dd_data:
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
return rc;
}
@@ -784,7 +795,8 @@ 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 *reply;
unsigned long flags;
int size = 0;
@@ -982,13 +994,15 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
job = evt->set_job;
evt->set_job = NULL;
if (job) {
- job->reply->reply_payload_rcv_len = size;
+ reply = job->reply;
+ reply->reply_payload_rcv_len = size;
+
/* make error code available to userspace */
- job->reply->result = 0;
+ reply->result = 0;
job->dd_data = NULL;
/* complete the job back to userspace */
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
- job->job_done(job);
+ bsg_job_done(job, 0, size);
spin_lock_irqsave(&phba->ct_ev_lock, flags);
}
}
@@ -1004,16 +1018,18 @@ error_ct_unsol_exit:
/**
* lpfc_bsg_hba_set_event - process a SET_EVENT bsg vendor command
- * @job: SET_EVENT fc_bsg_job
+ * @job: SET_EVENT 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct set_ct_event *event_req;
struct lpfc_bsg_event *evt;
int rc = 0;
+ struct fc_bsg_request *req = job->request;
struct bsg_job_data *dd_data = NULL;
uint32_t ev_mask;
unsigned long flags;
@@ -1036,7 +1052,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;
+ req->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);
@@ -1087,12 +1103,15 @@ job_error:
/**
* lpfc_bsg_hba_get_event - process a GET_EVENT bsg vendor command
- * @job: GET_EVENT fc_bsg_job
+ * @job: GET_EVENT 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct get_ct_event *event_req;
struct get_ct_event_reply *event_reply;
@@ -1111,10 +1130,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;
+ req->rqst_data.h_vendor.vendor_cmd;
event_reply = (struct get_ct_event_reply *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ reply->reply_data.vendor_reply.vendor_rsp;
spin_lock_irqsave(&phba->ct_ev_lock, flags);
list_for_each_entry(evt, &phba->ct_ev_waiters, node) {
if (evt->reg_id == event_req->ev_reg_id) {
@@ -1134,7 +1153,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;
+ reply->reply_payload_rcv_len = 0;
rc = -ENOENT;
goto job_error;
}
@@ -1150,12 +1169,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 =
+ 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;
+ reply->reply_payload_rcv_len = 0;
if (evt_dat) {
kfree(evt_dat->data);
@@ -1166,13 +1185,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;
- job->job_done(job);
+ reply->result = 0;
+ bsg_job_done(job, 0, reply->reply_payload_rcv_len);
return 0;
job_error:
job->dd_data = NULL;
- job->reply->result = rc;
+ reply->result = rc;
return rc;
}
@@ -1199,7 +1218,8 @@ 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 *reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp;
struct lpfc_nodelist *ndlp;
@@ -1218,6 +1238,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
bmp = dd_data->context_un.iocb.bmp;
rsp = &rspiocbq->iocb;
ndlp = dd_data->context_un.iocb.ndlp;
+ reply = job->reply;
pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -1238,7 +1259,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
} else
rc = -EACCES;
} else
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
rsp->un.genreq64.bdl.bdeSize;
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
@@ -1247,10 +1268,10 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
kfree(bmp);
kfree(dd_data);
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
/* complete the job back to userspace */
- job->job_done(job);
+ bsg_job_done(job, rc, reply->reply_payload_rcv_len);
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
return;
}
@@ -1264,8 +1285,8 @@ 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,
- struct lpfc_dmabuf *bmp, int num_entry)
+lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job,
+ uint32_t tag, struct lpfc_dmabuf *bmp, int num_entry)
{
IOCB_t *icmd;
struct lpfc_iocbq *ctiocb = NULL;
@@ -1394,15 +1415,18 @@ no_dd_data:
/**
* lpfc_bsg_send_mgmt_rsp - process a SEND_MGMT_RESP bsg vendor command
- * @job: SEND_MGMT_RESP fc_bsg_job
+ * @job: SEND_MGMT_RESP 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
+ struct fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
struct send_mgmt_resp *mgmt_resp = (struct send_mgmt_resp *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ req->rqst_data.h_vendor.vendor_cmd;
struct ulp_bde64 *bpl;
struct lpfc_dmabuf *bmp = NULL;
struct scatterlist *sgel = NULL;
@@ -1415,7 +1439,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;
+ reply->reply_payload_rcv_len = 0;
if (!reqbfrcnt || (reqbfrcnt > (80 * BUF_SZ_4K))) {
rc = -ERANGE;
@@ -1463,7 +1487,7 @@ send_mgmt_rsp_free_bmp:
kfree(bmp);
send_mgmt_rsp_exit:
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
return rc;
}
@@ -1477,7 +1501,7 @@ send_mgmt_rsp_exit:
* on device.
*/
static int
-lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba, struct fc_bsg_job *job)
+lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba, struct bsg_job *job)
{
struct lpfc_vport **vports;
struct Scsi_Host *shost;
@@ -1561,8 +1585,11 @@ 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 *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
struct diag_mode_set *loopback_mode;
uint32_t link_flags;
uint32_t timeout;
@@ -1572,7 +1599,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;
+ reply->reply_payload_rcv_len = 0;
if (job->request_len < sizeof(struct fc_bsg_request) +
sizeof(struct diag_mode_set)) {
@@ -1592,7 +1619,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;
+ req->rqst_data.h_vendor.vendor_cmd;
link_flags = loopback_mode->type;
timeout = loopback_mode->timeout * 100;
@@ -1664,10 +1691,11 @@ loopback_mode_exit:
job_error:
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
return rc;
}
@@ -1735,8 +1763,11 @@ link_diag_state_set_out:
* 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 *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
struct diag_mode_set *loopback_mode;
uint32_t link_flags, timeout, req_len, alloc_len;
struct lpfc_mbx_set_link_diag_loopback *link_diag_loopback;
@@ -1744,7 +1775,7 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
int mbxstatus, i, rc = 0;
/* no data to return just the return code */
- job->reply->reply_payload_rcv_len = 0;
+ reply->reply_payload_rcv_len = 0;
if (job->request_len < sizeof(struct fc_bsg_request) +
sizeof(struct diag_mode_set)) {
@@ -1764,7 +1795,7 @@ lpfc_sli4_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;
+ req->rqst_data.h_vendor.vendor_cmd;
link_flags = loopback_mode->type;
timeout = loopback_mode->timeout * 100;
@@ -1838,10 +1869,11 @@ loopback_mode_exit:
job_error:
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
return rc;
}
@@ -1853,17 +1885,16 @@ 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 Scsi_Host *shost = fc_bsg_to_shost(job);
struct lpfc_vport *vport;
struct lpfc_hba *phba;
int rc;
- shost = job->shost;
if (!shost)
return -ENODEV;
- vport = (struct lpfc_vport *)job->shost->hostdata;
+ vport = (struct lpfc_vport *)shost->hostdata;
if (!vport)
return -ENODEV;
phba = vport->phba;
@@ -1890,17 +1921,16 @@ 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 Scsi_Host *shost;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
struct lpfc_vport *vport;
struct lpfc_hba *phba;
int rc;
- shost = job->shost;
if (!shost)
return -ENODEV;
- vport = (struct lpfc_vport *)job->shost->hostdata;
+ vport = (struct lpfc_vport *)shost->hostdata;
if (!vport)
return -ENODEV;
phba = vport->phba;
@@ -1929,9 +1959,11 @@ lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
* 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 Scsi_Host *shost;
+ struct fc_bsg_request *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
struct lpfc_vport *vport;
struct lpfc_hba *phba;
LPFC_MBOXQ_t *pmboxq;
@@ -1944,12 +1976,11 @@ lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
struct diag_status *diag_status_reply;
int mbxstatus, rc = 0;
- shost = job->shost;
if (!shost) {
rc = -ENODEV;
goto job_error;
}
- vport = (struct lpfc_vport *)job->shost->hostdata;
+ vport = (struct lpfc_vport *)shost->hostdata;
if (!vport) {
rc = -ENODEV;
goto job_error;
@@ -1987,7 +2018,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;
+ req->rqst_data.h_vendor.vendor_cmd;
timeout = link_diag_test_cmd->timeout * 100;
rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1);
@@ -2038,7 +2069,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;
+ reply->reply_data.vendor_reply.vendor_rsp;
if (job->reply_len <
sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) {
@@ -2066,10 +2097,11 @@ link_diag_test_exit:
job_error:
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
return rc;
}
@@ -2618,9 +2650,12 @@ 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_request *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct diag_mode_test *diag_mode;
struct lpfc_bsg_event *evt;
@@ -2649,7 +2684,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;
+ reply->reply_payload_rcv_len = 0;
if (job->request_len <
sizeof(struct fc_bsg_request) + sizeof(struct diag_mode_test)) {
@@ -2667,7 +2702,7 @@ lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
}
diag_mode = (struct diag_mode_test *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ req->rqst_data.h_vendor.vendor_cmd;
if ((phba->link_state == LPFC_HBA_ERROR) ||
(psli->sli_flag & LPFC_BLOCK_MGMT_IO) ||
@@ -2854,11 +2889,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 =
+ 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;
+ reply->reply_payload_rcv_len = size;
}
}
@@ -2888,22 +2923,26 @@ err_loopback_test_exit:
loopback_test_exit:
kfree(dataout);
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
/* complete the job back to userspace if no error */
if (rc == 0)
- job->job_done(job);
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
return rc;
}
/**
* lpfc_bsg_get_dfc_rev - process a GET_DFC_REV bsg vendor command
- * @job: GET_DFC_REV fc_bsg_job
+ * @job: GET_DFC_REV 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_request *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct get_mgmt_rev *event_req;
struct get_mgmt_rev_reply *event_reply;
@@ -2919,10 +2958,10 @@ lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
}
event_req = (struct get_mgmt_rev *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ req->rqst_data.h_vendor.vendor_cmd;
event_reply = (struct get_mgmt_rev_reply *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ reply->reply_data.vendor_reply.vendor_rsp;
if (job->reply_len <
sizeof(struct fc_bsg_request) + sizeof(struct get_mgmt_rev_reply)) {
@@ -2936,9 +2975,10 @@ 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;
+ reply->result = rc;
if (rc == 0)
- job->job_done(job);
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
return rc;
}
@@ -2957,7 +2997,8 @@ void
lpfc_bsg_issue_mbox_cmpl(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 *reply;
uint32_t size;
unsigned long flags;
uint8_t *pmb, *pmb_buf;
@@ -2980,8 +3021,9 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
job = dd_data->context_un.mbox.set_job;
if (job) {
+ reply = job->reply;
size = job->reply_payload.payload_len;
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
pmb_buf, size);
@@ -3002,8 +3044,9 @@ lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
kfree(dd_data);
if (job) {
- job->reply->result = 0;
- job->job_done(job);
+ reply->result = 0;
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
}
return;
}
@@ -3131,11 +3174,12 @@ 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 *reply;
uint8_t *pmb, *pmb_buf;
unsigned long flags;
uint32_t size;
@@ -3160,13 +3204,14 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
job = dd_data->context_un.mbox.set_job;
if (job) {
+ reply = job->reply;
size = job->reply_payload.payload_len;
- job->reply->reply_payload_rcv_len =
+ 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;
+ reply->result = 0;
job->dd_data = NULL;
/* need to hold the lock util we set job->dd_data to NULL
* to hold off the timeout handler from midlayer to take
@@ -3206,7 +3251,8 @@ job_done_out:
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 *reply;
/* handle the BSG job with mailbox command */
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS)
@@ -3226,9 +3272,11 @@ lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
mempool_free(pmboxq, phba->mbox_mem_pool);
/* complete the bsg job if we have it */
- if (job)
- job->job_done(job);
-
+ if (job) {
+ reply = job->reply;
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
+ }
return;
}
@@ -3243,7 +3291,8 @@ 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 *reply;
/* handle the BSG job with the mailbox command */
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS)
@@ -3261,9 +3310,11 @@ lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
lpfc_bsg_mbox_ext_session_reset(phba);
/* complete the bsg job if we have it */
- if (job)
- job->job_done(job);
-
+ if (job) {
+ reply = job->reply;
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
+ }
return;
}
@@ -3371,10 +3422,11 @@ 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)
{
+ struct fc_bsg_request *req = job->request;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
struct dfc_mbox_req *mbox_req;
struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf;
@@ -3387,7 +3439,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 *)req->rqst_data.h_vendor.vendor_cmd;
/* pointer to the start of mailbox command */
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
@@ -3538,10 +3590,11 @@ 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)
{
+ struct fc_bsg_request *req = job->request;
struct dfc_mbox_req *mbox_req;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
uint32_t ext_buf_cnt;
@@ -3552,7 +3605,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
int rc = 0, i;
mbox_req =
- (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+ (struct dfc_mbox_req *)req->rqst_data.h_vendor.vendor_cmd;
/* pointer to the start of mailbox command */
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
@@ -3687,7 +3740,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;
@@ -3808,8 +3861,9 @@ 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 *reply = job->reply;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
struct lpfc_dmabuf *dmabuf;
uint8_t *pbuf;
@@ -3841,7 +3895,7 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
struct lpfc_dmabuf, list);
list_del_init(&dmabuf->list);
pbuf = (uint8_t *)dmabuf->virt;
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
pbuf, size);
@@ -3855,8 +3909,8 @@ 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;
- job->job_done(job);
+ reply->result = 0;
+ bsg_job_done(job, 0, reply->reply_payload_rcv_len);
return SLI_CONFIG_HANDLED;
}
@@ -3870,9 +3924,10 @@ 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 *reply = job->reply;
struct lpfc_sli_config_mbox *sli_cfg_mbx;
struct bsg_job_data *dd_data = NULL;
LPFC_MBOXQ_t *pmboxq = NULL;
@@ -3969,8 +4024,8 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
}
/* wait for additoinal external buffers */
- job->reply->result = 0;
- job->job_done(job);
+ reply->result = 0;
+ bsg_job_done(job, 0, 0);
return SLI_CONFIG_HANDLED;
job_error:
@@ -3990,7 +4045,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;
@@ -4035,14 +4090,14 @@ 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 *req = job->request;
struct dfc_mbox_req *mbox_req;
int rc;
- mbox_req =
- (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+ mbox_req = (struct dfc_mbox_req *)req->rqst_data.h_vendor.vendor_cmd;
/* mbox command with/without single external buffer */
if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0)
@@ -4112,9 +4167,11 @@ sli_cfg_ext_error:
* let our completion handler finish the command.
**/
static uint32_t
-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_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
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 */
@@ -4135,7 +4192,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
/* in case no data is transferred */
- job->reply->reply_payload_rcv_len = 0;
+ reply->reply_payload_rcv_len = 0;
/* sanity check to protect driver */
if (job->reply_payload.payload_len > BSG_MBOX_SIZE ||
@@ -4153,8 +4210,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
goto job_done;
}
- mbox_req =
- (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+ mbox_req = (struct dfc_mbox_req *)req->rqst_data.h_vendor.vendor_cmd;
/* check if requested extended data lengths are valid */
if ((mbox_req->inExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t)) ||
@@ -4374,7 +4430,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 =
+ reply->reply_payload_rcv_len =
sg_copy_from_buffer(job->reply_payload.sg_list,
job->reply_payload.sg_cnt,
pmbx, size);
@@ -4403,15 +4459,18 @@ 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
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;
+ 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,
@@ -4422,7 +4481,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;
+ req->rqst_data.h_vendor.vendor_cmd;
mbox_req->extMboxTag = 0;
mbox_req->extSeqNum = 0;
}
@@ -4431,15 +4490,15 @@ lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
if (rc == 0) {
/* job done */
- job->reply->result = 0;
+ reply->result = 0;
job->dd_data = NULL;
- job->job_done(job);
+ bsg_job_done(job, 0, reply->reply_payload_rcv_len);
} else if (rc == 1)
/* job submitted, will complete later*/
rc = 0; /* return zero, no error */
else {
/* some error occurred */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
}
@@ -4469,7 +4528,8 @@ 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 *reply;
IOCB_t *rsp;
struct lpfc_dmabuf *bmp;
struct lpfc_bsg_menlo *menlo;
@@ -4486,6 +4546,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
menlo = &dd_data->context_un.menlo;
job = menlo->set_job;
+ reply = job->reply;
job->dd_data = NULL; /* so timeout handler does not reply */
spin_lock(&phba->hbalock);
@@ -4509,7 +4570,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
* of the exchange.
*/
menlo_resp = (struct menlo_response *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ reply->reply_data.vendor_reply.vendor_rsp;
menlo_resp->xri = rsp->ulpContext;
if (rsp->ulpStatus) {
if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
@@ -4527,7 +4588,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
} else
rc = -EACCES;
} else
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
rsp->un.genreq64.bdl.bdeSize;
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
@@ -4536,16 +4597,16 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
kfree(bmp);
kfree(dd_data);
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
/* complete the job back to userspace */
- job->job_done(job);
+ bsg_job_done(job, reply->result, reply->reply_payload_rcv_len);
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
return;
}
/**
* lpfc_menlo_cmd - send an ioctl for menlo hardware
- * @job: fc_bsg_job to handle
+ * @job: bsg_job to handle
*
* This function issues a gen request 64 CR ioctl for all menlo cmd requests,
* all the command completions will return the xri for the command.
@@ -4553,9 +4614,12 @@ 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct lpfc_iocbq *cmdiocbq, *rspiocbq;
IOCB_t *cmd, *rsp;
@@ -4572,7 +4636,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;
+ reply->reply_payload_rcv_len = 0;
if (job->request_len <
sizeof(struct fc_bsg_request) +
@@ -4602,10 +4666,10 @@ lpfc_menlo_cmd(struct fc_bsg_job *job)
}
menlo_cmd = (struct menlo_command *)
- job->request->rqst_data.h_vendor.vendor_cmd;
+ req->rqst_data.h_vendor.vendor_cmd;
menlo_resp = (struct menlo_response *)
- job->reply->reply_data.vendor_reply.vendor_rsp;
+ reply->reply_data.vendor_reply.vendor_rsp;
/* allocate our bsg tracking structure */
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
@@ -4733,19 +4797,21 @@ free_dd:
kfree(dd_data);
no_dd_data:
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
job->dd_data = NULL;
return rc;
}
/**
* lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
- * @job: fc_bsg_job to handle
+ * @job: bsg_job to handle
**/
static int
-lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
+lpfc_bsg_hst_vendor(struct bsg_job *job)
{
- int command = job->request->rqst_data.h_vendor.vendor_cmd[0];
+ struct fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
+ int command = req->rqst_data.h_vendor.vendor_cmd[0];
int rc;
switch (command) {
@@ -4782,9 +4848,9 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
break;
default:
rc = -EINVAL;
- job->reply->reply_payload_rcv_len = 0;
+ reply->reply_payload_rcv_len = 0;
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
break;
}
@@ -4793,15 +4859,17 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
/**
* lpfc_bsg_request - handle a bsg request from the FC transport
- * @job: fc_bsg_job to handle
+ * @job: bsg_job to handle
**/
int
-lpfc_bsg_request(struct fc_bsg_job *job)
+lpfc_bsg_request(struct bsg_job *job)
{
+ struct fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
uint32_t msgcode;
int rc;
- msgcode = job->request->msgcode;
+ msgcode = req->msgcode;
switch (msgcode) {
case FC_BSG_HST_VENDOR:
rc = lpfc_bsg_hst_vendor(job);
@@ -4814,9 +4882,9 @@ lpfc_bsg_request(struct fc_bsg_job *job)
break;
default:
rc = -EINVAL;
- job->reply->reply_payload_rcv_len = 0;
+ reply->reply_payload_rcv_len = 0;
/* make error code available to userspace */
- job->reply->result = rc;
+ reply->result = rc;
break;
}
@@ -4825,15 +4893,17 @@ lpfc_bsg_request(struct fc_bsg_job *job)
/**
* lpfc_bsg_timeout - handle timeout of a bsg request from the FC transport
- * @job: fc_bsg_job that has timed out
+ * @job: bsg_job that has timed out
*
* This function just aborts the job's IOCB. The aborted IOCB will return to
* 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 = (struct lpfc_vport *)job->shost->hostdata;
+ struct fc_bsg_reply *reply = job->reply;
+ struct Scsi_Host *shost = fc_bsg_to_shost(job);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct lpfc_iocbq *cmdiocb;
struct lpfc_bsg_event *evt;
@@ -4857,7 +4927,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
iocb = &dd_data->context_un.iocb;
cmdiocb = iocb->cmdiocbq;
/* hint to completion handler that the job timed out */
- job->reply->result = -EAGAIN;
+ reply->result = -EAGAIN;
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
/* this will call our completion handler */
spin_lock_irq(&phba->hbalock);
@@ -4869,24 +4939,26 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
/* this event has no job anymore */
evt->set_job = NULL;
job->dd_data = NULL;
- job->reply->reply_payload_rcv_len = 0;
+ reply->reply_payload_rcv_len = 0;
/* Return -EAGAIN which is our way of signallying the
* app to retry.
*/
- job->reply->result = -EAGAIN;
+ reply->result = -EAGAIN;
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
- job->job_done(job);
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
break;
case TYPE_MBOX:
mbox = &dd_data->context_un.mbox;
/* this mbox has no job anymore */
mbox->set_job = NULL;
job->dd_data = NULL;
- job->reply->reply_payload_rcv_len = 0;
- job->reply->result = -EAGAIN;
+ reply->reply_payload_rcv_len = 0;
+ reply->result = -EAGAIN;
/* the mbox completion handler can now be run */
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
- job->job_done(job);
+ bsg_job_done(job, reply->result,
+ reply->reply_payload_rcv_len);
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_PORT)
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_ABTS;
break;
@@ -4894,7 +4966,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
menlo = &dd_data->context_un.menlo;
cmdiocb = menlo->cmdiocbq;
/* hint to completion handler that the job timed out */
- job->reply->result = -EAGAIN;
+ reply->result = -EAGAIN;
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
/* this will call our completion handler */
spin_lock_irq(&phba->hbalock);
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index fc20c24..202bbcd 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -415,8 +415,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 *);
void __lpfc_sli_ringtx_put(struct lpfc_hba *, struct lpfc_sli_ring *,
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 08/10] bfa: convert bfa to blk bsg lib
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
` (6 preceding siblings ...)
2011-07-24 8:59 ` [PATCH RFC/RFT 07/10] lpfc: convert lpfc " michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 09/10] zfcp: convert zfcp " michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 10/10] ibmvfc: convert ibmvfc " michaelc
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Krishna Gudipati, Jing Huang
From: Mike Christie <michaelc@cs.wisc.edu>
This converts bfa to use the bsg lib. I also coverted it
to use shost_priv in the bfa bsg code.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Krishna Gudipati <kgudipat@brocade.com>
Cc: Jing Huang <huangj@brocade.com>
---
drivers/scsi/bfa/bfad_bsg.c | 58 +++++++++++++++++++++++--------------------
drivers/scsi/bfa/bfad_im.h | 4 +-
2 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 89f863e..6414244 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -1710,11 +1710,12 @@ 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)
{
- uint32_t vendor_cmd = job->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 fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
+ uint32_t vendor_cmd = req->rqst_data.h_vendor.vendor_cmd[0];
+ struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job));
struct bfad_s *bfad = im_port->bfad;
void *payload_kbuf;
int rc = -EINVAL;
@@ -1748,18 +1749,18 @@ 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;
+ reply->reply_payload_rcv_len = job->reply_payload.payload_len;
+ reply->result = rc;
- job->job_done(job);
+ bsg_job_done(job, reply->result, reply->reply_payload_rcv_len);
return rc;
error:
/* free the command buffer */
kfree(payload_kbuf);
out:
- job->reply->result = rc;
+ reply->result = rc;
job->reply_len = sizeof(uint32_t);
- job->reply->reply_payload_rcv_len = 0;
+ reply->reply_payload_rcv_len = 0;
return rc;
}
@@ -1885,7 +1886,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;
@@ -1925,27 +1926,28 @@ 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 fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
+ struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(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_s *bfad = im_port->bfad;
bfa_bsg_fcpt_t *bsg_fcpt;
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;
+ uint32_t command_type = req->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;
+ reply->reply_payload_rcv_len = 0;
/* Get the payload passed in from userspace */
- bsg_data = (struct bfa_bsg_data *) (((char *)job->request) +
+ bsg_data = (struct bfa_bsg_data *) (((char *)req) +
sizeof(struct fc_bsg_request));
if (bsg_data == NULL)
goto out;
@@ -2086,13 +2088,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;
+ reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
+ reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
} else {
- job->reply->reply_payload_rcv_len =
+ reply->reply_payload_rcv_len =
sizeof(struct fc_bsg_ctels_reply);
job->reply_len = sizeof(uint32_t);
- job->reply->reply_data.ctels_reply.status =
+ reply->reply_data.ctels_reply.status =
FC_CTELS_STATUS_REJECT;
}
@@ -2118,20 +2120,22 @@ out_free_mem:
kfree(bsg_fcpt);
kfree(drv_fcxp);
out:
- job->reply->result = rc;
+ reply->result = rc;
if (rc == BFA_STATUS_OK)
- job->job_done(job);
+ bsg_job_done(job, reply->result, reply->reply_payload_rcv_len);
return rc;
}
int
-bfad_im_bsg_request(struct fc_bsg_job *job)
+bfad_im_bsg_request(struct bsg_job *job)
{
+ struct fc_bsg_reply *reply = job->reply;
+ struct fc_bsg_request *req = job->request;
uint32_t rc = BFA_STATUS_OK;
- switch (job->request->msgcode) {
+ switch (req->msgcode) {
case FC_BSG_HST_VENDOR:
/* Process BSG HST Vendor requests */
rc = bfad_im_bsg_vendor_request(job);
@@ -2144,8 +2148,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;
+ reply->result = rc = -EINVAL;
+ reply->reply_payload_rcv_len = 0;
break;
}
@@ -2153,7 +2157,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 4fe34d5..d7cc6a6 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -141,7 +141,7 @@ 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);
#endif
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 09/10] zfcp: convert zfcp to blk bsg lib
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
` (7 preceding siblings ...)
2011-07-24 8:59 ` [PATCH RFC/RFT 08/10] bfa: convert bfa " michaelc
@ 2011-07-24 8:59 ` michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 10/10] ibmvfc: convert ibmvfc " michaelc
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Christof Schmitt
From: Mike Christie <michaelc@cs.wisc.edu>
This patch converts zfcp to the blk bsg lib. The differences
visible to the driver are:
- fc_bsg_job is now named bsg_job.
- no rport pointer. Can access it through the device pointer.
- the request and reply pointers on the scsi_bsg_job struct
are now void pointers, so you cannot do bsg_job->request->some_field.
Patch is only compile tested and made over scsi-misc.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Christof Schmitt <christof.schmitt@de.ibm.com>
---
drivers/s390/scsi/zfcp_ext.h | 4 ++--
drivers/s390/scsi/zfcp_fc.c | 33 +++++++++++++++++----------------
2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 03627cfd..bfe6ea7 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -94,8 +94,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 *);
/* zfcp_fsf.c */
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 297e6b7..164b0d9 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -818,26 +818,27 @@ 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;
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);
+ bsg_job_done(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)
{
+ struct fc_bsg_request *jq = job->request;
u32 preamble_word1;
u8 gs_type;
struct zfcp_adapter *adapter;
- preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
+ preamble_word1 = jq->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:
@@ -857,7 +858,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);
@@ -866,11 +867,12 @@ 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;
- struct fc_rport *rport = job->rport;
+ struct fc_rport *rport = fc_bsg_to_rport(job);
+ struct fc_bsg_request *jq = job->request;
struct zfcp_port *port;
u32 d_id;
@@ -882,13 +884,13 @@ 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(jq->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);
}
-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;
@@ -911,14 +913,13 @@ 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;
struct zfcp_fsf_ct_els *ct_els = job->dd_data;
+ struct fc_bsg_request *jq = job->request;
- shost = job->rport ? rport_to_shost(job->rport) : job->shost;
- adapter = (struct zfcp_adapter *)shost->hostdata[0];
+ adapter = shost_priv(fc_bsg_to_shost(job));
if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
return -EINVAL;
@@ -927,7 +928,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 (jq->msgcode) {
case FC_BSG_RPT_ELS:
case FC_BSG_HST_ELS_NOLOGIN:
return zfcp_fc_exec_els_job(job, adapter);
@@ -939,7 +940,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;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC/RFT 10/10] ibmvfc: convert ibmvfc to blk bsg lib
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
` (8 preceding siblings ...)
2011-07-24 8:59 ` [PATCH RFC/RFT 09/10] zfcp: convert zfcp " michaelc
@ 2011-07-24 8:59 ` michaelc
9 siblings, 0 replies; 13+ messages in thread
From: michaelc @ 2011-07-24 8:59 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Brian King
From: Mike Christie <michaelc@cs.wisc.edu>
This patch converts ibmvfc to the bsg lib. The differences
visible to the driver are:
- fc_bsg_job is now named bsg_job.
- no rport pointer. Can access it through the device pointer.
- the request and reply pointers on the bsg_job struct
are now void pointers, so you cannot do bsg_job->request->some_field.
Patch is only compile tested and made over scsi-misc.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Brian King <brking@linux.vnet.ibm.com>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 44 +++++++++++++++++++++------------------
1 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index bdfa223..48b4140 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1704,14 +1704,14 @@ 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(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;
@@ -1817,42 +1817,46 @@ 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(job->shost);
- struct fc_rport *rport = job->rport;
+ struct ibmvfc_host *vhost = shost_priv(fc_bsg_to_shost(job));
+ struct fc_rport *rport;
+ struct fc_bsg_request *req = job->request;
+ struct fc_bsg_reply *reply = job->reply;
struct ibmvfc_passthru_mad *mad;
struct ibmvfc_event *evt;
union ibmvfc_iu rsp_iu;
unsigned long flags, port_id = -1;
- unsigned int code = job->request->msgcode;
+ unsigned int code = req->msgcode;
int rc = 0, req_seg, rsp_seg, issue_login = 0;
u32 fc_flags, rsp_len;
ENTER;
- job->reply->reply_payload_rcv_len = 0;
- if (rport)
- port_id = rport->port_id;
+ reply->reply_payload_rcv_len = 0;
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 = (req->rqst_data.h_els.port_id[0] << 16) |
+ (req->rqst_data.h_els.port_id[1] << 8) |
+ req->rqst_data.h_els.port_id[2];
case FC_BSG_RPT_ELS:
+ rport = dev_to_rport(job->dev);
+ port_id = rport->port_id;
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 = (req->rqst_data.h_ct.port_id[0] << 16) |
+ (req->rqst_data.h_ct.port_id[1] << 8) |
+ req->rqst_data.h_ct.port_id[2];
case FC_BSG_RPT_CT:
+ rport = dev_to_rport(job->dev);
+ port_id = rport->port_id;
fc_flags = IBMVFC_FC_CT_IU;
break;
default:
@@ -1940,13 +1944,13 @@ 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;
+ 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;
- job->job_done(job);
+ reply->result = rc;
+ bsg_job_done(job, reply->result, reply->reply_payload_rcv_len);
rc = 0;
out:
dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH RFC/RFT 01/10] block: add bsg heler library
2011-07-24 8:59 ` [PATCH RFC/RFT 01/10] block: add bsg heler library michaelc
@ 2011-07-24 18:32 ` Jens Axboe
0 siblings, 0 replies; 13+ messages in thread
From: Jens Axboe @ 2011-07-24 18:32 UTC (permalink / raw)
To: michaelc@cs.wisc.edu; +Cc: linux-scsi@vger.kernel.org
On 2011-07-24 10:59, michaelc@cs.wisc.edu wrote:
> From: Mike Christie <michaelc@cs.wisc.edu>
>
> This moves the FC classes bsg code to the block layer and
> makes it a lib so that other classes like iscsi and SAS can use it.
>
> It is helpful because working with the request queue, bios,
> creating scatterlists, etc are a pain that the LLD does not
> have to worry about with normal IOs and should not have to
> worry about for bsg requests.
Mike, I'm going to queue this up for post -rc1.
--
Jens Axboe
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RFC/RFT 05/10] libfc: convert to blk bsg lib
2011-07-24 8:59 ` [PATCH RFC/RFT 05/10] libfc: convert to blk " michaelc
@ 2011-07-28 1:13 ` Love, Robert W
0 siblings, 0 replies; 13+ messages in thread
From: Love, Robert W @ 2011-07-28 1:13 UTC (permalink / raw)
To: michaelc@cs.wisc.edu; +Cc: linux-scsi@vger.kernel.org
On Sun, 2011-07-24 at 03:59 -0500, michaelc@cs.wisc.edu wrote:
> From: Mike Christie <michaelc@cs.wisc.edu>
>
> This patch converts libfc to the blk bsg lib. The differences
> visible to the driver are:
> - fc_bsg_job is now named bsg_job.
> - no rport pointer. Can access it through the device pointer.
> - the request and reply pointers on the blk_bsg_job struct
> are now void pointers, so you cannot do bsg_job->request->some_field.
>
> Patch is only quickly tested with fcping and made over scsi-misc.
>
> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
> Cc: Robert Love <robert.w.love@intel.com>
Lightly tested using fcping and fcnsq from the fcoe-utils package. The
change seems like a good idea to me.
Tested-by: Robert Love <robert.w.love@intel.com>
I noticed that there's a "Selected by: SCSI_ISCSI_ATTRS [=n] && SCSI
[=y] && NET [=y]" in the kernel configuration (make menuconfig), but I
didn't notice the same for SCSI_FC_ATTRS. I think we want that, and
maybe some other drivers want to have it auto-selected too.
//Rob
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-07-28 1:13 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-24 8:59 [PATCH RFC/RFT 00/10] add block layer bsg helper lib michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 01/10] block: add bsg heler library michaelc
2011-07-24 18:32 ` Jens Axboe
2011-07-24 8:59 ` [PATCH RFC/RFT 02/10] iscsi class: add bsg support to iscsi class michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 03/10] be2iscsi: add bsg support michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 04/10] FC class: convert to scsi bsg lib michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 05/10] libfc: convert to blk " michaelc
2011-07-28 1:13 ` Love, Robert W
2011-07-24 8:59 ` [PATCH RFC/RFT 06/10] qla2xxx: convert qla2xxx " michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 07/10] lpfc: convert lpfc " michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 08/10] bfa: convert bfa " michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 09/10] zfcp: convert zfcp " michaelc
2011-07-24 8:59 ` [PATCH RFC/RFT 10/10] ibmvfc: convert ibmvfc " michaelc
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox