[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCH v2] spapr_vscsi: Fix REPORT_LUNS handling
From: |
Alexander Graf |
Subject: |
Re: [Qemu-ppc] [PATCH v2] spapr_vscsi: Fix REPORT_LUNS handling |
Date: |
Mon, 20 Jan 2014 16:03:43 +0100 |
On 12.01.2014, at 23:34, Nathan Whitehorn <address@hidden> wrote:
> Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known
> LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC
> specifications.
>
> Since SRP implements only a single SCSI target port per connection, the SRP
> target is required to report all available LUNs in response to a REPORT_LUNS
> command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was
> forwarding such requests to the first QEMU SCSI target, with the result that
> initiators that relied on this feature would only see LUNs on the first QEMU
> SCSI target.
>
> Behavior for REPORT_LUNS commands addressed to any other LUN is not specified
> by the standard and so is left unchanged. This preserves behavior under Linux
> and SLOF, which enumerate possible LUNs by hand and so address no commands
> either to LUN 0 or the well-known REPORT_LUNS LUN.
>
> Signed-off-by: Nathan Whitehorn <address@hidden>
Thanks, applied to ppc-next.
Alex
> --
> hw/scsi/spapr_vscsi.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 60 insertions(+)
>
> diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
> index c0c46d7..123a942 100644
> --- a/hw/scsi/spapr_vscsi.c
> +++ b/hw/scsi/spapr_vscsi.c
> @@ -63,6 +63,8 @@
> #define SCSI_SENSE_BUF_SIZE 96
> #define SRP_RSP_SENSE_DATA_LEN 18
>
> +#define SRP_REPORT_LUNS_WLUN 0xc10100000000000
> +
> typedef union vscsi_crq {
> struct viosrp_crq s;
> uint8_t raw[16];
> @@ -720,12 +722,70 @@ static void vscsi_inquiry_no_target(VSCSIState *s,
> vscsi_req *req)
> }
> }
>
> +static void vscsi_report_luns(VSCSIState *s, vscsi_req *req)
> +{
> + BusChild *kid;
> + int i, len, n, rc;
> + uint8_t *resp_data;
> + bool found_lun0;
> +
> + n = 0;
> + found_lun0 = false;
> + QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
> + SCSIDevice *dev = SCSI_DEVICE(kid->child);
> +
> + n += 8;
> + if (dev->channel == 0 && dev->id == 0 && dev->lun == 0) {
> + found_lun0 = true;
> + }
> + }
> + if (!found_lun0) {
> + n += 8;
> + }
> + len = n+8;
> +
> + resp_data = g_malloc0(len);
> + memset(resp_data, 0, len);
> + stl_be_p(resp_data, n);
> + i = found_lun0 ? 8 : 16;
> + QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
> + DeviceState *qdev = kid->child;
> + SCSIDevice *dev = SCSI_DEVICE(qdev);
> +
> + if (dev->id == 0 && dev->channel == 0) {
> + resp_data[i] = 0; /* Use simple LUN for 0 (SAM5 4.7.7.1)
> */
> + } else {
> + resp_data[i] = (2 << 6); /* Otherwise LUN addressing (4.7.7.4)
> */
> + }
> + resp_data[i] |= dev->id;
> + resp_data[i+1] = (dev->channel << 5);
> + resp_data[i+1] |= dev->lun;
> + i += 8;
> + }
> +
> + vscsi_preprocess_desc(req);
> + rc = vscsi_srp_transfer_data(s, req, 0, resp_data, len);
> + g_free(resp_data);
> + if (rc < 0) {
> + vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
> + vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
> + } else {
> + vscsi_send_rsp(s, req, 0, len - rc, 0);
> + }
> +}
> +
> static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
> {
> union srp_iu *srp = &req->iu.srp;
> SCSIDevice *sdev;
> int n, lun;
>
> + if ((srp->cmd.lun == 0 || be64_to_cpu(srp->cmd.lun) ==
> SRP_REPORT_LUNS_WLUN)
> + && srp->cmd.cdb[0] == REPORT_LUNS) {
> + vscsi_report_luns(s, req);
> + return 0;
> + }
> +
> sdev = vscsi_device_find(&s->bus, be64_to_cpu(srp->cmd.lun), &lun);
> if (!sdev) {
> DPRINTF("VSCSI: Command for lun %08" PRIx64 " with no drive\n",
>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-ppc] [PATCH v2] spapr_vscsi: Fix REPORT_LUNS handling,
Alexander Graf <=