patch-2.3.39 linux/drivers/usb/usb.c
Next file: linux/drivers/usb/usb.h
Previous file: linux/drivers/usb/usb-debug.c
Back to the patch index
Back to the overall index
- Lines: 221
- Date:
Mon Jan 10 16:05:19 2000
- Orig file:
v2.3.38/linux/drivers/usb/usb.c
- Orig date:
Fri Jan 7 19:13:22 2000
diff -u --recursive --new-file v2.3.38/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
@@ -39,8 +39,8 @@
/*
* We have a per-interface "registered driver" list.
*/
-static LIST_HEAD(usb_driver_list);
-static LIST_HEAD(usb_bus_list);
+LIST_HEAD(usb_driver_list);
+LIST_HEAD(usb_bus_list);
static struct usb_busmap busmap;
@@ -240,6 +240,7 @@
bus->bandwidth_isoc_reqs = 0;
INIT_LIST_HEAD(&bus->bus_list);
+ INIT_LIST_HEAD(&bus->inodes);
return bus;
}
@@ -268,6 +269,8 @@
/* Add it to the list of buses */
list_add(&bus->bus_list, &usb_bus_list);
+ usbdevfs_add_bus(bus);
+
info("new USB bus registered, assigned bus number %d", bus->busnum);
}
@@ -284,6 +287,8 @@
proc_usb_remove_bus(bus);
+ usbdevfs_remove_bus(bus);
+
clear_bit(bus->busnum, busmap.busmap);
}
@@ -443,6 +448,8 @@
dev->bus = bus;
dev->parent = parent;
atomic_set(&dev->refcnt, 1);
+ INIT_LIST_HEAD(&dev->inodes);
+ INIT_LIST_HEAD(&dev->filelist);
dev->bus->op->allocate(dev);
@@ -1154,11 +1161,6 @@
kfree(cf->interface);
}
kfree(dev->config);
-
- if (dev->string) {
- kfree(dev->string);
- dev->string = 0;
- }
}
void usb_init_root_hub(struct usb_device *dev)
@@ -1230,6 +1232,7 @@
/* remove /proc/bus/usb entry */
proc_usb_remove_device(dev);
+ usbdevfs_remove_device(dev);
/* Free up the device itself, including its device number */
if (dev->devnum > 0)
@@ -1491,6 +1494,11 @@
return -1;
}
+ if (dev->descriptor.bNumConfigurations < 1) {
+ warn("not enough configurations");
+ return -1;
+ }
+
dev->config = (struct usb_config_descriptor *)
kmalloc(dev->descriptor.bNumConfigurations *
sizeof(struct usb_config_descriptor), GFP_KERNEL);
@@ -1547,54 +1555,45 @@
return result;
}
-char *usb_string(struct usb_device *dev, int index)
+int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
{
- int i, len, ret;
- char *ptr;
- union {
- unsigned char buffer[256];
- struct usb_string_descriptor desc;
- } u;
-
- if (index <= 0)
- return 0;
- if (dev->string)
- kfree (dev->string);
-
- if (dev->string_langid == 0) {
- /* read string descriptor 0 */
- ret = usb_get_string(dev, 0, 0, u.buffer, 4);
- if (ret >= 0 && u.desc.bLength >= 4)
- dev->string_langid = le16_to_cpup(&u.desc.wData[0]);
- else
- err("error getting string");
- dev->string_langid |= 0x10000; /* so it's non-zero */
- }
-
- if (usb_get_string(dev, dev->string_langid, index, u.buffer, 4) < 0 ||
- ((ret = usb_get_string(dev, dev->string_langid, index, u.buffer,
- u.desc.bLength)) < 0)) {
- err("error retrieving string");
- return NULL;
- }
+ unsigned char *tbuf;
+ int err;
+ unsigned int u, idx;
- if (ret > 0) ret /= 2; /* going from 16-bit chars to 8-bit */
- len = u.desc.bLength / 2; /* includes terminating null */
- /* after removing bLength & bDescType */
- if (ret < len) len = ret; /* use min of (ret, len) */
-
- ptr = kmalloc(len, GFP_KERNEL);
- if (!ptr) {
- err("couldn't allocate memory for string");
- return NULL;
+ if (size <= 0 || !buf)
+ return -EINVAL;
+ buf[0] = 0;
+ tbuf = kmalloc(256, GFP_KERNEL);
+ if (!tbuf)
+ return -ENOMEM;
+ /*
+ * is this two step process necessary? can't we just
+ * ask for a maximum length string and then take the length
+ * that was returned?
+ */
+ err = usb_get_string(dev, dev->string_langid, index, tbuf, 4);
+ if (err < 0)
+ goto errout;
+ err = usb_get_string(dev, dev->string_langid, index, tbuf, tbuf[0]);
+ if (err < 0)
+ goto errout;
+ size--;
+ for (idx = 0, u = 2; u < tbuf[0]; u += 2) {
+ if (idx >= size)
+ break;
+ if (tbuf[u+1]) {
+ buf[idx++] = '?'; /* non ASCII character */
+ continue;
+ }
+ buf[idx++] = tbuf[u];
}
+ buf[idx] = 0;
+ err = idx;
- for (i = 0; i < len - 1; ++i)
- ptr[i] = le16_to_cpup(&u.desc.wData[i]);
- ptr[i] = 0;
-
- dev->string = ptr;
- return ptr;
+ errout:
+ kfree(tbuf);
+ return err;
}
/*
@@ -1606,10 +1605,10 @@
*/
int usb_new_device(struct usb_device *dev)
{
+ unsigned char *buf;
int addr, err;
- info("USB new device connect, assigned device number %d",
- dev->devnum);
+ info("USB new device connect, assigned device number %d", dev->devnum);
dev->maxpacketsize = 0; /* Default to 8 byte max packet size */
dev->epmaxpacketin [0] = 8;
@@ -1657,8 +1656,7 @@
return 1;
}
- err=usb_get_configuration(dev);
-
+ err = usb_get_configuration(dev);
if (err < 0) {
err("unable to get configuration (error=%d)", err);
clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
@@ -1674,6 +1672,21 @@
err("failed to set default configuration");
return -1;
}
+ /* get langid for strings */
+ buf = kmalloc(256, GFP_KERNEL);
+ if (!buf) {
+ err("out of memory\n");
+ } else {
+ err = usb_get_string(dev, 0, 0, buf, 4);
+ if (err < 0) {
+ err("error getting string descriptor 0 (error=%d)\n", err);
+ } else if (buf[0] < 4) {
+ err("string descriptpr 0 too short\n");
+ } else
+ dev->string_langid = buf[2] | (buf[3]<< 8);
+ kfree(buf);
+ info("USB device number %d default language ID 0x%x", dev->devnum, dev->string_langid);
+ }
usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
usb_show_string(dev, "Product", dev->descriptor.iProduct);
@@ -1681,6 +1694,7 @@
/* now that the basic setup is over, add a /proc/bus/usb entry */
proc_usb_add_device(dev);
+ usbdevfs_add_device(dev);
/* find drivers willing to handle this device */
usb_find_drivers(dev);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)