aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kagan <rkagan@virtuozzo.com>2017-04-26 17:18:05 +0300
committerKevin O'Connor <kevin@koconnor.net>2017-05-02 19:57:04 -0400
commit8579fd20c89f0bbc258d6eedb993ecb1bf431027 (patch)
treef368183c08e8561613070720033280bdd119fb08
parent3aadef4fd9ce7671c9cc1559c64cb439510856d9 (diff)
downloadseabios-hppa-8579fd20c89f0bbc258d6eedb993ecb1bf431027.zip
seabios-hppa-8579fd20c89f0bbc258d6eedb993ecb1bf431027.tar.gz
seabios-hppa-8579fd20c89f0bbc258d6eedb993ecb1bf431027.tar.bz2
usb-uas: enumerate luns with REPORT LUNS
Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
-rw-r--r--src/hw/usb-uas.c45
1 files 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;
}