summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/drivers/usb.h
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/drivers/usb.h')
-rw-r--r--qemu/roms/openbios/drivers/usb.h357
1 files changed, 357 insertions, 0 deletions
diff --git a/qemu/roms/openbios/drivers/usb.h b/qemu/roms/openbios/drivers/usb.h
new file mode 100644
index 000000000..2e23a1370
--- /dev/null
+++ b/qemu/roms/openbios/drivers/usb.h
@@ -0,0 +1,357 @@
+/*
+ * Driver for USB ported from CoreBoot
+ *
+ * Copyright (C) 2014 BALATON Zoltan
+ *
+ * This file was part of the libpayload project.
+ *
+ * Copyright (C) 2008 coresystems GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __USB_H
+#define __USB_H
+#include <drivers/pci.h>
+
+typedef enum { host_to_device = 0, device_to_host = 1 } dev_req_dir;
+typedef enum { standard_type = 0, class_type = 1, vendor_type =
+ 2, reserved_type = 3
+} dev_req_type;
+typedef enum { dev_recp = 0, iface_recp = 1, endp_recp = 2, other_recp = 3
+} dev_req_recp;
+
+typedef enum {
+ GET_STATUS = 0,
+ CLEAR_FEATURE = 1,
+ SET_FEATURE = 3,
+ SET_ADDRESS = 5,
+ GET_DESCRIPTOR = 6,
+ SET_DESCRIPTOR = 7,
+ GET_CONFIGURATION = 8,
+ SET_CONFIGURATION = 9,
+ GET_INTERFACE = 10,
+ SET_INTERFACE = 11,
+ SYNCH_FRAME = 12
+} bRequest_Codes;
+
+typedef enum {
+ ENDPOINT_HALT = 0,
+ DEVICE_REMOTE_WAKEUP = 1,
+ TEST_MODE = 2
+} feature_selectors;
+
+enum {
+ audio_device = 0x01,
+ comm_device = 0x02,
+ hid_device = 0x03,
+ physical_device = 0x05,
+ imaging_device = 0x06,
+ printer_device = 0x07,
+ msc_device = 0x08,
+ hub_device = 0x09,
+ cdc_device = 0x0a,
+ ccid_device = 0x0b,
+ security_device = 0x0d,
+ video_device = 0x0e,
+ healthcare_device = 0x0f,
+ diagnostic_device = 0xdc,
+ wireless_device = 0xe0,
+ misc_device = 0xef,
+};
+
+enum { hid_subclass_none = 0, hid_subclass_boot = 1 };
+
+enum {
+ hid_boot_proto_none = 0,
+ hid_boot_proto_keyboard = 1,
+ hid_boot_proto_mouse = 2
+};
+
+typedef struct {
+ union {
+ struct {
+#ifdef CONFIG_BIG_ENDIAN
+ dev_req_dir data_dir:1;
+ dev_req_type req_type:2;
+ dev_req_recp req_recp:5;
+#else
+ dev_req_recp req_recp:5;
+ dev_req_type req_type:2;
+ dev_req_dir data_dir:1;
+#endif
+ } __attribute__ ((packed));
+ unsigned char bmRequestType;
+ } __attribute__ ((packed));
+ unsigned char bRequest;
+ unsigned short wValue;
+ unsigned short wIndex;
+ unsigned short wLength;
+} __attribute__ ((packed)) dev_req_t;
+
+struct usbdev_hc;
+typedef struct usbdev_hc hci_t;
+
+struct usbdev;
+typedef struct usbdev usbdev_t;
+
+typedef enum { SETUP, IN, OUT } direction_t;
+typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3
+} endpoint_type;
+
+typedef struct {
+ usbdev_t *dev;
+ int endpoint;
+ direction_t direction;
+ int toggle;
+ int maxpacketsize;
+ endpoint_type type;
+ int interval; /* expressed as binary logarithm of the number
+ of microframes (i.e. t = 125us * 2^interval) */
+} endpoint_t;
+
+enum { FULL_SPEED = 0, LOW_SPEED = 1, HIGH_SPEED = 2, SUPER_SPEED = 3 };
+
+struct usbdev {
+ hci_t *controller;
+ endpoint_t endpoints[32];
+ int num_endp;
+ int address; // usb address
+ int hub; // hub, device is attached to
+ int port; // port where device is attached
+ int speed; // 1: lowspeed, 0: fullspeed, 2: highspeed
+ u32 quirks; // quirks field. got to love usb
+ void *data;
+ u8 *descriptor;
+ u8 *configuration;
+ void (*init) (usbdev_t *dev);
+ void (*destroy) (usbdev_t *dev);
+ void (*poll) (usbdev_t *dev);
+};
+
+typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3} hc_type;
+
+struct usbdev_hc {
+ hci_t *next;
+ u32 reg_base;
+ hc_type type;
+ usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable
+
+ /* start(): Resume operation. */
+ void (*start) (hci_t *controller);
+ /* stop(): Stop operation but keep controller initialized. */
+ void (*stop) (hci_t *controller);
+ /* reset(): Perform a controller reset. The controller needs to
+ be (re)initialized afterwards to work (again). */
+ void (*reset) (hci_t *controller);
+ /* init(): Initialize a (previously reset) controller
+ to a working state. */
+ void (*init) (hci_t *controller);
+ /* shutdown(): Stop operation, detach host controller and shutdown
+ this driver instance. After calling shutdown() any
+ other usage of this hci_t* is invalid. */
+ void (*shutdown) (hci_t *controller);
+
+ int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize);
+ int (*control) (usbdev_t *dev, direction_t pid, int dr_length,
+ void *devreq, int data_length, u8 *data);
+ void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming);
+ void (*destroy_intr_queue) (endpoint_t *ep, void *queue);
+ u8* (*poll_intr_queue) (void *queue);
+ void *instance;
+
+ /* set_address(): Tell the usb device its address and
+ return it. xHCI controllers want to
+ do this by themself. Also, the usbdev
+ structure has to be allocated and
+ initialized. */
+ int (*set_address) (hci_t *controller, int speed, int hubport, int hubaddr);
+ /* finish_device_config(): Another hook for xHCI,
+ returns 0 on success. */
+ int (*finish_device_config) (usbdev_t *dev);
+ /* destroy_device(): Finally, destroy all structures that
+ were allocated during set_address()
+ and finish_device_config(). */
+ void (*destroy_device) (hci_t *controller, int devaddr);
+};
+
+typedef struct {
+ unsigned char bDescLength;
+ unsigned char bDescriptorType;
+ unsigned char bNbrPorts;
+ union {
+ struct {
+#ifdef CONFIG_BIG_ENDIAN
+ unsigned long:8;
+ unsigned long arePortIndicatorsSupported:1;
+ unsigned long ttThinkTime:2;
+ unsigned long overcurrentProtectionMode:2;
+ unsigned long isCompoundDevice:1;
+ unsigned long logicalPowerSwitchingMode:2;
+#else
+ unsigned long logicalPowerSwitchingMode:2;
+ unsigned long isCompoundDevice:1;
+ unsigned long overcurrentProtectionMode:2;
+ unsigned long ttThinkTime:2;
+ unsigned long arePortIndicatorsSupported:1;
+ unsigned long:8;
+#endif
+ } __attribute__ ((packed));
+ unsigned short wHubCharacteristics;
+ } __attribute__ ((packed));
+ unsigned char bPowerOn2PwrGood;
+ unsigned char bHubContrCurrent;
+ char DeviceRemovable[];
+} __attribute__ ((packed)) hub_descriptor_t;
+
+typedef struct {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned short bcdUSB;
+ unsigned char bDeviceClass;
+ unsigned char bDeviceSubClass;
+ unsigned char bDeviceProtocol;
+ unsigned char bMaxPacketSize0;
+ unsigned short idVendor;
+ unsigned short idProduct;
+ unsigned short bcdDevice;
+ unsigned char iManufacturer;
+ unsigned char iProduct;
+ unsigned char iSerialNumber;
+ unsigned char bNumConfigurations;
+} __attribute__ ((packed)) device_descriptor_t;
+
+typedef struct {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned short wTotalLength;
+ unsigned char bNumInterfaces;
+ unsigned char bConfigurationValue;
+ unsigned char iConfiguration;
+ unsigned char bmAttributes;
+ unsigned char bMaxPower;
+} __attribute__ ((packed)) configuration_descriptor_t;
+
+typedef struct {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned char bInterfaceNumber;
+ unsigned char bAlternateSetting;
+ unsigned char bNumEndpoints;
+ unsigned char bInterfaceClass;
+ unsigned char bInterfaceSubClass;
+ unsigned char bInterfaceProtocol;
+ unsigned char iInterface;
+} __attribute__ ((packed)) interface_descriptor_t;
+
+typedef struct {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned char bEndpointAddress;
+ unsigned char bmAttributes;
+ unsigned short wMaxPacketSize;
+ unsigned char bInterval;
+} __attribute__ ((packed)) endpoint_descriptor_t;
+
+typedef struct {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned short bcdHID;
+ unsigned char bCountryCode;
+ unsigned char bNumDescriptors;
+ unsigned char bReportDescriptorType;
+ unsigned short wReportDescriptorLength;
+} __attribute__ ((packed)) hid_descriptor_t;
+
+hci_t *new_controller (void);
+void detach_controller (hci_t *controller);
+void usb_poll (void);
+void init_device_entry (hci_t *controller, int num);
+
+void set_feature (usbdev_t *dev, int endp, int feature, int rtype);
+void get_status (usbdev_t *dev, int endp, int rtype, int len, void *data);
+void set_configuration (usbdev_t *dev);
+int clear_feature (usbdev_t *dev, int endp, int feature, int rtype);
+int clear_stall (endpoint_t *ep);
+
+void usb_hub_init (usbdev_t *dev);
+void usb_hid_init (usbdev_t *dev);
+void usb_msc_init (usbdev_t *dev);
+void usb_generic_init (usbdev_t *dev);
+
+u8 *get_descriptor (usbdev_t *dev, unsigned char bmRequestType,
+ int descType, int descIdx, int langID);
+
+static inline unsigned char
+gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp)
+{
+ return (dir << 7) | (type << 5) | recp;
+}
+
+/* default "set address" handler */
+int generic_set_address (hci_t *controller, int speed, int hubport, int hubaddr);
+
+void usb_detach_device(hci_t *controller, int devno);
+int usb_attach_device(hci_t *controller, int hubaddress, int port, int speed);
+
+u32 usb_quirk_check(u16 vendor, u16 device);
+int usb_interface_check(u16 vendor, u16 device);
+
+#define USB_QUIRK_MSC_FORCE_PROTO_SCSI (1 << 0)
+#define USB_QUIRK_MSC_FORCE_PROTO_ATAPI (1 << 1)
+#define USB_QUIRK_MSC_FORCE_PROTO_UFI (1 << 2)
+#define USB_QUIRK_MSC_FORCE_PROTO_RBC (1 << 3)
+#define USB_QUIRK_MSC_FORCE_TRANS_BBB (1 << 4)
+#define USB_QUIRK_MSC_FORCE_TRANS_CBI (1 << 5)
+#define USB_QUIRK_MSC_FORCE_TRANS_CBI_I (1 << 6)
+#define USB_QUIRK_MSC_NO_TEST_UNIT_READY (1 << 7)
+#define USB_QUIRK_MSC_SHORT_INQUIRY (1 << 8)
+#define USB_QUIRK_TEST (1 << 31)
+#define USB_QUIRK_NONE 0
+
+#ifdef CONFIG_DEBUG_USB
+#define usb_debug(fmt, args...) do { printk(fmt , ##args); } while (0)
+#else
+#define usb_debug(fmt, args...)
+#endif
+
+/**
+ * To be implemented by libpayload-client. It's called by the USB stack
+ * when a new USB device is found which isn't claimed by a built in driver,
+ * so the client has the chance to know about it.
+ *
+ * @param dev descriptor for the USB device
+ */
+void __attribute__((weak)) usb_generic_create (usbdev_t *dev);
+
+/**
+ * To be implemented by libpayload-client. It's called by the USB stack
+ * when it finds out that a USB device is removed which wasn't claimed by a
+ * built in driver.
+ *
+ * @param dev descriptor for the USB device
+ */
+void __attribute__((weak)) usb_generic_remove (usbdev_t *dev);
+
+#endif