Signed-off-by: Roman Kagan rkagan@virtuozzo.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; }