aboutsummaryrefslogtreecommitdiffstats
path: root/src/usb.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2010-02-17 23:24:42 -0500
committerKevin O'Connor <kevin@koconnor.net>2010-02-17 23:24:42 -0500
commit7149fc813139cf564a4456815461c18a8b208e89 (patch)
treeb0866113b1380d34b1d9e1d4a1ffd8fc375f289f /src/usb.c
parent3c160dde75b9920f048d4276026d680d0f582dc9 (diff)
downloadseabios-7149fc813139cf564a4456815461c18a8b208e89.tar.gz
Initial support for booting from USB drives.
This patch adds initial support for USB Mass Storage Controllers. This includes support for bulk transfers on UHCI controllers. Code to detect a USB MSC device is added, and wrappers for sending "cdb" block commands over USB are added. The scsi "inquiry" command is also added.
Diffstat (limited to 'src/usb.c')
-rw-r--r--src/usb.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/usb.c b/src/usb.c
index 1ed3c80a..cc3b2012 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -13,6 +13,7 @@
#include "usb-ohci.h" // ohci_init
#include "usb-hid.h" // usb_keyboard_setup
#include "usb-hub.h" // usb_hub_init
+#include "usb-msc.h" // usb_msc_init
#include "usb.h" // struct usb_s
#include "biosvar.h" // GET_GLOBAL
@@ -39,6 +40,33 @@ send_control(u32 endp, int dir, const void *cmd, int cmdsize
}
struct usb_pipe *
+alloc_bulk_pipe(u32 endp)
+{
+ struct usb_s *cntl = endp2cntl(endp);
+ switch (cntl->type) {
+ default:
+ case USB_TYPE_UHCI:
+ return uhci_alloc_bulk_pipe(endp);
+ case USB_TYPE_OHCI:
+ return NULL;
+ }
+}
+
+int
+usb_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize)
+{
+ u32 endp = GET_FLATPTR(pipe->endp);
+ struct usb_s *cntl = endp2cntl(endp);
+ switch (cntl->type) {
+ default:
+ case USB_TYPE_UHCI:
+ return uhci_send_bulk(pipe, dir, data, datasize);
+ case USB_TYPE_OHCI:
+ return -1;
+ }
+}
+
+struct usb_pipe *
alloc_intr_pipe(u32 endp, int period)
{
struct usb_s *cntl = endp2cntl(endp);
@@ -220,6 +248,7 @@ configure_usb_device(struct usb_s *cntl, int lowspeed)
if ((iface->bInterfaceClass != USB_CLASS_HID
|| iface->bInterfaceSubClass != USB_INTERFACE_SUBCLASS_BOOT
|| iface->bInterfaceProtocol != USB_INTERFACE_PROTOCOL_KEYBOARD)
+ && (iface->bInterfaceClass != USB_CLASS_MASS_STORAGE)
&& (iface->bInterfaceClass != USB_CLASS_HUB))
// Not a supported device.
goto fail;
@@ -237,8 +266,11 @@ configure_usb_device(struct usb_s *cntl, int lowspeed)
free(config);
return usb_hub_init(endp);
}
- ret = usb_keyboard_init(endp, iface, ((void*)config + config->wTotalLength
- - (void*)iface));
+ int imax = (void*)config + config->wTotalLength - (void*)iface;
+ if (iface->bInterfaceClass == USB_CLASS_MASS_STORAGE)
+ ret = usb_msc_init(endp, iface, imax);
+ else
+ ret = usb_keyboard_init(endp, iface, imax);
if (ret)
goto fail;