static void ush_hsic_port_disable(void) { hsic_enable = 0; if ((hsic.modem_dev) && (hsic.autosuspend_enable != 0)) { dev_dbg(&pci_dev->dev, "Disable auto suspend in port disable\n"); usb_disable_autosuspend(hsic.modem_dev); usb_disable_autosuspend(hsic.rh_dev); hsic.autosuspend_enable = 0; } if (hsic.rh_dev) { if (hsic.autosuspend_enable != 0) { dev_dbg(&pci_dev->dev, "Disable auto suspend in port disable\n"); usb_disable_autosuspend(hsic.rh_dev); hsic.autosuspend_enable = 0; } clear_port_feature(hsic.rh_dev, HSIC_USH_PORT, USB_PORT_FEAT_POWER); usb_enable_autosuspend(hsic.rh_dev); hsic.autosuspend_enable = 1; } s3_wake_unlock(); }
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 int csvt_probe(struct usb_serial *serial, const struct usb_device_id *id) { pr_debug("%s:\n", __func__); usb_enable_autosuspend(serial->dev); return 0; }
static ssize_t hsic_autosuspend_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int retval; int org_req; if (size > HSIC_ENABLE_SIZE) { dev_dbg(dev, "Invalid, size = %d\n", size); return -EINVAL; } if (sscanf(buf, "%d", &org_req) != 1) { dev_dbg(dev, "Invalid, value\n"); return -EINVAL; } mutex_lock(&hsic.hsic_mutex); hsic.autosuspend_enable = org_req; if (hsic.modem_dev != NULL) { if (hsic.autosuspend_enable == 0) { dev_dbg(dev, "Modem dev autosuspend disable\n"); usb_disable_autosuspend(hsic.modem_dev); } else { dev_dbg(dev, "Enable auto suspend\n"); usb_enable_autosuspend(hsic.modem_dev); hsic_wakeup_irq_init(); } } if (hsic.rh_dev != NULL) { if (hsic.autosuspend_enable == 0) { dev_dbg(dev, "port autosuspend disable\n"); usb_disable_autosuspend(hsic.rh_dev); } else { dev_dbg(dev, "port Enable auto suspend\n"); usb_enable_autosuspend(hsic.rh_dev); } } mutex_unlock(&hsic.hsic_mutex); return size; }
static int wrigley_cdc_bind(struct usbnet *dev, struct usb_interface *intf) { int status = cdc_bind(dev, intf); if (!status) { dev->rx_urb_size = WRIGLEY_DOWNLINK_MTU + dev->net->hard_header_len; device_init_wakeup(&dev->udev->dev, 1); usb_enable_autosuspend(interface_to_usbdev(intf)); oob_wake_register(intf); dev->udev->autosuspend_delay = msecs_to_jiffies(1000); dev->udev->parent->autosuspend_delay = 0; } return status; }
static void tegra_usbdevice_added(struct usb_device *udev) { const struct usb_device_descriptor *desc = &udev->descriptor; if (desc->idVendor == mdata->vid && desc->idProduct == mdata->pid) { pr_debug("%s: Device %s added.\n", udev->product, __func__); if (callback && callback->usbnotify) callback->usbnotify(udev, true); if (mdata->wake_capable) device_set_wakeup_enable(&udev->dev, true); if (mdata->autosuspend_ready) usb_enable_autosuspend(udev); } }
static void baseband_xmm_device_add_handler(struct usb_device *udev) { struct usb_interface *intf = usb_ifnum_to_if(udev, 0); const struct usb_device_id *id; if (intf == NULL) return; id = usb_match_id(intf, xmm_pm_ids); if (id) { pr_debug("persist_enabled: %u\n", udev->persist_enabled); pr_debug("Add device %d <%s %s>\n", udev->devnum, udev->manufacturer, udev->product); usbdev = udev; usb_enable_autosuspend(udev); pr_debug("enable autosuspend\n"); } }
static void rmnet_usb_disable_hsic_autosuspend(struct usbnet *usbnet, int enable_autosuspend) { struct usb_device *usb_dev = usbnet->udev; struct rmnet_ctrl_udev *rmnet_udev = (struct rmnet_ctrl_udev *)usbnet->data[1]; usb_get_dev(usb_dev); if (!enable_autosuspend) { usb_disable_autosuspend(usb_dev); rmnet_udev->autosuspend_disabled = 1; rmnet_udev->autosuspend_dis_cnt++; } else { usb_enable_autosuspend(usb_dev); rmnet_udev->autosuspend_disabled = 0; rmnet_udev->autosuspend_en_cnt++; } usb_put_dev(usb_dev); }
static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) { int retval =0 ; PMINI_ADAPTER psAdapter = NULL; PS_INTERFACE_ADAPTER psIntfAdapter = NULL; struct usb_device *udev = NULL; // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!"); if((intf == NULL) || (id == NULL)) { // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL"); return -EINVAL; } /* Allocate Adapter structure */ if((psAdapter = kmalloc(sizeof(MINI_ADAPTER), GFP_KERNEL)) == NULL) { //BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); return -ENOMEM; } memset(psAdapter, 0, sizeof(MINI_ADAPTER)); /* Init default driver debug state */ psAdapter->stDebugState.debug_level = DBG_LVL_CURR; psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; memset (psAdapter->stDebugState.subtype, 0, sizeof (psAdapter->stDebugState.subtype)); /* Technically, one can start using BCM_DEBUG_PRINT after this point. * However, realize that by default the Type/Subtype bitmaps are all zero now; * so no prints will actually appear until the TestApp turns on debug paths via * the ioctl(); so practically speaking, in early init, no logging happens. * * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug * during early init. * Further, we turn this OFF once init_module() completes. */ psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff; BCM_SHOW_DEBUG_BITMAP(psAdapter); retval = InitAdapter(psAdapter); if(retval) { BCM_DEBUG_PRINT (psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InitAdapter Failed\n"); AdapterFree(psAdapter); return retval; } /* Allocate interface adapter structure */ if((psAdapter->pvInterfaceAdapter = kmalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL)) == NULL) { BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); AdapterFree (psAdapter); return -ENOMEM; } memset(psAdapter->pvInterfaceAdapter, 0, sizeof(S_INTERFACE_ADAPTER)); psIntfAdapter = InterfaceAdapterGet(psAdapter); psIntfAdapter->psAdapter = psAdapter; /* Store usb interface in Interface Adapter */ psIntfAdapter->interface = intf; usb_set_intfdata(intf, psIntfAdapter); BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter); retval = InterfaceAdapterInit(psIntfAdapter); if(retval) { /* If the Firmware/Cfg File is not present * then return success, let the application * download the files. */ if(-ENOENT == retval){ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "File Not Found, Use App to Download\n"); return STATUS_SUCCESS; } BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapterInit Failed \n"); usb_set_intfdata(intf, NULL); udev = interface_to_usbdev (intf); usb_put_dev(udev); if(psAdapter->bUsbClassDriverRegistered == TRUE) usb_deregister_dev (intf, &usbbcm_class); InterfaceAdapterFree(psIntfAdapter); return retval ; } if(psAdapter->chip_id > T3) { uint32_t uiNackZeroLengthInt=4; if(wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt))) { return -EIO;; } } udev = interface_to_usbdev (intf); /* Check whether the USB-Device Supports remote Wake-Up */ if(USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) { /* If Suspend then only support dynamic suspend */ if(psAdapter->bDoSuspend) { udev->autosuspend_delay = 0; intf->needs_remote_wakeup = 1; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) udev->autosuspend_disabled = 0; #else usb_enable_autosuspend(udev); #endif device_init_wakeup(&intf->dev,1); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) usb_autopm_disable(intf); #endif INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend); BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n"); } else { intf->needs_remote_wakeup = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) udev->autosuspend_disabled = 1; #else usb_disable_autosuspend(udev); #endif } } psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0; return retval; }
static int ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) { __u8 ifc_num; struct usb_host_interface *ifc_desc; struct usb_endpoint_descriptor *ep_desc; int i; struct ks_bridge *ksb; unsigned long flags; struct data_pkt *pkt; ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber; switch (id->idProduct) { case 0x9008: if (ifc_num != 0) return -ENODEV; ksb = __ksb[BOOT_BRIDGE_INDEX]; break; case 0x9048: case 0x904C: case 0x9075: if (ifc_num != 2) return -ENODEV; ksb = __ksb[EFS_BRIDGE_INDEX]; break; default: return -ENODEV; } if (!ksb) { pr_err("ksb is not initialized"); return -ENODEV; } ksb->udev = usb_get_dev(interface_to_usbdev(ifc)); ksb->ifc = ifc; ifc_desc = ifc->cur_altsetting; for (i = 0; i < ifc_desc->desc.bNumEndpoints; i++) { ep_desc = &ifc_desc->endpoint[i].desc; if (!ksb->in_epAddr && usb_endpoint_is_bulk_in(ep_desc)) ksb->in_epAddr = ep_desc->bEndpointAddress; if (!ksb->out_epAddr && usb_endpoint_is_bulk_out(ep_desc)) ksb->out_epAddr = ep_desc->bEndpointAddress; } if (!(ksb->in_epAddr && ksb->out_epAddr)) { pr_err("could not find bulk in and bulk out endpoints"); usb_put_dev(ksb->udev); ksb->ifc = NULL; return -ENODEV; } ksb->in_pipe = usb_rcvbulkpipe(ksb->udev, ksb->in_epAddr); ksb->out_pipe = usb_sndbulkpipe(ksb->udev, ksb->out_epAddr); usb_set_intfdata(ifc, ksb); set_bit(USB_DEV_CONNECTED, &ksb->flags); atomic_set(&ksb->tx_pending_cnt, 0); atomic_set(&ksb->rx_pending_cnt, 0); dbg_log_event(ksb, "PID-ATT", id->idProduct, 0); /*free up stale buffers if any from previous disconnect*/ spin_lock_irqsave(&ksb->lock, flags); while (!list_empty(&ksb->to_ks_list)) { pkt = list_first_entry(&ksb->to_ks_list, struct data_pkt, list); list_del_init(&pkt->list); ksb_free_data_pkt(pkt); } while (!list_empty(&ksb->to_mdm_list)) { pkt = list_first_entry(&ksb->to_mdm_list, struct data_pkt, list); list_del_init(&pkt->list); ksb_free_data_pkt(pkt); } spin_unlock_irqrestore(&ksb->lock, flags); ksb->fs_dev = (struct miscdevice *)id->driver_info; misc_register(ksb->fs_dev); if (device_can_wakeup(&ksb->udev->dev)) { ifc->needs_remote_wakeup = 1; usb_enable_autosuspend(ksb->udev); } atomic_set(&ksb->pmlock_cnt, 0); pr_info("usb dev connected"); return 0; }
static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_endpoint_descriptor *ep_desc; struct btusb_data *data; struct hci_dev *hdev; int i, version, err; BT_DBG("intf %p id %p", intf, id); /* interface numbers are hardcoded in the spec */ if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; if (!id->driver_info) { const struct usb_device_id *match; match = usb_match_id(intf, blacklist_table); if (match) id = match; } if (id->driver_info == BTUSB_IGNORE) return -ENODEV; if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER) return -ENODEV; if (ignore_csr && id->driver_info & BTUSB_CSR) return -ENODEV; if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER) return -ENODEV; if (id->driver_info & BTUSB_ATH3012) { struct usb_device *udev = interface_to_usbdev(intf); version = get_rome_version(udev); BT_INFO("Rome Version: 0x%x", version); /* Old firmware would otherwise let ath3k driver load * patch and sysconfig files */ if (version) rome_download(udev); else if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) { BT_INFO("FW for ar3k is yet to be downloaded"); return -ENODEV; } } data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { ep_desc = &intf->cur_altsetting->endpoint[i].desc; if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) { data->intr_ep = ep_desc; continue; } if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) { data->bulk_tx_ep = ep_desc; continue; } if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) { data->bulk_rx_ep = ep_desc; continue; } } if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) return -ENODEV; data->cmdreq_type = USB_TYPE_CLASS; data->udev = interface_to_usbdev(intf); data->intf = intf; spin_lock_init(&data->lock); INIT_WORK(&data->work, btusb_work); INIT_WORK(&data->waker, btusb_waker); spin_lock_init(&data->txlock); init_usb_anchor(&data->tx_anchor); init_usb_anchor(&data->intr_anchor); init_usb_anchor(&data->bulk_anchor); init_usb_anchor(&data->isoc_anchor); init_usb_anchor(&data->deferred); hdev = hci_alloc_dev(); if (!hdev) return -ENOMEM; hdev->bus = HCI_USB; hci_set_drvdata(hdev, data); data->hdev = hdev; SET_HCIDEV_DEV(hdev, &intf->dev); hdev->open = btusb_open; hdev->close = btusb_close; hdev->flush = btusb_flush; hdev->send = btusb_send_frame; hdev->notify = btusb_notify; if (id->driver_info & BTUSB_BCM92035) hdev->setup = btusb_setup_bcm92035; if (id->driver_info & BTUSB_INTEL) hdev->setup = btusb_setup_intel; /* Interface numbers are hardcoded in the specification */ data->isoc = usb_ifnum_to_if(data->udev, 1); if (!reset) set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) { if (!disable_scofix) set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); } if (id->driver_info & BTUSB_BROKEN_ISOC) data->isoc = NULL; if (id->driver_info & BTUSB_DIGIANSWER) { data->cmdreq_type = USB_TYPE_VENDOR; set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); } if (id->driver_info & BTUSB_CSR) { struct usb_device *udev = data->udev; /* Old firmware would otherwise execute USB reset */ if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117) set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); } if (id->driver_info & BTUSB_SNIFFER) { struct usb_device *udev = data->udev; /* New sniffer firmware has crippled HCI interface */ if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); data->isoc = NULL; } if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, data->isoc, data); if (err < 0) { hci_free_dev(hdev); return err; } } err = hci_register_dev(hdev); if (err < 0) { hci_free_dev(hdev); return err; } usb_set_intfdata(intf, data); usb_enable_autosuspend(data->udev); return 0; }
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; struct usb_host_interface *intf = serial->interface->cur_altsetting; int retval = -ENODEV; __u8 nintf; __u8 ifnum; bool is_gobi1k = id->driver_info ? true : false; dbg("%s", __func__); dbg("Is Gobi 1000 = %d", is_gobi1k); nintf = serial->dev->actconfig->desc.bNumInterfaces; dbg("Num Interfaces = %d", nintf); ifnum = intf->desc.bInterfaceNumber; dbg("This Interface = %d", ifnum); data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; spin_lock_init(&data->susp_lock); if (!(board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2)) usb_enable_autosuspend(serial->dev); switch (nintf) { case 1: if (serial->interface->num_altsetting == 2) intf = &serial->interface->altsetting[1]; else if (serial->interface->num_altsetting > 2) break; if (intf->desc.bNumEndpoints == 2 && usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { dbg("QDL port found"); if (serial->interface->num_altsetting == 1) { retval = 0; break; } retval = usb_set_interface(serial->dev, ifnum, 1); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; case 3: case 4: if (ifnum == 1 && !is_gobi1k) { dbg("Gobi 2K+ DM/DIAG interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum == 2) { dbg("Modem port found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum==3 && !is_gobi1k) { dbg("Gobi 2K+ NMEA GPS interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; case 9: if (get_radio_flag() & 0x20000) usb_diag_enable = true; if (ifnum != EFS_SYNC_IFC_NUM && !(!usb_diag_enable && ifnum == DUN_IFC_NUM && (board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2))) { kfree(data); break; } retval = 0; break; default: dev_err(&serial->dev->dev, "unknown number of interfaces: %d\n", nintf); kfree(data); retval = -ENODEV; } if (retval != -ENODEV) usb_set_serial_data(serial, data); return retval; }
/* * Probe a i2400m interface and register it * * @iface: USB interface to link to * @id: USB class/subclass/protocol id * @returns: 0 if ok, < 0 errno code on error. * * Alloc a net device, initialize the bus-specific details and then * calls the bus-generic initialization routine. That will register * the wimax and netdev devices, upload the firmware [using * _bus_bm_*()], call _bus_dev_start() to finalize the setup of the * communication with the device and then will start to talk to it to * finnish setting it up. */ static int i2400mu_probe(struct usb_interface *iface, const struct usb_device_id *id) { int result; struct net_device *net_dev; struct device *dev = &iface->dev; struct i2400m *i2400m; struct i2400mu *i2400mu; struct usb_device *usb_dev = interface_to_usbdev(iface); if (usb_dev->speed != USB_SPEED_HIGH) dev_err(dev, "device not connected as high speed\n"); /* Allocate instance [calls i2400m_netdev_setup() on it]. */ result = -ENOMEM; net_dev = alloc_netdev(sizeof(*i2400mu), "wmx%d", i2400mu_netdev_setup); if (net_dev == NULL) { dev_err(dev, "no memory for network device instance\n"); goto error_alloc_netdev; } SET_NETDEV_DEV(net_dev, dev); SET_NETDEV_DEVTYPE(net_dev, &i2400mu_type); i2400m = net_dev_to_i2400m(net_dev); i2400mu = container_of(i2400m, struct i2400mu, i2400m); i2400m->wimax_dev.net_dev = net_dev; i2400mu->usb_dev = usb_get_dev(usb_dev); i2400mu->usb_iface = iface; usb_set_intfdata(iface, i2400mu); i2400m->bus_tx_block_size = I2400MU_BLK_SIZE; /* * Room required in the Tx queue for USB message to accommodate * a smallest payload while allocating header space is 16 bytes. * Adding this room for the new tx message increases the * possibilities of including any payload with size <= 16 bytes. */ i2400m->bus_tx_room_min = I2400MU_BLK_SIZE; i2400m->bus_pl_size_max = I2400MU_PL_SIZE_MAX; i2400m->bus_setup = NULL; i2400m->bus_dev_start = i2400mu_bus_dev_start; i2400m->bus_dev_stop = i2400mu_bus_dev_stop; i2400m->bus_release = NULL; i2400m->bus_tx_kick = i2400mu_bus_tx_kick; i2400m->bus_reset = i2400mu_bus_reset; i2400m->bus_bm_retries = I2400M_USB_BOOT_RETRIES; i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send; i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack; i2400m->bus_bm_mac_addr_impaired = 0; switch (id->idProduct) { case USB_DEVICE_ID_I6050: case USB_DEVICE_ID_I6050_2: case USB_DEVICE_ID_I6150: case USB_DEVICE_ID_I6150_2: case USB_DEVICE_ID_I6150_3: case USB_DEVICE_ID_I6250: i2400mu->i6050 = 1; break; default: break; } if (i2400mu->i6050) { i2400m->bus_fw_names = i2400mu_bus_fw_names_6050; i2400mu->endpoint_cfg.bulk_out = 0; i2400mu->endpoint_cfg.notification = 3; i2400mu->endpoint_cfg.reset_cold = 2; i2400mu->endpoint_cfg.bulk_in = 1; } else { i2400m->bus_fw_names = i2400mu_bus_fw_names_5x50; i2400mu->endpoint_cfg.bulk_out = 0; i2400mu->endpoint_cfg.notification = 1; i2400mu->endpoint_cfg.reset_cold = 2; i2400mu->endpoint_cfg.bulk_in = 3; } #ifdef CONFIG_PM iface->needs_remote_wakeup = 1; /* autosuspend (15s delay) */ device_init_wakeup(dev, 1); pm_runtime_set_autosuspend_delay(&usb_dev->dev, 15000); usb_enable_autosuspend(usb_dev); #endif result = i2400m_setup(i2400m, I2400M_BRI_MAC_REINIT); if (result < 0) { dev_err(dev, "cannot setup device: %d\n", result); goto error_setup; } result = i2400mu_debugfs_add(i2400mu); if (result < 0) { dev_err(dev, "Can't register i2400mu's debugfs: %d\n", result); goto error_debugfs_add; } return 0; error_debugfs_add: i2400m_release(i2400m); error_setup: usb_set_intfdata(iface, NULL); usb_put_dev(i2400mu->usb_dev); free_netdev(net_dev); error_alloc_netdev: return result; }
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; struct usb_host_interface *intf = serial->interface->cur_altsetting; int retval = -ENODEV; __u8 nintf; __u8 ifnum; bool is_gobi1k = id->driver_info ? true : false; dbg("%s", __func__); dbg("Is Gobi 1000 = %d", is_gobi1k); nintf = serial->dev->actconfig->desc.bNumInterfaces; dbg("Num Interfaces = %d", nintf); ifnum = intf->desc.bInterfaceNumber; dbg("This Interface = %d", ifnum); data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; spin_lock_init(&data->susp_lock); /* ++SSD_RIL */ if (!(board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2)) /* --SSD_RIL */ usb_enable_autosuspend(serial->dev); switch (nintf) { case 1: /* QDL mode */ /* Gobi 2000 has a single altsetting, older ones have two */ if (serial->interface->num_altsetting == 2) intf = &serial->interface->altsetting[1]; else if (serial->interface->num_altsetting > 2) break; if (intf->desc.bNumEndpoints == 2 && usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { dbg("QDL port found"); if (serial->interface->num_altsetting == 1) { retval = 0; /* Success */ break; } retval = usb_set_interface(serial->dev, ifnum, 1); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; case 3: case 4: /* Composite mode; don't bind to the QMI/net interface as that * gets handled by other drivers. */ /* Gobi 1K USB layout: * 0: serial port (doesn't respond) * 1: serial port (doesn't respond) * 2: AT-capable modem port * 3: QMI/net * * Gobi 2K+ USB layout: * 0: QMI/net * 1: DM/DIAG (use libqcdm from ModemManager for communication) * 2: AT-capable modem port * 3: NMEA */ if (ifnum == 1 && !is_gobi1k) { dbg("Gobi 2K+ DM/DIAG interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum == 2) { dbg("Modem port found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum==3 && !is_gobi1k) { /* * NMEA (serial line 9600 8N1) * # echo "\$GPS_START" > /dev/ttyUSBx * # echo "\$GPS_STOP" > /dev/ttyUSBx */ dbg("Gobi 2K+ NMEA GPS interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; case 8: case 9: /* ++SSD_RIL */ if (get_radio_flag() & 0x20000) usb_diag_enable = true; /* --SSD_RIL */ if (ifnum != EFS_SYNC_IFC_NUM && !(!usb_diag_enable && ifnum == DUN_IFC_NUM && (board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2))) { /* SSD_RIL: Add DUN interface for serial USB*/ #ifdef CONFIG_BUILD_EDIAG if (ifnum != SYSMON_IFC_NUM) { #endif kfree(data); break; #ifdef CONFIG_BUILD_EDIAG } #endif } #ifdef CONFIG_BUILD_EDIAG if (ifnum == SYSMON_IFC_NUM) dev_info(&serial->dev->dev, "SYSMON device is created as TTY device\n"); #endif retval = 0; break; default: dev_err(&serial->dev->dev, "unknown number of interfaces: %d\n", nintf); kfree(data); retval = -ENODEV; } /* Set serial->private if not returning -ENODEV */ if (retval != -ENODEV) usb_set_serial_data(serial, data); return retval; }
static int rmnet_usb_probe(struct usb_interface *iface, const struct usb_device_id *prod) { struct usbnet *unet; struct driver_info *info = (struct driver_info *)prod->driver_info; struct usb_device *udev; int status = 0; unsigned int i, unet_id, rdev_cnt, n = 0; bool mux; struct rmnet_ctrl_dev *dev; udev = interface_to_usbdev(iface); if (iface->num_altsetting != 1) { dev_err(&iface->dev, "%s invalid num_altsetting %u\n", __func__, iface->num_altsetting); status = -EINVAL; goto out; } mux = test_bit(info->data, &mux_enabled); rdev_cnt = mux ? no_rmnet_insts_per_dev : 1; info->in = 0; for (n = 0; n < rdev_cnt; n++) { /* */ info->in++; status = usbnet_probe(iface, prod); if (status < 0) { dev_err(&iface->dev, "usbnet_probe failed %d\n", status); goto out; } unet_id = n + info->data * no_rmnet_insts_per_dev; unet_list[unet_id] = unet = usb_get_intfdata(iface); /* */ unet->data[3] = n; /* */ unet->data[1] = unet->data[4] = mux; /* */ set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]); /* */ rmnet_usb_setup(unet->net, mux); /* */ status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask); if (status) { usbnet_disconnect(iface); goto out; } status = rmnet_usb_ctrl_probe(iface, unet->status, info->data, &unet->data[1]); if (status) { device_remove_file(&unet->net->dev, &dev_attr_dbg_mask); usbnet_disconnect(iface); goto out; } status = rmnet_usb_data_debugfs_init(unet); if (status) dev_dbg(&iface->dev, "mode debugfs file is not available\n"); } usb_enable_autosuspend(udev); if (udev->parent && !udev->parent->parent) { /* */ device_set_wakeup_enable(&udev->dev, 1); device_set_wakeup_enable(&udev->parent->dev, 1); } return 0; out: for (i = 0; i < n; i++) { /* */ unet_id = i + info->data * no_rmnet_insts_per_dev; unet = unet_list[unet_id]; dev = (struct rmnet_ctrl_dev *)unet->data[1]; rmnet_usb_data_debugfs_cleanup(unet); rmnet_usb_ctrl_disconnect(dev); device_remove_file(&unet->net->dev, &dev_attr_dbg_mask); usb_set_intfdata(iface, unet_list[unet_id]); usbnet_disconnect(iface); unet_list[unet_id] = NULL; } return status; }
static int rmnet_usb_probe(struct usb_interface *iface, const struct usb_device_id *prod) { struct usbnet *unet; struct driver_info *info; struct usb_device *udev; unsigned int iface_num; static int first_rmnet_iface_num = -EINVAL; int status = 0; iface_num = iface->cur_altsetting->desc.bInterfaceNumber; if (iface->num_altsetting != 1) { dev_err(&iface->dev, "%s invalid num_altsetting %u\n", __func__, iface->num_altsetting); status = -EINVAL; goto out; } info = (struct driver_info *)prod->driver_info; if (!test_bit(iface_num, &info->data)) return -ENODEV; status = usbnet_probe(iface, prod); if (status < 0) { dev_err(&iface->dev, "usbnet_probe failed %d\n", status); goto out; } unet = usb_get_intfdata(iface); /*set rmnet operation mode to eth by default*/ set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]); /*update net device*/ rmnet_usb_setup(unet->net); /*create /sys/class/net/rmnet_usbx/dbg_mask*/ status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask); if (status) goto out; if (first_rmnet_iface_num == -EINVAL) first_rmnet_iface_num = iface_num; /*save control device intstance */ unet->data[1] = (unsigned long)ctrl_dev \ [iface_num - first_rmnet_iface_num]; status = rmnet_usb_ctrl_probe(iface, unet->status, (struct rmnet_ctrl_dev *)unet->data[1]); if (status) goto out; //ASUS_BSP+++ BennyCheng "fix rmnet driver probe fail with user build" #ifdef CONFIG_DEBUG_FS status = rmnet_usb_data_debugfs_init(unet); if (status) dev_dbg(&iface->dev, "mode debugfs file is not available\n"); #endif //ASUS_BSP--- BennyCheng "fix rmnet driver probe fail with user build" udev = unet->udev; usb_enable_autosuspend(udev); if (udev->parent && !udev->parent->parent) { /* allow modem and roothub to wake up suspended system */ device_set_wakeup_enable(&udev->dev, 1); device_set_wakeup_enable(&udev->parent->dev, 1); /* set default autosuspend timeout for modem and roothub */ //ASUS_BSP+++ BennyCheng "extend hsic autosuspend delay time from 1s to 2s" pm_runtime_set_autosuspend_delay(&udev->dev, 2000); //ASUS_BSP--- BennyCheng "extend hsic autosuspend delay time from 1s to 2s" pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200); } out: return status; }
static int chaoskey_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct usb_host_interface *altsetting = interface->cur_altsetting; int i; int in_ep = -1; struct chaoskey *dev; int result; int size; usb_dbg(interface, "probe %s-%s", udev->product, udev->serial); /* Find the first bulk IN endpoint and its packet size */ for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { if (usb_endpoint_is_bulk_in(&altsetting->endpoint[i].desc)) { in_ep = usb_endpoint_num(&altsetting->endpoint[i].desc); size = usb_endpoint_maxp(&altsetting->endpoint[i].desc); break; } } /* Validate endpoint and size */ if (in_ep == -1) { usb_dbg(interface, "no IN endpoint found"); return -ENODEV; } if (size <= 0) { usb_dbg(interface, "invalid size (%d)", size); return -ENODEV; } if (size > CHAOSKEY_BUF_LEN) { usb_dbg(interface, "size reduced from %d to %d\n", size, CHAOSKEY_BUF_LEN); size = CHAOSKEY_BUF_LEN; } /* Looks good, allocate and initialize */ dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL); if (dev == NULL) return -ENOMEM; dev->buf = kmalloc(size, GFP_KERNEL); if (dev->buf == NULL) { kfree(dev); return -ENOMEM; } /* Construct a name using the product and serial values. Each * device needs a unique name for the hwrng code */ if (udev->product && udev->serial) { dev->name = kmalloc(strlen(udev->product) + 1 + strlen(udev->serial) + 1, GFP_KERNEL); if (dev->name == NULL) { kfree(dev->buf); kfree(dev); return -ENOMEM; } strcpy(dev->name, udev->product); strcat(dev->name, "-"); strcat(dev->name, udev->serial); } dev->interface = interface; dev->in_ep = in_ep; dev->size = size; dev->present = 1; init_waitqueue_head(&dev->wait_q); mutex_init(&dev->lock); mutex_init(&dev->rng_lock); usb_set_intfdata(interface, dev); result = usb_register_dev(interface, &chaoskey_class); if (result) { usb_err(interface, "Unable to allocate minor number."); usb_set_intfdata(interface, NULL); chaoskey_free(dev); return result; } dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name; dev->hwrng.read = chaoskey_rng_read; /* Set the 'quality' metric. Quality is measured in units of * 1/1024's of a bit ("mills"). This should be set to 1024, * but there is a bug in the hwrng core which masks it with * 1023. * * The patch that has been merged to the crypto development * tree for that bug limits the value to 1024 at most, so by * setting this to 1024 + 1023, we get 1023 before the fix is * merged and 1024 afterwards. We'll patch this driver once * both bits of code are in the same tree. */ dev->hwrng.quality = 1024 + 1023; dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0); if (!dev->hwrng_registered) usb_err(interface, "Unable to register with hwrng"); usb_enable_autosuspend(udev); usb_dbg(interface, "chaoskey probe success, size %d", dev->size); return 0; }
static int __devinit if_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *data_desc; struct usb_link_device *usb_ld = (struct usb_link_device *)id->driver_info; struct link_device *ld = &usb_ld->ld; struct usb_interface *data_intf; struct usb_device *usbdev = interface_to_usbdev(intf); struct device *dev, *ehci_dev, *root_hub; struct if_usb_devdata *pipe; struct urb *urb; int i; int j; int dev_id; int err; /* To detect usb device order probed */ dev_id = intf->cur_altsetting->desc.bInterfaceNumber; if (dev_id >= IF_USB_DEVNUM_MAX) { dev_err(&intf->dev, "Device id %d cannot support\n", dev_id); return -EINVAL; } if (!usb_ld) { dev_err(&intf->dev, "if_usb device doesn't be allocated\n"); err = ENOMEM; goto out; } mif_info("probe dev_id=%d usb_device_id(0x%p), usb_ld (0x%p)\n", dev_id, id, usb_ld); usb_ld->usbdev = usbdev; usb_get_dev(usbdev); for (i = 0; i < IF_USB_DEVNUM_MAX; i++) { data_intf = usb_ifnum_to_if(usbdev, i); /* remap endpoint of RAW to no.1 for LTE modem */ if (i == 0) pipe = &usb_ld->devdata[1]; else if (i == 1) pipe = &usb_ld->devdata[0]; else pipe = &usb_ld->devdata[i]; pipe->disconnected = 0; pipe->data_intf = data_intf; data_desc = data_intf->cur_altsetting; /* Endpoints */ if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { pipe->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); pipe->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); pipe->rx_buf_size = 1024*4; } else { pipe->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); pipe->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); pipe->rx_buf_size = 1024*4; } if (i == 0) { dev_info(&usbdev->dev, "USB IF USB device found\n"); } else { err = usb_driver_claim_interface(&if_usb_driver, data_intf, usb_ld); if (err < 0) { mif_err("failed to cliam usb interface\n"); goto out; } } usb_set_intfdata(data_intf, usb_ld); usb_ld->dev_count++; pm_suspend_ignore_children(&data_intf->dev, true); for (j = 0; j < URB_COUNT; j++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { mif_err("alloc urb fail\n"); err = -ENOMEM; goto out2; } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer = usb_alloc_coherent(usbdev, pipe->rx_buf_size, GFP_KERNEL, &urb->transfer_dma); if (!urb->transfer_buffer) { mif_err( "Failed to allocate transfer buffer\n"); usb_free_urb(urb); err = -ENOMEM; goto out2; } usb_fill_bulk_urb(urb, usbdev, pipe->rx_pipe, urb->transfer_buffer, pipe->rx_buf_size, usb_rx_complete, pipe); usb_anchor_urb(urb, &pipe->urbs); } } /* temporary call reset_resume */ atomic_set(&usb_ld->suspend_count, 1); if_usb_reset_resume(data_intf); atomic_set(&usb_ld->suspend_count, 0); SET_HOST_ACTIVE(usb_ld->pdata, 1); usb_ld->host_wake_timeout_flag = 0; if (gpio_get_value(usb_ld->pdata->gpio_phone_active)) { struct link_pm_data *pm_data = usb_ld->link_pm_data; int delay = pm_data->autosuspend_delay_ms ?: DEFAULT_AUTOSUSPEND_DELAY_MS; pm_runtime_set_autosuspend_delay(&usbdev->dev, delay); dev = &usbdev->dev; if (dev->parent) { dev_dbg(&usbdev->dev, "if_usb Runtime PM Start!!\n"); usb_enable_autosuspend(usb_ld->usbdev); /* s5p-ehci runtime pm allow - usb phy suspend mode */ root_hub = &usbdev->bus->root_hub->dev; ehci_dev = root_hub->parent; mif_debug("ehci device = %s, %s\n", dev_driver_string(ehci_dev), dev_name(ehci_dev)); pm_runtime_allow(ehci_dev); if (!pm_data->autosuspend) pm_runtime_forbid(dev); if (has_hub(usb_ld)) link_pm_preactive(pm_data); pm_data->root_hub = root_hub; } usb_ld->flow_suspend = 0; /* Queue work if skbs were pending before a disconnect/probe */ if (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0); usb_ld->if_usb_connected = 1; /*USB3503*/ mif_debug("hub active complete\n"); usb_change_modem_state(usb_ld, STATE_ONLINE); } else {
static int chaoskey_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct usb_host_interface *altsetting = interface->cur_altsetting; struct usb_endpoint_descriptor *epd; int in_ep; struct chaoskey *dev; int result = -ENOMEM; int size; int res; usb_dbg(interface, "probe %s-%s", udev->product, udev->serial); /* Find the first bulk IN endpoint and its packet size */ res = usb_find_bulk_in_endpoint(altsetting, &epd); if (res) { usb_dbg(interface, "no IN endpoint found"); return res; } in_ep = usb_endpoint_num(epd); size = usb_endpoint_maxp(epd); /* Validate endpoint and size */ if (size <= 0) { usb_dbg(interface, "invalid size (%d)", size); return -ENODEV; } if (size > CHAOSKEY_BUF_LEN) { usb_dbg(interface, "size reduced from %d to %d\n", size, CHAOSKEY_BUF_LEN); size = CHAOSKEY_BUF_LEN; } /* Looks good, allocate and initialize */ dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL); if (dev == NULL) goto out; dev->buf = kmalloc(size, GFP_KERNEL); if (dev->buf == NULL) goto out; dev->urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->urb) goto out; usb_fill_bulk_urb(dev->urb, udev, usb_rcvbulkpipe(udev, in_ep), dev->buf, size, chaos_read_callback, dev); /* Construct a name using the product and serial values. Each * device needs a unique name for the hwrng code */ if (udev->product && udev->serial) { dev->name = kmalloc(strlen(udev->product) + 1 + strlen(udev->serial) + 1, GFP_KERNEL); if (dev->name == NULL) goto out; strcpy(dev->name, udev->product); strcat(dev->name, "-"); strcat(dev->name, udev->serial); } dev->interface = interface; dev->in_ep = in_ep; if (le16_to_cpu(udev->descriptor.idVendor) != ALEA_VENDOR_ID) dev->reads_started = 1; dev->size = size; dev->present = 1; init_waitqueue_head(&dev->wait_q); mutex_init(&dev->lock); mutex_init(&dev->rng_lock); usb_set_intfdata(interface, dev); result = usb_register_dev(interface, &chaoskey_class); if (result) { usb_err(interface, "Unable to allocate minor number."); goto out; } dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name; dev->hwrng.read = chaoskey_rng_read; dev->hwrng.quality = 1024; dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0); if (!dev->hwrng_registered) usb_err(interface, "Unable to register with hwrng"); usb_enable_autosuspend(udev); usb_dbg(interface, "chaoskey probe success, size %d", dev->size); return 0; out: usb_set_intfdata(interface, NULL); chaoskey_free(dev); return result; }
static int hsictty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; struct hsictty_port_private *portdata; struct hsictty_intf_private *intfdata; int channel = -1; int ret = -EINVAL; portdata = usb_get_serial_port_data(port); intfdata = usb_get_serial_data(port->serial); down(&portdata->ch_sem_w); down(&portdata->ch_sem_r); channel = tty->index; if (!intfdata->multi_channel_mode && channel != HSIC_DATA_START_CHANNEL) { hsictty_dbg("%s: invalid channel mode -- ch:%d!\n", __func__, channel); goto out; } switch (cmd) { case HSIC_TTY_IOCTL_SET_MULTIMODE: { int mode = 1; int i = 0, j = 0; struct usb_serial_port *port_tmp; struct hsictty_port_private *portdata_tmp; struct urb *urb; if (copy_from_user(&mode, (int *)arg, sizeof(int))) { hsictty_error("%s: copy param failed\n", __func__); ret = -EFAULT; goto out; } intfdata->multi_channel_mode = mode; /*set tx zlp support for multi-channel, clear tx zlp support for bootrom */ for (i = 0; i < port->serial->num_ports; ++i) { port_tmp = port->serial->port[i]; portdata_tmp = usb_get_serial_port_data(port_tmp); for (j = 0; j < N_OUT_URB; j++) { urb = portdata_tmp->out_urbs[j]; if (urb) { if (mode) urb->transfer_flags |= URB_ZERO_PACKET; else urb->transfer_flags &= ~URB_ZERO_PACKET; } } } hsictty_dbg ("%s: set hsic tty multi-channel mode to [%d][%s] from user space!\n", __func__, mode, mode ? "multi-channel mode" : "single channel mode"); } break; case HSIC_TTY_IOCTL_HSIC_RESET: { int i = 0; struct usb_serial_port *port_tmp; struct hsictty_port_private *portdata_tmp; //struct tty_struct *tty = NULL; pm_qos_update_request_timeout(&dl_kfc_num_qos, 3, 15 * 1000 * 1000); pm_qos_update_request_timeout(&dl_kfc_freq_qos, 1200000, 15 * 1000 * 1000); if (intfdata->support_pm) { pm_runtime_resume(&port->serial->dev->dev); usb_disable_autosuspend(port->serial->dev); } intfdata->multi_channel_mode = 0; for (i = 1; i < port->serial->num_ports; ++i) { port_tmp = port->serial->port[i]; portdata_tmp = usb_get_serial_port_data(port_tmp); portdata_tmp->opened = 0; #ifndef USE_READ_WORK complete_all(&portdata_tmp->rx_notifier); #endif complete_all(&portdata_tmp->tx_notifier); /* hangup here before diconncest marked * may casue tty abnormally opened in serial core. tty = tty_port_tty_get(&port_tmp->port); if (tty) { tty_vhangup(tty); tty_kref_put(tty); } */ clear_bit(i, &intfdata->channel_open_flag); } #ifdef BACKUP_DATA_DUMP if (!dumped) { dumped = 1; backup_dump(HSIC_DATA_START_CHANNEL, 0); backup_dump(HSIC_DATA_START_CHANNEL, 1); } #endif hsictty_info ("%s: hsic tty reset triggerred from userspace!\n", __func__); } break; case HSIC_TTY_IOCTL_HSIC_PM_ENABLE: if (intfdata->support_pm) { usb_enable_autosuspend(port->serial->dev); //pm_runtime_set_autosuspend_delay(&port->serial->dev->dev, 200); /* enable ehci root_hub runtime_pm */ pm_runtime_allow(port->serial->dev->dev.parent->parent); } hsictty_info("%s: hsic pm enable from userspace!\n", __func__); break; default: hsictty_error("%s: illgal command !\n", __func__); ret = -ENOIOCTLCMD; goto out; } ret = 0; out: up(&portdata->ch_sem_w); up(&portdata->ch_sem_r); return ret; }
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; struct usb_host_interface *intf = serial->interface->cur_altsetting; int retval = -ENODEV; __u8 nintf; __u8 ifnum; dbg("%s", __func__); nintf = serial->dev->actconfig->desc.bNumInterfaces; dbg("Num Interfaces = %d", nintf); ifnum = intf->desc.bInterfaceNumber; dbg("This Interface = %d", ifnum); data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; spin_lock_init(&data->susp_lock); usb_enable_autosuspend(serial->dev); switch (nintf) { case 1: /* QDL mode */ /* Gobi 2000 has a single altsetting, older ones have two */ if (serial->interface->num_altsetting == 2) intf = &serial->interface->altsetting[1]; else if (serial->interface->num_altsetting > 2) break; if (intf->desc.bNumEndpoints == 2 && usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { dbg("QDL port found"); if (serial->interface->num_altsetting == 1) { retval = 0; /* Success */ break; } retval = usb_set_interface(serial->dev, ifnum, 1); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; case 3: case 4: /* Composite mode */ /* ifnum == 0 is a broadband network adapter */ if (ifnum == 1) { /* * Diagnostics Monitor (serial line 9600 8N1) * Qualcomm DM protocol * use "libqcdm" (ModemManager) for communication */ dbg("Diagnostics Monitor found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum == 2) { dbg("Modem port found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum==3) { /* * NMEA (serial line 9600 8N1) * # echo "\$GPS_START" > /dev/ttyUSBx * # echo "\$GPS_STOP" > /dev/ttyUSBx */ dbg("NMEA GPS interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; default: dev_err(&serial->dev->dev, "unknown number of interfaces: %d\n", nintf); kfree(data); retval = -ENODEV; } /* Set serial->private if not returning -ENODEV */ if (retval != -ENODEV) usb_set_serial_data(serial, data); return retval; }
static int ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) { __u8 ifc_num; struct usb_host_interface *ifc_desc; struct usb_endpoint_descriptor *ep_desc; int i; struct ks_bridge *ksb; ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber; switch (id->idProduct) { case 0x9008: if (ifc_num != 0) return -ENODEV; ksb = __ksb[BOOT_BRIDGE_INDEX]; break; case 0x9048: case 0x904C: if (ifc_num != 2) return -ENODEV; ksb = __ksb[EFS_BRIDGE_INDEX]; break; default: return -ENODEV; } if (!ksb) { pr_err("ksb is not initialized"); return -ENODEV; } ksb->udev = usb_get_dev(interface_to_usbdev(ifc)); ksb->ifc = ifc; ifc_desc = ifc->cur_altsetting; for (i = 0; i < ifc_desc->desc.bNumEndpoints; i++) { ep_desc = &ifc_desc->endpoint[i].desc; if (!ksb->in_epAddr && usb_endpoint_is_bulk_in(ep_desc)) ksb->in_epAddr = ep_desc->bEndpointAddress; if (!ksb->out_epAddr && usb_endpoint_is_bulk_out(ep_desc)) ksb->out_epAddr = ep_desc->bEndpointAddress; } if (!(ksb->in_epAddr && ksb->out_epAddr)) { pr_err("could not find bulk in and bulk out endpoints"); usb_put_dev(ksb->udev); ksb->ifc = NULL; return -ENODEV; } ksb->in_pipe = usb_rcvbulkpipe(ksb->udev, ksb->in_epAddr); ksb->out_pipe = usb_sndbulkpipe(ksb->udev, ksb->out_epAddr); usb_set_intfdata(ifc, ksb); set_bit(USB_DEV_CONNECTED, &ksb->flags); dbg_log_event(ksb, "PID-ATT", id->idProduct, 0); ksb->fs_dev = (struct miscdevice *)id->driver_info; misc_register(ksb->fs_dev); ifc->needs_remote_wakeup = 1; usb_enable_autosuspend(ksb->udev); pr_debug("usb dev connected"); return 0; }
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; struct usb_host_interface *intf = serial->interface->cur_altsetting; int retval = -ENODEV; __u8 nintf; __u8 ifnum; bool is_gobi1k = id->driver_info ? true : false; dbg("%s", __func__); dbg("Is Gobi 1000 = %d", is_gobi1k); nintf = serial->dev->actconfig->desc.bNumInterfaces; dbg("Num Interfaces = %d", nintf); ifnum = intf->desc.bInterfaceNumber; dbg("This Interface = %d", ifnum); data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; spin_lock_init(&data->susp_lock); #ifdef CONFIG_MDM_HSIC_PM if (id->idVendor == 0x05c6 && id->idProduct == 0x9008) check_chip_configuration(serial->dev->product); if (id->idVendor == 0x05c6 && (id->idProduct == 0x9008 || id->idProduct == 0x9048 || id->idProduct == 0x904c)) goto set_interface; usb_enable_autosuspend(serial->dev); set_interface: #endif switch (nintf) { case 1: /* QDL mode */ /* Gobi 2000 has a single altsetting, older ones have two */ if (serial->interface->num_altsetting == 2) intf = &serial->interface->altsetting[1]; else if (serial->interface->num_altsetting > 2) break; if (intf->desc.bNumEndpoints == 2 && usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { dbg("QDL port found"); if (serial->interface->num_altsetting == 1) { retval = 0; /* Success */ break; } retval = usb_set_interface(serial->dev, ifnum, 1); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; case 3: case 4: /* Composite mode; don't bind to the QMI/net interface as that * gets handled by other drivers. */ /* Gobi 1K USB layout: * 0: serial port (doesn't respond) * 1: serial port (doesn't respond) * 2: AT-capable modem port * 3: QMI/net * * Gobi 2K+ USB layout: * 0: QMI/net * 1: DM/DIAG (use libqcdm from ModemManager for communication) * 2: AT-capable modem port * 3: NMEA */ if (ifnum == 1 && !is_gobi1k) { dbg("Gobi 2K+ DM/DIAG interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum == 2) { dbg("Modem port found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } else if (ifnum==3 && !is_gobi1k) { /* * NMEA (serial line 9600 8N1) * # echo "\$GPS_START" > /dev/ttyUSBx * # echo "\$GPS_STOP" > /dev/ttyUSBx */ dbg("Gobi 2K+ NMEA GPS interface found"); retval = usb_set_interface(serial->dev, ifnum, 0); if (retval < 0) { dev_err(&serial->dev->dev, "Could not set interface, error %d\n", retval); retval = -ENODEV; kfree(data); } } break; case 9: if (ifnum != EFS_SYNC_IFC_NUM) { kfree(data); break; } retval = 0; break; default: dev_err(&serial->dev->dev, "unknown number of interfaces: %d\n", nintf); kfree(data); retval = -ENODEV; } /* Set serial->private if not returning -ENODEV */ if (retval != -ENODEV) usb_set_serial_data(serial, data); return retval; }
static int ipc_bridge_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct ipc_bridge *dev; struct usb_device *udev = interface_to_usbdev(intf); struct usb_host_interface *intf_desc; struct usb_endpoint_descriptor *ep; u16 wMaxPacketSize; int ret; intf_desc = intf->cur_altsetting; if (intf_desc->desc.bNumEndpoints != 1 || !usb_endpoint_is_int_in( &intf_desc->endpoint[0].desc)) { dev_err(&intf->dev, "driver expects only 1 int ep\n"); return -ENODEV; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { dev_err(&intf->dev, "fail to allocate dev\n"); return -ENOMEM; } __ipc_bridge_dev = dev; dev->inturb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->inturb) { dev_err(&intf->dev, "fail to allocate int urb\n"); ret = -ENOMEM; goto free_dev; } ep = &intf->cur_altsetting->endpoint[0].desc; wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); dev->intbuf = kmalloc(wMaxPacketSize, GFP_KERNEL); if (!dev->intbuf) { dev_err(&intf->dev, "%s: error allocating int buffer\n", __func__); ret = -ENOMEM; goto free_inturb; } usb_fill_int_urb(dev->inturb, udev, usb_rcvintpipe(udev, ep->bEndpointAddress), dev->intbuf, wMaxPacketSize, ipc_bridge_int_cb, dev, ep->bInterval); dev->in_ctlreq = kmalloc(sizeof(*dev->in_ctlreq), GFP_KERNEL); if (!dev->in_ctlreq) { dev_err(&intf->dev, "error allocating IN control req\n"); ret = -ENOMEM; goto free_intbuf; } dev->in_ctlreq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); dev->in_ctlreq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; dev->in_ctlreq->wValue = 0; dev->in_ctlreq->wIndex = intf->cur_altsetting->desc.bInterfaceNumber; dev->in_ctlreq->wLength = cpu_to_le16(IPC_BRIDGE_MAX_READ_SZ); dev->readurb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->readurb) { dev_err(&intf->dev, "fail to allocate read urb\n"); ret = -ENOMEM; goto free_in_ctlreq; } dev->readbuf = kmalloc(IPC_BRIDGE_MAX_READ_SZ, GFP_KERNEL); if (!dev->readbuf) { dev_err(&intf->dev, "fail to allocate read buffer\n"); ret = -ENOMEM; goto free_readurb; } dev->out_ctlreq = kmalloc(sizeof(*dev->out_ctlreq), GFP_KERNEL); if (!dev->out_ctlreq) { dev_err(&intf->dev, "error allocating OUT control req\n"); ret = -ENOMEM; goto free_readbuf; } dev->out_ctlreq->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); dev->out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; dev->out_ctlreq->wValue = 0; dev->out_ctlreq->wIndex = intf->cur_altsetting->desc.bInterfaceNumber; dev->writeurb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->writeurb) { dev_err(&intf->dev, "fail to allocate write urb\n"); ret = -ENOMEM; goto free_out_ctlreq; } dev->udev = usb_get_dev(interface_to_usbdev(intf)); dev->intf = intf; spin_lock_init(&dev->lock); init_completion(&dev->write_done); init_waitqueue_head(&dev->read_wait_q); INIT_LIST_HEAD(&dev->rx_list); mutex_init(&dev->open_mutex); mutex_init(&dev->read_mutex); mutex_init(&dev->write_mutex); usb_set_intfdata(intf, dev); usb_enable_autosuspend(udev); dev->pdev = platform_device_alloc("ipc_bridge", -1); if (!dev->pdev) { dev_err(&intf->dev, "fail to allocate pdev\n"); ret = -ENOMEM; goto destroy_mutex; } ret = platform_device_add_data(dev->pdev, &ipc_bridge_pdata, sizeof(struct ipc_bridge_platform_data)); if (ret) { dev_err(&intf->dev, "fail to add pdata\n"); goto put_pdev; } ret = platform_device_add(dev->pdev); if (ret) { dev_err(&intf->dev, "fail to add pdev\n"); goto put_pdev; } ret = ipc_bridge_submit_inturb(dev, GFP_KERNEL); if (ret) { dev_err(&intf->dev, "fail to start reading\n"); goto del_pdev; } ipc_bridge_debugfs_init(); return 0; del_pdev: platform_device_del(dev->pdev); put_pdev: platform_device_put(dev->pdev); destroy_mutex: usb_disable_autosuspend(udev); mutex_destroy(&dev->write_mutex); mutex_destroy(&dev->read_mutex); mutex_destroy(&dev->open_mutex); usb_put_dev(dev->udev); usb_free_urb(dev->writeurb); free_out_ctlreq: kfree(dev->out_ctlreq); free_readbuf: kfree(dev->readbuf); free_readurb: usb_free_urb(dev->readurb); free_in_ctlreq: kfree(dev->in_ctlreq); free_intbuf: kfree(dev->intbuf); free_inturb: usb_free_urb(dev->inturb); free_dev: kfree(dev); __ipc_bridge_dev = NULL; return ret; }
/* the root hub will call this callback when device added/removed */ void hsic_notify(struct usb_device *udev, unsigned action) { int retval; struct pci_dev *pdev = to_pci_dev(udev->bus->controller); printk(KERN_ERR "pdev device ID: %d, portnum: %d", pdev->device, udev->portnum); /* Ignore and only valid for HSIC. Filter out * the USB devices added by other USB2 host driver */ if (pdev->device != USH_PCI_ID) return; /* Ignore USB devices on external hub */ if (udev->parent && udev->parent->parent) return; switch (action) { case USB_DEVICE_ADD: pr_debug("Notify HSIC add device\n"); /* Root hub */ if (!udev->parent) { if (udev->speed == USB_SPEED_HIGH) { pr_debug("%s rh device set\n", __func__); hsic.rh_dev = udev; pr_debug("%s Disable autosuspend\n", __func__); pm_runtime_set_autosuspend_delay(&udev->dev, hsic.bus_inactivityDuration); usb_disable_autosuspend(udev); } } else { if (udev->portnum != HSIC_USH_PORT) { pr_debug("%s ignore ush ports except port5\n", __func__); pr_debug("%s ush ports %d\n", __func__, udev->portnum); break; } /* Modem devices */ hsic.modem_dev = udev; pm_runtime_set_autosuspend_delay (&udev->dev, hsic.port_inactivityDuration); if (hsic.remoteWakeup_enable) { pr_debug("%s Modem dev remote wakeup enabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 1); device_set_wakeup_capable (&hsic.rh_dev->dev, 1); } else { pr_debug("%s Modem dev remote wakeup disabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 0); device_set_wakeup_capable (&hsic.rh_dev->dev, 0); } usb_disable_autosuspend(hsic.modem_dev); usb_disable_autosuspend(hsic.rh_dev); #if 0 if (hsic.autosuspend_enable) { pr_debug("%s----> enable autosuspend\n", __func__); usb_enable_autosuspend(udev->parent); hsic_wakeup_irq_init(); } if (hsic.autosuspend_enable == 0) { pr_debug("%s Modem dev autosuspend disable\n", __func__); usb_disable_autosuspend(hsic.modem_dev); } #endif } break; case USB_DEVICE_REMOVE: pr_debug("Notify HSIC delete device\n"); /* Root hub */ if (udev->speed != USB_SPEED_HIGH) { pr_debug("%s ignore ss port\n", __func__); break; } if (!udev->parent) { pr_debug("%s rh_dev deleted\n", __func__); hsic.rh_dev = NULL; } else { /* Modem devices */ pr_debug("%s----> modem dev deleted\n", __func__); hsic.modem_dev = NULL; usb_disable_autosuspend(hsic.rh_dev); } break; case MODEM_WORK_FLUSH: if (udev == hsic.modem_dev) { pr_debug("Notify MODEM work flush\n"); synchronize_irq(gpio_to_irq(hsic.aux_gpio)); flush_work(&hsic.hsic_aux); } break; default: pr_debug("Notify action not supported\n"); break ; } return; }
static ssize_t hsic_port_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int retval; int org_req; if (size > HSIC_ENABLE_SIZE) return -EINVAL; if (sscanf(buf, "%d", &org_req) != 1) { dev_dbg(dev, "Invalid, value\n"); return -EINVAL; } if (delayed_work_pending(&hsic.hsic_aux)) { dev_dbg(dev, "%s---->Wait for delayed work finish\n", __func__); retval = wait_event_interruptible(hsic.aux_wq, hsic.hsic_aux_finish); if (retval < 0) return retval; if (org_req) return size; } mutex_lock(&hsic.hsic_mutex); if (!hsic.rh_dev) { dev_dbg(&pci_dev->dev, "root hub is already removed\n"); mutex_unlock(&hsic.hsic_mutex); return -ENODEV; } if (hsic.modem_dev) { pm_runtime_get_sync(&hsic.modem_dev->dev); pm_runtime_put(&hsic.modem_dev->dev); } if (hsic.rh_dev) { pm_runtime_get_sync(&hsic.rh_dev->dev); pm_runtime_put(&hsic.rh_dev->dev); } if (hsic.port_disconnect == 0) hsic_port_logical_disconnect(hsic.rh_dev, HSIC_USH_PORT); else ush_hsic_port_disable(); if (org_req) { dev_dbg(dev, "enable hsic\n"); msleep(20); ush_hsic_port_enable(); } else { dev_dbg(dev, "disable hsic\n"); if ((hsic.rh_dev) && (hsic.autosuspend_enable == 0)) { hsic.autosuspend_enable = 1; usb_enable_autosuspend(hsic.rh_dev); } } mutex_unlock(&hsic.hsic_mutex); return size; }
/* the root hub will call this callback when device added/removed */ static void hsic_notify(struct usb_device *udev, unsigned action) { int retval; struct pci_dev *pdev = to_pci_dev(udev->bus->controller); /* Ignore and only valid for HSIC. Filter out * the USB devices added by other USB2 host driver */ if (pdev->device != 0x119d) return; /* Ignore USB devices on external hub */ if (udev->parent && udev->parent->parent) return; /* Only valid for hsic port1 */ if (udev->portnum == 2) { pr_debug("%s ignore hsic port2\n", __func__); return; } switch (action) { case USB_DEVICE_ADD: pr_debug("Notify HSIC add device\n"); /* Root hub */ if (!udev->parent) { hsic.rh_dev = udev; pr_debug("%s Enable autosuspend\n", __func__); pm_runtime_set_autosuspend_delay(&udev->dev, hsic.bus_inactivityDuration); hsic.autosuspend_enable = 1; usb_enable_autosuspend(udev); } else { /* Modem devices */ hsic.modem_dev = udev; pm_runtime_set_autosuspend_delay (&udev->dev, hsic.port_inactivityDuration); udev->persist_enabled = 0; if (hsic.remoteWakeup_enable) { pr_debug("%s Modem dev remote wakeup enabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 1); device_set_wakeup_capable (&hsic.rh_dev->dev, 1); } else { pr_debug("%s Modem dev remote wakeup disabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 0); device_set_wakeup_capable (&hsic.rh_dev->dev, 0); } pr_debug("%s Disable autosuspend\n", __func__); usb_disable_autosuspend(hsic.modem_dev); hsic.autosuspend_enable = 0; pr_debug("%s----> Enable AUX irq\n", __func__); retval = hsic_aux_irq_init(); if (retval) dev_err(&pci_dev->dev, "unable to request IRQ\n"); } break; case USB_DEVICE_REMOVE: pr_debug("Notify HSIC delete device\n"); /* Root hub */ if (!udev->parent) { pr_debug("%s rh_dev deleted\n", __func__); hsic.rh_dev = NULL; hsic.autosuspend_enable = 1; } else { /* Modem devices */ pr_debug("%s----> modem dev deleted\n", __func__); hsic.modem_dev = NULL; } s3_wake_unlock(); break; default: pr_debug("Notify action not supported\n"); break ; } return; }
/** * @brief This function makes USB device to suspend. * * @param handle A pointer to moal_handle structure * * @return 0 --success, otherwise fail */ int woal_enter_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 == MTRUE) { PRINTM(MERROR, "Device already suspended\n"); LEAVE(); return -EFAULT; } handle->suspend_wait_q_woken = MFALSE; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) #ifdef CONFIG_PM /* Enter into USB suspend */ usb_lock_device(udev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) udev->autosuspend_delay = 0; /* Autosuspend delay in jiffies */ #else pm_runtime_set_autosuspend_delay(&udev->dev, 0); /* Autosuspend delay in jiffies */ #endif /* < 2.6.38 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) udev->autosuspend_disabled = 0; /* /sys/bus/usb/devices/.../power/level < auto */ #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 = 1; #else atomic_set(&intf->pm_usage_cnt, 1); #endif /* < 2.6.32 */ usb_autopm_put_interface(intf); #else usb_lock_device(udev); atomic_set(&udev->dev.power.usage_count, 1); usb_enable_autosuspend(udev); usb_unlock_device(udev); #endif /* < 2.6.34 */ #endif /* >= 2.6.24 */ #endif /* CONFIG_PM */ //lxy /* Wait for suspend to complete */ wait_event_interruptible(handle->suspend_wait_q, handle->suspend_wait_q_woken); LEAVE(); return 0; }
static int rmnet_usb_probe(struct usb_interface *iface, const struct usb_device_id *prod) { struct usbnet *unet; struct driver_info *info = (struct driver_info *)prod->driver_info; struct usb_device *udev; int status = 0; unsigned int i, unet_id, rdev_cnt, n = 0; bool mux; struct rmnet_ctrl_dev *dev; udev = interface_to_usbdev(iface); if (iface->num_altsetting != 1) { dev_err(&iface->dev, "%s invalid num_altsetting %u\n", __func__, iface->num_altsetting); status = -EINVAL; goto out; } mux = test_bit(info->data, &mux_enabled); rdev_cnt = mux ? no_rmnet_insts_per_dev : 1; info->in = 0; for (n = 0; n < rdev_cnt; n++) { /* Use this filed to increment device count this will be * used by bind to determin the forward link and reverse * link network interface names. */ info->in++; status = usbnet_probe(iface, prod); if (status < 0) { dev_err(&iface->dev, "usbnet_probe failed %d\n", status); goto out; } unet_id = n + info->data * no_rmnet_insts_per_dev; unet_list[unet_id] = unet = usb_get_intfdata(iface); /*store mux id for later access*/ unet->data[3] = n; /*save mux info for control and usbnet devices*/ unet->data[1] = unet->data[4] = mux; /*set rmnet operation mode to eth by default*/ set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]); /*update net device*/ rmnet_usb_setup(unet->net, mux); /*create /sys/class/net/rmnet_usbx/dbg_mask*/ status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask); if (status) { usbnet_disconnect(iface); goto out; } status = rmnet_usb_ctrl_probe(iface, unet->status, info->data, &unet->data[1]); if (status) { device_remove_file(&unet->net->dev, &dev_attr_dbg_mask); usbnet_disconnect(iface); goto out; } status = rmnet_usb_data_debugfs_init(unet); if (status) dev_dbg(&iface->dev, "mode debugfs file is not available\n"); } usb_enable_autosuspend(udev); if (udev->parent && !udev->parent->parent) { /* allow modem and roothub to wake up suspended system */ device_set_wakeup_enable(&udev->dev, 1); device_set_wakeup_enable(&udev->parent->dev, 1); } return 0; out: for (i = 0; i < n; i++) { /* This cleanup happens only for MUX case */ unet_id = i + info->data * no_rmnet_insts_per_dev; unet = unet_list[unet_id]; dev = (struct rmnet_ctrl_dev *)unet->data[1]; rmnet_usb_data_debugfs_cleanup(unet); rmnet_usb_ctrl_disconnect(dev); device_remove_file(&unet->net->dev, &dev_attr_dbg_mask); usb_set_intfdata(iface, unet_list[unet_id]); usbnet_disconnect(iface); unet_list[unet_id] = NULL; } return status; }
static void hsicdev_add(struct usb_device *udev) { pr_debug("Notify HSIC add device\n"); if (is_ush_hsic(udev) == 0) { pr_debug("Not a USH HSIC device\n"); return; } /* Root hub */ if (!udev->parent) { if (udev->speed == USB_SPEED_HIGH) { pr_debug("%s rh device set\n", __func__); hsic.rh_dev = udev; pr_debug("%s Disable autosuspend\n", __func__); pm_runtime_set_autosuspend_delay(&udev->dev, hsic.bus_inactivityDuration); usb_disable_autosuspend(udev); hsic.autosuspend_enable = 0; } } else { if (udev->portnum != HSIC_USH_PORT) { pr_debug("%s ignore ush ports %d\n", __func__, udev->portnum); return; } /* Modem devices */ hsic.port_disconnect = 0; hsic.modem_dev = udev; pm_runtime_set_autosuspend_delay (&udev->dev, hsic.port_inactivityDuration); if (hsic.remoteWakeup_enable) { pr_debug("%s Modem dev remote wakeup enabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 1); device_set_wakeup_capable (&hsic.rh_dev->dev, 1); } else { pr_debug("%s Modem dev remote wakeup disabled\n", __func__); device_set_wakeup_capable (&hsic.modem_dev->dev, 0); device_set_wakeup_capable (&hsic.rh_dev->dev, 0); } hsic.autosuspend_enable = HSIC_AUTOSUSPEND; if (hsic.autosuspend_enable) { pr_debug("%s----> enable autosuspend\n", __func__); usb_enable_autosuspend(hsic.modem_dev); usb_enable_autosuspend(hsic.rh_dev); hsic_wakeup_irq_init(); } if (hsic.autosuspend_enable == 0) { pr_debug("%s Modem dev autosuspend disable\n", __func__); usb_disable_autosuspend(hsic.modem_dev); usb_disable_autosuspend(hsic.rh_dev); } } }