Exemple #1
0
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
					u16 portstatus, u16 portchange)
{
	struct usb_device *hub = hubstate->dev;
	struct usb_device *dev;
	unsigned int delay = HUB_SHORT_RESET_TIME;
	int i;
	char *portstr, *tempstr;



    DBG_HOST_HUB("### >>> Enter hub.c file --> usb_hub_port_connect_change function \n");
	dbg("port %d, portstatus %x, change %x, %s",
		port + 1, portstatus, portchange, portspeed (portstatus));
  


	/* Clear the connection change status */
	usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);


	/* Disconnect any existing devices under this port */
	if (hub->children[port])
		usb_disconnect(&hub->children[port]);



	/* Return now if nothing is connected */
	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
		if (portstatus & USB_PORT_STAT_ENABLE)
			usb_hub_port_disable(hub, port);

		return;
	}



	if (usb_hub_port_debounce(hub, port)) {
		err("connect-debounce failed, port %d disabled", port+1);
		usb_hub_port_disable(hub, port);
		return;
	}

	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;

		/* Allocate a new device struct */
		dev = usb_alloc_dev(hub, hub->bus);
		if (!dev) {
			err("couldn't allocate usb_device");
			break;
		}

		hub->children[port] = dev;

		/* Reset the device */
		if (usb_hub_port_reset(hub, port, dev, delay)) {
			usb_free_dev(dev);
			break;
		}

		/* Find a new device ID for it */
		usb_connect(dev);

		/* Set up TT records, if needed  */
		if (hub->tt) {
			dev->tt = hub->tt;
			dev->ttport = hub->ttport;
		} else if (dev->speed != USB_SPEED_HIGH
				&& hub->speed == USB_SPEED_HIGH) {
			dev->tt = &hubstate->tt;
			dev->ttport = port + 1;
		}

		/* Create a readable topology string */
		cdev = dev;
		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);

		/* Run it through the hoops (find a driver, etc) */
		if (!usb_new_device(dev))
			goto done;

		/* Free the configuration if there was an error */
		usb_free_dev(dev);

		/* Switch to a long reset time */
		delay = HUB_LONG_RESET_TIME;
	}

	hub->children[port] = NULL;
	usb_hub_port_disable(hub, port);
done:
	up(&usb_address0_sem);
	if (portstr)
		kfree(portstr);
	if (tempstr)
		kfree(tempstr);
}
Exemple #2
0
static void usb_hub_port_connect_change(struct usb_device *hub, int port,
					struct usb_port_status *portsts)
{
	struct usb_device *dev;
	unsigned short portstatus, portchange;
	unsigned int delay = HUB_SHORT_RESET_TIME;
	int i;
	char *portstr, *tempstr;
        int devnum;

	portstatus = le16_to_cpu(portsts->wPortStatus);
	portchange = le16_to_cpu(portsts->wPortChange);
	dbg("port %d, portstatus %x, change %x, %s",
		port + 1, portstatus, portchange, portspeed (portstatus));

	/* Clear the connection change status */
	usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);

	/* Disconnect any existing devices under this port */
	down(&hub->bus->dev_tree_sem);
	if (hub->children[port])
		usb_disconnect(&hub->children[port]);

	/* Return now if nothing is connected */
	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
		if (portstatus & USB_PORT_STAT_ENABLE)
			usb_hub_port_disable(hub, port);

		up(&hub->bus->dev_tree_sem);
		return;
	}
	up(&hub->bus->dev_tree_sem);

	/* Some low speed devices have problems with the quick delay, so */
	/*  be a bit pessimistic with those devices. RHbug #23670 */
	if (portstatus & USB_PORT_STAT_LOW_SPEED) {
		wait_ms(400);
		delay = HUB_LONG_RESET_TIME;
	}

	down(&usb_address0_sem);
	down(&hub->bus->dev_tree_sem);

	tempstr = kmalloc(1024, GFP_KERNEL);
	portstr = kmalloc(1024, GFP_KERNEL);

	for (i = 0; i < HUB_PROBE_TRIES; i++) {
		struct usb_device *pdev, *cdev;

		/* Allocate a new device struct */
		dev = usb_alloc_dev(hub, hub->bus);
		if (!dev) {
			err("couldn't allocate usb_device");
			break;
		}

		hub->children[port] = dev;

		/* Reset the device */
		if (usb_hub_port_reset(hub, port, dev, delay)) {
			usb_free_dev(dev);
			break;
		}

		/* Find a new device ID for it */
		usb_connect(dev);

		/* Create a readable topology string */
		cdev = dev;
		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);
                devnum = dev->devnum;
		/* Run it through the hoops (find a driver, etc) */
		if (!usb_new_device(dev))
			goto done;

		/* Free the configuration if there was an error */
		usb_free_dev(dev);

		/* Switch to a long reset time */
		delay = HUB_LONG_RESET_TIME;
	}
        err("failed adding a new device.  Address=%d",devnum);

	hub->children[port] = NULL;
	usb_hub_port_disable(hub, port);
done:
	up(&hub->bus->dev_tree_sem);
	up(&usb_address0_sem);
	if (portstr)
		kfree(portstr);
	if (tempstr)
		kfree(tempstr);
}
Exemple #3
0
int usb_find_devices(void)
{
  struct usb_bus *bus;
  int ret, changes = 0;

  for (bus = usb_busses; bus; bus = bus->next) {
    struct usb_device *devices, *dev;

    /* Find all of the devices and put them into a temporary list */
    ret = usb_os_find_devices(bus, &devices);
    if (ret < 0)
      return ret;

    /*
     * Now walk through all of the devices we know about and compare
     * against this new list. Any duplicates will be removed from the new
     * list. If we don't find it in the new list, the device was removed.
     * Any devices still in the new list, are new to us.
     */
    dev = bus->devices;
    while (dev) {
      int found = 0;
      struct usb_device *ndev, *tdev = dev->next;

      ndev = devices;
      while (ndev) {
        struct usb_device *tndev = ndev->next;

        if (!strcmp(dev->filename, ndev->filename)) {
          /* Remove it from the new devices list */
          LIST_DEL(devices, ndev);

          usb_free_dev(ndev);
          found = 1;
          break;
        }

        ndev = tndev;
      }

      if (!found) {
        /* The device was removed from the system */
        LIST_DEL(bus->devices, dev);
        usb_free_dev(dev);
        changes++;
      }

      dev = tdev;
    }

    /*
     * Anything on the *devices list is new. So add them to bus->devices and
     * process them like the new device it is.
     */
    dev = devices;
    while (dev) {
      struct usb_device *tdev = dev->next;

      /*
       * Remove it from the temporary list first and add it to the real
       * bus->devices list.
       */
      LIST_DEL(devices, dev);

      LIST_ADD(bus->devices, dev);

      /*
       * Some ports fetch the descriptors on scanning (like Linux) so we don't
       * need to fetch them again.
       */
      if (!dev->config) {
        usb_dev_handle *udev;

        udev = usb_open(dev);
        if (udev) {
          usb_fetch_and_parse_descriptors(udev);

          usb_close(udev);
        }
      }

      changes++;

      dev = tdev;
    }

    usb_os_determine_children(bus);
  }

  return changes;
}
Exemple #4
0
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
					u16 portstatus, u16 portchange)
{
	struct usb_device *hub = hubstate->dev;
	struct usb_device *dev;
	unsigned int delay = HUB_SHORT_RESET_TIME;
	int i;

	dbg("port %d, portstatus %x, change %x, %s",
		port + 1, portstatus, portchange, portspeed (portstatus));

	/* Clear the connection change status */
	usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);

	/* Disconnect any existing devices under this port */
	if (hub->children[port])
		usb_disconnect(&hub->children[port]);

	/* Return now if nothing is connected */
	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
		if (portstatus & USB_PORT_STAT_ENABLE)
			usb_hub_port_disable(hub, port);

		return;
	}

	if (usb_hub_port_debounce(hub, port)) {
		err("connect-debounce failed, port %d disabled", port+1);
		usb_hub_port_disable(hub, port);
		return;
	}

	down(&usb_address0_sem);

	for (i = 0; i < HUB_PROBE_TRIES; i++) {
		struct usb_device *pdev;
		int len;

		/* Allocate a new device struct */
		dev = usb_alloc_dev(hub, hub->bus);
		if (!dev) {
			err("couldn't allocate usb_device");
			break;
		}

		/* Reset the device */
		if (usb_hub_port_reset(hub, port, dev, delay)) {
			usb_free_dev(dev);
			break;
		}

		/* Find a new device ID for it */
		usb_connect(dev);

		/* Set up TT records, if needed  */
		if (hub->tt) {
			dev->tt = hub->tt;
			dev->ttport = hub->ttport;
		} else if (dev->speed != USB_SPEED_HIGH
				&& hub->speed == USB_SPEED_HIGH) {
			dev->tt = &hubstate->tt;
			dev->ttport = port + 1;
		}

		/* 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 (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);
 		USB_SET_LED(USB_CONNECT); //2005-02-24 by kanki for USB LED

		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)) {
			hub->children[port] = dev;
			goto done;
		}

		/* Free the configuration if there was an error */
		usb_free_dev(dev);

		/* Switch to a long reset time */
		delay = HUB_LONG_RESET_TIME;
	}

	usb_hub_port_disable(hub, port);
done:
	up(&usb_address0_sem);
}
Exemple #5
0
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
					u16 portstatus, u16 portchange)
{
	struct usb_device *hub = hubstate->dev;
	struct usb_device *dev;
	unsigned int delay = HUB_SHORT_RESET_TIME;
	int i;

	dbg("port %d, portstatus %x, change %x, %s",
		port + 1, portstatus, portchange, portspeed (portstatus));

	/* Clear the connection change status */
	usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);

	/* Disconnect any existing devices under this port */
	if (hub->children[port])
		usb_disconnect(&hub->children[port]);

	/* Return now if nothing is connected */
	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
		if (portstatus & USB_PORT_STAT_ENABLE)
			usb_hub_port_disable(hub, port);

		return;
	}

	if (usb_hub_port_debounce(hub, port)) {
		err("connect-debounce failed, port %d disabled", port+1);
		usb_hub_port_disable(hub, port);
		return;
	}

	down(&usb_address0_sem);

	for (i = 0; i < HUB_PROBE_TRIES; i++) {
		struct usb_device *pdev;
		int len;

		/* Allocate a new device struct */
		dev = usb_alloc_dev(hub, hub->bus);
		if (!dev) {
			err("couldn't allocate usb_device");
			break;
		}

		hub->children[port] = dev;
		
		/* add by Levis for wakeup BP */
		int begin = 0;
#ifdef CONFIG_ARCH_EZXBASE
			set_GPIO_mode(GPIO_IN | GPIO_BP_RDY);
			if(!GPIO_is_high(GPIO_BP_RDY))
			{
				if(GPIO_is_high(GPIO_AP_RDY ))
				{
					GPCR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY );
					udelay(WAKE_UP_BP_UDELAY);
					GPSR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY );
				}else {
					GPSR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY );
					udelay(WAKE_UP_BP_UDELAY);
					GPCR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY );
				}
				begin = jiffies;
				while(!GPIO_is_high(GPIO_BP_RDY) && (jiffies < (begin+HZ)))					;
				if(!GPIO_is_high(GPIO_BP_RDY))
				{
					printk("%s: Wakeup BP timeout! BP is still in sleep state!\n", __FUNCTION__);		
				}				
			}
#else  
		set_GPIO_mode(GPIO_IN | 41);
		if(GPIO_is_high(41))
		{
			if(GPIO_is_high(GPIO_MCU_INT_SW))
				GPCR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);		
			else {
				GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);		
			}	
			begin = jiffies;
			while(GPIO_is_high(41) && (jiffies < (begin+HZ))) printk("%s: waitting for BP active!\n", __FUNCTION__);
			if(GPIO_is_high(GPIO_MCU_INT_SW))
				GPCR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);		
			else {
				GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);		
			}	
		}
#endif	
		/* end Levis */

		/* Reset the device */
		if (usb_hub_port_reset(hub, port, dev, delay)) {
			usb_free_dev(dev);
			break;
		}

		/* Find a new device ID for it */
		usb_connect(dev);

		/* Set up TT records, if needed  */
		if (hub->tt) {
			dev->tt = hub->tt;
			dev->ttport = hub->ttport;
		} else if (dev->speed != USB_SPEED_HIGH
				&& hub->speed == USB_SPEED_HIGH) {
			dev->tt = &hubstate->tt;
			dev->ttport = port + 1;
		}

		/* 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 (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))
			goto done;

		/* Free the configuration if there was an error */
		usb_free_dev(dev);

		/* Switch to a long reset time */
		delay = HUB_LONG_RESET_TIME;
	}

	hub->children[port] = NULL;
	usb_hub_port_disable(hub, port);
done:
	up(&usb_address0_sem);
}