From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC PATCH v2 07/13] scsi: add walking of hierarchical LUNs
Date: Mon, 6 Jun 2011 18:04:16 +0200 [thread overview]
Message-ID: <1307376262-1255-8-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1307376262-1255-1-git-send-email-pbonzini@redhat.com>
This adds support for parsing a hierarchical LUN and mapping the
result to the qdev hierarchy.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi-bus.c | 83 +++++++++++++++++++++++++++++++++++++++++++----------
hw/scsi.h | 9 +++++-
hw/spapr_vscsi.c | 6 ++-
3 files changed, 79 insertions(+), 19 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index b64ed68..54f308d 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -841,33 +841,84 @@ retry:
abort();
}
-/* Extract bus and target from the given LUN and use it to identify a
- SCSIDevice from a SCSIBus. Right now, only 1 target per bus is
- supported. In the future a SCSIDevice could host its own SCSIBus,
- in an alternation of devices that select a bus (target ports) and
- devices that select a target (initiator ports). */
-SCSIDevice *scsi_decode_lun(SCSIBus *sbus, uint64_t sam_lun, int *lun)
+/* Reusable implementation of the decode_lun entry in SCSIBusOps. */
+SCSIDevice *scsi_decode_bus_from_lun(SCSIBus *sbus, uint64_t sam_lun,
+ uint64_t *next_lun)
{
- int bus, target, decoded_lun;
- uint64_t next_lun;
+ int bus, target;
+ uint64_t my_next_lun;
+ SCSIDevice *sdev;
- if (!scsi_decode_level(sam_lun, &bus, &target, &next_lun)) {
+ if (!scsi_decode_level(sam_lun, &bus, &target, &my_next_lun)) {
/* Unsupported LUN format. */
return NULL;
}
- if (bus >= sbus->ndev || (bus == 0 && target > 0)) {
+ if (bus >= sbus->ndev) {
/* Out of range. */
return NULL;
}
- if (target != 0) {
- /* Only one target for now. */
+
+ sdev = sbus->devs[bus];
+ if (!sdev) {
+ return NULL;
+ } else if (!sdev->children || !sdev->children->ops->decode_lun) {
+ *next_lun = my_next_lun;
+ return target ? NULL : sdev;
+ } else {
+ /* Next we'll find the target, so pass down the same LUN we got. */
+ return sdev->children->ops->decode_lun(sdev->children, sam_lun,
+ next_lun);
+ }
+}
+
+SCSIDevice *scsi_decode_target_from_lun(SCSIBus *sbus, uint64_t sam_lun,
+ uint64_t *next_lun)
+{
+ int bus, target;
+ SCSIDevice *sdev;
+
+ if (!scsi_decode_level(sam_lun, &bus, &target, next_lun)) {
+ /* Unsupported LUN format. */
+ return NULL;
+ }
+ if (target >= sbus->ndev) {
+ /* Out of range. */
return NULL;
}
+ sdev = sbus->devs[target];
+ if (!sdev || !sdev->children || !sdev->children->ops->decode_lun ||
+ (*next_lun >> 56) == ADDR_WELL_KNOWN_LUN) {
+ return sdev;
+ } else {
+ return sdev->children->ops->decode_lun(sdev->children, *next_lun,
+ next_lun);
+ }
+}
+
+/* Extract bus and target from the given LUN and use it to identify a
+ SCSIDevice from a SCSIBus. Right now, only 1 target per bus is
+ supported. In the future a SCSIDevice could host its own SCSIBus,
+ in an alternation of devices that select a bus (target ports) and
+ devices that select a target (initiator ports). */
+SCSIDevice *scsi_decode_lun(SCSIBus *sbus, uint64_t sam_lun,
+ uint8_t *cdb, int *lun)
+{
+ int decoded_lun;
+ uint64_t next_lun;
+ SCSIDevice *sdev;
+
+ sdev = sbus->ops->decode_lun(sbus, sam_lun, &next_lun);
+ if (!sdev) {
+ return NULL;
+ }
decoded_lun = scsi_get_lun(next_lun);
- if (decoded_lun != LUN_INVALID) {
- *lun = decoded_lun;
- return sbus->devs[bus];
+ if (decoded_lun == LUN_INVALID) {
+ return NULL;
+ }
+ if ((decoded_lun & ~LUN_WLUN_MASK) == LUN_WLUN_BASE) {
+ return sdev;
}
- return NULL;
+ *lun = decoded_lun;
+ return scsi_find_lun(sdev, decoded_lun, cdb);
}
diff --git a/hw/scsi.h b/hw/scsi.h
index 67d18cc..9f70771 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -92,6 +92,8 @@ struct SCSIBusOps {
void (*complete)(SCSIRequest *req, uint32_t arg);
void (*cancel)(SCSIRequest *req);
int (*get_child_lun)(SCSIDevice *dev);
+ SCSIDevice *(*decode_lun)(SCSIBus *sbus, uint64_t sam_lun,
+ uint64_t *next_lun);
};
struct SCSIBus {
@@ -156,7 +158,12 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
int scsi_sense_valid(SCSISense sense);
-SCSIDevice *scsi_decode_lun(SCSIBus *sbus, uint64_t sam_lun, int *lun);
+SCSIDevice *scsi_decode_lun(SCSIBus *sbus, uint64_t sam_lun, uint8_t *cdb,
+ int *lun);
+SCSIDevice *scsi_decode_bus_from_lun(SCSIBus *sbus, uint64_t sam_lun,
+ uint64_t *next_lun);
+SCSIDevice *scsi_decode_target_from_lun(SCSIBus *sbus, uint64_t sam_lun,
+ uint64_t *next_lun);
SCSIDevice *scsi_find_lun(SCSIDevice *sdev, int lun, uint8_t *cdb);
SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, DeviceState *initiator,
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 5b5fa87..ace9dac 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -637,7 +637,8 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
SCSIDevice *sdev;
int n, lun;
- sdev = scsi_decode_lun(&s->bus, be64_to_cpu(srp->cmd.lun), &lun);
+ sdev = scsi_decode_lun(&s->bus, be64_to_cpu(srp->cmd.lun),
+ srp->cmd.cdb, &lun);
if (!sdev) {
if (srp->cmd.cdb[0] == INQUIRY) {
vscsi_inquiry_no_target(s, req);
@@ -915,7 +916,8 @@ static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data)
static const struct SCSIBusOps vscsi_scsi_ops = {
.transfer_data = vscsi_transfer_data,
.complete = vscsi_command_complete,
- .cancel = vscsi_request_cancelled
+ .cancel = vscsi_request_cancelled,
+ .decode_lun = scsi_decode_bus_from_lun
};
static int spapr_vscsi_init(VIOsPAPRDevice *dev)
--
1.7.4.4
next prev parent reply other threads:[~2011-06-06 16:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-06 16:04 [Qemu-devel] [RFC PATCH v2 00/13] support hierarchical LUNs Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 01/13] scsi: cleanup reset and destroy callbacks Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 02/13] scsi: support parsing of SAM logical unit numbers Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 03/13] scsi: add initiator field to SCSIRequest Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 04/13] scsi: let a SCSIDevice have children devices Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 05/13] scsi: let the bus pick a LUN for the child device Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 06/13] scsi-generic: fix passthrough of devices with LUN != 0 Paolo Bonzini
2011-06-06 16:04 ` Paolo Bonzini [this message]
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 08/13] scsi: introduce the scsi-path device Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 09/13] scsi: introduce the scsi-target device Paolo Bonzini
2011-06-07 8:09 ` Stefan Hajnoczi
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 10/13] scsi: include bus and device levels Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 11/13] qdev: introduce automatic creation of buses Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 12/13] scsi: create scsi-path and scsi-target devices automatically Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 13/13] scsi: delete handling of REPORT LUNS and unknown LUNs outside scsi-target Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1307376262-1255-8-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).