blob: d27107f46d8f86135c2a2abdf765291cd6535cab [file] [log] [blame]
/*****************************************************************************
* 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 <stdio.h>
#include <stdbool.h>
#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, aligned(4)));
#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_dev *hub;
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