mirror of
https://xff.cz/git/u-boot/
synced 2025-09-01 08:42:12 +02:00
Merge branch 'master' of git://git.denx.de/u-boot-usb
This commit is contained in:
12
common/usb.c
12
common/usb.c
@@ -805,6 +805,18 @@ struct usb_device *usb_alloc_new_device(void *controller)
|
||||
return &usb_dev[dev_index - 1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the newly created device node.
|
||||
* Called in error cases where configuring a newly attached
|
||||
* device fails for some reason.
|
||||
*/
|
||||
void usb_free_device(void)
|
||||
{
|
||||
dev_index--;
|
||||
USB_PRINTF("Freeing device node: %d\n", dev_index);
|
||||
memset(&usb_dev[dev_index], 0, sizeof(struct usb_device));
|
||||
usb_dev[dev_index].devnum = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* By the time we get here, the device has gotten a new device ID
|
||||
|
@@ -259,6 +259,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
|
||||
/* Run it through the hoops (find a driver, etc) */
|
||||
if (usb_new_device(usb)) {
|
||||
/* Woops, disable the port */
|
||||
usb_free_device();
|
||||
dev->children[port] = NULL;
|
||||
USB_HUB_PRINTF("hub: disabling port %d\n", port + 1);
|
||||
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
|
||||
}
|
||||
@@ -396,14 +398,37 @@ static int usb_hub_configure(struct usb_device *dev)
|
||||
for (i = 0; i < dev->maxchild; i++) {
|
||||
ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
|
||||
unsigned short portstatus, portchange;
|
||||
int ret;
|
||||
ulong start = get_timer(0);
|
||||
|
||||
if (usb_get_port_status(dev, i + 1, portsts) < 0) {
|
||||
USB_HUB_PRINTF("get_port_status failed\n");
|
||||
/*
|
||||
* Wait for (whichever finishes first)
|
||||
* - A maximum of 10 seconds
|
||||
* This is a purely observational value driven by connecting
|
||||
* a few broken pen drives and taking the max * 1.5 approach
|
||||
* - connection_change and connection state to report same
|
||||
* state
|
||||
*/
|
||||
do {
|
||||
ret = usb_get_port_status(dev, i + 1, portsts);
|
||||
if (ret < 0) {
|
||||
USB_HUB_PRINTF("get_port_status failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
portstatus = le16_to_cpu(portsts->wPortStatus);
|
||||
portchange = le16_to_cpu(portsts->wPortChange);
|
||||
|
||||
if ((portchange & USB_PORT_STAT_C_CONNECTION) ==
|
||||
(portstatus & USB_PORT_STAT_CONNECTION))
|
||||
break;
|
||||
|
||||
mdelay(100);
|
||||
} while (get_timer(start) < CONFIG_SYS_HZ * 10);
|
||||
|
||||
if (ret < 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
portstatus = le16_to_cpu(portsts->wPortStatus);
|
||||
portchange = le16_to_cpu(portsts->wPortChange);
|
||||
USB_HUB_PRINTF("Port %d Status %X Change %X\n",
|
||||
i + 1, portstatus, portchange);
|
||||
|
||||
|
@@ -970,6 +970,16 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss)
|
||||
return 0;
|
||||
}
|
||||
usb_request_sense(srb, ss);
|
||||
/*
|
||||
* Check the Key Code Qualifier, if it matches
|
||||
* "Not Ready - medium not present"
|
||||
* (the sense Key equals 0x2 and the ASC is 0x3a)
|
||||
* return immediately as the medium being absent won't change
|
||||
* unless there is a user action.
|
||||
*/
|
||||
if ((srb->sense_buf[2] == 0x02) &&
|
||||
(srb->sense_buf[12] == 0x3a))
|
||||
return -1;
|
||||
mdelay(100);
|
||||
} while (retries--);
|
||||
|
||||
|
Reference in New Issue
Block a user