Merge git://git.denx.de/u-boot-usb

master
Tom Rini 9 years ago
commit d83c25c318
  1. 98
      common/usb.c
  2. 7
      drivers/usb/host/dwc2.c
  3. 50
      drivers/usb/host/ehci-hcd.c
  4. 10
      drivers/usb/musb-new/musb_host.c
  5. 53
      drivers/usb/musb-new/usb-compat.h
  6. 17
      include/usb.h

@ -566,13 +566,12 @@ static int usb_get_descriptor(struct usb_device *dev, unsigned char type,
}
/**********************************************************************
* gets configuration cfgno and store it in the buffer
* gets len of configuration cfgno
*/
int usb_get_configuration_no(struct usb_device *dev,
unsigned char *buffer, int cfgno)
int usb_get_configuration_len(struct usb_device *dev, int cfgno)
{
int result;
unsigned int length;
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 9);
struct usb_config_descriptor *config;
config = (struct usb_config_descriptor *)&buffer[0];
@ -586,17 +585,23 @@ int usb_get_configuration_no(struct usb_device *dev,
"(expected %i, got %i)\n", 9, result);
return -EIO;
}
length = le16_to_cpu(config->wTotalLength);
return le16_to_cpu(config->wTotalLength);
}
if (length > USB_BUFSIZ) {
printf("%s: failed to get descriptor - too long: %d\n",
__func__, length);
return -EIO;
}
/**********************************************************************
* gets configuration cfgno and store it in the buffer
*/
int usb_get_configuration_no(struct usb_device *dev, int cfgno,
unsigned char *buffer, int length)
{
int result;
struct usb_config_descriptor *config;
config = (struct usb_config_descriptor *)&buffer[0];
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length);
debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, length);
config->wTotalLength = length; /* validated, with CPU byte order */
debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result,
le16_to_cpu(config->wTotalLength));
config->wTotalLength = result; /* validated, with CPU byte order */
return result;
}
@ -1070,7 +1075,7 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
int usb_select_config(struct usb_device *dev)
{
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
unsigned char *tmpbuf = 0;
int err;
err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
@ -1084,14 +1089,23 @@ int usb_select_config(struct usb_device *dev)
le16_to_cpus(&dev->descriptor.bcdDevice);
/* only support for one config for now */
err = usb_get_configuration_no(dev, tmpbuf, 0);
err = usb_get_configuration_len(dev, 0);
if (err >= 0) {
tmpbuf = (unsigned char *)malloc_cache_aligned(err);
if (!tmpbuf)
err = -ENOMEM;
else
err = usb_get_configuration_no(dev, 0, tmpbuf, err);
}
if (err < 0) {
printf("usb_new_device: Cannot read configuration, " \
"skipping device %04x:%04x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct);
free(tmpbuf);
return err;
}
usb_parse_config(dev, tmpbuf, 0);
free(tmpbuf);
usb_set_maxpacket(dev);
/*
* we set the default configuration here
@ -1200,4 +1214,60 @@ bool usb_device_has_child_on_port(struct usb_device *parent, int port)
#endif
}
#ifdef CONFIG_DM_USB
void usb_find_usb2_hub_address_port(struct usb_device *udev,
uint8_t *hub_address, uint8_t *hub_port)
{
struct udevice *parent;
struct usb_device *uparent, *ttdev;
/*
* When called from usb-uclass.c: usb_scan_device() udev->dev points
* to the parent udevice, not the actual udevice belonging to the
* udev as the device is not instantiated yet. So when searching
* for the first usb-2 parent start with udev->dev not
* udev->dev->parent .
*/
ttdev = udev;
parent = udev->dev;
uparent = dev_get_parent_priv(parent);
while (uparent->speed != USB_SPEED_HIGH) {
struct udevice *dev = parent;
if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
printf("Error: Cannot find high speed parent of usb-1 device\n");
*hub_address = 0;
*hub_port = 0;
return;
}
ttdev = dev_get_parent_priv(dev);
parent = dev->parent;
uparent = dev_get_parent_priv(parent);
}
*hub_address = uparent->devnum;
*hub_port = ttdev->portnr;
}
#else
void usb_find_usb2_hub_address_port(struct usb_device *udev,
uint8_t *hub_address, uint8_t *hub_port)
{
/* Find out the nearest parent which is high speed */
while (udev->parent->parent != NULL)
if (udev->parent->speed != USB_SPEED_HIGH) {
udev = udev->parent;
} else {
*hub_address = udev->parent->devnum;
*hub_port = udev->portnr;
return;
}
printf("Error: Cannot find high speed parent of usb-1 device\n");
*hub_address = 0;
*hub_port = 0;
}
#endif
/* EOF */

@ -823,12 +823,13 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev,
(*pid << DWC2_HCTSIZ_PID_OFFSET),
&hc_regs->hctsiz);
if (!in) {
memcpy(priv->aligned_buffer, (char *)buffer + done, len);
if (!in && xfer_len) {
memcpy(priv->aligned_buffer, (char *)buffer + done,
xfer_len);
flush_dcache_range((unsigned long)priv->aligned_buffer,
(unsigned long)((void *)priv->aligned_buffer +
roundup(len, ARCH_DMA_MINALIGN)));
roundup(xfer_len, ARCH_DMA_MINALIGN)));
}
writel(phys_to_bus((unsigned long)priv->aligned_buffer),

@ -279,56 +279,16 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed)
static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
struct QH *qh)
{
struct usb_device *ttdev;
int parent_devnum;
uint8_t portnr = 0;
uint8_t hubaddr = 0;
if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL)
return;
/*
* For full / low speed devices we need to get the devnum and portnr of
* the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
* in the tree before that one!
*/
#ifdef CONFIG_DM_USB
/*
* When called from usb-uclass.c: usb_scan_device() udev->dev points
* to the parent udevice, not the actual udevice belonging to the
* udev as the device is not instantiated yet. So when searching
* for the first usb-2 parent start with udev->dev not
* udev->dev->parent .
*/
struct udevice *parent;
struct usb_device *uparent;
ttdev = udev;
parent = udev->dev;
uparent = dev_get_parent_priv(parent);
while (uparent->speed != USB_SPEED_HIGH) {
struct udevice *dev = parent;
if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
printf("ehci: Error cannot find high-speed parent of usb-1 device\n");
return;
}
ttdev = dev_get_parent_priv(dev);
parent = dev->parent;
uparent = dev_get_parent_priv(parent);
}
parent_devnum = uparent->devnum;
#else
ttdev = udev;
while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
ttdev = ttdev->parent;
if (!ttdev->parent)
return;
parent_devnum = ttdev->parent->devnum;
#endif
usb_find_usb2_hub_address_port(udev, &hubaddr, &portnr);
qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
QH_ENDPT2_HUBADDR(parent_devnum));
qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(portnr) |
QH_ENDPT2_HUBADDR(hubaddr));
}
static int

@ -2092,9 +2092,13 @@ int musb_urb_enqueue(
}
#else
if (tt_needed(musb, urb->dev)) {
u16 hub_port = find_tt(urb->dev);
qh->h_addr_reg = (u8) (hub_port >> 8);
qh->h_port_reg = (u8) (hub_port & 0xff);
uint8_t portnr = 0;
uint8_t hubaddr = 0;
usb_find_usb2_hub_address_port(urb->dev,
&hubaddr,
&portnr);
qh->h_addr_reg = hubaddr;
qh->h_port_reg = portnr;
}
#endif
}

@ -68,38 +68,6 @@ static inline int usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd,
}
#ifdef CONFIG_DM_USB
static inline u16 find_tt(struct usb_device *udev)
{
struct udevice *parent;
struct usb_device *uparent, *ttdev;
/*
* When called from usb-uclass.c: usb_scan_device() udev->dev points
* to the parent udevice, not the actual udevice belonging to the
* udev as the device is not instantiated yet. So when searching
* for the first usb-2 parent start with udev->dev not
* udev->dev->parent .
*/
ttdev = udev;
parent = udev->dev;
uparent = dev_get_parent_priv(parent);
while (uparent->speed != USB_SPEED_HIGH) {
struct udevice *dev = parent;
if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
printf("musb: Error cannot find high speed parent of usb-1 device\n");
return 0;
}
ttdev = dev_get_parent_priv(dev);
parent = dev->parent;
uparent = dev_get_parent_priv(parent);
}
return (uparent->devnum << 8) | (ttdev->portnr - 1);
}
static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev)
{
struct udevice *parent = udev->dev->parent;
@ -129,27 +97,6 @@ static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev)
return NULL;
}
#else
static inline u16 find_tt(struct usb_device *dev)
{
u8 chid;
u8 hub;
/* Find out the nearest parent which is high speed */
while (dev->parent->parent != NULL)
if (dev->parent->speed != USB_SPEED_HIGH)
dev = dev->parent;
else
break;
/* determine the port address at that hub */
hub = dev->parent->devnum;
for (chid = 0; chid < USB_MAXCHILDREN; chid++)
if (dev->parent->children[chid] == dev)
break;
return (hub << 8) | chid;
}
static inline struct usb_device *usb_dev_get_parent(struct usb_device *dev)
{
return dev->parent;

@ -266,8 +266,9 @@ int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int transfer_len, int interval);
int usb_disable_asynch(int disable);
int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
int cfgno);
int usb_get_configuration_no(struct usb_device *dev, int cfgno,
unsigned char *buffer, int length);
int usb_get_configuration_len(struct usb_device *dev, int cfgno);
int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
unsigned char id, void *buf, int size);
int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
@ -874,6 +875,18 @@ int legacy_hub_port_reset(struct usb_device *dev, int port,
int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat);
/*
* usb_find_usb2_hub_address_port() - Get hub address and port for TT setting
*
* Searches for the first HS hub above the given device. If a
* HS hub is found, the hub address and the port the device is
* connected to is return, as required for SPLIT transactions
*
* @param: udev full speed or low speed device
*/
void usb_find_usb2_hub_address_port(struct usb_device *udev,
uint8_t *hub_address, uint8_t *hub_port);
/**
* usb_alloc_new_device() - Allocate a new device
*

Loading…
Cancel
Save