Blob Blame History Raw
From bd21ce9f5a9ba8539e3b44b635d10cce501f58bf Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 9 May 2017 11:24:37 +0200
Subject: [PATCH 4/4] usb-uas: enumerate luns with REPORT LUNS

RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Message-id: <20170509112437.30666-5-pbonzini@redhat.com>
Patchwork-id: 75054
O-Subject: [RHEL7.4 seabios PATCH 4/4] usb-uas: enumerate luns with REPORT LUNS
Bugzilla: 1020622
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>

From: Roman Kagan <rkagan@virtuozzo.com>

Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 8579fd20c89f0bbc258d6eedb993ecb1bf431027)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 src/hw/usb-uas.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/src/hw/usb-uas.c b/src/hw/usb-uas.c
index 10e3845..f00221a 100644
--- a/src/hw/usb-uas.c
+++ b/src/hw/usb-uas.c
@@ -86,8 +86,9 @@ typedef struct {
 
 struct uasdrive_s {
     struct drive_s drive;
+    struct usbdevice_s *usbdev;
     struct usb_pipe *command, *status, *data_in, *data_out;
-    int lun;
+    u32 lun;
 };
 
 int
@@ -168,30 +169,41 @@ fail:
     return DISK_RET_EBADTRACK;
 }
 
-static int
-uas_lun_setup(struct usbdevice_s *usbdev,
-              struct usb_pipe *command, struct usb_pipe *status,
-              struct usb_pipe *data_in, struct usb_pipe *data_out,
-              int lun)
+static void
+uas_init_lun(struct uasdrive_s *drive, struct usbdevice_s *usbdev,
+             struct usb_pipe *command, struct usb_pipe *status,
+             struct usb_pipe *data_in, struct usb_pipe *data_out,
+             u32 lun)
 {
-    // Allocate drive structure.
-    struct uasdrive_s *drive = malloc_fseg(sizeof(*drive));
-    if (!drive) {
-        warn_noalloc();
-        return -1;
-    }
     memset(drive, 0, sizeof(*drive));
     if (usb_32bit_pipe(data_in))
         drive->drive.type = DTYPE_UAS_32;
     else
         drive->drive.type = DTYPE_UAS;
+    drive->usbdev = usbdev;
     drive->command = command;
     drive->status = status;
     drive->data_in = data_in;
     drive->data_out = data_out;
     drive->lun = lun;
+}
+
+static int
+uas_add_lun(u32 lun, struct drive_s *tmpl_drv)
+{
+    struct uasdrive_s *tmpl_lun =
+        container_of(tmpl_drv, struct uasdrive_s, drive);
+    struct uasdrive_s *drive = malloc_fseg(sizeof(*drive));
+    if (!drive) {
+        warn_noalloc();
+        return -1;
+    }
+    uas_init_lun(drive, tmpl_lun->usbdev,
+                 tmpl_lun->command, tmpl_lun->status,
+                 tmpl_lun->data_in, tmpl_lun->data_out,
+                 lun);
 
-    int prio = bootprio_find_usb(usbdev, lun);
+    int prio = bootprio_find_usb(drive->usbdev, drive->lun);
     int ret = scsi_drive_setup(&drive->drive, "USB UAS", prio);
     if (ret) {
         free(drive);
@@ -258,9 +270,10 @@ usb_uas_setup(struct usbdevice_s *usbdev)
     if (!command || !status || !data_in || !data_out)
         goto fail;
 
-    /* TODO: send REPORT LUNS.  For now, only LUN 0 is recognized.  */
-    int ret = uas_lun_setup(usbdev, command, status, data_in, data_out, 0);
-    if (ret < 0) {
+    struct uasdrive_s lun0;
+    uas_init_lun(&lun0, usbdev, command, status, data_in, data_out, 0);
+    int ret = scsi_rep_luns_scan(&lun0.drive, uas_add_lun);
+    if (ret <= 0) {
         dprintf(1, "Unable to configure UAS drive.\n");
         goto fail;
     }
-- 
1.8.3.1