patch-2.4.20 linux-2.4.20/drivers/usb/hub.c
Next file: linux-2.4.20/drivers/usb/inode.c
Previous file: linux-2.4.20/drivers/usb/hpusbscsi.c
Back to the patch index
Back to the overall index
- Lines: 243
- Date:
Thu Nov 28 15:53:14 2002
- Orig file:
linux-2.4.19/drivers/usb/hub.c
- Orig date:
Fri Aug 2 17:39:44 2002
diff -urN linux-2.4.19/drivers/usb/hub.c linux-2.4.20/drivers/usb/hub.c
@@ -155,7 +155,7 @@
static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint)
{
struct usb_device *dev = hub->dev;
- struct usb_hub_status hubstatus;
+ struct usb_hub_status *hubstatus;
char portstr[USB_MAXCHILDREN + 1];
unsigned int pipe;
int i, maxp, ret;
@@ -258,20 +258,29 @@
dbg("port removable status: %s", portstr);
- ret = usb_get_hub_status(dev, &hubstatus);
+ hubstatus = kmalloc(sizeof *hubstatus, GFP_KERNEL);
+ if (!hubstatus) {
+ err("Unable to allocate hubstatus");
+ kfree(hub->descriptor);
+ return -1;
+ }
+ ret = usb_get_hub_status(dev, hubstatus);
if (ret < 0) {
err("Unable to get hub status (err = %d)", ret);
+ kfree(hubstatus);
kfree(hub->descriptor);
return -1;
}
- le16_to_cpus(&hubstatus.wHubStatus);
+ le16_to_cpus(&hubstatus->wHubStatus);
dbg("local power source is %s",
- (hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good");
+ (hubstatus->wHubStatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good");
dbg("%sover-current condition exists",
- (hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+ (hubstatus->wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+
+ kfree(hubstatus);
/* Start the interrupt endpoint */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
@@ -287,8 +296,11 @@
return -1;
}
- FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
- hub, endpoint->bInterval);
+ FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub,
+ /* NOTE: in 2.5 fill_int_urb() converts the encoding */
+ (dev->speed == USB_SPEED_HIGH)
+ ? 1 << (endpoint->bInterval - 1)
+ : endpoint->bInterval);
ret = usb_submit_urb(hub->urb);
if (ret) {
err("usb_submit_urb failed (%d)", ret);
@@ -666,7 +678,6 @@
struct usb_device *dev;
unsigned int delay = HUB_SHORT_RESET_TIME;
int i;
- char *portstr, *tempstr;
dbg("port %d, portstatus %x, change %x, %s",
port + 1, portstatus, portchange, portspeed (portstatus));
@@ -694,11 +705,9 @@
down(&usb_address0_sem);
- tempstr = kmalloc(1024, GFP_KERNEL);
- portstr = kmalloc(1024, GFP_KERNEL);
-
for (i = 0; i < HUB_PROBE_TRIES; i++) {
- struct usb_device *pdev, *cdev;
+ struct usb_device *pdev;
+ int len;
/* Allocate a new device struct */
dev = usb_alloc_dev(hub, hub->bus);
@@ -728,32 +737,28 @@
dev->ttport = port + 1;
}
- /* Create a readable topology string */
- cdev = dev;
+ /* Save readable and stable topology id, distinguishing
+ * devices by location for diagnostics, tools, etc. The
+ * string is a path along hub ports, from the root. Each
+ * device's id will be stable until USB is re-cabled, and
+ * hubs are often labeled with these port numbers.
+ *
+ * Initial size: ".NN" times five hubs + NUL = 16 bytes max
+ * (quite rare, since most hubs have 4-6 ports).
+ */
pdev = dev->parent;
- if (portstr && tempstr) {
- portstr[0] = 0;
- while (pdev) {
- int port;
-
- for (port = 0; port < pdev->maxchild; port++)
- if (pdev->children[port] == cdev)
- break;
-
- strcpy(tempstr, portstr);
- if (!strlen(tempstr))
- sprintf(portstr, "%d", port + 1);
- else
- sprintf(portstr, "%d/%s", port + 1, tempstr);
-
- cdev = pdev;
- pdev = pdev->parent;
- }
- info("USB new device connect on bus%d/%s, assigned device number %d",
- dev->bus->busnum, portstr, dev->devnum);
- } else
- info("USB new device connect on bus%d, assigned device number %d",
- dev->bus->busnum, dev->devnum);
+ if (pdev->devpath [0] != '0') /* parent not root? */
+ len = snprintf (dev->devpath, sizeof dev->devpath,
+ "%s.%d", pdev->devpath, port + 1);
+ /* root == "0", root port 2 == "2", port 3 that hub "2.3" */
+ else
+ len = snprintf (dev->devpath, sizeof dev->devpath,
+ "%d", port + 1);
+ if (len == sizeof dev->devpath)
+ warn ("devpath size! usb/%03d/%03d path %s",
+ dev->bus->busnum, dev->devnum, dev->devpath);
+ info("new USB device %s-%s, assigned address %d",
+ dev->bus->bus_name, dev->devpath, dev->devnum);
/* Run it through the hoops (find a driver, etc) */
if (!usb_new_device(dev))
@@ -770,10 +775,6 @@
usb_hub_port_disable(hub, port);
done:
up(&usb_address0_sem);
- if (portstr)
- kfree(portstr);
- if (tempstr)
- kfree(tempstr);
}
static void usb_hub_events(void)
@@ -782,7 +783,7 @@
struct list_head *tmp;
struct usb_device *dev;
struct usb_hub *hub;
- struct usb_hub_status hubsts;
+ struct usb_hub_status *hubsts;
u16 hubstatus;
u16 hubchange;
u16 portstatus;
@@ -872,21 +873,27 @@
} /* end for i */
/* deal with hub status changes */
- if (usb_get_hub_status(dev, &hubsts) < 0)
- err("get_hub_status failed");
- else {
- hubstatus = le16_to_cpup(&hubsts.wHubStatus);
- hubchange = le16_to_cpup(&hubsts.wHubChange);
- if (hubchange & HUB_CHANGE_LOCAL_POWER) {
- dbg("hub power change");
- usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
- }
- if (hubchange & HUB_CHANGE_OVERCURRENT) {
- dbg("hub overcurrent change");
- wait_ms(500); /* Cool down */
- usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
- usb_hub_power_on(hub);
+ hubsts = kmalloc(sizeof *hubsts, GFP_KERNEL);
+ if (!hubsts) {
+ err("couldn't allocate hubsts");
+ } else {
+ if (usb_get_hub_status(dev, hubsts) < 0)
+ err("get_hub_status failed");
+ else {
+ hubstatus = le16_to_cpup(&hubsts->wHubStatus);
+ hubchange = le16_to_cpup(&hubsts->wHubChange);
+ if (hubchange & HUB_CHANGE_LOCAL_POWER) {
+ dbg("hub power change");
+ usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
+ }
+ if (hubchange & HUB_CHANGE_OVERCURRENT) {
+ dbg("hub overcurrent change");
+ wait_ms(500); /* Cool down */
+ usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
+ usb_hub_power_on(hub);
+ }
}
+ kfree(hubsts);
}
up(&hub->khubd_sem);
} /* end while (1) */
@@ -995,7 +1002,7 @@
int usb_reset_device(struct usb_device *dev)
{
struct usb_device *parent = dev->parent;
- struct usb_device_descriptor descriptor;
+ struct usb_device_descriptor *descriptor;
int i, ret, port = -1;
if (!parent) {
@@ -1044,17 +1051,22 @@
* If nothing changed, we reprogram the configuration and then
* the alternate settings.
*/
- ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor,
- sizeof(descriptor));
+ descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
+ if (!descriptor) {
+ return -ENOMEM;
+ }
+ ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, descriptor,
+ sizeof(*descriptor));
if (ret < 0)
return ret;
- le16_to_cpus(&descriptor.bcdUSB);
- le16_to_cpus(&descriptor.idVendor);
- le16_to_cpus(&descriptor.idProduct);
- le16_to_cpus(&descriptor.bcdDevice);
+ le16_to_cpus(&descriptor->bcdUSB);
+ le16_to_cpus(&descriptor->idVendor);
+ le16_to_cpus(&descriptor->idProduct);
+ le16_to_cpus(&descriptor->bcdDevice);
- if (memcmp(&dev->descriptor, &descriptor, sizeof(descriptor))) {
+ if (memcmp(&dev->descriptor, descriptor, sizeof(*descriptor))) {
+ kfree(descriptor);
usb_destroy_configuration(dev);
ret = usb_get_device_descriptor(dev);
@@ -1084,6 +1096,8 @@
return 1;
}
+ kfree(descriptor);
+
ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
if (ret < 0) {
err("failed to set active configuration (error=%d)", ret);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)