From patchwork Thu Dec 14 10:14:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 848453 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yy8hL0xqTz9s1h for ; Thu, 14 Dec 2017 21:20:18 +1100 (AEDT) Received: from localhost ([::1]:39977 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQci-0004Mu-6n for incoming@patchwork.ozlabs.org; Thu, 14 Dec 2017 05:20:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52070) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQXy-0001HQ-JB for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePQXp-0004M1-9o for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:22 -0500 Received: from mx2.suse.de ([195.135.220.15]:59090) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ePQXo-0004HH-Os for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:13 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 22F16ADF5; Thu, 14 Dec 2017 10:15:09 +0000 (UTC) From: Hannes Reinecke To: Paolo Bonzini Date: Thu, 14 Dec 2017 11:14:32 +0100 Message-Id: <20171214101435.26265-2-hare@suse.de> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171214101435.26265-1-hare@suse.de> References: <20171214101435.26265-1-hare@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 195.135.220.15 Subject: [Qemu-devel] [PATCH 1/4] scsi: use 64-bit LUN X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hannes Reinecke , qemu-devel@nongnu.org, Hannes Reinecke Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The LUN value really is a 64-bit number, so we should as well treat it as such. And we should be using accessor functions to provide backwards compability. Signed-off-by: Hannes Reinecke --- hw/scsi/esp.c | 6 ++- hw/scsi/lsi53c895a.c | 7 +-- hw/scsi/megasas.c | 24 +++++---- hw/scsi/mptsas.c | 10 ++-- hw/scsi/scsi-bus.c | 137 ++++++++++++++++++++++++++++++++----------------- hw/scsi/scsi-disk.c | 6 +-- hw/scsi/scsi-generic.c | 2 +- hw/scsi/spapr_vscsi.c | 17 +++--- hw/scsi/virtio-scsi.c | 10 ++-- hw/scsi/vmw_pvscsi.c | 22 ++++---- hw/usb/dev-storage.c | 11 ++-- hw/usb/dev-uas.c | 27 +++------- include/hw/scsi/scsi.h | 56 +++++++++++++++++--- 13 files changed, 207 insertions(+), 128 deletions(-) diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index ee586e7d6c..12b76bc5c4 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -136,8 +136,10 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) trace_esp_do_busid_cmd(busid); lun = busid & 7; - current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun); - s->current_req = scsi_req_new(current_lun, 0, lun, buf, s); + current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, + scsi_lun_from_int(lun)); + s->current_req = scsi_req_new(current_lun, 0, scsi_lun_from_int(lun), + buf, s); datalen = scsi_req_enqueue(s->current_req); s->ti_size = datalen; if (datalen != 0) { diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 191505df5b..907ba880bf 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -811,7 +811,7 @@ static void lsi_do_command(LSIState *s) s->command_complete = 0; id = (s->select_tag >> 8) & 0xf; - dev = scsi_device_find(&s->bus, 0, id, s->current_lun); + dev = scsi_device_find(&s->bus, 0, id, scsi_lun_from_int(s->current_lun)); if (!dev) { lsi_bad_selection(s, id); return; @@ -820,8 +820,9 @@ static void lsi_do_command(LSIState *s) assert(s->current == NULL); s->current = g_new0(lsi_request, 1); s->current->tag = s->select_tag; - s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun, buf, - s->current); + s->current->req = scsi_req_new(dev, s->current->tag, + scsi_lun_from_int(s->current_lun), + buf, s->current); n = scsi_req_enqueue(s->current->req); if (n) { diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index d5eae6239a..2b9fb71b12 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -756,7 +756,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd) uint16_t pd_id; if (num_pd_disks < 8) { - pd_id = ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF); + pd_id = ((sdev->id & 0xFF) << 8) | scsi_lun_to_int(sdev->lun); info.device.port_addr[num_pd_disks] = cpu_to_le64(megasas_get_sata_addr(pd_id)); } @@ -975,7 +975,7 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd) if (num_pd_disks >= max_pd_disks) break; - pd_id = ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF); + pd_id = ((sdev->id & 0xFF) << 8) | scsi_lun_to_int(sdev->lun); info.addr[num_pd_disks].device_id = cpu_to_le16(pd_id); info.addr[num_pd_disks].encl_device_id = 0xFFFF; info.addr[num_pd_disks].encl_index = 0; @@ -1028,7 +1028,8 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun, info->inquiry_data[0] = 0x7f; /* Force PQual 0x3, PType 0x1f */ info->vpd_page83[0] = 0x7f; megasas_setup_inquiry(cmdbuf, 0, sizeof(info->inquiry_data)); - cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd); + cmd->req = scsi_req_new(sdev, cmd->index, scsi_lun_from_int(lun), + cmdbuf, cmd); if (!cmd->req) { trace_megasas_dcmd_req_alloc_failed(cmd->index, "PD get info std inquiry"); @@ -1110,7 +1111,7 @@ static int megasas_dcmd_pd_get_info(MegasasState *s, MegasasCmd *cmd) pd_id = le16_to_cpu(cmd->frame->dcmd.mbox[0]); target_id = (pd_id >> 8) & 0xFF; lun_id = pd_id & 0xFF; - sdev = scsi_device_find(&s->bus, 0, target_id, lun_id); + sdev = scsi_device_find(&s->bus, 0, target_id, scsi_lun_from_int(lun_id)); trace_megasas_dcmd_pd_get_info(cmd->index, pd_id); if (sdev) { @@ -1200,7 +1201,7 @@ static int megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd) if (num_ld_disks >= max_ld_disks) { break; } - info.targetid[num_ld_disks] = sdev->lun; + info.targetid[num_ld_disks] = scsi_lun_to_int(sdev->lun); num_ld_disks++; dcmd_size++; } @@ -1335,7 +1336,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd) QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { SCSIDevice *sdev = SCSI_DEVICE(kid->child); - uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF); + uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | scsi_lun_to_int(sdev->lun); struct mfi_array *array; struct mfi_ld_config *ld; uint64_t pd_size; @@ -1595,7 +1596,7 @@ static int megasas_finish_internal_dcmd(MegasasCmd *cmd, SCSIRequest *req, size_t resid) { int retval = MFI_STAT_OK; - int lun = req->lun; + int lun = scsi_lun_to_int(req->lun); trace_megasas_dcmd_internal_finish(cmd->index, cmd->dcmd_opcode, lun); cmd->iov_size -= resid; @@ -1671,7 +1672,7 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd, return MFI_STAT_DEVICE_NOT_FOUND; } } - sdev = scsi_device_find(&s->bus, 0, target_id, lun_id); + sdev = scsi_device_find(&s->bus, 0, target_id, scsi_lun_from_int(lun_id)); cmd->iov_size = le32_to_cpu(cmd->frame->header.data_len); trace_megasas_handle_scsi(mfi_frame_desc[frame_cmd], is_logical, @@ -1700,7 +1701,8 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd, return MFI_STAT_SCSI_DONE_WITH_ERROR; } - cmd->req = scsi_req_new(sdev, cmd->index, lun_id, cdb, cmd); + cmd->req = scsi_req_new(sdev, cmd->index, scsi_lun_from_int(lun_id), + cdb, cmd); if (!cmd->req) { trace_megasas_scsi_req_alloc_failed( mfi_frame_desc[frame_cmd], target_id, lun_id); @@ -1744,7 +1746,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd) cdb_len = cmd->frame->header.cdb_len; if (target_id < MFI_MAX_LD && lun_id == 0) { - sdev = scsi_device_find(&s->bus, 0, target_id, lun_id); + sdev = scsi_device_find(&s->bus, 0, target_id, 0); } trace_megasas_handle_io(cmd->index, @@ -1775,7 +1777,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd) megasas_encode_lba(cdb, lba_start, lba_count, is_write); cmd->req = scsi_req_new(sdev, cmd->index, - lun_id, cdb, cmd); + scsi_lun_from_int(lun_id), cdb, cmd); if (!cmd->req) { trace_megasas_scsi_req_alloc_failed( mfi_frame_desc[frame_cmd], target_id, lun_id); diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c index f6db1b0103..f103984152 100644 --- a/hw/scsi/mptsas.c +++ b/hw/scsi/mptsas.c @@ -276,7 +276,7 @@ static int mptsas_scsi_device_find(MPTSASState *s, int bus, int target, return MPI_IOCSTATUS_SCSI_INVALID_TARGETID; } - *sdev = scsi_device_find(&s->bus, bus, target, lun[1]); + *sdev = scsi_device_find(&s->bus, bus, target, scsi_lun_from_str(lun)); if (!*sdev) { return MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE; } @@ -322,7 +322,7 @@ static int mptsas_process_scsi_io_request(MPTSASState *s, } req->sreq = scsi_req_new(sdev, scsi_io->MsgContext, - scsi_io->LUN[1], scsi_io->CDB, req); + sdev->lun, scsi_io->CDB, req); if (req->sreq->cmd.xfer > scsi_io->DataLength) { goto overrun; @@ -430,7 +430,7 @@ static void mptsas_process_scsi_task_mgmt(MPTSASState *s, MPIMsgSCSITaskMgmt *re reply.IOCStatus = status; goto out; } - if (sdev->lun != req->LUN[1]) { + if (sdev->lun != scsi_lun_from_str(req->LUN)) { reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN; goto out; } @@ -477,7 +477,7 @@ static void mptsas_process_scsi_task_mgmt(MPTSASState *s, MPIMsgSCSITaskMgmt *re reply.IOCStatus = status; goto out; } - if (sdev->lun != req->LUN[1]) { + if (sdev->lun != scsi_lun_from_str(req->LUN)) { reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN; goto out; } @@ -515,7 +515,7 @@ reply_maybe_async: reply.IOCStatus = status; goto out; } - if (sdev->lun != req->LUN[1]) { + if (sdev->lun != scsi_lun_from_str(req->LUN)) { reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN; goto out; } diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 977f7bce1f..a0e66d0e01 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -20,7 +20,7 @@ static void scsi_target_free_buf(SCSIRequest *req); static Property scsi_props[] = { DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1), - DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1), + DEFINE_PROP_UINT64("lun", SCSIDevice, lun, -1), DEFINE_PROP_END_OF_LIST(), }; @@ -68,7 +68,7 @@ int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf, return rc; } -static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t lun, +static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint64_t lun, uint8_t *buf, void *hba_private) { SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s); @@ -147,6 +147,22 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state) } } +static int scsi_device_count(SCSIBus *bus, int channel, int id) +{ + BusChild *kid; + int luns = 0; + + QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, ChildrenHead, sibling) { + DeviceState *qdev = kid->child; + SCSIDevice *dev = SCSI_DEVICE(qdev); + + if (dev->channel == channel && dev->id == id) { + luns++; + } + } + return luns; +} + static void scsi_qdev_realize(DeviceState *qdev, Error **errp) { SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -162,9 +178,15 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp) error_setg(errp, "bad scsi device id: %d", dev->id); return; } - if (dev->lun != -1 && dev->lun > bus->info->max_lun) { - error_setg(errp, "bad scsi device lun: %d", dev->lun); - return; + if (dev->lun != -1) { + /* Compat: commandline might have passed old-style linear LUN */ + if (dev->lun < 0xffff) { + if (dev->lun > bus->info->max_lun) { + error_setg(errp, "bad scsi device lun: %"PRIu64"", dev->lun); + return; + } + dev->lun = scsi_lun_from_int(dev->lun); + } } if (dev->id == -1) { @@ -181,15 +203,18 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp) } dev->id = id; } else if (dev->lun == -1) { - int lun = -1; + int lun = 0; do { - d = scsi_device_find(bus, dev->channel, dev->id, ++lun); - } while (d && d->lun == lun && lun < bus->info->max_lun); - if (d && d->lun == lun) { + d = scsi_device_find(bus, dev->channel, dev->id, + scsi_lun_from_int(lun)); + lun++; + } while (d && scsi_lun_to_int(d->lun) == lun && + lun < bus->info->max_lun); + if (d && scsi_lun_to_int(d->lun) == lun) { error_setg(errp, "no free lun"); return; } - dev->lun = lun; + dev->lun = scsi_lun_from_int(lun); } else { d = scsi_device_find(bus, dev->channel, dev->id, dev->lun); assert(d); @@ -197,6 +222,10 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp) error_setg(errp, "lun already used by '%s'", d->qdev.id); return; } + if (scsi_device_count(bus, dev->channel, dev->id) >= bus->info->max_lun) { + error_setg(errp, "bad scsi device lun: %"PRIu64"", dev->lun); + return; + } } QTAILQ_INIT(&dev->requests); @@ -385,16 +414,6 @@ struct SCSITargetReq { int buf_len; }; -static void store_lun(uint8_t *outbuf, int lun) -{ - if (lun < 256) { - outbuf[1] = lun; - return; - } - outbuf[1] = (lun & 255); - outbuf[0] = (lun >> 8) | 0x40; -} - static bool scsi_target_emulate_report_luns(SCSITargetReq *r) { BusChild *kid; @@ -438,7 +457,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) SCSIDevice *dev = SCSI_DEVICE(qdev); if (dev->channel == channel && dev->id == id) { - store_lun(&r->buf[i], dev->lun); + scsi_lun_to_str(dev->lun, &r->buf[i]); i += 8; } } @@ -631,7 +650,7 @@ static const struct SCSIReqOps reqops_target_command = { SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, - uint32_t tag, uint32_t lun, void *hba_private) + uint32_t tag, uint64_t lun, void *hba_private) { SCSIRequest *req; SCSIBus *bus = scsi_bus_from_device(d); @@ -652,11 +671,11 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, object_ref(OBJECT(d)); object_ref(OBJECT(qbus->parent)); notifier_list_init(&req->cancel_notifiers); - trace_scsi_req_alloc(req->dev->id, req->lun, req->tag); + trace_scsi_req_alloc(req->dev->id, scsi_lun_to_int(req->lun), req->tag); return req; } -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint64_t lun, uint8_t *buf, void *hba_private) { SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); @@ -694,14 +713,14 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, } if (ret != 0) { - trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]); + trace_scsi_req_parse_bad(d->id, scsi_lun_to_int(lun), tag, buf[0]); req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private); } else { assert(cmd.len != 0); - trace_scsi_req_parsed(d->id, lun, tag, buf[0], + trace_scsi_req_parsed(d->id, scsi_lun_to_int(lun), tag, buf[0], cmd.mode, cmd.xfer); if (cmd.lba != -1) { - trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0], + trace_scsi_req_parsed_lba(d->id, scsi_lun_to_int(lun), tag, buf[0], cmd.lba); } @@ -719,16 +738,17 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, switch (buf[0]) { case INQUIRY: - trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]); + trace_scsi_inquiry(d->id, scsi_lun_to_int(lun), tag, + cmd.buf[1], cmd.buf[2]); break; case TEST_UNIT_READY: - trace_scsi_test_unit_ready(d->id, lun, tag); + trace_scsi_test_unit_ready(d->id, scsi_lun_to_int(lun), tag); break; case REPORT_LUNS: - trace_scsi_report_luns(d->id, lun, tag); + trace_scsi_report_luns(d->id, scsi_lun_to_int(lun), tag); break; case REQUEST_SENSE: - trace_scsi_request_sense(d->id, lun, tag); + trace_scsi_request_sense(d->id, scsi_lun_to_int(lun), tag); break; default: break; @@ -816,8 +836,8 @@ int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed) void scsi_req_build_sense(SCSIRequest *req, SCSISense sense) { - trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag, - sense.key, sense.asc, sense.ascq); + trace_scsi_req_build_sense(req->dev->id, scsi_lun_to_int(req->lun), + req->tag, sense.key, sense.asc, sense.ascq); req->sense_len = scsi_build_sense(req->sense, sense); } @@ -848,7 +868,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req) static void scsi_req_dequeue(SCSIRequest *req) { - trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); + trace_scsi_req_dequeue(req->dev->id, scsi_lun_to_int(req->lun), req->tag); req->retry = false; if (req->enqueued) { QTAILQ_REMOVE(&req->dev->requests, req, next); @@ -1339,10 +1359,11 @@ void scsi_req_unref(SCSIRequest *req) void scsi_req_continue(SCSIRequest *req) { if (req->io_canceled) { - trace_scsi_req_continue_canceled(req->dev->id, req->lun, req->tag); + trace_scsi_req_continue_canceled(req->dev->id, + scsi_lun_to_int(req->lun), req->tag); return; } - trace_scsi_req_continue(req->dev->id, req->lun, req->tag); + trace_scsi_req_continue(req->dev->id, scsi_lun_to_int(req->lun), req->tag); if (req->cmd.mode == SCSI_XFER_TO_DEV) { req->ops->write_data(req); } else { @@ -1357,10 +1378,11 @@ void scsi_req_data(SCSIRequest *req, int len) { uint8_t *buf; if (req->io_canceled) { - trace_scsi_req_data_canceled(req->dev->id, req->lun, req->tag, len); + trace_scsi_req_data_canceled(req->dev->id, scsi_lun_to_int(req->lun), + req->tag, len); return; } - trace_scsi_req_data(req->dev->id, req->lun, req->tag, len); + trace_scsi_req_data(req->dev->id, scsi_lun_to_int(req->lun), req->tag, len); assert(req->cmd.mode != SCSI_XFER_NONE); if (!req->sg) { req->resid -= len; @@ -1463,7 +1485,7 @@ void scsi_req_cancel_complete(SCSIRequest *req) * */ void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier) { - trace_scsi_req_cancel(req->dev->id, req->lun, req->tag); + trace_scsi_req_cancel(req->dev->id, scsi_lun_to_int(req->lun), req->tag); if (notifier) { notifier_list_add(&req->cancel_notifiers, notifier); } @@ -1488,7 +1510,7 @@ void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier) void scsi_req_cancel(SCSIRequest *req) { - trace_scsi_req_cancel(req->dev->id, req->lun, req->tag); + trace_scsi_req_cancel(req->dev->id, scsi_lun_to_int(req->lun), req->tag); if (!req->enqueued) { return; } @@ -1539,7 +1561,7 @@ void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense) if (sense.key != UNIT_ATTENTION) { return; } - trace_scsi_device_set_ua(sdev->id, sdev->lun, sense.key, + trace_scsi_device_set_ua(sdev->id, scsi_lun_to_int(sdev->lun), sense.key, sense.asc, sense.ascq); /* @@ -1576,9 +1598,21 @@ static char *scsibus_get_dev_path(DeviceState *dev) id = qdev_get_dev_path(hba); if (id) { - path = g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun); + if (scsi_lun_to_int(d->lun) < 0x3fff) { + path = g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, + scsi_lun_to_int(d->lun)); + } else { + path = g_strdup_printf("%s/%d:%d:%"PRIx64"", id, d->channel, d->id, + d->lun); + } } else { - path = g_strdup_printf("%d:%d:%d", d->channel, d->id, d->lun); + if (scsi_lun_to_int(d->lun) < 0x3fff) { + path = g_strdup_printf("%d:%d:%d", d->channel, d->id, + scsi_lun_to_int(d->lun)); + } else { + path = g_strdup_printf("%d:%d:%"PRIu64"", d->channel, d->id, + d->lun); + } } g_free(id); return path; @@ -1587,11 +1621,16 @@ static char *scsibus_get_dev_path(DeviceState *dev) static char *scsibus_get_fw_dev_path(DeviceState *dev) { SCSIDevice *d = SCSI_DEVICE(dev); - return g_strdup_printf("channel@%x/%s@%x,%x", d->channel, - qdev_fw_name(dev), d->id, d->lun); + if (scsi_lun_to_int(d->lun) > 0x3fff) { + return g_strdup_printf("channel@%x/%s@%x,%d", d->channel, + qdev_fw_name(dev), d->id, scsi_lun_to_int(d->lun)); + } else { + return g_strdup_printf("channel@%x/%s@%x,%"PRIx64"", d->channel, + qdev_fw_name(dev), d->id, d->lun); + } } -SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, uint64_t lun) { BusChild *kid; SCSIDevice *target_dev = NULL; @@ -1618,6 +1657,7 @@ static int put_scsi_requests(QEMUFile *f, void *pv, size_t size, SCSIDevice *s = pv; SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus); SCSIRequest *req; + uint32_t lun; QTAILQ_FOREACH(req, &s->requests, next) { assert(!req->io_canceled); @@ -1626,8 +1666,9 @@ static int put_scsi_requests(QEMUFile *f, void *pv, size_t size, qemu_put_sbyte(f, req->retry ? 1 : 2); qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf)); + lun = (uint32_t)((req->lun >> 32) & 0xFFFFFFFF); qemu_put_be32s(f, &req->tag); - qemu_put_be32s(f, &req->lun); + qemu_put_be32s(f, &lun); if (bus->info->save_request) { bus->info->save_request(f, req); } @@ -1656,7 +1697,7 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size, qemu_get_buffer(f, buf, sizeof(buf)); qemu_get_be32s(f, &tag); qemu_get_be32s(f, &lun); - req = scsi_req_new(s, tag, lun, buf, NULL); + req = scsi_req_new(s, tag, (uint64_t)lun << 32, buf, NULL); req->retry = (sbyte == 1); if (bus->info->load_request) { req->hba_private = bus->info->load_request(f, req); diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 12431177a7..cbee840601 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2517,7 +2517,7 @@ static const SCSIReqOps *const scsi_disk_reqops_dispatch[256] = { [WRITE_VERIFY_16] = &scsi_disk_dma_reqops, }; -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint64_t lun, uint8_t *buf, void *hba_private) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); @@ -2533,7 +2533,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, req = scsi_req_alloc(ops, &s->qdev, tag, lun, hba_private); #ifdef DEBUG_SCSI - DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); + DPRINTF("Command: lun=%"PRIu64" tag=0x%x data=0x%02x", lun, tag, buf[0]); { int i; for (i = 1; i < scsi_cdb_length(buf); i++) { @@ -2847,7 +2847,7 @@ static const SCSIReqOps scsi_block_dma_reqops = { }; static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag, - uint32_t lun, uint8_t *buf, + uint64_t lun, uint8_t *buf, void *hba_private) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index bd0d9ff355..4a161a69b1 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -557,7 +557,7 @@ const SCSIReqOps scsi_generic_req_ops = { .save_request = scsi_generic_save_request, }; -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint64_t lun, uint8_t *buf, void *hba_private) { return scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private); diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 360db53ac8..160c1de6b3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -136,9 +136,9 @@ static void vscsi_put_req(vscsi_req *req) req->active = 0; } -static SCSIDevice *vscsi_device_find(SCSIBus *bus, uint64_t srp_lun, int *lun) +static SCSIDevice *vscsi_device_find(SCSIBus *bus, uint64_t srp_lun, uint64_t *lun) { - int channel = 0, id = 0; + int channel = 0, id = 0, l; retry: switch (srp_lun >> 62) { @@ -149,16 +149,16 @@ retry: srp_lun <<= 16; goto retry; } - *lun = (srp_lun >> 48) & 0xff; + l = (srp_lun >> 48) & 0xff; break; case 1: - *lun = (srp_lun >> 48) & 0x3fff; + l = (srp_lun >> 48) & 0x3fff; break; case 2: channel = (srp_lun >> 53) & 0x7; id = (srp_lun >> 56) & 0x3f; - *lun = (srp_lun >> 48) & 0x1f; + l = (srp_lun >> 48) & 0x1f; break; case 3: *lun = -1; @@ -166,7 +166,7 @@ retry: default: abort(); } - + *lun = scsi_lun_from_int(l); return scsi_device_find(bus, channel, id, *lun); } @@ -752,7 +752,7 @@ static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) } resp_data[i] |= dev->id; resp_data[i+1] = (dev->channel << 5); - resp_data[i+1] |= dev->lun; + resp_data[i+1] |= scsi_lun_to_int(dev->lun); i += 8; } @@ -822,8 +822,9 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) { union viosrp_iu *iu = &req->iu; vscsi_req *tmpreq; - int i, lun = 0, resp = SRP_TSK_MGMT_COMPLETE; + int i, resp = SRP_TSK_MGMT_COMPLETE; SCSIDevice *d; + uint64_t lun = 0; uint64_t tag = iu->srp.rsp.tag; uint8_t sol_not = iu->srp.cmd.sol_not; diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 3aa99717e2..f98bfb3db5 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -25,9 +25,9 @@ #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-access.h" -static inline int virtio_scsi_get_lun(uint8_t *lun) +static inline uint64_t virtio_scsi_get_lun(uint8_t *lun) { - return ((lun[2] << 8) | lun[3]) & 0x3FFF; + return (((uint64_t)(lun[2] << 8) | lun[3]) & 0x3FFF) << 48; } static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) @@ -737,10 +737,10 @@ void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, evt->lun[1] = dev->id; /* Linux wants us to keep the same encoding we use for REPORT LUNS. */ - if (dev->lun >= 256) { - evt->lun[2] = (dev->lun >> 8) | 0x40; + if (scsi_lun_to_int(dev->lun) >= 256) { + evt->lun[2] = (scsi_lun_to_int(dev->lun) >> 8) | 0x40; } - evt->lun[3] = dev->lun & 0xFF; + evt->lun[3] = scsi_lun_to_int(dev->lun) & 0xFF; } virtio_scsi_complete_req(req); } diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c index d564e5caff..e2d36f8709 100644 --- a/hw/scsi/vmw_pvscsi.c +++ b/hw/scsi/vmw_pvscsi.c @@ -135,7 +135,7 @@ typedef struct PVSCSIRequest { PVSCSIState *dev; uint8_t sense_key; uint8_t completed; - int lun; + uint64_t lun; QEMUSGList sgl; PVSCSISGState sg; struct PVSCSIRingReqDesc req; @@ -551,7 +551,7 @@ pvscsi_send_msg(PVSCSIState *s, SCSIDevice *dev, uint32_t msg_type) msg.type = msg_type; msg.bus = dev->channel; msg.target = dev->id; - msg.lun[1] = dev->lun; + scsi_lun_to_str(dev->lun, msg.lun); pvscsi_msg_ring_put(s, (PVSCSIRingMsgDesc *)&msg); pvscsi_ring_flush_msg(&s->rings); @@ -597,15 +597,15 @@ pvscsi_request_cancelled(SCSIRequest *req) static SCSIDevice* pvscsi_device_find(PVSCSIState *s, int channel, int target, - uint8_t *requested_lun, uint8_t *target_lun) + uint8_t *requested_lun, uint64_t *target_lun) { - if (requested_lun[0] || requested_lun[2] || requested_lun[3] || - requested_lun[4] || requested_lun[5] || requested_lun[6] || - requested_lun[7] || (target > PVSCSI_MAX_DEVS)) { + uint64_t lun64 = scsi_lun_from_str(requested_lun); + + if (scsi_lun_to_int(lun64) > 255 || (target > PVSCSI_MAX_DEVS)) { return NULL; } else { - *target_lun = requested_lun[1]; - return scsi_device_find(&s->bus, channel, target, *target_lun); + *target_lun = lun64; + return scsi_device_find(&s->bus, channel, target, lun64); } } @@ -614,7 +614,7 @@ pvscsi_queue_pending_descriptor(PVSCSIState *s, SCSIDevice **d, struct PVSCSIRingReqDesc *descr) { PVSCSIRequest *pvscsi_req; - uint8_t lun; + uint64_t lun; pvscsi_req = g_malloc0(sizeof(*pvscsi_req)); pvscsi_req->dev = s; @@ -823,14 +823,14 @@ pvscsi_on_cmd_unknown(PVSCSIState *s) static uint64_t pvscsi_on_cmd_reset_device(PVSCSIState *s) { - uint8_t target_lun = 0; + uint64_t target_lun = 0; struct PVSCSICmdDescResetDevice *cmd = (struct PVSCSICmdDescResetDevice *) s->curr_cmd_data; SCSIDevice *sdev; sdev = pvscsi_device_find(s, 0, cmd->target, cmd->lun, &target_lun); - trace_pvscsi_on_cmd_reset_dev(cmd->target, (int) target_lun, sdev); + trace_pvscsi_on_cmd_reset_dev(cmd->target, scsi_lun_to_int(target_lun), sdev); if (sdev != NULL) { s->resetting++; diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 8a61ec94c8..14a62ed829 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -371,11 +371,12 @@ static void usb_msd_handle_control(USBDevice *dev, USBPacket *p, case ClassInterfaceRequest | GetMaxLun: maxlun = 0; for (;;) { - scsi_dev = scsi_device_find(&s->bus, 0, 0, maxlun+1); + scsi_dev = scsi_device_find(&s->bus, 0, 0, + scsi_lun_from_int(maxlun+1)); if (scsi_dev == NULL) { break; } - if (scsi_dev->lun != maxlun+1) { + if (scsi_lun_to_int(scsi_dev->lun) != maxlun+1) { break; } maxlun++; @@ -429,7 +430,8 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p) goto fail; } DPRINTF("Command on LUN %d\n", cbw.lun); - scsi_dev = scsi_device_find(&s->bus, 0, 0, cbw.lun); + scsi_dev = scsi_device_find(&s->bus, 0, 0, + scsi_lun_from_int(cbw.lun)); if (scsi_dev == NULL) { error_report("usb-msd: Bad LUN %d", cbw.lun); goto fail; @@ -447,7 +449,8 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p) tag, cbw.flags, cbw.cmd_len, s->data_len); assert(le32_to_cpu(s->csw.residue) == 0); s->scsi_len = 0; - s->req = scsi_req_new(scsi_dev, tag, cbw.lun, cbw.cmd, NULL); + s->req = scsi_req_new(scsi_dev, tag, scsi_lun_from_int(cbw.lun), + cbw.cmd, NULL); #ifdef DEBUG_MSD scsi_req_print(s->req); #endif diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index c218b53f09..6f4207e868 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -461,19 +461,6 @@ static void usb_uas_queue_write_ready(UASRequest *req) /* --------------------------------------------------------------------- */ -static int usb_uas_get_lun(uint64_t lun64) -{ - return (lun64 >> 48) & 0xff; -} - -static SCSIDevice *usb_uas_get_dev(UASDevice *uas, uint64_t lun64) -{ - if ((lun64 >> 56) != 0x00) { - return NULL; - } - return scsi_device_find(&uas->bus, 0, 0, usb_uas_get_lun(lun64)); -} - static void usb_uas_complete_data_packet(UASRequest *req) { USBPacket *p; @@ -547,7 +534,7 @@ static UASRequest *usb_uas_alloc_request(UASDevice *uas, uas_iu *iu) req->uas = uas; req->tag = be16_to_cpu(iu->hdr.tag); req->lun = be64_to_cpu(iu->command.lun); - req->dev = usb_uas_get_dev(req->uas, req->lun); + req->dev = scsi_device_find(&uas->bus, 0, 0, req->lun); return req; } @@ -709,7 +696,7 @@ static void usb_uas_command(UASDevice *uas, uas_iu *iu) } trace_usb_uas_command(uas->dev.addr, req->tag, - usb_uas_get_lun(req->lun), + scsi_lun_to_int(req->lun), req->lun >> 32, req->lun & 0xffffffff); QTAILQ_INSERT_TAIL(&uas->requests, req, next); if (uas_using_streams(uas) && uas->data3[req->tag] != NULL) { @@ -719,7 +706,7 @@ static void usb_uas_command(UASDevice *uas, uas_iu *iu) } req->req = scsi_req_new(req->dev, req->tag, - usb_uas_get_lun(req->lun), + scsi_lun_to_int(req->lun), iu->command.cdb, req); if (uas->requestlog) { scsi_req_print(req->req); @@ -747,9 +734,8 @@ bad_target: static void usb_uas_task(UASDevice *uas, uas_iu *iu) { uint16_t tag = be16_to_cpu(iu->hdr.tag); - uint64_t lun64 = be64_to_cpu(iu->task.lun); - SCSIDevice *dev = usb_uas_get_dev(uas, lun64); - int lun = usb_uas_get_lun(lun64); + uint64_t lun = be64_to_cpu(iu->task.lun); + SCSIDevice *dev = scsi_device_find(&uas->bus, 0, 0, lun); UASRequest *req; uint16_t task_tag; @@ -776,7 +762,8 @@ static void usb_uas_task(UASDevice *uas, uas_iu *iu) break; case UAS_TMF_LOGICAL_UNIT_RESET: - trace_usb_uas_tmf_logical_unit_reset(uas->dev.addr, tag, lun); + trace_usb_uas_tmf_logical_unit_reset(uas->dev.addr, tag, + scsi_lun_to_int(lun)); qdev_reset_all(&dev->qdev); usb_uas_queue_response(uas, tag, UAS_RC_TMF_COMPLETE); break; diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 23a8ee6a7d..f1b4a759de 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -23,9 +23,9 @@ struct SCSIRequest { SCSIDevice *dev; const SCSIReqOps *ops; uint32_t refcount; - uint32_t tag; - uint32_t lun; uint32_t status; + uint32_t tag; + uint64_t lun; void *hba_private; size_t resid; SCSICommand cmd; @@ -61,7 +61,7 @@ typedef struct SCSIDeviceClass { void (*realize)(SCSIDevice *dev, Error **errp); int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf, void *hba_private); - SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun, + SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint64_t lun, uint8_t *buf, void *hba_private); void (*unit_attention_reported)(SCSIDevice *s); } SCSIDeviceClass; @@ -79,7 +79,7 @@ struct SCSIDevice uint32_t sense_len; QTAILQ_HEAD(, SCSIRequest) requests; uint32_t channel; - uint32_t lun; + uint64_t lun; int blocksize; int type; uint64_t max_lba; @@ -149,6 +149,48 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); } +static inline uint64_t scsi_lun_from_int(unsigned int lun) +{ + if (lun < 256) { + /* Use peripheral addressing */ + return (uint64_t)lun << 48; + } else if (lun < 0x3fff) { + /* Use flat space addressing */ + return ((uint64_t)lun | 0x4000) << 48; + } + /* Return Logical unit not specified addressing */ + return (uint64_t)-1; +} + +static inline int scsi_lun_to_int(uint64_t lun64) +{ + return (lun64 >> 48) & 0x3fff; +} + +static inline uint64_t scsi_lun_from_str(uint8_t *lun) +{ + int i; + uint64_t lun64 = 0; + + for (i = 0; i < 8; i += 2) { + lun64 |= (uint64_t)lun[i] << ((i + 1) * 8) | + (uint64_t)lun[i + 1] << (i * 8); + } + return lun64; +} + +static inline void scsi_lun_to_str(uint64_t lun64, uint8_t *lun) +{ + int i; + + memset(lun, 0, 8); + for (i = 6; i >= 0; i -= 2) { + lun[i] = (lun64 >> 8) & 0xFF; + lun[i + 1] = lun64 & 0xFF; + lun64 = lun64 >> 16; + } +} + SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, int unit, bool removable, int bootindex, const char *serial, Error **errp); @@ -156,8 +198,8 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated); void scsi_legacy_handle_cmdline(void); SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, - uint32_t tag, uint32_t lun, void *hba_private); -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, + uint32_t tag, uint64_t lun, void *hba_private); +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint64_t lun, uint8_t *buf, void *hba_private); int32_t scsi_req_enqueue(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req); @@ -183,7 +225,7 @@ void scsi_device_report_change(SCSIDevice *dev, SCSISense sense); void scsi_device_unit_attention_reported(SCSIDevice *dev); void scsi_generic_read_device_identification(SCSIDevice *dev); int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); -SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, uint64_t lun); /* scsi-generic.c. */ extern const SCSIReqOps scsi_generic_req_ops; From patchwork Thu Dec 14 10:14:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 848450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yy8bY40QLz9sCZ for ; Thu, 14 Dec 2017 21:16:09 +1100 (AEDT) Received: from localhost ([::1]:39961 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQYh-0001KF-5u for incoming@patchwork.ozlabs.org; Thu, 14 Dec 2017 05:16:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52044) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQXv-0001DQ-Mz for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePQXp-0004LY-2d for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:19 -0500 Received: from mx2.suse.de ([195.135.220.15]:59089) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ePQXo-0004HE-On for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:13 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 1ECFFADCA; Thu, 14 Dec 2017 10:15:09 +0000 (UTC) From: Hannes Reinecke To: Paolo Bonzini Date: Thu, 14 Dec 2017 11:14:33 +0100 Message-Id: <20171214101435.26265-3-hare@suse.de> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171214101435.26265-1-hare@suse.de> References: <20171214101435.26265-1-hare@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 195.135.220.15 Subject: [Qemu-devel] [PATCH 2/4] virtio-scsi: implement target rescan X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hannes Reinecke , qemu-devel@nongnu.org, Hannes Reinecke Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Implement a new virtio-scsi command 'rescan' to return a list of attached targets. The guest is required to set the 'next_id' field to the next expected target id; the host will return either that or the next higher target id (if present), or -1 if no additional targets are found. Signed-off-by: Hannes Reinecke --- hw/scsi/scsi-bus.c | 10 +++++ hw/scsi/scsi-disk.c | 16 +++++++- hw/scsi/virtio-scsi.c | 55 ++++++++++++++++++++++++++++ include/hw/scsi/scsi.h | 6 ++- include/hw/virtio/virtio-scsi.h | 7 +++- include/scsi/constants.h | 11 ++++++ include/standard-headers/linux/virtio_scsi.h | 15 ++++++++ 7 files changed, 115 insertions(+), 5 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index a0e66d0e01..83497ac916 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -21,6 +21,7 @@ static Property scsi_props[] = { DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1), DEFINE_PROP_UINT64("lun", SCSIDevice, lun, -1), + DEFINE_PROP_UINT8("protocol", SCSIDevice, protocol, SCSI_PROTOCOL_SAS), DEFINE_PROP_END_OF_LIST(), }; @@ -189,6 +190,15 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp) } } + if (dev->protocol != SCSI_PROTOCOL_FCP && + dev->protocol != SCSI_PROTOCOL_SPI && + dev->protocol != SCSI_PROTOCOL_SRP && + dev->protocol != SCSI_PROTOCOL_ISCSI && + dev->protocol != SCSI_PROTOCOL_SAS && + dev->protocol != SCSI_PROTOCOL_UAS) { + error_setg(errp, "invalid scsi protocol id: %d", dev->protocol); + return; + } if (dev->id == -1) { int id = -1; if (dev->lun == -1) { diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index cbee840601..1313aafae3 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -668,7 +668,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) } if (s->qdev.port_wwn) { - outbuf[buflen++] = 0x61; // SAS / Binary + outbuf[buflen++] = s->qdev.protocol << 8 | 0x1; // Binary outbuf[buflen++] = 0x93; // PIV / Target port / NAA outbuf[buflen++] = 0; // reserved outbuf[buflen++] = 8; @@ -677,7 +677,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) } if (s->port_index) { - outbuf[buflen++] = 0x61; // SAS / Binary + outbuf[buflen++] = s->qdev.protocol << 8 | 0x1; // Binary outbuf[buflen++] = 0x94; // PIV / Target port / relative target port outbuf[buflen++] = 0; // reserved outbuf[buflen++] = 4; @@ -2355,6 +2355,18 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) return; } + if (dev->protocol == SCSI_PROTOCOL_FCP) { + if (!s->qdev.port_wwn) { + error_setg(errp, + "Missing port_wwn for FCP protocol"); + return; + } + if (!s->qdev.node_wwn && (s->qdev.port_wwn >> 60) != 0x02) { + error_setg(errp, + "port_wwn is not a IEEE Extended identifier"); + return; + } + } if (dev->type == TYPE_DISK) { blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err); if (err) { diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index f98bfb3db5..fa2031f636 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -19,6 +19,7 @@ #include "hw/virtio/virtio-scsi.h" #include "qemu/error-report.h" #include "qemu/iov.h" +#include "qemu/cutils.h" #include "sysemu/block-backend.h" #include "hw/scsi/scsi.h" #include "scsi/constants.h" @@ -386,6 +387,7 @@ fail: static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req) { VirtIODevice *vdev = (VirtIODevice *)s; + VirtIOSCSICommon *c = VIRTIO_SCSI_COMMON(vdev); uint32_t type; int r = 0; @@ -415,6 +417,55 @@ static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req) req->resp.an.event_actual = 0; req->resp.an.response = VIRTIO_SCSI_S_OK; } + } else if (type == VIRTIO_SCSI_T_RESCAN) { + if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSIRescanReq), + sizeof(VirtIOSCSIRescanResp)) < 0) { + virtio_scsi_bad_req(req); + return; + } else { + BusChild *kid; + SCSIDevice *dev = NULL; + + if (req->req.rescan.next_id != -1) { + QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { + DeviceState *qdev = kid->child; + SCSIDevice *d = SCSI_DEVICE(qdev); + + if (d->id >= req->req.rescan.next_id) { + dev = d; + break; + } + } + } + if (dev) { + req->resp.rescan.id = dev->id; + req->resp.rescan.transport = dev->protocol; + if (dev->protocol == SCSI_PROTOCOL_FCP && + dev->port_wwn && !dev->node_wwn) { + dev->node_wwn = ((uint64_t)1 << 56) | + (dev->port_wwn & ~((uint64_t)0xff << 56)); + } + stq_be_p(req->resp.rescan.node_wwn, dev->node_wwn); + stq_be_p(req->resp.rescan.port_wwn, dev->port_wwn); + } else { + req->resp.rescan.id = -1; + if (c->conf.wwnn && c->conf.wwpn) { + req->resp.rescan.transport = SCSI_PROTOCOL_FCP; + } else { + req->resp.rescan.transport = SCSI_PROTOCOL_SAS; + } + if (c->conf.wwnn) { + uint64_t wwnn; + qemu_strtou64(c->conf.wwnn, NULL, 16, &wwnn); + stq_be_p(req->resp.rescan.node_wwn, wwnn); + } + if (c->conf.wwpn) { + uint64_t wwpn; + qemu_strtou64(c->conf.wwpn, NULL, 16, &wwpn); + stq_be_p(req->resp.rescan.port_wwn, wwpn); + } + } + } } if (r == 0) { virtio_scsi_complete_req(req); @@ -927,8 +978,12 @@ static Property virtio_scsi_properties[] = { VIRTIO_SCSI_F_HOTPLUG, true), DEFINE_PROP_BIT("param_change", VirtIOSCSI, host_features, VIRTIO_SCSI_F_CHANGE, true), + DEFINE_PROP_BIT("rescan", VirtIOSCSI, host_features, + VIRTIO_SCSI_F_RESCAN, true), DEFINE_PROP_LINK("iothread", VirtIOSCSI, parent_obj.conf.iothread, TYPE_IOTHREAD, IOThread *), + DEFINE_PROP_STRING("wwpn", VirtIOSCSI, parent_obj.conf.wwpn), + DEFINE_PROP_STRING("wwnn", VirtIOSCSI, parent_obj.conf.wwnn), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index f1b4a759de..cb2b2bddcd 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -71,19 +71,21 @@ struct SCSIDevice DeviceState qdev; VMChangeStateEntry *vmsentry; QEMUBH *bh; - uint32_t id; BlockConf conf; SCSISense unit_attention; bool sense_is_ua; uint8_t sense[SCSI_SENSE_BUF_SIZE]; uint32_t sense_len; QTAILQ_HEAD(, SCSIRequest) requests; + uint32_t id; uint32_t channel; uint64_t lun; int blocksize; - int type; + uint8_t type; + uint8_t protocol; uint64_t max_lba; uint64_t wwn; + uint64_t node_wwn; uint64_t port_wwn; }; diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 4c0bcdb788..2503680d0c 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -42,6 +42,8 @@ typedef struct virtio_scsi_ctrl_tmf_req VirtIOSCSICtrlTMFReq; typedef struct virtio_scsi_ctrl_tmf_resp VirtIOSCSICtrlTMFResp; typedef struct virtio_scsi_ctrl_an_req VirtIOSCSICtrlANReq; typedef struct virtio_scsi_ctrl_an_resp VirtIOSCSICtrlANResp; +typedef struct virtio_scsi_rescan_req VirtIOSCSIRescanReq; +typedef struct virtio_scsi_rescan_resp VirtIOSCSIRescanResp; typedef struct virtio_scsi_event VirtIOSCSIEvent; typedef struct virtio_scsi_config VirtIOSCSIConfig; @@ -52,8 +54,9 @@ struct VirtIOSCSIConf { uint32_t cmd_per_lun; #ifdef CONFIG_VHOST_SCSI char *vhostfd; - char *wwpn; #endif + char *wwpn; + char *wwnn; CharBackend chardev; uint32_t boot_tpgt; IOThread *iothread; @@ -116,12 +119,14 @@ typedef struct VirtIOSCSIReq { VirtIOSCSICmdResp cmd; VirtIOSCSICtrlTMFResp tmf; VirtIOSCSICtrlANResp an; + VirtIOSCSIRescanResp rescan; VirtIOSCSIEvent event; } resp; union { VirtIOSCSICmdReq cmd; VirtIOSCSICtrlTMFReq tmf; VirtIOSCSICtrlANReq an; + VirtIOSCSIRescanReq rescan; } req; } VirtIOSCSIReq; diff --git a/include/scsi/constants.h b/include/scsi/constants.h index a141dd71f8..ee93727052 100644 --- a/include/scsi/constants.h +++ b/include/scsi/constants.h @@ -223,6 +223,17 @@ #define TYPE_INACTIVE 0x20 #define TYPE_NO_LUN 0x7f +/* + * Protocol identifiers + */ + +#define SCSI_PROTOCOL_FCP 0x00 +#define SCSI_PROTOCOL_SPI 0x01 +#define SCSI_PROTOCOL_SRP 0x04 +#define SCSI_PROTOCOL_ISCSI 0x05 +#define SCSI_PROTOCOL_SAS 0x06 +#define SCSI_PROTOCOL_UAS 0x09 +#define SCSI_PROTOCOL_UNSPEC 0x0f /* Mode page codes for mode sense/set */ #define MODE_PAGE_R_W_ERROR 0x01 #define MODE_PAGE_HD_GEOMETRY 0x04 diff --git a/include/standard-headers/linux/virtio_scsi.h b/include/standard-headers/linux/virtio_scsi.h index ab66166b6a..5b3a930569 100644 --- a/include/standard-headers/linux/virtio_scsi.h +++ b/include/standard-headers/linux/virtio_scsi.h @@ -96,6 +96,19 @@ struct virtio_scsi_ctrl_an_resp { uint8_t response; } QEMU_PACKED; +/* Target rescan */ +struct virtio_scsi_rescan_req { + __virtio32 type; + __virtio32 next_id; +} QEMU_PACKED; + +struct virtio_scsi_rescan_resp { + __virtio32 id; + __virtio32 transport; + uint8_t node_wwn[8]; + uint8_t port_wwn[8]; +} QEMU_PACKED; + struct virtio_scsi_event { __virtio32 event; uint8_t lun[8]; @@ -120,6 +133,7 @@ struct virtio_scsi_config { #define VIRTIO_SCSI_F_HOTPLUG 1 #define VIRTIO_SCSI_F_CHANGE 2 #define VIRTIO_SCSI_F_T10_PI 3 +#define VIRTIO_SCSI_F_RESCAN 4 /* Response codes */ #define VIRTIO_SCSI_S_OK 0 @@ -140,6 +154,7 @@ struct virtio_scsi_config { #define VIRTIO_SCSI_T_TMF 0 #define VIRTIO_SCSI_T_AN_QUERY 1 #define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 +#define VIRTIO_SCSI_T_RESCAN 3 /* Valid TMF subtypes. */ #define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 From patchwork Thu Dec 14 10:14:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 848448 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yy8bS1Q3yz9sNc for ; Thu, 14 Dec 2017 21:16:03 +1100 (AEDT) Received: from localhost ([::1]:39957 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQYb-0001EH-EY for incoming@patchwork.ozlabs.org; Thu, 14 Dec 2017 05:16:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51994) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQXt-0001D2-0A for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePQXp-0004LT-2e for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:16 -0500 Received: from mx2.suse.de ([195.135.220.15]:59092) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ePQXo-0004HF-Ok for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:13 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 2A00DAE24; Thu, 14 Dec 2017 10:15:09 +0000 (UTC) From: Hannes Reinecke To: Paolo Bonzini Date: Thu, 14 Dec 2017 11:14:34 +0100 Message-Id: <20171214101435.26265-4-hare@suse.de> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171214101435.26265-1-hare@suse.de> References: <20171214101435.26265-1-hare@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 195.135.220.15 Subject: [Qemu-devel] [PATCH 3/4] virtio-scsi: Implement 'native LUN' feature X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hannes Reinecke , qemu-devel@nongnu.org, Hannes Reinecke Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The 'native LUN' feature allows virtio-scsi to use the LUN numbers from the underlying storage directly, without having to modify the LUN number when sending over the wire. It works by shifting the existing LUN number down by 8 bytes, and add the virtio-specific 8-byte LUN steering header. With that virtio doesn't have to mangle the LUN number, allowing us to pass the 'real' LUN number to the guest. Of course, we do cut off the last 8 bytes of the 'real' LUN number, but I'm not aware of any array utilizing that, so the impact should be negligible. Signed-off-by: Hannes Reinecke --- hw/scsi/virtio-scsi.c | 29 ++++++++++++++++++++-------- include/hw/scsi/scsi.h | 4 ++-- include/standard-headers/linux/virtio_scsi.h | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index fa2031f636..ec91c8c403 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -26,20 +26,30 @@ #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-access.h" -static inline uint64_t virtio_scsi_get_lun(uint8_t *lun) +static inline uint64_t virtio_scsi_get_lun(VirtIODevice *vdev, uint8_t *lun) { - return (((uint64_t)(lun[2] << 8) | lun[3]) & 0x3FFF) << 48; + uint64_t lun64; + + if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_NATIVE_LUN)) { + lun64 = scsi_lun_from_str(lun) << 16; + } else { + lun64 = (((uint64_t)(lun[2] << 8) | lun[3]) & 0x3FFF) << 48; + } + return lun64; } static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) { + VirtIODevice *vdev = VIRTIO_DEVICE(s); + if (lun[0] != 1) { return NULL; } - if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) { + if (!virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_NATIVE_LUN) && + lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) { return NULL; } - return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); + return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(vdev, lun)); } void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req) @@ -270,7 +280,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) if (!d) { goto fail; } - if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { + if (d->lun != virtio_scsi_get_lun(VIRTIO_DEVICE(s), req->req.tmf.lun)) { goto incorrect_lun; } QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) { @@ -307,7 +317,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) if (!d) { goto fail; } - if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { + if (d->lun != virtio_scsi_get_lun(VIRTIO_DEVICE(s), req->req.tmf.lun)) { goto incorrect_lun; } s->resetting++; @@ -321,7 +331,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) if (!d) { goto fail; } - if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { + if (d->lun != virtio_scsi_get_lun(VIRTIO_DEVICE(s), req->req.tmf.lun)) { goto incorrect_lun; } @@ -609,7 +619,8 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) } virtio_scsi_ctx_check(s, d); req->sreq = scsi_req_new(d, req->req.cmd.tag, - virtio_scsi_get_lun(req->req.cmd.lun), + virtio_scsi_get_lun(VIRTIO_DEVICE(s), + req->req.cmd.lun), req->req.cmd.cdb, req); if (req->sreq->cmd.mode != SCSI_XFER_NONE @@ -980,6 +991,8 @@ static Property virtio_scsi_properties[] = { VIRTIO_SCSI_F_CHANGE, true), DEFINE_PROP_BIT("rescan", VirtIOSCSI, host_features, VIRTIO_SCSI_F_RESCAN, true), + DEFINE_PROP_BIT("native_lun", VirtIOSCSI, host_features, + VIRTIO_SCSI_F_NATIVE_LUN, true), DEFINE_PROP_LINK("iothread", VirtIOSCSI, parent_obj.conf.iothread, TYPE_IOTHREAD, IOThread *), DEFINE_PROP_STRING("wwpn", VirtIOSCSI, parent_obj.conf.wwpn), diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index cb2b2bddcd..a18e430c08 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -175,8 +175,8 @@ static inline uint64_t scsi_lun_from_str(uint8_t *lun) uint64_t lun64 = 0; for (i = 0; i < 8; i += 2) { - lun64 |= (uint64_t)lun[i] << ((i + 1) * 8) | - (uint64_t)lun[i + 1] << (i * 8); + lun64 = lun64 << 16; + lun64 |= ((uint64_t)lun[i] << 8) | (uint64_t)lun[i + 1]; } return lun64; } diff --git a/include/standard-headers/linux/virtio_scsi.h b/include/standard-headers/linux/virtio_scsi.h index 5b3a930569..911fc2db82 100644 --- a/include/standard-headers/linux/virtio_scsi.h +++ b/include/standard-headers/linux/virtio_scsi.h @@ -134,6 +134,7 @@ struct virtio_scsi_config { #define VIRTIO_SCSI_F_CHANGE 2 #define VIRTIO_SCSI_F_T10_PI 3 #define VIRTIO_SCSI_F_RESCAN 4 +#define VIRTIO_SCSI_F_NATIVE_LUN 5 /* Response codes */ #define VIRTIO_SCSI_S_OK 0 From patchwork Thu Dec 14 10:14:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 848449 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yy8bS1Q3Cz9sCZ for ; Thu, 14 Dec 2017 21:16:03 +1100 (AEDT) Received: from localhost ([::1]:39956 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQYZ-0001DG-Kr for incoming@patchwork.ozlabs.org; Thu, 14 Dec 2017 05:15:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQXs-0001D1-Uy for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePQXo-0004LD-VQ for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:16 -0500 Received: from mx2.suse.de ([195.135.220.15]:59088) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ePQXo-0004HG-Oo for qemu-devel@nongnu.org; Thu, 14 Dec 2017 05:15:12 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 212B1ADCC; Thu, 14 Dec 2017 10:15:09 +0000 (UTC) From: Hannes Reinecke To: Paolo Bonzini Date: Thu, 14 Dec 2017 11:14:35 +0100 Message-Id: <20171214101435.26265-5-hare@suse.de> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171214101435.26265-1-hare@suse.de> References: <20171214101435.26265-1-hare@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 195.135.220.15 Subject: [Qemu-devel] [PATCH 4/4] scsi: support REPORT_LUNS for LUNs != 0 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hannes Reinecke , qemu-devel@nongnu.org, Hannes Reinecke Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" SPC doesn't restrict the use of REPORT LUNS to LUN 0, so we shouldn't be doing so, either. Signed-off-by: Hannes Reinecke --- hw/scsi/scsi-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 83497ac916..67ac472c14 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -548,7 +548,7 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf) int fixed_sense = (req->cmd.buf[1] & 1) == 0; if (req->lun != 0 && - buf[0] != INQUIRY && buf[0] != REQUEST_SENSE) { + buf[0] != INQUIRY && buf[0] != REQUEST_SENSE && buf[0] != REPORT_LUNS) { scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED)); scsi_req_complete(req, CHECK_CONDITION); return 0;