mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 21:51:31 +00:00
Merge git://git.denx.de/u-boot-usb
This commit is contained in:
commit
d83c25c318
6 changed files with 115 additions and 120 deletions
98
common/usb.c
98
common/usb.c
|
@ -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,
|
int usb_get_configuration_len(struct usb_device *dev, int cfgno)
|
||||||
unsigned char *buffer, int cfgno)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
unsigned int length;
|
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 9);
|
||||||
struct usb_config_descriptor *config;
|
struct usb_config_descriptor *config;
|
||||||
|
|
||||||
config = (struct usb_config_descriptor *)&buffer[0];
|
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);
|
"(expected %i, got %i)\n", 9, result);
|
||||||
return -EIO;
|
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",
|
* gets configuration cfgno and store it in the buffer
|
||||||
__func__, length);
|
*/
|
||||||
return -EIO;
|
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);
|
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length);
|
||||||
debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, length);
|
debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result,
|
||||||
config->wTotalLength = length; /* validated, with CPU byte order */
|
le16_to_cpu(config->wTotalLength));
|
||||||
|
config->wTotalLength = result; /* validated, with CPU byte order */
|
||||||
|
|
||||||
return result;
|
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)
|
int usb_select_config(struct usb_device *dev)
|
||||||
{
|
{
|
||||||
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
|
unsigned char *tmpbuf = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
|
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);
|
le16_to_cpus(&dev->descriptor.bcdDevice);
|
||||||
|
|
||||||
/* only support for one config for now */
|
/* 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) {
|
if (err < 0) {
|
||||||
printf("usb_new_device: Cannot read configuration, " \
|
printf("usb_new_device: Cannot read configuration, " \
|
||||||
"skipping device %04x:%04x\n",
|
"skipping device %04x:%04x\n",
|
||||||
dev->descriptor.idVendor, dev->descriptor.idProduct);
|
dev->descriptor.idVendor, dev->descriptor.idProduct);
|
||||||
|
free(tmpbuf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
usb_parse_config(dev, tmpbuf, 0);
|
usb_parse_config(dev, tmpbuf, 0);
|
||||||
|
free(tmpbuf);
|
||||||
usb_set_maxpacket(dev);
|
usb_set_maxpacket(dev);
|
||||||
/*
|
/*
|
||||||
* we set the default configuration here
|
* we set the default configuration here
|
||||||
|
@ -1200,4 +1214,60 @@ bool usb_device_has_child_on_port(struct usb_device *parent, int port)
|
||||||
#endif
|
#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 */
|
/* EOF */
|
||||||
|
|
|
@ -823,12 +823,13 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev,
|
||||||
(*pid << DWC2_HCTSIZ_PID_OFFSET),
|
(*pid << DWC2_HCTSIZ_PID_OFFSET),
|
||||||
&hc_regs->hctsiz);
|
&hc_regs->hctsiz);
|
||||||
|
|
||||||
if (!in) {
|
if (!in && xfer_len) {
|
||||||
memcpy(priv->aligned_buffer, (char *)buffer + done, len);
|
memcpy(priv->aligned_buffer, (char *)buffer + done,
|
||||||
|
xfer_len);
|
||||||
|
|
||||||
flush_dcache_range((unsigned long)priv->aligned_buffer,
|
flush_dcache_range((unsigned long)priv->aligned_buffer,
|
||||||
(unsigned long)((void *)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),
|
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,
|
static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
|
||||||
struct QH *qh)
|
struct QH *qh)
|
||||||
{
|
{
|
||||||
struct usb_device *ttdev;
|
uint8_t portnr = 0;
|
||||||
int parent_devnum;
|
uint8_t hubaddr = 0;
|
||||||
|
|
||||||
if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL)
|
if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
usb_find_usb2_hub_address_port(udev, &hubaddr, &portnr);
|
||||||
* 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;
|
qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(portnr) |
|
||||||
parent = udev->dev;
|
QH_ENDPT2_HUBADDR(hubaddr));
|
||||||
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
|
|
||||||
|
|
||||||
qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
|
|
||||||
QH_ENDPT2_HUBADDR(parent_devnum));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -2092,9 +2092,13 @@ int musb_urb_enqueue(
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (tt_needed(musb, urb->dev)) {
|
if (tt_needed(musb, urb->dev)) {
|
||||||
u16 hub_port = find_tt(urb->dev);
|
uint8_t portnr = 0;
|
||||||
qh->h_addr_reg = (u8) (hub_port >> 8);
|
uint8_t hubaddr = 0;
|
||||||
qh->h_port_reg = (u8) (hub_port & 0xff);
|
usb_find_usb2_hub_address_port(urb->dev,
|
||||||
|
&hubaddr,
|
||||||
|
&portnr);
|
||||||
|
qh->h_addr_reg = hubaddr;
|
||||||
|
qh->h_port_reg = portnr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,38 +68,6 @@ static inline int usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DM_USB
|
#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)
|
static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev)
|
||||||
{
|
{
|
||||||
struct udevice *parent = udev->dev->parent;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
#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)
|
static inline struct usb_device *usb_dev_get_parent(struct usb_device *dev)
|
||||||
{
|
{
|
||||||
return dev->parent;
|
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);
|
void *buffer, int transfer_len, int interval);
|
||||||
int usb_disable_asynch(int disable);
|
int usb_disable_asynch(int disable);
|
||||||
int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
|
int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
|
||||||
int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
|
int usb_get_configuration_no(struct usb_device *dev, int cfgno,
|
||||||
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,
|
int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
|
||||||
unsigned char id, void *buf, int size);
|
unsigned char id, void *buf, int size);
|
||||||
int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
|
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);
|
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
|
* usb_alloc_new_device() - Allocate a new device
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue