[U-Boot] [RFC PATCH 1/2] USB: SS: Add support for Super Speed USB interface
Vivek Gautam
gautam.vivek at samsung.com
Tue Oct 23 12:54:46 CEST 2012
This adds usb framework support for super-speed usb, which will
further facilitate to add stack support for xHCI.
Signed-off-by: Vikas C Sajjan <vikas.sajjan at samsung.com>
Signedoff-by: Vivek Gautam <gautam.vivek at samsung.com>
---
common/cmd_usb.c | 6 +-
common/usb.c | 41 ++++++++-
common/usb_hub.c | 26 +++++-
common/usb_storage.c | 35 +++++----
include/common.h | 2 +
include/linux/usb/ch9.h | 2 +-
include/usb.h | 15 +++-
include/usb_defs.h | 26 ++++++-
include/usbdescriptors.h | 201 ++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 322 insertions(+), 32 deletions(-)
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index c128455..013b2e8 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -262,7 +262,7 @@ void usb_display_config(struct usb_device *dev)
ifdesc = &config->if_desc[i];
usb_display_if_desc(&ifdesc->desc, dev);
for (ii = 0; ii < ifdesc->no_of_ep; ii++) {
- epdesc = &ifdesc->ep_desc[ii];
+ epdesc = &ifdesc->ep_desc[ii].ep_desc;
usb_display_ep_desc(epdesc);
}
}
@@ -271,7 +271,9 @@ void usb_display_config(struct usb_device *dev)
static inline char *portspeed(int speed)
{
- if (speed == USB_SPEED_HIGH)
+ if (speed == USB_SPEED_SUPER)
+ return "5 Gb/s";
+ else if (speed == USB_SPEED_HIGH)
return "480 Mb/s";
else if (speed == USB_SPEED_LOW)
return "1.5 Mb/s";
diff --git a/common/usb.c b/common/usb.c
index 50b8175..691d9ac 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -304,7 +304,7 @@ usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)
struct usb_endpoint_descriptor *ep;
u16 ep_wMaxPacketSize;
- ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
+ ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx].ep_desc;
b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize);
@@ -360,6 +360,7 @@ static int usb_parse_config(struct usb_device *dev,
int index, ifno, epno, curr_if_num;
int i;
u16 ep_wMaxPacketSize;
+ struct usb_interface *if_desc = NULL;
ifno = -1;
epno = -1;
@@ -401,21 +402,27 @@ static int usb_parse_config(struct usb_device *dev,
break;
case USB_DT_ENDPOINT:
epno = dev->config.if_desc[ifno].no_of_ep;
+ if_desc = &dev->config.if_desc[ifno];
/* found an endpoint */
- dev->config.if_desc[ifno].no_of_ep++;
- memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
+ if_desc->no_of_ep++;
+ memcpy(&if_desc->ep_desc[epno].ep_desc,
&buffer[index], buffer[index]);
ep_wMaxPacketSize = get_unaligned(&dev->config.\
if_desc[ifno].\
ep_desc[epno].\
- wMaxPacketSize);
+ ep_desc.wMaxPacketSize);
put_unaligned(le16_to_cpu(ep_wMaxPacketSize),
&dev->config.\
if_desc[ifno].\
ep_desc[epno].\
- wMaxPacketSize);
+ ep_desc.wMaxPacketSize);
USB_PRINTF("if %d, ep %d\n", ifno, epno);
break;
+ case USB_DT_SS_ENDPOINT_COMP:
+ if_desc = &dev->config.if_desc[ifno];
+ memcpy(&(if_desc->ep_desc[epno].ss_ep_comp),
+ &buffer[index], buffer[index]);
+ break;
default:
if (head->bLength == 0)
return 1;
@@ -659,6 +666,18 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid,
return result;
}
+/* Allocate usb device */
+int usb_alloc_dev(struct usb_device *dev)
+{
+ int res;
+
+ USB_PRINTF("alloc device\n");
+ res = usb_control_msg(dev, usb_sndctrlpipe(dev->parent, 0),
+ USB_REQ_ALLOC_DEV, 0, 0, 0,
+ NULL, 0, USB_CNTL_TIMEOUT);
+
+ return res;
+}
static void usb_try_string_workarounds(unsigned char *buf, int *length)
{
@@ -852,7 +871,10 @@ int usb_new_device(struct usb_device *dev)
struct usb_device_descriptor *desc;
int port = -1;
struct usb_device *parent = dev->parent;
+
+#ifndef CONFIG_USB_XHCI
unsigned short portstatus;
+#endif
/* send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is
* only 18 bytes long, this will terminate with a short packet. But if
@@ -889,12 +911,21 @@ int usb_new_device(struct usb_device *dev)
return 1;
}
+ /*
+ * Putting up the code here for slot assignment and initialization:
+ * xHCI spec sec 4.3.2, 4.3.3
+ */
+#ifdef CONFIG_USB_XHCI
+ /* Call if and only if device is attached and detected */
+ usb_alloc_dev(dev);
+#else
/* reset the port for the second time */
err = hub_port_reset(dev->parent, port, &portstatus);
if (err < 0) {
printf("\n Couldn't reset port %i\n", port);
return 1;
}
+#endif
}
#endif
diff --git a/common/usb_hub.c b/common/usb_hub.c
index e4a1201..8a00894 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -204,7 +204,12 @@ int hub_port_reset(struct usb_device *dev, int port,
}
-void usb_hub_port_connect_change(struct usb_device *dev, int port)
+/*
+ * Adding the flag do_port_reset: USB 2.0 device requires port reset
+ * while USB 3.0 device does not.
+ */
+void usb_hub_port_connect_change(struct usb_device *dev, int port,
+ int do_port_reset)
{
struct usb_device *usb;
ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
@@ -235,11 +240,21 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
}
mdelay(200);
+#ifdef CONFIG_USB_XHCI
+ /* Reset the port */
+ if (do_port_reset) {
+ if (hub_port_reset(dev, port, &portstatus) < 0) {
+ printf("cannot reset port %i!?\n", port + 1);
+ return;
+ }
+ }
+#else
/* Reset the port */
if (hub_port_reset(dev, port, &portstatus) < 0) {
printf("cannot reset port %i!?\n", port + 1);
return;
}
+#endif
mdelay(200);
@@ -409,7 +424,10 @@ static int usb_hub_configure(struct usb_device *dev)
if (portchange & USB_PORT_STAT_C_CONNECTION) {
USB_HUB_PRINTF("port %d connection change\n", i + 1);
- usb_hub_port_connect_change(dev, i);
+ usb_hub_port_connect_change(dev, i, 0);
+ } else if ((portstatus & 0x1) == 1) {
+ USB_HUB_PRINTF("port %d connection change\n", i + 1);
+ usb_hub_port_connect_change(dev, i, 1);
}
if (portchange & USB_PORT_STAT_C_ENABLE) {
USB_HUB_PRINTF("port %d enable change, status %x\n",
@@ -426,7 +444,7 @@ static int usb_hub_configure(struct usb_device *dev)
USB_HUB_PRINTF("already running port %i " \
"disabled by hub (EMI?), " \
"re-enabling...\n", i + 1);
- usb_hub_port_connect_change(dev, i);
+ usb_hub_port_connect_change(dev, i, 0);
}
}
if (portstatus & USB_PORT_STAT_SUSPEND) {
@@ -470,7 +488,7 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
if (iface->desc.bNumEndpoints != 1)
return 0;
- ep = &iface->ep_desc[0];
+ ep = &iface->ep_desc[0].ep_desc;
/* Output endpoint? Curiousier and curiousier.. */
if (!(ep->bEndpointAddress & USB_DIR_IN))
return 0;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 0c2a4c7..53d41d8 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -262,7 +262,7 @@ int usb_stor_scan(int mode)
usb_max_devs = 0;
for (i = 0; i < USB_MAX_DEVICE; i++) {
dev = usb_get_dev_index(i); /* get device */
- USB_STOR_PRINTF("i=%d\n", i);
+ USB_STOR_PRINTF("i=%d, dev_num=%d\n", i, dev->devnum);
if (dev == NULL)
break; /* no more devices available */
@@ -278,10 +278,11 @@ int usb_stor_scan(int mode)
lun++) {
usb_dev_desc[usb_max_devs].lun = lun;
if (usb_stor_get_info(dev, &usb_stor[start],
- &usb_dev_desc[usb_max_devs]) == 1) {
- usb_max_devs++;
- }
+ &usb_dev_desc[usb_max_devs]) == 1) {
+ usb_max_devs++;
+ }
}
+
}
/* if storage device */
if (usb_max_devs == USB_MAX_STOR_DEV) {
@@ -511,7 +512,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
dir_in = US_DIRECTION(srb->cmd[0]);
#ifdef BBB_COMDAT_TRACE
- printf("dir %d lun %d cmdlen %d cmd %p datalen %d pdata %p\n",
+ printf("dir %d lun %d cmdlen %d cmd %p datalen %lu pdata %p\n",
dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen,
srb->pdata);
if (srb->cmdlen) {
@@ -1208,6 +1209,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
{
struct usb_interface *iface;
int i;
+ struct usb_endpoint_descriptor *ep_desc;
unsigned int flags = 0;
int protocol = 0;
@@ -1290,24 +1292,25 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
* We will ignore any others.
*/
for (i = 0; i < iface->desc.bNumEndpoints; i++) {
+ ep_desc = &iface->ep_desc[i].ep_desc;
/* is it an BULK endpoint? */
- if ((iface->ep_desc[i].bmAttributes &
- USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
- if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
- ss->ep_in = iface->ep_desc[i].bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
+ if ((ep_desc->bmAttributes &
+ USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
+ if (ep_desc->bEndpointAddress & USB_DIR_IN)
+ ss->ep_in = ep_desc->bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
else
ss->ep_out =
- iface->ep_desc[i].bEndpointAddress &
+ ep_desc->bEndpointAddress &
USB_ENDPOINT_NUMBER_MASK;
}
/* is it an interrupt endpoint? */
- if ((iface->ep_desc[i].bmAttributes &
- USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
- ss->ep_int = iface->ep_desc[i].bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
- ss->irqinterval = iface->ep_desc[i].bInterval;
+ if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT) {
+ ss->ep_int = ep_desc->bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ ss->irqinterval = ep_desc->bInterval;
}
}
USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",
diff --git a/include/common.h b/include/common.h
index b23e90b..ef5f687 100644
--- a/include/common.h
+++ b/include/common.h
@@ -211,6 +211,8 @@ typedef void (interrupt_handler_t)(void *);
#define MIN(x, y) min(x, y)
#define MAX(x, y) max(x, y)
+#define min3(a, b, c) min(min(a, b), c)
+
/*
* Return the absolute value of a number.
*
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index ce1d1e1..33af2f4 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -122,7 +122,6 @@
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
-
/**
* struct usb_ctrlrequest - SETUP data for a USB device control request
* @bRequestType: matches the USB bmRequestType field
@@ -491,6 +490,7 @@ enum usb_device_speed {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
USB_SPEED_HIGH, /* usb 2.0 */
+ USB_SPEED_SUPER, /* usb 3.0 */
USB_SPEED_VARIABLE, /* wireless (usb 2.5) */
};
diff --git a/include/usb.h b/include/usb.h
index 9dd8791..a7a0f22 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -73,6 +73,16 @@ struct usb_descriptor_header {
unsigned char bDescriptorType;
} __attribute__ ((packed));
+struct usb_ep_desc {
+ struct usb_endpoint_descriptor ep_desc;
+ /*
+ * Super Speed Device will have Super Speed Endpoint
+ * Companion Descriptor (section 9.6.7 of usb 3.0 spec)
+ * Revision 1.0 June 6th 2011
+ */
+ struct usb_ss_ep_comp_descriptor ss_ep_comp;
+};
+
/* Interface */
struct usb_interface {
struct usb_interface_descriptor desc;
@@ -81,7 +91,7 @@ struct usb_interface {
unsigned char num_altsetting;
unsigned char act_altsetting;
- struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
+ struct usb_ep_desc ep_desc[USB_MAXENDPOINTS];
} __attribute__ ((packed));
/* Configuration information.. */
@@ -153,7 +163,8 @@ struct usb_device {
defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
- defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X)
+ defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
+ defined(CONFIG_USB_XHCI)
int usb_lowlevel_init(int index, void **controller);
int usb_lowlevel_stop(int index);
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 8032e57..e681609 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -84,7 +84,8 @@
#define USB_SPEED_FULL 0x0 /* 12Mbps */
#define USB_SPEED_LOW 0x1 /* 1.5Mbps */
#define USB_SPEED_HIGH 0x2 /* 480Mbps */
-#define USB_SPEED_RESERVED 0x3
+#define USB_SPEED_SUPER 0x3 /* 5Gbps */
+#define USB_SPEED_RESERVED 0x4
/* Descriptor types */
#define USB_DT_DEVICE 0x01
@@ -93,6 +94,9 @@
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
+/* From the USB 3.0 spec */
+#define USB_DT_SS_ENDPOINT_COMP 0x30
+
#define USB_DT_HID (USB_TYPE_CLASS | 0x01)
#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02)
#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
@@ -156,6 +160,7 @@
#define USB_REQ_SET_IDLE 0x0A
#define USB_REQ_SET_PROTOCOL 0x0B
+#define USB_REQ_ALLOC_DEV 0xDE
/* "pipe" definitions */
@@ -227,6 +232,23 @@
#define USB_PORT_STAT_SPEED \
(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
+/*
+ * Additions to wPortStatus bit field from USB 3.0
+ * See USB 3.0 spec Table 10-10
+ */
+#define USB_PORT_STAT_LINK_STATE 0x01e0
+#define USB_SS_PORT_STAT_POWER 0x0200
+#define USB_SS_PORT_STAT_SPEED 0x1c00
+#define USB_PORT_STAT_SPEED_5GBPS 0x0000
+
+/*
+ * USB 3.0 wPortChange bit fields
+ * See USB 3.0 spec Table 10-11
+ */
+#define USB_PORT_STAT_C_BH_RESET 0x0020
+#define USB_PORT_STAT_C_LINK_STATE 0x0040
+#define USB_PORT_STAT_C_CONFIG_ERROR 0x0080
+
/* wPortChange bits */
#define USB_PORT_STAT_C_CONNECTION 0x0001
#define USB_PORT_STAT_C_ENABLE 0x0002
@@ -240,7 +262,7 @@
#define HUB_CHAR_OCPM 0x0018
/*
- *Hub Status & Hub Change bit masks
+ * Hub Status & Hub Change bit masks
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h
index de1069f..527e895 100644
--- a/include/usbdescriptors.h
+++ b/include/usbdescriptors.h
@@ -192,6 +192,15 @@
* standard usb descriptor structures
*/
+/* USB_DT_SS_ENDPOINT_COMP: SuperSpeed Endpoint Companion descriptor */
+struct usb_ss_ep_comp_descriptor {
+ u8 bLength;
+ u8 bDescriptorType; /* 0x30 */
+ u8 bMaxBurst;
+ u8 bmAttributes;
+ u16 wBytesPerInterval;
+} __attribute__ ((packed));
+
struct usb_endpoint_descriptor {
u8 bLength;
u8 bDescriptorType; /* 0x5 */
@@ -545,4 +554,196 @@ static inline void print_device_descriptor(struct usb_device_descriptor *d)
#define print_device_descriptor(d)
#endif /* DEBUG */
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * Get the endpoint's number
+ *
+ * @param epd Endpoint descriptor to be checked
+ * @return epd's number, 0 to 15.
+ */
+static inline int usb_endpoint_num(struct usb_endpoint_descriptor *epd)
+{
+ return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+}
+
+/**
+ * Get the endpoint's transfer type
+ *
+ * @param epd Endpoint to be checked
+ * @return One of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according
+ * to @epd's transfer type.
+ */
+static inline int usb_endpoint_type(struct usb_endpoint_descriptor *epd)
+{
+ return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+}
+
+/**
+ * usb_endpoint_dir_in - check if the endpoint has IN direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type IN, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_in(struct usb_endpoint_descriptor *epd)
+{
+ return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN;
+}
+
+/**
+ * usb_endpoint_dir_out - check if the endpoint has OUT direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type OUT, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_out(
+ struct usb_endpoint_descriptor *epd)
+{
+ return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
+}
+
+/**
+ * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type bulk, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_bulk(
+ struct usb_endpoint_descriptor *epd)
+{
+ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_BULK;
+}
+
+/**
+ * usb_endpoint_xfer_control - check if the endpoint has control transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type control, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_control(
+ struct usb_endpoint_descriptor *epd)
+{
+ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_CONTROL;
+}
+
+/**
+ * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type interrupt, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_int(
+ struct usb_endpoint_descriptor *epd)
+{
+ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_INT;
+}
+
+/**
+ * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type isochronous, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_isoc(
+ struct usb_endpoint_descriptor *epd)
+{
+ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_ISOC;
+}
+
+/**
+ * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_in(
+ struct usb_endpoint_descriptor *epd)
+{
+ return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_out(
+ struct usb_endpoint_descriptor *epd)
+{
+ return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_in(
+ struct usb_endpoint_descriptor *epd)
+{
+ return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_out(
+ struct usb_endpoint_descriptor *epd)
+{
+ return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_in(
+ struct usb_endpoint_descriptor *epd)
+{
+ return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_out(
+ struct usb_endpoint_descriptor *epd)
+{
+ return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_maxp - get endpoint's max packet size
+ * @epd: endpoint to be checked
+ *
+ * Returns @epd's max packet
+ */
+static inline int usb_endpoint_maxp(struct usb_endpoint_descriptor *epd)
+{
+ return le16_to_cpu(epd->wMaxPacketSize);
+}
+
#endif
--
1.7.6.5
More information about the U-Boot
mailing list