patch-2.3.13 linux/drivers/usb/usb.c

Next file: linux/drivers/usb/usb.h
Previous file: linux/drivers/usb/uhci.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.12/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
@@ -51,40 +51,49 @@
 
 int usb_register(struct usb_driver *new_driver)
 {
-	struct list_head *tmp = usb_bus_list.next;
+	struct list_head *tmp;
+
+	printk("usbcore: Registering new driver %s\n", new_driver->name);
+
 	/* Add it to the list of known drivers */
 	list_add(&new_driver->driver_list, &usb_driver_list);
 
 	/*
-         * We go through all existing devices, and see if any of them would
-         * be acceptable to the new driver.. This is done using a depth-first
-         * search for devices without a registered driver already, then 
+	 * We go through all existing devices, and see if any of them would
+	 * be acceptable to the new driver.. This is done using a depth-first
+	 * search for devices without a registered driver already, then 
 	 * running 'probe' with each of the drivers registered on every one 
 	 * of these.
 	 */
-        while (tmp!= &usb_bus_list) {
-		struct usb_bus * bus = list_entry(tmp,struct
-			usb_bus,bus_list);
-	        tmp=tmp->next;  
+	tmp = usb_bus_list.next;
+	while (tmp != &usb_bus_list) {
+		struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list);
+
+	        tmp = tmp->next;
 		usb_check_support(bus->root_hub);
-        }
+	}
 	return 0;
 }
 
 void usb_deregister(struct usb_driver *driver)
 {
-      struct list_head *tmp = usb_bus_list.next;
-      /*first we remove the driver, to be sure it doesn't get used by
-       *another thread while we are stepping through removing entries
-       */
+	struct list_head *tmp;
+
+	printk("usbcore: Deregistering driver %s\n", driver->name);
+
+	/*
+	 * first we remove the driver, to be sure it doesn't get used by
+	 * another thread while we are stepping through removing entries
+	 */
 	list_del(&driver->driver_list);
-      printk("usbcore: deregistering driver\n");
-      while (tmp!= &usb_bus_list) {
-              struct usb_bus * bus = list_entry(tmp,struct 
-            		usb_bus,bus_list);
-              tmp=tmp->next;
-              usb_driver_purge(driver,bus->root_hub);
-      }
+
+	tmp = usb_bus_list.next;
+	while (tmp != &usb_bus_list) {
+		struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list);
+
+		tmp = tmp->next;
+		usb_driver_purge(driver, bus->root_hub);
+	}
 }
 
 /* This function is part of a depth-first search down the device tree,
@@ -93,45 +102,82 @@
 void usb_driver_purge(struct usb_driver *driver,struct usb_device *dev)
 {
        int i;
-       if (dev==NULL){
-               printk("null device being passed in!!!\n");
-               return;
-       }
-       for (i=0;i<USB_MAXCHILDREN;i++)
-               if (dev->children[i]!=NULL)
-                       usb_driver_purge(driver,dev->children[i]);
-       /*now we check this device*/
-       if(dev->driver==driver) {
-               /*
-                * Note: this is not the correct way to do this, this
-                * uninitializes and reinitializes EVERY driver
-                */
-               printk("disconnecting driverless device\n");
-               dev->driver->disconnect(dev);
-               dev->driver=NULL;
-               /* This will go back through the list looking for a driver
-                * that can handle the device
-		*/
-               usb_device_descriptor(dev);
-      }
+
+	if (!dev) {
+		printk(KERN_ERR "usbcore: null device being purged!!!\n");
+		return;
+	}
+
+	for (i=0; i<USB_MAXCHILDREN; i++)
+		if (dev->children[i])
+			usb_driver_purge(driver, dev->children[i]);
+
+	/* now we check this device */
+	if (dev->driver == driver) {
+		/*
+		 * Note: this is not the correct way to do this, this
+		 * uninitializes and reinitializes EVERY driver
+		 */
+		printk(KERN_INFO "disconnect driverless device %d\n",
+			dev->devnum);
+		dev->driver->disconnect(dev);
+		dev->driver = NULL;
+
+		/*
+		 * This will go back through the list looking for a driver
+		 * that can handle the device
+		 */
+		usb_find_driver(dev);
+	}
 }
 
 /*
  * New functions for (de)registering a controller
  */
+struct usb_bus *usb_alloc_bus(struct usb_operations *op)
+{
+	struct usb_bus *bus;
+
+	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		return NULL;
+
+	memset(&bus->devmap, 0, sizeof(struct usb_devmap));
+
+	bus->op = op;
+	bus->root_hub = NULL;
+	bus->hcpriv = NULL;
+
+	INIT_LIST_HEAD(&bus->bus_list);
+
+	return bus;
+}
+
+void usb_free_bus(struct usb_bus *bus)
+{
+	if (!bus)
+		return;
+
+	if (bus->bus_list.next != &bus->bus_list)
+		printk(KERN_ERR "usbcore: freeing non-empty bus\n");
+
+	kfree(bus);
+}
+
 void usb_register_bus(struct usb_bus *new_bus)
 {
-      /* Add it to the list of buses */
-      list_add(&new_bus->bus_list, &usb_bus_list);
-      printk("New bus registered\n");
+	/* Add it to the list of buses */
+	list_add(&new_bus->bus_list, &usb_bus_list);
+	printk("New USB bus registered\n");
 }
 
 void usb_deregister_bus(struct usb_bus *bus)
 {
-        /* NOTE: make sure that all the devices are removed by the
-         * controller code, as well as having it call this when cleaning
+	/*
+	 * NOTE: make sure that all the devices are removed by the
+	 * controller code, as well as having it call this when cleaning
 	 * itself up
-         */
+	 */
 	list_del(&bus->bus_list);
 }
 
@@ -141,18 +187,20 @@
  */
 void usb_check_support(struct usb_device *dev)
 {
-      int i;
-      if (dev==NULL)
-      {
-              printk("null device being passed in!!!\n");
-              return;
-      }
-      for (i=0;i<USB_MAXCHILDREN;i++)
-              if (dev->children[i]!=NULL)
-                      usb_check_support(dev->children[i]);
-      /*now we check this device*/
-      if (dev->driver==NULL)
-	      usb_device_descriptor(dev);
+	int i;
+
+	if (!dev) {
+		printk(KERN_ERR "usbcore: null device being checked!!!\n");
+		return;
+	}
+
+	for (i=0; i<USB_MAXCHILDREN; i++)
+		if (dev->children[i])
+			usb_check_support(dev->children[i]);
+
+	/* now we check this device */
+	if (!dev->driver && dev->devnum > 0)
+		usb_find_driver(dev);
 }
 /*
  * This entrypoint gets called for each new device.
@@ -161,7 +209,7 @@
  * looking for one that will accept this device as
  * his..
  */
-int usb_device_descriptor(struct usb_device *dev)
+int usb_find_driver(struct usb_device *dev)
 {
 	struct list_head *tmp = usb_driver_list.next;
 
@@ -174,6 +222,7 @@
 		dev->driver = driver;
 		return 1;
 	}
+
 	/*
 	 * Ok, no driver accepted the device, so show the info
 	 * for debugging..
@@ -243,8 +292,7 @@
 	if (len <= 0)
 		return -1;
 
-	if (n_len < 2 || n_len > len)
-	{
+	if (n_len < 2 || n_len > len) {
 		int i;
 		printk("Short descriptor. (%d, %d):\n", len, n_len);
 		for (i = 0; i < len; ++i)
@@ -272,8 +320,7 @@
 	parsed += ptr[parsed];
 	len -= parsed;
 
-	while((i = usb_check_descriptor(ptr+parsed, len, 0x25))>=0)
-	{
+	while((i = usb_check_descriptor(ptr+parsed, len, 0x25)) >= 0) {
 		usb_audio_endpoint(endpoint, ptr+parsed+i);
 		len -= ptr[parsed+i];
 		parsed += ptr[parsed+i];
@@ -295,23 +342,20 @@
 	len -= ptr[parsed];
 	parsed += ptr[parsed];
 
-	while((i=usb_check_descriptor(ptr+parsed, len, 0x24))>=0)
-	{
+	while((i=usb_check_descriptor(ptr+parsed, len, 0x24)) >= 0) {
 		usb_audio_interface(interface, ptr+parsed+i);
 		len -= ptr[parsed+i];
 		parsed += ptr[parsed+i];
 	}
 	
-	if (interface->bNumEndpoints > USB_MAXENDPOINTS)
-	{
+	if (interface->bNumEndpoints > USB_MAXENDPOINTS) {
 		printk(KERN_WARNING "usb: too many endpoints.\n");
 		return -1;
 	}
 
 	interface->endpoint = (struct usb_endpoint_descriptor *)
 		kmalloc(interface->bNumEndpoints * sizeof(struct usb_endpoint_descriptor), GFP_KERNEL);
-	if(interface->endpoint==NULL)
-	{
+	if (!interface->endpoint) {
 		printk(KERN_WARNING "usb: out of memory.\n");
 		return -1;	
 	}
@@ -323,7 +367,8 @@
 //			len -= 9;
 //		}
 		retval = usb_parse_endpoint(dev, interface->endpoint + i, ptr + parsed, len);
-		if (retval < 0) return retval;
+		if (retval < 0)
+			return retval;
 		parsed += retval;
 		len -= retval;
 	}
@@ -345,13 +390,7 @@
 	parsed += *ptr;
 	le16_to_cpus(&config->wTotalLength);
 
-	if (config->MaxPower == 200) {
-		printk("bNumInterfaces kludge\n");
-		config->bNumInterfaces += 3;
-	}
-
-	if (config->bNumInterfaces > USB_MAXINTERFACES)
-	{
+	if (config->bNumInterfaces > USB_MAXINTERFACES) {
 		printk(KERN_WARNING "usb: too many interfaces.\n");
 		return -1;
 
@@ -359,17 +398,16 @@
 
 	config->altsetting = (struct usb_alternate_setting *)
 	        kmalloc(USB_MAXALTSETTING * sizeof(struct usb_alternate_setting), GFP_KERNEL);
-	if (config->altsetting == NULL) {
-	  printk(KERN_WARNING "usb: out of memory.\n");
-	  return -1;
+	if (!config->altsetting) {
+		printk(KERN_WARNING "usb: out of memory.\n");
+		return -1;
 	}
 	config->act_altsetting = 0;
 	config->num_altsetting = 1;
 
 	config->altsetting->interface = (struct usb_interface_descriptor *)
 		kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL);
-	if(config->altsetting->interface==NULL)
-	{
+	if (!config->altsetting->interface) {
 		printk(KERN_WARNING "usb: out of memory.\n");
 		return -1;	
 	}
@@ -389,26 +427,26 @@
 
 	// now parse for additional alternate settings
 	for (j = 1; j < USB_MAXALTSETTING; j++) {
-	  retval = usb_expect_descriptor(ptr + parsed, len, USB_DT_INTERFACE, 9);
-	  if (retval) 
-	    break;
-	  config->num_altsetting++;
-	  as = config->altsetting + j;
-	  as->interface = (struct usb_interface_descriptor *)
-	    kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL);
-	  if (as->interface == NULL) {
-	    printk(KERN_WARNING "usb: out of memory.\n");
-	    return -1;
-	  }
-	  memset(as->interface, 0, config->bNumInterfaces * sizeof(struct usb_interface_descriptor));
-	  for (i = 0; i < config->bNumInterfaces; i++) {
-	    retval = usb_parse_interface(dev, as->interface + i, 
+		retval = usb_expect_descriptor(ptr + parsed, len, USB_DT_INTERFACE, 9);
+		if (retval) 
+			break;
+		config->num_altsetting++;
+		as = config->altsetting + j;
+		as->interface = (struct usb_interface_descriptor *)
+			kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL);
+		if (!as->interface) {
+			printk(KERN_WARNING "usb: out of memory.\n");
+			return -1;
+		}
+		memset(as->interface, 0, config->bNumInterfaces * sizeof(struct usb_interface_descriptor));
+		for (i = 0; i < config->bNumInterfaces; i++) {
+			retval = usb_parse_interface(dev, as->interface + i, 
 					 ptr + parsed, len);
-	    if (retval < 0)
-	      return parsed;
-	    parsed += retval;
-	    len -= retval;
-	  }
+			if (retval < 0)
+				return parsed;
+			parsed += retval;
+			len -= retval;
+		}
 	}
 	return parsed;
 }
@@ -418,16 +456,14 @@
 	int i;
 	unsigned char *ptr = __buf;
 
-	if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG)
-	{
+	if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
 		printk(KERN_WARNING "usb: too many configurations.\n");
 		return -1;
 	}
 
 	dev->config = (struct usb_config_descriptor *)
 		kmalloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor), GFP_KERNEL);
-	if(dev->config==NULL)
-	{
+	if (!dev->config) {
 		printk(KERN_WARNING "usb: out of memory.\n");
 		return -1;	
 	}
@@ -451,21 +487,18 @@
 	struct usb_alternate_setting *as;
 	struct usb_interface_descriptor *ifp;
 	
-	if(dev->config==NULL)
+	if (!dev->config)
 		return;
 
-	for(c = 0; c < dev->descriptor.bNumConfigurations; c++)
-	{
+	for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
 		cf = &dev->config[c];
-		if (cf->altsetting == NULL)
+		if (!cf->altsetting)
 		        break;
-		for (a = 0; a < cf->num_altsetting; a++)
-		{
+		for (a = 0; a < cf->num_altsetting; a++) {
 		        as = &cf->altsetting[a];
 			if (as->interface == NULL)
 			        break;
-			for(i=0;i<cf->bNumInterfaces;i++)
-			{
+			for(i=0;i<cf->bNumInterfaces;i++) {
 			        ifp = &as->interface[i];
 				if(ifp->endpoint==NULL)
 				       break;
@@ -609,45 +642,6 @@
 	return ret;
 }
 
-int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
-{
-	devrequest dr;
-
-	dr.requesttype = USB_RT_HUB | 0x80;
-	dr.request = USB_REQ_GET_DESCRIPTOR;
-	dr.value = (USB_DT_HUB << 8);
-	dr.index = 0;
-	dr.length = size;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, data, size);
-}
-
-int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
-{
-	devrequest dr;
-
-	dr.requesttype = USB_RT_PORT;
-	dr.request = USB_REQ_CLEAR_FEATURE;
-	dr.value = feature;
-	dr.index = port;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
-int usb_set_port_feature(struct usb_device *dev, int port, int feature)
-{
-	devrequest dr;
-
-	dr.requesttype = USB_RT_PORT;
-	dr.request = USB_REQ_SET_FEATURE;
-	dr.value = feature;
-	dr.index = port;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
-}
-
 int usb_get_status (struct usb_device *dev, int type, int target, void *data)
 {
 	devrequest dr;
@@ -661,32 +655,6 @@
 	return dev->bus->op->control_msg (dev, usb_rcvctrlpipe (dev,0), &dr, data, 2);
 }
 
-int usb_get_hub_status(struct usb_device *dev, void *data)
-{
-	devrequest dr;
-
-	dr.requesttype = USB_RT_HUB | 0x80;
-	dr.request = USB_REQ_GET_STATUS;
-	dr.value = 0;
-	dr.index = 0;
-	dr.length = 4;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, data, 4);
-}
-
-int usb_get_port_status(struct usb_device *dev, int port, void *data)
-{
-	devrequest dr;
-
-	dr.requesttype = USB_RT_PORT | 0x80;
-	dr.request = USB_REQ_GET_STATUS;
-	dr.value = 0;
-	dr.index = port;
-	dr.length = 4;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, data, 4);
-}
-
 int usb_get_protocol(struct usb_device *dev)
 {
 	unsigned char buf[8];
@@ -741,21 +709,19 @@
 static void usb_set_maxpacket(struct usb_device *dev)
 {
 	int i;
-	struct usb_endpoint_descriptor *ep;
 	int act_as = dev->actconfig->act_altsetting;
 	struct usb_alternate_setting *as = dev->actconfig->altsetting + act_as;
-	struct usb_interface_descriptor *ip = as->interface;
 
 	for (i=0; i<dev->actconfig->bNumInterfaces; i++) {
-		if (as->interface[i].bInterfaceNumber == dev->ifnum) {
-			ip = &as->interface[i];
-			break;
+		struct usb_interface_descriptor *ip = &as->interface[i];
+		struct usb_endpoint_descriptor *ep = ip->endpoint;
+		int e;
+
+		for (e=0; e<ip->bNumEndpoints; e++) {
+			dev->epmaxpacket[ep[e].bEndpointAddress & 0x0f] =
+				ep[e].wMaxPacketSize;
 		}
 	}
-	ep = ip->endpoint;
-	for (i=0; i<ip->bNumEndpoints; i++) {
-		dev->epmaxpacket[ep[i].bEndpointAddress & 0x0f] = ep[i].wMaxPacketSize;
-	}
 }
 
 int usb_clear_halt(struct usb_device *dev, int endp)
@@ -776,9 +742,8 @@
 	result = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
 
 	/* dont clear if failed */
-	if (result) {
+	if (result)
 	    return result;
-	}
 
 #if 1	/* lets be really tough */
 	dr.requesttype = 0x80 | USB_RT_ENDPOINT;
@@ -788,12 +753,10 @@
 
 	result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 2);
 
-	if (result) {
+	if (result)
 	    return result;
-	}
-	if (status & 1) {
+	if (status & 1)
 	    return 1;		/* still halted */
-	}
 #endif
 	usb_endpoint_running(dev, endp & 0x0f);
 
@@ -1014,37 +977,27 @@
  * and is in the default state. We need to identify the thing and
  * get the ball rolling..
  */
-void usb_new_device(struct usb_device *dev)
+int usb_new_device(struct usb_device *dev)
 {
-	int addr, i;
+	int addr;
 
-	printk("USB new device connect, assigned device number %d\n",
+	printk(KERN_INFO "USB new device connect, assigned device number %d\n",
 		dev->devnum);
 
 	dev->maxpacketsize = 0;		/* Default to 8 byte max packet size */
         dev->epmaxpacket[0] = 8;
 
+	/* We still haven't set the Address yet */
 	addr = dev->devnum;
 	dev->devnum = 0;
 
-#if 1
 	/* Slow devices */
-	for (i = 0; i < 5; i++) {
-		if (!usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8))
-			break;
-
-		printk("get_descriptor failed, waiting\n");
-		wait_ms(200);
-	}
-	if (i == 5) {
-		printk("giving up\n");
-		return;
+	if (usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8)) {
+		printk(KERN_ERR "USB device not responding, giving up\n");
+		dev->devnum = -1;
+		return 1;
 	}
-#endif
 
-#if 0
-	printk("maxpacketsize: %d\n", dev->descriptor.bMaxPacketSize0);
-#endif
 	dev->epmaxpacket[0] = dev->descriptor.bMaxPacketSize0;
 	switch (dev->descriptor.bMaxPacketSize0) {
 		case 8: dev->maxpacketsize = 0; break;
@@ -1052,36 +1005,29 @@
 		case 32: dev->maxpacketsize = 2; break;
 		case 64: dev->maxpacketsize = 3; break;
 	}
-#if 0
-	printk("dev->mps: %d\n", dev->maxpacketsize);
-#endif
 
 	dev->devnum = addr;
 
-#if 1
 	if (usb_set_address(dev)) {
-		printk("Unable to set address\n");
-		/* FIXME: We should disable the port */
-		return;
+		printk(KERN_ERR "USB device not accepting new address\n");
+		dev->devnum = -1;
+		return 1;
 	}
-#else
-	usb_set_address(dev);
-#endif
 
 	wait_ms(10);	/* Let the SET_ADDRESS settle */
 
 	if (usb_get_device_descriptor(dev)) {
-		printk("Unable to get device descriptor\n");
-		return;
+		printk(KERN_ERR "Unable to get device descriptor\n");
+		dev->devnum = -1;
+		return 1;
 	}
 
 	if (usb_get_configuration(dev)) {
-		printk("Unable to get configuration\n");
-		return;
+		printk(KERN_ERR "Unable to get configuration\n");
+		dev->devnum = -1;
+		return 1;
 	}
 
-	/* usb_get_stringtable(dev); */
-
 	dev->actconfig = dev->config;
 	dev->ifnum = 0;
 	usb_set_maxpacket(dev);
@@ -1090,20 +1036,16 @@
 	usb_show_string(dev, "Product", dev->descriptor.iProduct);
 	usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
 
-#if 0
-	printk("Vendor: %X\n", dev->descriptor.idVendor);
-	printk("Product: %X\n", dev->descriptor.idProduct);
-#endif
-
-	if (usb_device_descriptor(dev)==0)
-	{
+	if (!usb_find_driver(dev)) {
 		/*
 		 * Ok, no driver accepted the device, so show the info for
 		 * debugging
 		 */
-		printk ("Unknown new USB device:\n");
+		printk(KERN_DEBUG "Unknown new USB device:\n");
 		usb_show_device(dev);
 	}
+
+	return 0;
 }
 
 void* usb_request_irq(struct usb_device *dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
@@ -1111,6 +1053,15 @@
 	return dev->bus->op->request_irq(dev, pipe, handler, period, dev_id);
 }
 
+void *usb_request_bulk(struct usb_device *dev, unsigned int pipe, usb_device_irq handler, void *data, int len, void *dev_id)
+{
+	return dev->bus->op->request_bulk(dev, pipe, handler, data, len, dev_id);
+}
+
+int usb_terminate_bulk(struct usb_device *dev, void *first)
+{
+	return dev->bus->op->terminate_bulk(dev, first);
+}
 
 void *usb_allocate_isochronous (struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id)
 {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)