From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:39101) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R9gb1-0008Q1-CW for qemu-devel@nongnu.org; Fri, 30 Sep 2011 13:10:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R9gb0-00065t-78 for qemu-devel@nongnu.org; Fri, 30 Sep 2011 13:09:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:2577) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R9gaz-00065g-WF for qemu-devel@nongnu.org; Fri, 30 Sep 2011 13:09:58 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p8UGaxUa029020 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 30 Sep 2011 12:36:59 -0400 Received: from yakj.usersys.redhat.com (ovpn-112-17.ams2.redhat.com [10.36.112.17]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p8UGapa2013790 for ; Fri, 30 Sep 2011 12:36:58 -0400 From: Paolo Bonzini Date: Fri, 30 Sep 2011 18:36:07 +0200 Message-Id: <1317400569-7115-5-git-send-email-pbonzini@redhat.com> In-Reply-To: <1317400569-7115-1-git-send-email-pbonzini@redhat.com> References: <1317400569-7115-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 4/6] scsi: implement REPORT LUNS for arbitrary LUNs List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Signed-off-by: Paolo Bonzini --- hw/scsi-bus.c | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 39 insertions(+), 10 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index c0da8c7..17acf48 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -170,7 +170,7 @@ typedef struct SCSITargetReq SCSITargetReq; struct SCSITargetReq { SCSIRequest req; int len; - uint8_t buf[64]; + uint8_t buf[2056]; }; static void store_lun(uint8_t *outbuf, int lun) @@ -185,23 +185,52 @@ static void store_lun(uint8_t *outbuf, int lun) static bool scsi_target_emulate_report_luns(SCSITargetReq *r) { - int len; + DeviceState *qdev; + int i, len, n; + int id; + bool found_lun0; + if (r->req.cmd.xfer < 16) { return false; } if (r->req.cmd.buf[2] > 2) { return false; } - len = MIN(sizeof r->buf, r->req.cmd.xfer); + id = r->req.dev->id; + found_lun0 = false; + n = 0; + QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { + SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); + + if (dev->id == id) { + if (dev->lun == 0) { + found_lun0 = true; + } + n += 8; + } + } + if (!found_lun0) { + n += 8; + } + len = MIN(n + 8, r->req.cmd.xfer & ~7); + if (len > sizeof(r->buf)) { + /* TODO: > 256 LUNs? */ + return false; + } + memset(r->buf, 0, len); - if (r->req.dev->lun != 0) { - r->buf[3] = 16; - r->len = 24; - store_lun(&r->buf[16], r->req.dev->lun); - } else { - r->buf[3] = 8; - r->len = 16; + stl_be_p(&r->buf, n); + i = found_lun0 ? 8 : 16; + QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { + SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); + + if (dev->id == id) { + store_lun(&r->buf[i], dev->lun); + i += 8; + } } + assert(i == n + 8); + r->len = len; return true; } -- 1.7.6