/** * @brief This function makes USB device to resume. * * @param handle A pointer to moal_handle structure * * @return 0 --success, otherwise fail */ int woal_exit_usb_suspend(moal_handle * handle) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) #ifdef CONFIG_PM struct usb_device *udev = ((struct usb_card_rec *) (handle->card))->udev; #endif /* CONFIG_PM */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) struct usb_interface *intf = ((struct usb_card_rec *) (handle->card))->intf; #endif /* < 2.6.34 */ #endif /* >= 2.6.24 */ ENTER(); if (handle->is_suspended == MFALSE) { PRINTM(MERROR, "Device already resumed\n"); LEAVE(); return -EFAULT; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) #ifdef CONFIG_PM /* Exit from USB suspend */ usb_lock_device(udev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) udev->autosuspend_disabled = 1; /* /sys/bus/usb/devices/.../power/level < on */ #endif /* < 2.6.34 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) udev->autoresume_disabled = 0; #endif /* < 2.6.33 */ usb_unlock_device(udev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) intf->pm_usage_cnt = 0; #else atomic_set(&intf->pm_usage_cnt, 0); #endif /* < 2.6.32 */ usb_autopm_get_interface(intf); #else usb_lock_device(udev); atomic_set(&udev->dev.power.usage_count, 0); usb_disable_autosuspend(udev); usb_unlock_device(udev); #endif /* < 2.6.34 */ #endif /* >= 2.6.24 */ #endif /* CONFIG_PM */ //lxy LEAVE(); return 0; }
static struct usb_device *match_device(struct usb_device *dev, u16 vendor_id, u16 product_id) { struct usb_device *ret_dev = NULL; int child; dev_dbg(&dev->dev, "check for vendor %04x, product %04x ...\n", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); /* see if this device matches */ if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) && (product_id == le16_to_cpu(dev->descriptor.idProduct))) { dev_dbg(&dev->dev, "matched this device!\n"); ret_dev = usb_get_dev(dev); goto exit; } /* look through all of the children of this device */ for (child = 0; child < dev->maxchild; ++child) { if (dev->children[child]) { usb_lock_device(dev->children[child]); ret_dev = match_device(dev->children[child], vendor_id, product_id); usb_unlock_device(dev->children[child]); if (ret_dev) goto exit; } } exit: return ret_dev; }
static ssize_t set_autosuspend(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); int value, old_delay; int rc; if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || value <= - INT_MAX/HZ) return -EINVAL; value *= HZ; usb_lock_device(udev); old_delay = udev->autosuspend_delay; udev->autosuspend_delay = value; if (old_delay < 0) { /* Autosuspend wasn't allowed */ if (value >= 0) usb_autosuspend_device(udev); } else { /* Autosuspend was allowed */ if (value < 0) { rc = usb_autoresume_device(udev); if (rc < 0) { count = rc; udev->autosuspend_delay = old_delay; } } else { usb_try_autosuspend_device(udev); } } usb_unlock_device(udev); return count; }
static int ohci_rbus_suspend (struct usb_hcd *hcd, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); /* suspend root hub, hoping it keeps power during suspend */ if (time_before (jiffies, ohci->next_statechange)) msleep (100); #ifdef CONFIG_USB_SUSPEND (void) usb_suspend_device (hcd->self.root_hub, message); #else usb_lock_device (hcd->self.root_hub); (void) ohci_hub_suspend (hcd); usb_unlock_device (hcd->self.root_hub); #endif /* let things settle down a bit */ msleep (100); #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Disable USB PAD & cell clock */ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); } #endif /* CONFIG_PMAC_PBOOK */ return 0; }
static int ohci_rbus_resume (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int retval = 0; #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Re-enable USB PAD & cell clock */ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); if (of_node) pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1); } #endif /* CONFIG_PMAC_PBOOK */ /* resume root hub */ if (time_before (jiffies, ohci->next_statechange)) msleep (100); #ifdef CONFIG_USB_SUSPEND /* get extra cleanup even if remote wakeup isn't in use */ retval = usb_resume_device (hcd->self.root_hub); #else usb_lock_device (hcd->self.root_hub); retval = ohci_hub_resume (hcd); usb_unlock_device (hcd->self.root_hub); #endif return retval; }
static ssize_t set_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); int len = count; char *cp; int rc = count; warn_level(); cp = memchr(buf, '\n', count); if (cp) len = cp - buf; usb_lock_device(udev); if (len == sizeof on_string - 1 && strncmp(buf, on_string, len) == 0) usb_disable_autosuspend(udev); else if (len == sizeof auto_string - 1 && strncmp(buf, auto_string, len) == 0) usb_enable_autosuspend(udev); else rc = -EINVAL; usb_unlock_device(udev); return rc; }
static struct usb_device *match_device_name(struct usb_device *dev, const char *name) { struct usb_device *ret_dev = NULL; int child; dev_dbg(&dev->dev, "check for name %s ...\n", name); /* see if this device matches */ if (strcmp(dev_name(&dev->dev), name) == 0 ) { dev_dbg(&dev->dev, "matched this device!\n"); ret_dev = usb_get_dev(dev); goto exit; } /* look through all of the children of this device */ for (child = 0; child < dev->maxchild; ++child) { if (dev->children[child]) { usb_lock_device(dev->children[child]); ret_dev = match_device_name(dev->children[child], name); usb_unlock_device(dev->children[child]); if (ret_dev) goto exit; } } exit: return ret_dev; }
static irqreturn_t bb_wake_irq(int irq, void *dev_id) { struct opsdata data; struct usb_interface *iface; int cwrlevel = bb_get_cwr(); bool pwrstate_l2 = false; bb_getdata(&data); pwrstate_l2 = ((data.powerstate == BBSTATE_L02L2) || (data.powerstate == BBSTATE_L2)); if (cwrlevel && pwrstate_l2) { if (dlevel & DLEVEL_PM) pr_info("%s: Modem wakeup request from L2.\n", __func__); if (data.usbdev) { usb_lock_device(data.usbdev); iface = usb_ifnum_to_if(data.usbdev, 0); if (iface) { /* Resume usb host activity. */ usb_autopm_get_interface(iface); usb_autopm_put_interface_no_suspend(iface); } usb_unlock_device(data.usbdev); } } if (!cwrlevel && data.powerstate == BBSTATE_UNKNOWN && data.usbdev) { data.powerstate = BBSTATE_L0; bb_setdata(&data); if (dlevel & DLEVEL_PM) pr_info("%s: Network interface up.\n", __func__); } return IRQ_HANDLED; }
/* Do the work for CP initiated L2->L0 */ static void baseband_xmm_power_L2_resume_work(struct work_struct *work) { struct usb_interface *intf; pr_debug("%s {\n", __func__); l2_resume_work_done = false; if (!usbdev) { pr_debug("usbdev = %d\n",usbdev); return; } usb_lock_device(usbdev); intf = usb_ifnum_to_if(usbdev, 0); if(intf == NULL) { pr_debug("usb_ifnum_to_if's return vaule is NULL !! \n"); } if (usb_autopm_get_interface(intf) == 0) usb_autopm_put_interface(intf); usb_unlock_device(usbdev); l2_resume_work_done = true; pr_debug("} %s\n", __func__); }
static void ohci_rh_resume (void *_hcd) { struct usb_hcd *hcd = _hcd; usb_lock_device (hcd->self.root_hub); (void) ohci_hub_resume (hcd); usb_unlock_device (hcd->self.root_hub); }
/* Port 3 */ static ssize_t host_write_port3(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { struct usb_device *udev = to_usb_device(dev); usb_lock_device(udev); host_write_port(2, buf); usb_unlock_device(udev); return n; }
static void baseband_xmm_power_autopm_resume(struct work_struct *work) { struct usb_interface *intf; pr_debug("%s\n", __func__); if (usbdev) { usb_lock_device(usbdev); intf = usb_ifnum_to_if(usbdev, 0); usb_autopm_get_interface(intf); usb_autopm_put_interface(intf); usb_unlock_device(usbdev); } }
static ssize_t set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = udev = to_usb_device (dev); int config, value; if (sscanf (buf, "%u", &config) != 1 || config > 255) return -EINVAL; usb_lock_device(udev); value = usb_set_configuration (udev, config); usb_unlock_device(udev); return (value < 0) ? value : count; }
static ssize_t set_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); int len = count; char *cp; int rc = 0; int old_autosuspend_disabled, old_autoresume_disabled; cp = memchr(buf, '\n', count); if (cp) len = cp - buf; usb_lock_device(udev); old_autosuspend_disabled = udev->autosuspend_disabled; old_autoresume_disabled = udev->autoresume_disabled; /* Setting the flags without calling usb_pm_lock is a subject to * races, but who cares... */ if (len == sizeof on_string - 1 && strncmp(buf, on_string, len) == 0) { udev->autosuspend_disabled = 1; udev->autoresume_disabled = 0; rc = usb_external_resume_device(udev); } else if (len == sizeof auto_string - 1 && strncmp(buf, auto_string, len) == 0) { udev->autosuspend_disabled = 0; udev->autoresume_disabled = 0; rc = usb_external_resume_device(udev); } else if (len == sizeof suspend_string - 1 && strncmp(buf, suspend_string, len) == 0) { udev->autosuspend_disabled = 0; udev->autoresume_disabled = 1; rc = usb_external_suspend_device(udev, PMSG_SUSPEND); } else rc = -EINVAL; if (rc) { udev->autosuspend_disabled = old_autosuspend_disabled; udev->autoresume_disabled = old_autoresume_disabled; } usb_unlock_device(udev); return (rc < 0 ? rc : count); }
static ssize_t bMaxPower_show(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev; struct usb_host_config *actconfig; ssize_t rc = 0; udev = to_usb_device(dev); usb_lock_device(udev); actconfig = udev->actconfig; if (actconfig) rc = sprintf(buf, "%dmA\n", usb_get_max_power(udev, actconfig)); usb_unlock_device(udev); return rc; }
static ssize_t configuration_show(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev; struct usb_host_config *actconfig; ssize_t rc = 0; udev = to_usb_device(dev); usb_lock_device(udev); actconfig = udev->actconfig; if (actconfig && actconfig->string) rc = sprintf(buf, "%s\n", actconfig->string); usb_unlock_device(udev); return rc; }
/* Do the work for CP initiated L2->L0 */ static void xmm_power_l2_resume_work(struct work_struct *work) { struct usb_interface *intf; pr_debug("%s {\n", __func__); if (!usbdev) return; usb_lock_device(usbdev); intf = usb_ifnum_to_if(usbdev, 0); if (usb_autopm_get_interface(intf) == 0) usb_autopm_put_interface(intf); usb_unlock_device(usbdev); pr_debug("} %s\n", __func__); }
static ssize_t set_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); int config; if (sscanf(buf, "%d", &config) != 1 || config < 0 || config > 1) return -EINVAL; usb_lock_device(udev); if (config) udev->quirks |= USB_QUIRK_RESET_MORPHS; else udev->quirks &= ~USB_QUIRK_RESET_MORPHS; usb_unlock_device(udev); return count; }
static ssize_t avoid_reset_quirk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); int val; if (sscanf(buf, "%d", &val) != 1 || val < 0 || val > 1) return -EINVAL; usb_lock_device(udev); if (val) udev->quirks |= USB_QUIRK_RESET; else udev->quirks &= ~USB_QUIRK_RESET; usb_unlock_device(udev); return count; }
static ssize_t usb3_hardware_lpm_show(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_device *udev = to_usb_device(dev); const char *p; usb_lock_device(udev); if (udev->usb3_lpm_enabled) p = "enabled"; else p = "disabled"; usb_unlock_device(udev); return sprintf(buf, "%s\n", p); }
static ssize_t persist_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); int value; /* Hubs are always enabled for USB_PERSIST */ if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) return -EPERM; if (sscanf(buf, "%d", &value) != 1) return -EINVAL; usb_lock_device(udev); udev->persist_enabled = !!value; usb_unlock_device(udev); return count; }
/* "Safely remove a device" */ static ssize_t remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); int rc = 0; usb_lock_device(udev); if (udev->state != USB_STATE_NOTATTACHED) { /* To avoid races, first unconfigure and then remove */ usb_set_configuration(udev, -1); rc = usb_remove_device(udev); } if (rc == 0) rc = count; usb_unlock_device(udev); return rc; }
static ssize_t show_supports_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_interface *intf; struct usb_device *udev; int ret; intf = to_usb_interface(dev); udev = interface_to_usbdev(intf); usb_lock_device(udev); /* Devices will be autosuspended even when an interface isn't claimed */ if (!intf->dev.driver || to_usb_driver(intf->dev.driver)->supports_autosuspend) ret = sprintf(buf, "%u\n", 1); else ret = sprintf(buf, "%u\n", 0); usb_unlock_device(udev); return ret; }
static irqreturn_t m7400_wake_irq(int irq, void *dev_id) { struct usb_interface *intf; switch (modem_status) { case BBSTATE_L2: /* Resume usb host activity. */ if (m7400_usb_device) { usb_lock_device(m7400_usb_device); intf = usb_ifnum_to_if(m7400_usb_device, 0); usb_autopm_get_interface(intf); usb_autopm_put_interface(intf); usb_unlock_device(m7400_usb_device); } break; default: break; } return IRQ_HANDLED; }
static ssize_t read_descriptors(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); struct usb_device *udev = to_usb_device(dev); size_t nleft = count; size_t srclen, n; int cfgno; void *src; /* The binary attribute begins with the device descriptor. * Following that are the raw descriptor entries for all the * configurations (config plus subsidiary descriptors). */ usb_lock_device(udev); for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations && nleft > 0; ++cfgno) { if (cfgno < 0) { src = &udev->descriptor; srclen = sizeof(struct usb_device_descriptor); } else { src = udev->rawdescriptors[cfgno]; srclen = __le16_to_cpu(udev->config[cfgno].desc. wTotalLength); } if (off < srclen) { n = min(nleft, srclen - (size_t) off); memcpy(buf, src + off, n); nleft -= n; buf += n; off = 0; } else { off -= srclen; } } usb_unlock_device(udev); return count - nleft; }
static ssize_t set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); bool value; int ret; usb_lock_device(udev); ret = strtobool(buf, &value); if (!ret) ret = usb_set_usb2_hardware_lpm(udev, value); usb_unlock_device(udev); if (!ret) return count; return ret; }
static ssize_t read_descriptors(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct usb_device *udev = to_usb_device( container_of(kobj, struct device, kobj)); size_t nleft = count; size_t srclen, n; usb_lock_device(udev); /* The binary attribute begins with the device descriptor */ srclen = sizeof(struct usb_device_descriptor); if (off < srclen) { n = min_t(size_t, nleft, srclen - off); memcpy(buf, off + (char *) &udev->descriptor, n); nleft -= n; buf += n; off = 0; } else { off -= srclen; } /* Then follows the raw descriptor entry for the current * configuration (config plus subsidiary descriptors). */ if (udev->actconfig) { int cfgno = udev->actconfig - udev->config; srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); if (off < srclen) { n = min_t(size_t, nleft, srclen - off); memcpy(buf, off + udev->rawdescriptors[cfgno], n); nleft -= n; } } usb_unlock_device(udev); return count - nleft; }
/** * usb_find_device_by_name - find a specific usb device in the system * @name: the name of the device to find * * Returns a pointer to a struct usb_device if such a specified usb * device is present in the system currently. The usage count of the * device will be incremented if a device is found. Make sure to call * usb_put_dev() when the caller is finished with the device. * * If a device with the specified bus id is not found, NULL is returned. */ struct usb_device *usb_find_device_by_name(const char *name) { struct list_head *buslist; struct usb_bus *bus; struct usb_device *dev = NULL; mutex_lock(&usb_bus_list_lock); for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) { bus = container_of(buslist, struct usb_bus, bus_list); if (!bus->root_hub) continue; usb_lock_device(bus->root_hub); dev = match_device_name(bus->root_hub, name); usb_unlock_device(bus->root_hub); if (dev) goto exit; } exit: mutex_unlock(&usb_bus_list_lock); return dev; }
/* Do the work for CP initiated L2->L0 */ static void baseband_xmm_power_L2_resume_work(struct work_struct *work) { struct usb_interface *intf; pr_debug("%s {\n", __func__); if (!usbdev) return; usb_lock_device(usbdev); intf = usb_ifnum_to_if(usbdev, 0); if (!intf) { pr_err("%s: the interface is NULL\n", __func__); usb_unlock_device(usbdev); return; } if (usb_autopm_get_interface(intf) == 0) usb_autopm_put_interface(intf); usb_unlock_device(usbdev); pr_debug("} %s\n", __func__); }
/** * usb_find_device - find a specific usb device in the system * @vendor_id: the vendor id of the device to find * @product_id: the product id of the device to find * * Returns a pointer to a struct usb_device if such a specified usb * device is present in the system currently. The usage count of the * device will be incremented if a device is found. Make sure to call * usb_put_dev() when the caller is finished with the device. * * If a device with the specified vendor and product id is not found, * NULL is returned. */ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id) { struct list_head *buslist; struct usb_bus *bus; struct usb_device *dev = NULL; mutex_lock(&usb_bus_list_lock); for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) { bus = container_of(buslist, struct usb_bus, bus_list); if (!bus->root_hub) continue; usb_lock_device(bus->root_hub); dev = match_device(bus->root_hub, vendor_id, product_id); usb_unlock_device(bus->root_hub); if (dev) goto exit; } exit: mutex_unlock(&usb_bus_list_lock); return dev; }