summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/src/hw/usb-uas.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/seabios/src/hw/usb-uas.c')
-rw-r--r--qemu/roms/seabios/src/hw/usb-uas.c276
1 files changed, 0 insertions, 276 deletions
diff --git a/qemu/roms/seabios/src/hw/usb-uas.c b/qemu/roms/seabios/src/hw/usb-uas.c
deleted file mode 100644
index 10e38454a..000000000
--- a/qemu/roms/seabios/src/hw/usb-uas.c
+++ /dev/null
@@ -1,276 +0,0 @@
-// Code for handling usb attached scsi devices.
-//
-// only usb 2.0 for now.
-//
-// once we have xhci driver with usb 3.0 support this must
-// be updated to use usb3 streams so booting from usb3
-// devices actually works.
-//
-// Authors:
-// Gerd Hoffmann <kraxel@redhat.com>
-//
-// based on usb-msc.c which is written by:
-// Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "biosvar.h" // GET_GLOBALFLAT
-#include "block.h" // DTYPE_USB
-#include "blockcmd.h" // cdb_read
-#include "config.h" // CONFIG_USB_UAS
-#include "malloc.h" // free
-#include "output.h" // dprintf
-#include "std/disk.h" // DISK_RET_SUCCESS
-#include "string.h" // memset
-#include "usb.h" // struct usb_s
-#include "usb-uas.h" // usb_uas_init
-#include "util.h" // bootprio_find_usb
-
-#define UAS_UI_COMMAND 0x01
-#define UAS_UI_SENSE 0x03
-#define UAS_UI_RESPONSE 0x04
-#define UAS_UI_TASK_MGMT 0x05
-#define UAS_UI_READ_READY 0x06
-#define UAS_UI_WRITE_READY 0x07
-
-#define UAS_PIPE_ID_COMMAND 0x01
-#define UAS_PIPE_ID_STATUS 0x02
-#define UAS_PIPE_ID_DATA_IN 0x03
-#define UAS_PIPE_ID_DATA_OUT 0x04
-
-typedef struct {
- u8 id;
- u8 reserved;
- u16 tag;
-} PACKED uas_ui_header;
-
-typedef struct {
- u8 prio_taskattr; /* 6:3 priority, 2:0 task attribute */
- u8 reserved_1;
- u8 add_cdb_length; /* 7:2 additional adb length (dwords) */
- u8 reserved_2;
- u8 lun[8];
- u8 cdb[16];
- u8 add_cdb[];
-} PACKED uas_ui_command;
-
-typedef struct {
- u16 status_qualifier;
- u8 status;
- u8 reserved[7];
- u16 sense_length;
- u8 sense_data[18];
-} PACKED uas_ui_sense;
-
-typedef struct {
- u16 add_response_info;
- u8 response_code;
-} PACKED uas_ui_response;
-
-typedef struct {
- u8 function;
- u8 reserved;
- u16 task_tag;
- u8 lun[8];
-} PACKED uas_ui_task_mgmt;
-
-typedef struct {
- uas_ui_header hdr;
- union {
- uas_ui_command command;
- uas_ui_sense sense;
- uas_ui_task_mgmt task;
- uas_ui_response response;
- };
-} PACKED uas_ui;
-
-struct uasdrive_s {
- struct drive_s drive;
- struct usb_pipe *command, *status, *data_in, *data_out;
- int lun;
-};
-
-int
-uas_process_op(struct disk_op_s *op)
-{
- if (!CONFIG_USB_UAS)
- return DISK_RET_EBADTRACK;
-
- struct uasdrive_s *drive_gf = container_of(
- op->drive_gf, struct uasdrive_s, drive);
-
- uas_ui ui;
- memset(&ui, 0, sizeof(ui));
- ui.hdr.id = UAS_UI_COMMAND;
- ui.hdr.tag = 0xdead;
- ui.command.lun[1] = GET_GLOBALFLAT(drive_gf->lun);
- int blocksize = scsi_fill_cmd(op, ui.command.cdb, sizeof(ui.command.cdb));
- if (blocksize < 0)
- return default_process_op(op);
- int ret = usb_send_bulk(GET_GLOBALFLAT(drive_gf->command),
- USB_DIR_OUT, MAKE_FLATPTR(GET_SEG(SS), &ui),
- sizeof(ui.hdr) + sizeof(ui.command));
- if (ret) {
- dprintf(1, "uas: command send fail");
- goto fail;
- }
-
- memset(&ui, 0xff, sizeof(ui));
- ret = usb_send_bulk(GET_GLOBALFLAT(drive_gf->status),
- USB_DIR_IN, MAKE_FLATPTR(GET_SEG(SS), &ui), sizeof(ui));
- if (ret) {
- dprintf(1, "uas: status recv fail");
- goto fail;
- }
-
- switch (ui.hdr.id) {
- case UAS_UI_SENSE:
- goto have_sense;
- case UAS_UI_READ_READY:
- ret = usb_send_bulk(GET_GLOBALFLAT(drive_gf->data_in),
- USB_DIR_IN, op->buf_fl, op->count * blocksize);
- if (ret) {
- dprintf(1, "uas: data read fail");
- goto fail;
- }
- break;
- case UAS_UI_WRITE_READY:
- ret = usb_send_bulk(GET_GLOBALFLAT(drive_gf->data_out),
- USB_DIR_OUT, op->buf_fl, op->count * blocksize);
- if (ret) {
- dprintf(1, "uas: data write fail");
- goto fail;
- }
- break;
- default:
- dprintf(1, "uas: unknown status ui id %d", ui.hdr.id);
- goto fail;
- }
-
- memset(&ui, 0xff, sizeof(ui));
- ret = usb_send_bulk(GET_GLOBALFLAT(drive_gf->status),
- USB_DIR_IN, MAKE_FLATPTR(GET_SEG(SS), &ui), sizeof(ui));
- if (ret) {
- dprintf(1, "uas: status recv fail");
- goto fail;
- }
- if (ui.hdr.id != UAS_UI_SENSE) {
- dprintf(1, "uas: expected sense ui, got ui id %d", ui.hdr.id);
- goto fail;
- }
-
-have_sense:
- if (ui.sense.status == 0) {
- return DISK_RET_SUCCESS;
- }
-
-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)
-{
- // 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->command = command;
- drive->status = status;
- drive->data_in = data_in;
- drive->data_out = data_out;
- drive->lun = lun;
-
- int prio = bootprio_find_usb(usbdev, lun);
- int ret = scsi_drive_setup(&drive->drive, "USB UAS", prio);
- if (ret) {
- free(drive);
- return -1;
- }
- return 0;
-}
-
-int
-usb_uas_setup(struct usbdevice_s *usbdev)
-{
- if (!CONFIG_USB_UAS)
- return -1;
-
- // Verify right kind of device
- struct usb_interface_descriptor *iface = usbdev->iface;
- if (iface->bInterfaceSubClass != US_SC_SCSI ||
- iface->bInterfaceProtocol != US_PR_UAS) {
- dprintf(1, "Unsupported UAS device (subclass=%02x proto=%02x)\n"
- , iface->bInterfaceSubClass, iface->bInterfaceProtocol);
- return -1;
- }
-
- /* find & allocate pipes */
- struct usb_endpoint_descriptor *ep = NULL;
- struct usb_pipe *command = NULL;
- struct usb_pipe *status = NULL;
- struct usb_pipe *data_in = NULL;
- struct usb_pipe *data_out = NULL;
- u8 *desc = (u8*)iface;
- while (desc) {
- desc += desc[0];
- switch (desc[1]) {
- case USB_DT_ENDPOINT:
- ep = (void*)desc;
- break;
- case USB_DT_ENDPOINT_COMPANION:
- /* No support (yet) for usb3 streams */
- dprintf(1, "Superspeed UAS devices not supported (yet)\n");
- goto fail;
- case 0x24:
- switch (desc[2]) {
- case UAS_PIPE_ID_COMMAND:
- command = usb_alloc_pipe(usbdev, ep);
- break;
- case UAS_PIPE_ID_STATUS:
- status = usb_alloc_pipe(usbdev, ep);
- break;
- case UAS_PIPE_ID_DATA_IN:
- data_in = usb_alloc_pipe(usbdev, ep);
- break;
- case UAS_PIPE_ID_DATA_OUT:
- data_out = usb_alloc_pipe(usbdev, ep);
- break;
- default:
- goto fail;
- }
- break;
- default:
- desc = NULL;
- break;
- }
- }
- 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) {
- dprintf(1, "Unable to configure UAS drive.\n");
- goto fail;
- }
-
- return 0;
-
-fail:
- usb_free_pipe(usbdev, command);
- usb_free_pipe(usbdev, status);
- usb_free_pipe(usbdev, data_in);
- usb_free_pipe(usbdev, data_out);
- return -1;
-}