/***************************************************************************** * Copyright (c) 2013 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License * which accompanies this distribution, and is available at * http://www.opensource.org/licenses/bsd-license.php * * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ #ifndef __USB_CORE_H #define __USB_CORE_H #include #include #include "helpers.h" #include "usb.h" #include "tools.h" enum usb_hcd_type { USB_OHCI = 1, USB_EHCI = 2, USB_XHCI = 3, }; struct usb_hcd_dev; struct usb_hcd_dev { void *base; long type; long num; struct usb_hcd_ops *ops; void *priv; /* hcd owned structure */ long nextaddr; /* address for devices */ }; struct usb_pipe; /*******************************************/ /* Standard Endpoint Descriptor */ /*******************************************/ /* bmAttributes */ #define USB_EP_TYPE_MASK 0x03 #define USB_EP_TYPE_CONTROL 0 #define USB_EP_TYPE_ISOC 1 #define USB_EP_TYPE_BULK 2 #define USB_EP_TYPE_INTR 3 struct usb_ep_descr { uint8_t bLength; /* size of descriptor */ uint8_t bDescriptorType; /* Type = 5 */ uint8_t bEndpointAddress; uint8_t bmAttributes; uint16_t wMaxPacketSize; uint8_t bInterval; } __attribute__((packed)); #define DEV_HID_KEYB 0x030101 /* class=HIB, protocol=Keyboard */ #define DEV_HID_MOUSE 0x030102 /* class=HIB, protocol=Mouse */ #define DEV_HUB 0x090000 /* class=HUB, subclass, protocol */ #define DEV_MASS_RBC 0x080150 /* MassStorage, RBC, Bulk */ #define DEV_CDROM_ATAPI 0x080250 /* MassStorage, SFF-8020i , Bulk */ #define DEV_MASS_FLOPPY 0x080450 /* MassStorage, UFI, Bulk */ #define DEV_MASS_ATAPI 0x080550 /* MassStorage, SFF-8070i , Bulk */ #define DEV_MASS_SCSI 0x080650 /* MassStorage, SCSI, Bulk */ enum USB_SPEED_TYPE { USB_LOW_SPEED = 0, USB_FULL_SPEED = 1, USB_HIGH_SPEED = 2, USB_SUPER_SPEED = 3, }; /* Max number of endpoints supported in a device */ #define USB_DEV_EP_MAX 4 #define USB_TIMEOUT 5000 /* 5 sec usb timeout */ struct usb_dev { struct usb_dev *next; struct usb_hcd_dev *hcidev; struct usb_pipe *intr; struct usb_pipe *control; struct usb_pipe *bulk_in; struct usb_pipe *bulk_out; struct usb_ep_descr ep[USB_DEV_EP_MAX]; void *priv; uint32_t ep_cnt; uint32_t class; uint32_t speed; uint32_t addr; uint32_t mps0; uint32_t port; uint16_t intf_num; }; #define DEVICE_KEYBOARD 1 #define DEVICE_MOUSE 2 #define DEVICE_DISK 3 #define DEVICE_HUB 4 /* Structure in sync with FORTH code */ struct slof_usb_dev { void *udev; uint32_t port; uint32_t addr; uint32_t hcitype; uint32_t num; uint32_t devtype; } __attribute__((packed)); enum USB_PIPE_DIR { USB_PIPE_OUT = 0, USB_PIPE_IN, }; struct usb_pipe { struct usb_dev *dev; struct usb_pipe *next; uint32_t type; uint32_t speed; uint32_t dir; uint16_t epno; uint16_t mps; } __attribute__((packed)); #define REQ_GET_STATUS 0 /* see Table 9-4 */ #define REQ_CLEAR_FEATURE 1 #define REQ_GET_STATE 2 /* HUB specific */ #define REQ_SET_FEATURE 3 #define REQ_SET_ADDRESS 5 #define REQ_GET_DESCRIPTOR 6 #define REQ_SET_DESCRIPTOR 7 #define REQ_GET_CONFIGURATION 8 #define REQ_SET_CONFIGURATION 9 #define REQ_GET_INTERFACE 10 #define REQ_SET_INTERFACE 11 #define REQ_SYNCH_FRAME 12 #define FEATURE_DEVICE_REMOTE_WAKEUP 1 #define FEATURE_ENDPOINT_HALT 0 #define REQT_REC_DEVICE 0 #define REQT_REC_INTERFACE 1 #define REQT_REC_EP 2 #define REQT_REC_OTHER 3 #define REQT_TYPE_STANDARD (0 << 5) #define REQT_TYPE_CLASS (1 << 5) #define REQT_TYPE_VENDOR (2 << 5) #define REQT_TYPE_RSRVD (3 << 5) #define REQT_DIR_OUT (0 << 7) /* host -> device */ #define REQT_DIR_IN (1 << 7) /* device -> host */ #define DESCR_TYPE_DEVICE 1 /* see Table 9-5 */ #define DESCR_TYPE_CONFIGURATION 2 #define DESCR_TYPE_STRING 3 #define DESCR_TYPE_INTERFACE 4 #define DESCR_TYPE_ENDPOINT 5 #define DESCR_TYPE_HUB 0x29 /* Class Descriptor HUB */ #define DESCR_TYPE_HID 0x21 /* Class Descriptor HID */ #define DESCR_TYPE_REPORT 0x22 /* Class Descriptor HID */ #define DESCR_TYPE_PHYSICAL 0x23 /* Class Descriptor HID */ struct usb_dev_req { uint8_t bmRequestType; /* direction, recipient */ uint8_t bRequest; /* see spec: Table 9-3 */ uint16_t wValue; uint16_t wIndex; uint16_t wLength; /* number of bytes to transfer */ } __attribute__((packed)); /* Standard Device Descriptor (18 Bytes) */ /*******************************************/ struct usb_dev_descr { uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdUSB; uint8_t bDeviceClass; uint8_t bDeviceSubClass; uint8_t bDeviceProtocol; uint8_t bMaxPacketSize0; uint16_t idVendor; uint16_t idProduct; uint16_t bcdDevice; uint8_t iManufacturer; uint8_t iProduct; uint8_t iSerialNumber; uint8_t bNumConfigurations; } __attribute__((packed)); /*******************************************/ /* Standard Configuration Descriptor */ /*******************************************/ struct usb_dev_config_descr { uint8_t bLength; /* size of descriptor */ uint8_t bDescriptorType; /* Type = 2 */ uint16_t wTotalLength; /* total returned data */ uint8_t bNumInterfaces; /* interfaces supported by this config */ uint8_t bConfigurationValue; /* Configuration-ID for SetConfiguration */ uint8_t iConfiguration; /* index of string descriptor */ uint8_t bmAttributes; /* configuration characteristics */ uint8_t bMaxPower; /* in 2mA units */ } __attribute__((packed)); /*******************************************/ /* Standard Interface Descriptor */ /*******************************************/ struct usb_dev_intf_descr { uint8_t bLength; /* size of descriptor */ uint8_t bDescriptorType; /* Type = 4 */ uint8_t bInterfaceNumber; uint8_t bAlternateSetting; uint8_t bNumEndpoints; uint8_t bInterfaceClass; uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; /* protocol code */ uint8_t iInterface; /* index to string descriptor */ } __attribute__((packed)); /*******************************************/ /* HUB-Class Descriptor */ /*******************************************/ struct usb_dev_hub_descr { uint8_t bLength; /* size of complete descriptor */ uint8_t bDescriptorType; /* type = 0x29 for HUB */ uint8_t bNbrPorts; /* number of downstream ports */ uint8_t wHubCharacteristics; /* mode bits 7..0 */ uint8_t reserved; /* mode bits 15..8 */ uint8_t bPwrOn2PwrGood; /* in 2ms units */ uint8_t bHubContrCurrent; /* current requirement in mA */ uint8_t DeviceTable; /* length depends on number of ports */ } __attribute__((packed)); /*******************************************/ /* HID-Class Descriptor */ /*******************************************/ struct usb_dev_hid_descr { uint8_t bLength; /* size of this descriptor */ uint8_t bDescriptorType; /* type = 0x21 for HID */ uint16_t bcdHID; /* Sample: 0x0102 for 2.01 */ uint8_t bCountryCode; /* Hardware target country */ uint8_t bNumDescriptors; /* Number of HID class descr. */ uint8_t bReportType; /* Report Descriptor Type */ uint16_t wReportLength; /* Total Length of Report Descr. */ } __attribute__((packed)); struct usb_hcd_ops { const char *name; void (*init)(struct usb_hcd_dev *); void (*exit)(struct usb_hcd_dev *); void (*detect)(void); void (*disconnect)(void); int (*send_ctrl)(struct usb_pipe *pipe, struct usb_dev_req *req, void *data); struct usb_pipe* (*get_pipe)(struct usb_dev *dev, struct usb_ep_descr *ep, char *buf, size_t len); int (*transfer_bulk)(struct usb_pipe *pipe, void *td, void *td_phys, void *data, int size); void (*put_pipe)(struct usb_pipe *); int (*poll_intr)(struct usb_pipe *, uint8_t *); struct usb_hcd_ops *next; unsigned int usb_type; }; #define usb_get_intf_class(x) ((x & 0x00FF0000) >> 16) extern void usb_hcd_register(struct usb_hcd_ops *ops); extern struct usb_pipe *usb_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep, char *buf, size_t len); extern void usb_put_pipe(struct usb_pipe *pipe); extern int usb_poll_intr(struct usb_pipe *pipe, uint8_t *buf); extern int usb_send_ctrl(struct usb_pipe *pipe, struct usb_dev_req *req, void *data); extern struct usb_dev *usb_devpool_get(void); extern void usb_devpool_put(struct usb_dev *); extern int usb_setup_new_device(struct usb_dev *dev, unsigned int port); extern void usb_slof_populate_new_device(struct usb_dev *dev); extern int usb_dev_populate_pipe(struct usb_dev *dev, struct usb_ep_descr *ep, void *buf, size_t len); extern int usb_hid_kbd_init(struct usb_dev *dev); extern int usb_hid_kbd_exit(struct usb_dev *dev); extern int usb_msc_reset(struct usb_dev *dev); extern void usb_msc_resetrecovery(struct usb_dev *dev); #endif