From nobody Sat Feb 7 19:08:23 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1513246879255113.74935771474634; Thu, 14 Dec 2017 02:21:19 -0800 (PST) Received: from localhost ([::1]:39992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePQdX-00058O-Dp for importer@patchew.org; Thu, 14 Dec 2017 05:21:07 -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 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) X-Virus-Scanned: by amavisd-new at test-mx.suse.de 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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, ui= nt8_t busid) =20 trace_esp_do_busid_cmd(busid); lun =3D busid & 7; - current_lun =3D scsi_device_find(&s->bus, 0, s->current_dev->id, lun); - s->current_req =3D scsi_req_new(current_lun, 0, lun, buf, s); + current_lun =3D scsi_device_find(&s->bus, 0, s->current_dev->id, + scsi_lun_from_int(lun)); + s->current_req =3D scsi_req_new(current_lun, 0, scsi_lun_from_int(lun), + buf, s); datalen =3D scsi_req_enqueue(s->current_req); s->ti_size =3D datalen; if (datalen !=3D 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 =3D 0; =20 id =3D (s->select_tag >> 8) & 0xf; - dev =3D scsi_device_find(&s->bus, 0, id, s->current_lun); + dev =3D 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 =3D=3D NULL); s->current =3D g_new0(lsi_request, 1); s->current->tag =3D s->select_tag; - s->current->req =3D scsi_req_new(dev, s->current->tag, s->current_lun,= buf, - s->current); + s->current->req =3D scsi_req_new(dev, s->current->tag, + scsi_lun_from_int(s->current_lun), + buf, s->current); =20 n =3D 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, Megas= asCmd *cmd) uint16_t pd_id; =20 if (num_pd_disks < 8) { - pd_id =3D ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF); + pd_id =3D ((sdev->id & 0xFF) << 8) | scsi_lun_to_int(sdev->lun= ); info.device.port_addr[num_pd_disks] =3D cpu_to_le64(megasas_get_sata_addr(pd_id)); } @@ -975,7 +975,7 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, Me= gasasCmd *cmd) if (num_pd_disks >=3D max_pd_disks) break; =20 - pd_id =3D ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF); + pd_id =3D ((sdev->id & 0xFF) << 8) | scsi_lun_to_int(sdev->lun); info.addr[num_pd_disks].device_id =3D cpu_to_le16(pd_id); info.addr[num_pd_disks].encl_device_id =3D 0xFFFF; info.addr[num_pd_disks].encl_index =3D 0; @@ -1028,7 +1028,8 @@ static int megasas_pd_get_info_submit(SCSIDevice *sde= v, int lun, info->inquiry_data[0] =3D 0x7f; /* Force PQual 0x3, PType 0x1f */ info->vpd_page83[0] =3D 0x7f; megasas_setup_inquiry(cmdbuf, 0, sizeof(info->inquiry_data)); - cmd->req =3D scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd); + cmd->req =3D 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 =3D le16_to_cpu(cmd->frame->dcmd.mbox[0]); target_id =3D (pd_id >> 8) & 0xFF; lun_id =3D pd_id & 0xFF; - sdev =3D scsi_device_find(&s->bus, 0, target_id, lun_id); + sdev =3D scsi_device_find(&s->bus, 0, target_id, scsi_lun_from_int(lun= _id)); trace_megasas_dcmd_pd_get_info(cmd->index, pd_id); =20 if (sdev) { @@ -1200,7 +1201,7 @@ static int megasas_dcmd_ld_list_query(MegasasState *s= , MegasasCmd *cmd) if (num_ld_disks >=3D max_ld_disks) { break; } - info.targetid[num_ld_disks] =3D sdev->lun; + info.targetid[num_ld_disks] =3D scsi_lun_to_int(sdev->lun); num_ld_disks++; dcmd_size++; } @@ -1335,7 +1336,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, Meg= asasCmd *cmd) =20 QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { SCSIDevice *sdev =3D SCSI_DEVICE(kid->child); - uint16_t sdev_id =3D ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF); + uint16_t sdev_id =3D ((sdev->id & 0xFF) << 8) | scsi_lun_to_int(sd= ev->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 *c= md, SCSIRequest *req, size_t resid) { int retval =3D MFI_STAT_OK; - int lun =3D req->lun; + int lun =3D scsi_lun_to_int(req->lun); =20 trace_megasas_dcmd_internal_finish(cmd->index, cmd->dcmd_opcode, lun); cmd->iov_size -=3D resid; @@ -1671,7 +1672,7 @@ static int megasas_handle_scsi(MegasasState *s, Megas= asCmd *cmd, return MFI_STAT_DEVICE_NOT_FOUND; } } - sdev =3D scsi_device_find(&s->bus, 0, target_id, lun_id); + sdev =3D scsi_device_find(&s->bus, 0, target_id, scsi_lun_from_int(lun= _id)); =20 cmd->iov_size =3D 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, Megas= asCmd *cmd, return MFI_STAT_SCSI_DONE_WITH_ERROR; } =20 - cmd->req =3D scsi_req_new(sdev, cmd->index, lun_id, cdb, cmd); + cmd->req =3D 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, Megasas= Cmd *cmd, int frame_cmd) cdb_len =3D cmd->frame->header.cdb_len; =20 if (target_id < MFI_MAX_LD && lun_id =3D=3D 0) { - sdev =3D scsi_device_find(&s->bus, 0, target_id, lun_id); + sdev =3D scsi_device_find(&s->bus, 0, target_id, 0); } =20 trace_megasas_handle_io(cmd->index, @@ -1775,7 +1777,7 @@ static int megasas_handle_io(MegasasState *s, Megasas= Cmd *cmd, int frame_cmd) =20 megasas_encode_lba(cdb, lba_start, lba_count, is_write); cmd->req =3D 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; } =20 - *sdev =3D scsi_device_find(&s->bus, bus, target, lun[1]); + *sdev =3D 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, } =20 req->sreq =3D scsi_req_new(sdev, scsi_io->MsgContext, - scsi_io->LUN[1], scsi_io->CDB, req); + sdev->lun, scsi_io->CDB, req); =20 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 =3D status; goto out; } - if (sdev->lun !=3D req->LUN[1]) { + if (sdev->lun !=3D scsi_lun_from_str(req->LUN)) { reply.ResponseCode =3D 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 =3D status; goto out; } - if (sdev->lun !=3D req->LUN[1]) { + if (sdev->lun !=3D scsi_lun_from_str(req->LUN)) { reply.ResponseCode =3D MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN; goto out; } @@ -515,7 +515,7 @@ reply_maybe_async: reply.IOCStatus =3D status; goto out; } - if (sdev->lun !=3D req->LUN[1]) { + if (sdev->lun !=3D scsi_lun_from_str(req->LUN)) { reply.ResponseCode =3D 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[] =3D { 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(), }; =20 @@ -68,7 +68,7 @@ int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,= uint8_t *buf, return rc; } =20 -static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uin= t32_t lun, +static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uin= t64_t lun, uint8_t *buf, void *hba_private) { SCSIDeviceClass *sc =3D SCSI_DEVICE_GET_CLASS(s); @@ -147,6 +147,22 @@ static void scsi_dma_restart_cb(void *opaque, int runn= ing, RunState state) } } =20 +static int scsi_device_count(SCSIBus *bus, int channel, int id) +{ + BusChild *kid; + int luns =3D 0; + + QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, ChildrenHead, sibling= ) { + DeviceState *qdev =3D kid->child; + SCSIDevice *dev =3D SCSI_DEVICE(qdev); + + if (dev->channel =3D=3D channel && dev->id =3D=3D id) { + luns++; + } + } + return luns; +} + static void scsi_qdev_realize(DeviceState *qdev, Error **errp) { SCSIDevice *dev =3D 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 !=3D -1 && dev->lun > bus->info->max_lun) { - error_setg(errp, "bad scsi device lun: %d", dev->lun); - return; + if (dev->lun !=3D -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->lu= n); + return; + } + dev->lun =3D scsi_lun_from_int(dev->lun); + } } =20 if (dev->id =3D=3D -1) { @@ -181,15 +203,18 @@ static void scsi_qdev_realize(DeviceState *qdev, Erro= r **errp) } dev->id =3D id; } else if (dev->lun =3D=3D -1) { - int lun =3D -1; + int lun =3D 0; do { - d =3D scsi_device_find(bus, dev->channel, dev->id, ++lun); - } while (d && d->lun =3D=3D lun && lun < bus->info->max_lun); - if (d && d->lun =3D=3D lun) { + d =3D scsi_device_find(bus, dev->channel, dev->id, + scsi_lun_from_int(lun)); + lun++; + } while (d && scsi_lun_to_int(d->lun) =3D=3D lun && + lun < bus->info->max_lun); + if (d && scsi_lun_to_int(d->lun) =3D=3D lun) { error_setg(errp, "no free lun"); return; } - dev->lun =3D lun; + dev->lun =3D scsi_lun_from_int(lun); } else { d =3D 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) >=3D bus->info->= max_lun) { + error_setg(errp, "bad scsi device lun: %"PRIu64"", dev->lun); + return; + } } =20 QTAILQ_INIT(&dev->requests); @@ -385,16 +414,6 @@ struct SCSITargetReq { int buf_len; }; =20 -static void store_lun(uint8_t *outbuf, int lun) -{ - if (lun < 256) { - outbuf[1] =3D lun; - return; - } - outbuf[1] =3D (lun & 255); - outbuf[0] =3D (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(SCSITargetR= eq *r) SCSIDevice *dev =3D SCSI_DEVICE(qdev); =20 if (dev->channel =3D=3D channel && dev->id =3D=3D id) { - store_lun(&r->buf[i], dev->lun); + scsi_lun_to_str(dev->lun, &r->buf[i]); i +=3D 8; } } @@ -631,7 +650,7 @@ static const struct SCSIReqOps reqops_target_command = =3D { =20 =20 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 =3D 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; } =20 -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 =3D DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); @@ -694,14 +713,14 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag= , uint32_t lun, } =20 if (ret !=3D 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 =3D scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_pr= ivate); } else { assert(cmd.len !=3D 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 !=3D -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, bu= f[0], cmd.lba); } =20 @@ -719,16 +738,17 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag= , uint32_t lun, =20 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) =20 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 =3D scsi_build_sense(req->sense, sense); } =20 @@ -848,7 +868,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req) =20 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->t= ag); req->retry =3D 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->t= ag); 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 =3D=3D 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->lu= n), + 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 !=3D SCSI_XFER_NONE); if (!req->sg) { req->resid -=3D 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->ta= g); if (notifier) { notifier_list_add(&req->cancel_notifiers, notifier); } @@ -1488,7 +1510,7 @@ void scsi_req_cancel_async(SCSIRequest *req, Notifier= *notifier) =20 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->ta= g); if (!req->enqueued) { return; } @@ -1539,7 +1561,7 @@ void scsi_device_set_ua(SCSIDevice *sdev, SCSISense s= ense) if (sense.key !=3D 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.k= ey, sense.asc, sense.ascq); =20 /* @@ -1576,9 +1598,21 @@ static char *scsibus_get_dev_path(DeviceState *dev) =20 id =3D qdev_get_dev_path(hba); if (id) { - path =3D g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->= lun); + if (scsi_lun_to_int(d->lun) < 0x3fff) { + path =3D g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, + scsi_lun_to_int(d->lun)); + } else { + path =3D g_strdup_printf("%s/%d:%d:%"PRIx64"", id, d->channel,= d->id, + d->lun); + } } else { - path =3D g_strdup_printf("%d:%d:%d", d->channel, d->id, d->lun); + if (scsi_lun_to_int(d->lun) < 0x3fff) { + path =3D g_strdup_printf("%d:%d:%d", d->channel, d->id, + scsi_lun_to_int(d->lun)); + } else { + path =3D 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 =3D 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); + } } =20 -SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, uint64_t l= un) { BusChild *kid; SCSIDevice *target_dev =3D NULL; @@ -1618,6 +1657,7 @@ static int put_scsi_requests(QEMUFile *f, void *pv, s= ize_t size, SCSIDevice *s =3D pv; SCSIBus *bus =3D DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus); SCSIRequest *req; + uint32_t lun; =20 QTAILQ_FOREACH(req, &s->requests, next) { assert(!req->io_canceled); @@ -1626,8 +1666,9 @@ static int put_scsi_requests(QEMUFile *f, void *pv, s= ize_t size, =20 qemu_put_sbyte(f, req->retry ? 1 : 2); qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf)); + lun =3D (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, s= ize_t size, qemu_get_buffer(f, buf, sizeof(buf)); qemu_get_be32s(f, &tag); qemu_get_be32s(f, &lun); - req =3D scsi_req_new(s, tag, lun, buf, NULL); + req =3D scsi_req_new(s, tag, (uint64_t)lun << 32, buf, NULL); req->retry =3D (sbyte =3D=3D 1); if (bus->info->load_request) { req->hba_private =3D 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_dispa= tch[256] =3D { [WRITE_VERIFY_16] =3D &scsi_disk_dma_reqops, }; =20 -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 =3D DO_UPCAST(SCSIDiskState, qdev, d); @@ -2533,7 +2533,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, u= int32_t tag, uint32_t lun, req =3D scsi_req_alloc(ops, &s->qdev, tag, lun, hba_private); =20 #ifdef DEBUG_SCSI - DPRINTF("Command: lun=3D%d tag=3D0x%x data=3D0x%02x", lun, tag, buf[0]= ); + DPRINTF("Command: lun=3D%"PRIu64" tag=3D0x%x data=3D0x%02x", lun, tag,= buf[0]); { int i; for (i =3D 1; i < scsi_cdb_length(buf); i++) { @@ -2847,7 +2847,7 @@ static const SCSIReqOps scsi_block_dma_reqops =3D { }; =20 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 =3D 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 =3D { .save_request =3D scsi_generic_save_request, }; =20 -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 =3D 0; } =20 -static SCSIDevice *vscsi_device_find(SCSIBus *bus, uint64_t srp_lun, int *= lun) +static SCSIDevice *vscsi_device_find(SCSIBus *bus, uint64_t srp_lun, uint6= 4_t *lun) { - int channel =3D 0, id =3D 0; + int channel =3D 0, id =3D 0, l; =20 retry: switch (srp_lun >> 62) { @@ -149,16 +149,16 @@ retry: srp_lun <<=3D 16; goto retry; } - *lun =3D (srp_lun >> 48) & 0xff; + l =3D (srp_lun >> 48) & 0xff; break; =20 case 1: - *lun =3D (srp_lun >> 48) & 0x3fff; + l =3D (srp_lun >> 48) & 0x3fff; break; case 2: channel =3D (srp_lun >> 53) & 0x7; id =3D (srp_lun >> 56) & 0x3f; - *lun =3D (srp_lun >> 48) & 0x1f; + l =3D (srp_lun >> 48) & 0x1f; break; case 3: *lun =3D -1; @@ -166,7 +166,7 @@ retry: default: abort(); } - + *lun =3D scsi_lun_from_int(l); return scsi_device_find(bus, channel, id, *lun); } =20 @@ -752,7 +752,7 @@ static void vscsi_report_luns(VSCSIState *s, vscsi_req = *req) } resp_data[i] |=3D dev->id; resp_data[i+1] =3D (dev->channel << 5); - resp_data[i+1] |=3D dev->lun; + resp_data[i+1] |=3D scsi_lun_to_int(dev->lun); i +=3D 8; } =20 @@ -822,8 +822,9 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_= req *req) { union viosrp_iu *iu =3D &req->iu; vscsi_req *tmpreq; - int i, lun =3D 0, resp =3D SRP_TSK_MGMT_COMPLETE; + int i, resp =3D SRP_TSK_MGMT_COMPLETE; SCSIDevice *d; + uint64_t lun =3D 0; uint64_t tag =3D iu->srp.rsp.tag; uint8_t sol_not =3D iu->srp.cmd.sol_not; =20 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" =20 -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; } =20 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] =3D dev->id; =20 /* Linux wants us to keep the same encoding we use for REPORT LUNS= . */ - if (dev->lun >=3D 256) { - evt->lun[2] =3D (dev->lun >> 8) | 0x40; + if (scsi_lun_to_int(dev->lun) >=3D 256) { + evt->lun[2] =3D (scsi_lun_to_int(dev->lun) >> 8) | 0x40; } - evt->lun[3] =3D dev->lun & 0xFF; + evt->lun[3] =3D 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 =3D msg_type; msg.bus =3D dev->channel; msg.target =3D dev->id; - msg.lun[1] =3D dev->lun; + scsi_lun_to_str(dev->lun, msg.lun); =20 pvscsi_msg_ring_put(s, (PVSCSIRingMsgDesc *)&msg); pvscsi_ring_flush_msg(&s->rings); @@ -597,15 +597,15 @@ pvscsi_request_cancelled(SCSIRequest *req) =20 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 =3D scsi_lun_from_str(requested_lun); + + if (scsi_lun_to_int(lun64) > 255 || (target > PVSCSI_MAX_DEVS)) { return NULL; } else { - *target_lun =3D requested_lun[1]; - return scsi_device_find(&s->bus, channel, target, *target_lun); + *target_lun =3D lun64; + return scsi_device_find(&s->bus, channel, target, lun64); } } =20 @@ -614,7 +614,7 @@ pvscsi_queue_pending_descriptor(PVSCSIState *s, SCSIDev= ice **d, struct PVSCSIRingReqDesc *descr) { PVSCSIRequest *pvscsi_req; - uint8_t lun; + uint64_t lun; =20 pvscsi_req =3D g_malloc0(sizeof(*pvscsi_req)); pvscsi_req->dev =3D 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 =3D 0; + uint64_t target_lun =3D 0; struct PVSCSICmdDescResetDevice *cmd =3D (struct PVSCSICmdDescResetDevice *) s->curr_cmd_data; SCSIDevice *sdev; =20 sdev =3D pvscsi_device_find(s, 0, cmd->target, cmd->lun, &target_lun); =20 - 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); =20 if (sdev !=3D 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, US= BPacket *p, case ClassInterfaceRequest | GetMaxLun: maxlun =3D 0; for (;;) { - scsi_dev =3D scsi_device_find(&s->bus, 0, 0, maxlun+1); + scsi_dev =3D scsi_device_find(&s->bus, 0, 0, + scsi_lun_from_int(maxlun+1)); if (scsi_dev =3D=3D NULL) { break; } - if (scsi_dev->lun !=3D maxlun+1) { + if (scsi_lun_to_int(scsi_dev->lun) !=3D maxlun+1) { break; } maxlun++; @@ -429,7 +430,8 @@ static void usb_msd_handle_data(USBDevice *dev, USBPack= et *p) goto fail; } DPRINTF("Command on LUN %d\n", cbw.lun); - scsi_dev =3D scsi_device_find(&s->bus, 0, 0, cbw.lun); + scsi_dev =3D scsi_device_find(&s->bus, 0, 0, + scsi_lun_from_int(cbw.lun)); if (scsi_dev =3D=3D NULL) { error_report("usb-msd: Bad LUN %d", cbw.lun); goto fail; @@ -447,7 +449,8 @@ static void usb_msd_handle_data(USBDevice *dev, USBPack= et *p) tag, cbw.flags, cbw.cmd_len, s->data_len); assert(le32_to_cpu(s->csw.residue) =3D=3D 0); s->scsi_len =3D 0; - s->req =3D scsi_req_new(scsi_dev, tag, cbw.lun, cbw.cmd, NULL); + s->req =3D scsi_req_new(scsi_dev, tag, scsi_lun_from_int(cbw.l= un), + 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) =20 /* --------------------------------------------------------------------- */ =20 -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) !=3D 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 =3D uas; req->tag =3D be16_to_cpu(iu->hdr.tag); req->lun =3D be64_to_cpu(iu->command.lun); - req->dev =3D usb_uas_get_dev(req->uas, req->lun); + req->dev =3D scsi_device_find(&uas->bus, 0, 0, req->lun); return req; } =20 @@ -709,7 +696,7 @@ static void usb_uas_command(UASDevice *uas, uas_iu *iu) } =20 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] !=3D NULL) { @@ -719,7 +706,7 @@ static void usb_uas_command(UASDevice *uas, uas_iu *iu) } =20 req->req =3D 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 =3D be16_to_cpu(iu->hdr.tag); - uint64_t lun64 =3D be64_to_cpu(iu->task.lun); - SCSIDevice *dev =3D usb_uas_get_dev(uas, lun64); - int lun =3D usb_uas_get_lun(lun64); + uint64_t lun =3D be64_to_cpu(iu->task.lun); + SCSIDevice *dev =3D scsi_device_find(&uas->bus, 0, 0, lun); UASRequest *req; uint16_t task_tag; =20 @@ -776,7 +762,8 @@ static void usb_uas_task(UASDevice *uas, uas_iu *iu) break; =20 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); } =20 +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 =3D 0; + + for (i =3D 0; i < 8; i +=3D 2) { + lun64 |=3D (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 =3D 6; i >=3D 0; i -=3D 2) { + lun[i] =3D (lun64 >> 8) & 0xFF; + lun[i + 1] =3D lun64 & 0xFF; + lun64 =3D lun64 >> 16; + } +} + SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, int unit, bool removable, int bootin= dex, 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); =20 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, SCSISen= se 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 fix= ed); -SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lu= n); +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, uint64= _t lun); =20 /* scsi-generic.c. */ extern const SCSIReqOps scsi_generic_req_ops; --=20 2.12.3