static int __init bridge_init(void) { struct data_bridge *dev; int ret; int i = 0; ret = ctrl_bridge_init(); if (ret) return ret; bridge_wq = create_singlethread_workqueue("mdm_bridge"); if (!bridge_wq) { pr_err("%s: Unable to create workqueue:bridge\n", __func__); ret = -ENOMEM; goto free_ctrl; } for (i = 0; i < MAX_BRIDGE_DEVICES; i++) { dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { err("%s: unable to allocate dev\n", __func__); ret = -ENOMEM; goto error; } dev->wq = bridge_wq; /*transport name will be set during probe*/ dev->name = "none"; init_usb_anchor(&dev->tx_active); init_usb_anchor(&dev->rx_active); INIT_LIST_HEAD(&dev->rx_idle); skb_queue_head_init(&dev->rx_done); INIT_WORK(&dev->kevent, defer_kevent); INIT_WORK(&dev->process_rx_w, data_bridge_process_rx); __dev[i] = dev; } ret = usb_register(&bridge_driver); if (ret) { err("%s: unable to register mdm_bridge driver", __func__); goto error; } data_bridge_debugfs_init(); // ASUS_BSP+++ Wenli "tty device for AT command" #ifndef DISABLE_ASUS_DUN gdun_tty_setup(); #endif // ASUS_BSP--- Wenli "tty device for AT command" return 0; error: while (--i >= 0) { kfree(__dev[i]); __dev[i] = NULL; } destroy_workqueue(bridge_wq); free_ctrl: ctrl_bridge_exit(); return ret; }
/** * hdm_probe - probe function of USB device driver * @interface: Interface of the attached USB device * @id: Pointer to the USB ID table. * * This allocates and initializes the device instance, adds the new * entry to the internal list, scans the USB descriptors and registers * the interface with the core. * Additionally, the DCI objects are created and the hardware is sync'd. * * Return 0 on success. In case of an error a negative number is returned. */ static int hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_host_interface *usb_iface_desc = interface->cur_altsetting; struct usb_device *usb_dev = interface_to_usbdev(interface); struct device *dev = &usb_dev->dev; struct most_dev *mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); unsigned int i; unsigned int num_endpoints; struct most_channel_capability *tmp_cap; struct usb_endpoint_descriptor *ep_desc; int ret = 0; if (!mdev) goto err_out_of_memory; usb_set_intfdata(interface, mdev); num_endpoints = usb_iface_desc->desc.bNumEndpoints; mutex_init(&mdev->io_mutex); INIT_WORK(&mdev->poll_work_obj, wq_netinfo); timer_setup(&mdev->link_stat_timer, link_stat_timer_handler, 0); mdev->usb_device = usb_dev; mdev->link_stat_timer.expires = jiffies + (2 * HZ); mdev->iface.mod = hdm_usb_fops.owner; mdev->iface.driver_dev = &interface->dev; mdev->iface.interface = ITYPE_USB; mdev->iface.configure = hdm_configure_channel; mdev->iface.request_netinfo = hdm_request_netinfo; mdev->iface.enqueue = hdm_enqueue; mdev->iface.poison_channel = hdm_poison_channel; mdev->iface.dma_alloc = hdm_dma_alloc; mdev->iface.dma_free = hdm_dma_free; mdev->iface.description = mdev->description; mdev->iface.num_channels = num_endpoints; snprintf(mdev->description, sizeof(mdev->description), "%d-%s:%d.%d", usb_dev->bus->busnum, usb_dev->devpath, usb_dev->config->desc.bConfigurationValue, usb_iface_desc->desc.bInterfaceNumber); mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL); if (!mdev->conf) goto err_free_mdev; mdev->cap = kcalloc(num_endpoints, sizeof(*mdev->cap), GFP_KERNEL); if (!mdev->cap) goto err_free_conf; mdev->iface.channel_vector = mdev->cap; mdev->ep_address = kcalloc(num_endpoints, sizeof(*mdev->ep_address), GFP_KERNEL); if (!mdev->ep_address) goto err_free_cap; mdev->busy_urbs = kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL); if (!mdev->busy_urbs) goto err_free_ep_address; tmp_cap = mdev->cap; for (i = 0; i < num_endpoints; i++) { ep_desc = &usb_iface_desc->endpoint[i].desc; mdev->ep_address[i] = ep_desc->bEndpointAddress; mdev->padding_active[i] = false; mdev->is_channel_healthy[i] = true; snprintf(&mdev->suffix[i][0], MAX_SUFFIX_LEN, "ep%02x", mdev->ep_address[i]); tmp_cap->name_suffix = &mdev->suffix[i][0]; tmp_cap->buffer_size_packet = MAX_BUF_SIZE; tmp_cap->buffer_size_streaming = MAX_BUF_SIZE; tmp_cap->num_buffers_packet = BUF_CHAIN_SIZE; tmp_cap->num_buffers_streaming = BUF_CHAIN_SIZE; tmp_cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC | MOST_CH_ISOC | MOST_CH_SYNC; if (usb_endpoint_dir_in(ep_desc)) tmp_cap->direction = MOST_CH_RX; else tmp_cap->direction = MOST_CH_TX; tmp_cap++; init_usb_anchor(&mdev->busy_urbs[i]); spin_lock_init(&mdev->channel_lock[i]); } dev_notice(dev, "claimed gadget: Vendor=%4.4x ProdID=%4.4x Bus=%02x Device=%02x\n", le16_to_cpu(usb_dev->descriptor.idVendor), le16_to_cpu(usb_dev->descriptor.idProduct), usb_dev->bus->busnum, usb_dev->devnum); dev_notice(dev, "device path: /sys/bus/usb/devices/%d-%s:%d.%d\n", usb_dev->bus->busnum, usb_dev->devpath, usb_dev->config->desc.bConfigurationValue, usb_iface_desc->desc.bInterfaceNumber); ret = most_register_interface(&mdev->iface); if (ret) goto err_free_busy_urbs; mutex_lock(&mdev->io_mutex); if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) { mdev->dci = kzalloc(sizeof(*mdev->dci), GFP_KERNEL); if (!mdev->dci) { mutex_unlock(&mdev->io_mutex); most_deregister_interface(&mdev->iface); ret = -ENOMEM; goto err_free_busy_urbs; } mdev->dci->dev.init_name = "dci"; mdev->dci->dev.parent = &mdev->iface.dev; mdev->dci->dev.groups = dci_attr_groups; mdev->dci->dev.release = release_dci; if (device_register(&mdev->dci->dev)) { mutex_unlock(&mdev->io_mutex); most_deregister_interface(&mdev->iface); ret = -ENOMEM; goto err_free_dci; } mdev->dci->usb_device = mdev->usb_device; } mutex_unlock(&mdev->io_mutex); return 0; err_free_dci: kfree(mdev->dci); err_free_busy_urbs: kfree(mdev->busy_urbs); err_free_ep_address: kfree(mdev->ep_address); err_free_cap: kfree(mdev->cap); err_free_conf: kfree(mdev->conf); err_free_mdev: kfree(mdev); err_out_of_memory: if (ret == 0 || ret == -ENOMEM) { ret = -ENOMEM; dev_err(dev, "out of memory\n"); } return ret; }
int ctrl_bridge_probe(struct usb_interface *ifc, struct usb_host_endpoint *int_in, int id) { struct ctrl_bridge *dev; struct usb_device *udev; struct usb_endpoint_descriptor *ep; u16 wMaxPacketSize; int retval = 0; int interval; udev = interface_to_usbdev(ifc); dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { dev_err(&udev->dev, "%s: unable to allocate dev\n", __func__); return -ENOMEM; } dev->pdev = platform_device_alloc(ctrl_bridge_names[id], id); if (!dev->pdev) { dev_err(&dev->udev->dev, "%s: unable to allocate platform device\n", __func__); retval = -ENOMEM; goto nomem; } dev->udev = udev; dev->int_pipe = usb_rcvintpipe(udev, int_in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->intf = ifc; init_usb_anchor(&dev->tx_submitted); init_usb_anchor(&dev->tx_deferred); /*use max pkt size from ep desc*/ ep = &dev->intf->cur_altsetting->endpoint[0].desc; dev->inturb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->inturb) { dev_err(&udev->dev, "%s: error allocating int urb\n", __func__); retval = -ENOMEM; goto pdev_del; } wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); dev->intbuf = kmalloc(wMaxPacketSize, GFP_KERNEL); if (!dev->intbuf) { dev_err(&udev->dev, "%s: error allocating int buffer\n", __func__); retval = -ENOMEM; goto free_inturb; } interval = (udev->speed == USB_SPEED_HIGH) ? HS_INTERVAL : FS_LS_INTERVAL; usb_fill_int_urb(dev->inturb, udev, dev->int_pipe, dev->intbuf, wMaxPacketSize, notification_available_cb, dev, interval); dev->readurb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->readurb) { dev_err(&udev->dev, "%s: error allocating read urb\n", __func__); retval = -ENOMEM; goto free_intbuf; } dev->readbuf = kmalloc(DEFAULT_READ_URB_LENGTH, GFP_KERNEL); if (!dev->readbuf) { dev_err(&udev->dev, "%s: error allocating read buffer\n", __func__); retval = -ENOMEM; goto free_rurb; } dev->in_ctlreq = kmalloc(sizeof(*dev->in_ctlreq), GFP_KERNEL); if (!dev->in_ctlreq) { dev_err(&udev->dev, "%s:error allocating setup packet buffer\n", __func__); retval = -ENOMEM; goto free_rbuf; } 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 = dev->intf->cur_altsetting->desc.bInterfaceNumber; dev->in_ctlreq->wLength = cpu_to_le16(DEFAULT_READ_URB_LENGTH); __dev[id] = dev; platform_device_add(dev->pdev); ch_id++; return ctrl_bridge_start_read(dev); free_rbuf: kfree(dev->readbuf); free_rurb: usb_free_urb(dev->readurb); free_intbuf: kfree(dev->intbuf); free_inturb: usb_free_urb(dev->inturb); pdev_del: platform_device_unregister(dev->pdev); nomem: kfree(dev); return retval; }
int usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) { struct usbnet *dev; struct net_device *net; struct usb_host_interface *interface; struct driver_info *info; struct usb_device *xdev; int status; const char *name; struct usb_driver *driver = to_usb_driver(udev->dev.driver); /* usbnet already took usb runtime pm, so have to enable the feature * for usb interface, otherwise usb_autopm_get_interface may return * failure if USB_SUSPEND(RUNTIME_PM) is enabled. */ if (!driver->supports_autosuspend) { driver->supports_autosuspend = 1; pm_runtime_enable(&udev->dev); } name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; if (!info) { dev_dbg (&udev->dev, "blacklisted by %s\n", name); return -ENODEV; } xdev = interface_to_usbdev (udev); interface = udev->cur_altsetting; usb_get_dev (xdev); status = -ENOMEM; // set up our own records net = alloc_etherdev(sizeof(*dev)); if (!net) { dbg ("can't kmalloc dev"); goto out; } /* netdev_printk() needs this so do it as early as possible */ SET_NETDEV_DEV(net, &udev->dev); dev = netdev_priv(net); dev->udev = xdev; dev->intf = udev; dev->driver_info = info; dev->driver_name = name; dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK); skb_queue_head_init (&dev->rxq); skb_queue_head_init (&dev->txq); skb_queue_head_init (&dev->done); skb_queue_head_init(&dev->rxq_pause); dev->bh.func = usbnet_bh; dev->bh.data = (unsigned long) dev; INIT_WORK (&dev->kevent, kevent); init_usb_anchor(&dev->deferred); dev->delay.function = usbnet_bh; dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); mutex_init (&dev->phy_mutex); dev->net = net; strcpy (net->name, "usb%d"); memcpy (net->dev_addr, node_id, sizeof node_id); /* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case. */ dev->hard_mtu = net->mtu + net->hard_header_len; #if 0 // dma_supported() is deeply broken on almost all architectures // possible with some EHCI controllers if (dma_supported (&udev->dev, DMA_BIT_MASK(64))) net->features |= NETIF_F_HIGHDMA; #endif net->netdev_ops = &usbnet_netdev_ops; net->watchdog_timeo = TX_TIMEOUT_JIFFIES; net->ethtool_ops = &usbnet_ethtool_ops; // allow device-specific bind/init procedures // NOTE net->name still not usable ... if (info->bind) { status = info->bind (dev, udev); if (status < 0) goto out1; // heuristic: "usb%d" for links we know are two-host, // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better. if ((dev->driver_info->flags & FLAG_ETHER) != 0 && ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || (net->dev_addr [0] & 0x02) == 0)) strcpy (net->name, "eth%d"); /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) strcpy(net->name, "wlan%d"); /* WWAN devices should always be named "wwan%d" */ if ((dev->driver_info->flags & FLAG_WWAN) != 0) strcpy(net->name, "wwan%d"); /* maybe the remote can't receive an Ethernet MTU */ if (net->mtu > (dev->hard_mtu - net->hard_header_len)) net->mtu = dev->hard_mtu - net->hard_header_len; } else if (!info->in || !info->out) status = usbnet_get_endpoints (dev, udev); else { dev->in = usb_rcvbulkpipe (xdev, info->in); dev->out = usb_sndbulkpipe (xdev, info->out); if (!(info->flags & FLAG_NO_SETINT)) status = usb_set_interface (xdev, interface->desc.bInterfaceNumber, interface->desc.bAlternateSetting); else status = 0; } if (status >= 0 && dev->status) status = init_status (dev, udev); if (status < 0) goto out3; if (!dev->rx_urb_size) dev->rx_urb_size = dev->hard_mtu; dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); if ((dev->driver_info->flags & FLAG_WLAN) != 0) SET_NETDEV_DEVTYPE(net, &wlan_type); if ((dev->driver_info->flags & FLAG_WWAN) != 0) SET_NETDEV_DEVTYPE(net, &wwan_type); status = register_netdev (net); if (status) goto out3; netif_info(dev, probe, dev->net, "register '%s' at usb-%s-%s, %s, %pM\n", udev->dev.driver->name, xdev->bus->bus_name, xdev->devpath, dev->driver_info->description, net->dev_addr); // ok, it's ready to go. usb_set_intfdata (udev, dev); netif_device_attach (net); if (dev->driver_info->flags & FLAG_LINK_INTR) netif_carrier_off(net); return 0; out3: if (info->unbind) info->unbind (dev, udev); out1: free_netdev(net); out: usb_put_dev(xdev); return status; }
static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_skel *dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; size_t buffer_size; int i; int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { err("Out of memory"); goto error; } kref_init(&dev->kref); sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); mutex_init(&dev->io_mutex); spin_lock_init(&dev->err_lock); init_usb_anchor(&dev->submitted); dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; /* set up the endpoint information */ /* use only the first bulk-in and bulk-out endpoints */ iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) { /* we found a bulk in endpoint */ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); dev->bulk_in_size = buffer_size; dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!dev->bulk_in_buffer) { err("Could not allocate bulk_in_buffer"); goto error; } } if (!dev->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(endpoint)) { /* we found a bulk out endpoint */ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; } } if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { err("Could not find both bulk-in and bulk-out endpoints"); goto error; } /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); /* we can register the device now, as it is ready */ retval = usb_register_dev(interface, &skel_class); if (retval) { /* something prevented us from registering this driver */ err("Not able to get a minor for this device."); usb_set_intfdata(interface, NULL); goto error; } /* let the user know what node this device is now attached to */ info("USB Skeleton device now attached to USBSkel-%d", interface->minor); return 0; error: if (dev) /* this frees allocated memory */ kref_put(&dev->kref, skel_delete); return retval; }
static int diag_bridge_probe(struct usb_interface *ifc, const struct usb_device_id *id) { struct diag_bridge *dev; struct usb_host_interface *ifc_desc; struct usb_endpoint_descriptor *ep_desc; int i; int ret = -ENOMEM; __u8 ifc_num; pr_debug("id:%lu", id->driver_info); ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber; /* is this interface supported ? */ if (ifc_num != id->driver_info) return -ENODEV; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { pr_err("unable to allocate dev"); return -ENOMEM; } dev->pdev = platform_device_alloc("diag_bridge", -1); if (!dev->pdev) { pr_err("unable to allocate platform device"); kfree(dev); return -ENOMEM; } __dev = dev; dev->udev = usb_get_dev(interface_to_usbdev(ifc)); dev->ifc = ifc; kref_init(&dev->kref); mutex_init(&dev->ifc_mutex); init_usb_anchor(&dev->submitted); ifc_desc = ifc->cur_altsetting; for (i = 0; i < ifc_desc->desc.bNumEndpoints; i++) { ep_desc = &ifc_desc->endpoint[i].desc; if (!dev->in_epAddr && usb_endpoint_is_bulk_in(ep_desc)) dev->in_epAddr = ep_desc->bEndpointAddress; if (!dev->out_epAddr && usb_endpoint_is_bulk_out(ep_desc)) dev->out_epAddr = ep_desc->bEndpointAddress; } if (!(dev->in_epAddr && dev->out_epAddr)) { pr_err("could not find bulk in and bulk out endpoints"); ret = -ENODEV; goto error; } usb_set_intfdata(ifc, dev); diag_bridge_debugfs_init(); platform_device_add(dev->pdev); dev_dbg(&dev->ifc->dev, "%s: complete\n", __func__); return 0; error: if (dev) kref_put(&dev->kref, diag_bridge_delete); return ret; }
static int __init bridge_init(void) { struct data_bridge *dev; int ret; int i = 0; ret = ctrl_bridge_init(); if (ret) return ret; bridge_wq = create_singlethread_workqueue("mdm_bridge"); if (!bridge_wq) { pr_err("%s: Unable to create workqueue:bridge\n", __func__); ret = -ENOMEM; goto free_ctrl; } for (i = 0; i < MAX_BRIDGE_DEVICES; i++) { dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { err("%s: unable to allocate dev\n", __func__); ret = -ENOMEM; goto error; } dev->wq = bridge_wq; init_usb_anchor(&dev->tx_active); init_usb_anchor(&dev->rx_active); init_usb_anchor(&dev->delayed); INIT_LIST_HEAD(&dev->rx_idle); skb_queue_head_init(&dev->rx_done); INIT_WORK(&dev->kevent, defer_kevent); INIT_WORK(&dev->process_rx_w, data_bridge_process_rx); __dev[i] = dev; } ret = usb_register(&bridge_driver); if (ret) { err("%s: unable to register mdm_bridge driver", __func__); goto error; } data_bridge_debugfs_init(); return 0; error: while (--i >= 0) { kfree(__dev[i]); __dev[i] = NULL; } destroy_workqueue(bridge_wq); free_ctrl: ctrl_bridge_exit(); return ret; }
static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_skel *dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; size_t buffer_size; int i; int retval = -ENOMEM; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { err("Out of memory"); goto error; } kref_init(&dev->kref); sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); mutex_init(&dev->io_mutex); spin_lock_init(&dev->err_lock); init_usb_anchor(&dev->submitted); init_completion(&dev->bulk_in_completion); dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) { buffer_size = usb_endpoint_maxp(endpoint); dev->bulk_in_size = buffer_size; dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!dev->bulk_in_buffer) { err("Could not allocate bulk_in_buffer"); goto error; } dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->bulk_in_urb) { err("Could not allocate bulk_in_urb"); goto error; } } if (!dev->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(endpoint)) { dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; } } if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { err("Could not find both bulk-in and bulk-out endpoints"); goto error; } usb_set_intfdata(interface, dev); retval = usb_register_dev(interface, &skel_class); if (retval) { err("Not able to get a minor for this device."); usb_set_intfdata(interface, NULL); goto error; } dev_info(&interface->dev, "USB Skeleton device now attached to USBSkel-%d", interface->minor); return 0; error: if (dev) kref_put(&dev->kref, skel_delete); return retval; }
static int ar9170_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct ar9170_usb *aru; struct ar9170 *ar; struct usb_device *udev; int err; aru = ar9170_alloc(sizeof(*aru)); if (IS_ERR(aru)) { err = PTR_ERR(aru); goto out; } udev = interface_to_usbdev(intf); usb_get_dev(udev); aru->udev = udev; aru->intf = intf; ar = &aru->common; aru->req_one_stage_fw = ar9170_requires_one_stage(id); usb_set_intfdata(intf, aru); SET_IEEE80211_DEV(ar->hw, &intf->dev); init_usb_anchor(&aru->rx_submitted); init_usb_anchor(&aru->tx_pending); init_usb_anchor(&aru->tx_submitted); init_completion(&aru->cmd_wait); spin_lock_init(&aru->tx_urb_lock); aru->tx_pending_urbs = 0; aru->tx_submitted_urbs = 0; aru->common.stop = ar9170_usb_stop; aru->common.flush = ar9170_usb_flush; aru->common.open = ar9170_usb_open; aru->common.tx = ar9170_usb_tx; aru->common.exec_cmd = ar9170_usb_exec_cmd; aru->common.callback_cmd = ar9170_usb_callback_cmd; #ifdef CONFIG_PM udev->reset_resume = 1; #endif /* CONFIG_PM */ err = ar9170_usb_reset(aru); if (err) goto err_freehw; err = ar9170_usb_request_firmware(aru); if (err) goto err_freehw; err = ar9170_usb_init_device(aru); if (err) goto err_freefw; err = ar9170_usb_open(ar); if (err) goto err_unrx; err = ar9170_register(ar, &udev->dev); ar9170_usb_stop(ar); if (err) goto err_unrx; return 0; err_unrx: ar9170_usb_cancel_urbs(aru); err_freefw: release_firmware(aru->init_values); release_firmware(aru->firmware); err_freehw: usb_set_intfdata(intf, NULL); usb_put_dev(udev); ieee80211_free_hw(ar->hw); out: return err; }
/** * hdm_probe - probe function of USB device driver * @interface: Interface of the attached USB device * @id: Pointer to the USB ID table. * * This allocates and initializes the device instance, adds the new * entry to the internal list, scans the USB descriptors and registers * the interface with the core. * Additionally, the DCI objects are created and the hardware is sync'd. * * Return 0 on success. In case of an error a negative number is returned. */ static int hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_host_interface *usb_iface_desc = interface->cur_altsetting; struct usb_device *usb_dev = interface_to_usbdev(interface); struct device *dev = &usb_dev->dev; struct most_dev *mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); unsigned int i; unsigned int num_endpoints; struct most_channel_capability *tmp_cap; struct usb_endpoint_descriptor *ep_desc; int ret = 0; int err; if (!mdev) goto exit_ENOMEM; usb_set_intfdata(interface, mdev); num_endpoints = usb_iface_desc->desc.bNumEndpoints; mutex_init(&mdev->io_mutex); INIT_WORK(&mdev->poll_work_obj, wq_netinfo); setup_timer(&mdev->link_stat_timer, link_stat_timer_handler, (unsigned long)mdev); mdev->usb_device = usb_dev; mdev->link_stat_timer.expires = jiffies + (2 * HZ); mdev->iface.mod = hdm_usb_fops.owner; mdev->iface.interface = ITYPE_USB; mdev->iface.configure = hdm_configure_channel; mdev->iface.request_netinfo = hdm_request_netinfo; mdev->iface.enqueue = hdm_enqueue; mdev->iface.poison_channel = hdm_poison_channel; mdev->iface.description = mdev->description; mdev->iface.num_channels = num_endpoints; snprintf(mdev->description, sizeof(mdev->description), "usb_device %d-%s:%d.%d", usb_dev->bus->busnum, usb_dev->devpath, usb_dev->config->desc.bConfigurationValue, usb_iface_desc->desc.bInterfaceNumber); mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL); if (!mdev->conf) goto exit_free; mdev->cap = kcalloc(num_endpoints, sizeof(*mdev->cap), GFP_KERNEL); if (!mdev->cap) goto exit_free1; mdev->iface.channel_vector = mdev->cap; mdev->iface.priv = NULL; mdev->ep_address = kcalloc(num_endpoints, sizeof(*mdev->ep_address), GFP_KERNEL); if (!mdev->ep_address) goto exit_free2; mdev->busy_urbs = kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL); if (!mdev->busy_urbs) goto exit_free3; tmp_cap = mdev->cap; for (i = 0; i < num_endpoints; i++) { ep_desc = &usb_iface_desc->endpoint[i].desc; mdev->ep_address[i] = ep_desc->bEndpointAddress; mdev->padding_active[i] = false; mdev->is_channel_healthy[i] = true; snprintf(&mdev->suffix[i][0], MAX_SUFFIX_LEN, "ep%02x", mdev->ep_address[i]); tmp_cap->name_suffix = &mdev->suffix[i][0]; tmp_cap->buffer_size_packet = MAX_BUF_SIZE; tmp_cap->buffer_size_streaming = MAX_BUF_SIZE; tmp_cap->num_buffers_packet = BUF_CHAIN_SIZE; tmp_cap->num_buffers_streaming = BUF_CHAIN_SIZE; tmp_cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC | MOST_CH_ISOC | MOST_CH_SYNC; if (usb_endpoint_dir_in(ep_desc)) tmp_cap->direction = MOST_CH_RX; else tmp_cap->direction = MOST_CH_TX; tmp_cap++; init_usb_anchor(&mdev->busy_urbs[i]); spin_lock_init(&mdev->channel_lock[i]); err = drci_wr_reg(usb_dev, DRCI_REG_BASE + DRCI_COMMAND + ep_desc->bEndpointAddress * 16, 1); if (err < 0) dev_warn(dev, "DCI Sync for EP %02x failed", ep_desc->bEndpointAddress); } dev_notice(dev, "claimed gadget: Vendor=%4.4x ProdID=%4.4x Bus=%02x Device=%02x\n", le16_to_cpu(usb_dev->descriptor.idVendor), le16_to_cpu(usb_dev->descriptor.idProduct), usb_dev->bus->busnum, usb_dev->devnum); dev_notice(dev, "device path: /sys/bus/usb/devices/%d-%s:%d.%d\n", usb_dev->bus->busnum, usb_dev->devpath, usb_dev->config->desc.bConfigurationValue, usb_iface_desc->desc.bInterfaceNumber); mdev->parent = most_register_interface(&mdev->iface); if (IS_ERR(mdev->parent)) { ret = PTR_ERR(mdev->parent); goto exit_free4; } mutex_lock(&mdev->io_mutex); if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) { /* this increments the reference count of the instance * object of the core */ mdev->dci = create_most_dci_obj(mdev->parent); if (!mdev->dci) { mutex_unlock(&mdev->io_mutex); most_deregister_interface(&mdev->iface); ret = -ENOMEM; goto exit_free4; } kobject_uevent(&mdev->dci->kobj, KOBJ_ADD); mdev->dci->usb_device = mdev->usb_device; } mutex_unlock(&mdev->io_mutex); return 0; exit_free4: kfree(mdev->busy_urbs); exit_free3: kfree(mdev->ep_address); exit_free2: kfree(mdev->cap); exit_free1: kfree(mdev->conf); exit_free: kfree(mdev); exit_ENOMEM: if (ret == 0 || ret == -ENOMEM) { ret = -ENOMEM; dev_err(dev, "out of memory\n"); } return ret; }
int rmnet_usb_ctrl_init(void) { struct rmnet_ctrl_dev *dev; int n; int status; if (get_radio_flag() & 0x0001) usb_pm_debug_enabled = true; if (get_radio_flag() & 0x0002) enable_ctl_msg_debug = true; #ifdef HTC_LOG_RMNET_USB_CTRL if (get_radio_flag() & 0x0008) enable_dbg_rmnet_usb_ctrl = true; #endif for (n = 0; n < NUM_CTRL_CHANNELS; ++n) { dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { status = -ENOMEM; goto error0; } snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n); dev->wq = create_singlethread_workqueue(dev->name); if (!dev->wq) { pr_err("unable to allocate workqueue"); kfree(dev); goto error0; } mutex_init(&dev->dev_lock); spin_lock_init(&dev->rx_lock); init_waitqueue_head(&dev->read_wait_queue); init_waitqueue_head(&dev->open_wait_queue); INIT_LIST_HEAD(&dev->rx_list); init_usb_anchor(&dev->tx_submitted); init_usb_anchor(&dev->rx_submitted); INIT_WORK(&dev->get_encap_work, get_encap_work); status = rmnet_usb_ctrl_alloc_rx(dev); if (status < 0) { kfree(dev); goto error0; } ctrl_dev[n] = dev; } status = alloc_chrdev_region(&ctrldev_num, 0, NUM_CTRL_CHANNELS, DEVICE_NAME); if (IS_ERR_VALUE(status)) { pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n", __func__, status); goto error0; } ctrldev_classp = class_create(THIS_MODULE, DEVICE_NAME); if (IS_ERR(ctrldev_classp)) { pr_err("ERROR:%s: class_create() ENOMEM\n", __func__); status = -ENOMEM; goto error1; } for (n = 0; n < NUM_CTRL_CHANNELS; ++n) { cdev_init(&ctrl_dev[n]->cdev, &ctrldev_fops); ctrl_dev[n]->cdev.owner = THIS_MODULE; status = cdev_add(&ctrl_dev[n]->cdev, (ctrldev_num + n), 1); if (IS_ERR_VALUE(status)) { pr_err("%s: cdev_add() ret %i\n", __func__, status); kfree(ctrl_dev[n]); goto error2; } ctrl_dev[n]->devicep = device_create(ctrldev_classp, NULL, (ctrldev_num + n), NULL, DEVICE_NAME "%d", n); if (IS_ERR(ctrl_dev[n]->devicep)) { pr_err("%s: device_create() ENOMEM\n", __func__); status = -ENOMEM; cdev_del(&ctrl_dev[n]->cdev); kfree(ctrl_dev[n]); goto error2; } status = device_create_file(ctrl_dev[n]->devicep, &dev_attr_modem_wait); if (status) { device_destroy(ctrldev_classp, MKDEV(MAJOR(ctrldev_num), n)); cdev_del(&ctrl_dev[n]->cdev); kfree(ctrl_dev[n]); goto error2; } dev_set_drvdata(ctrl_dev[n]->devicep, ctrl_dev[n]); } rmnet_usb_ctrl_debugfs_init(); pr_info("rmnet usb ctrl Initialized.\n"); return 0; error2: while (--n >= 0) { cdev_del(&ctrl_dev[n]->cdev); device_destroy(ctrldev_classp, MKDEV(MAJOR(ctrldev_num), n)); } class_destroy(ctrldev_classp); n = NUM_CTRL_CHANNELS; error1: unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS); error0: while (--n >= 0) kfree(ctrl_dev[n]); return status; }
static int lcd_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_lcd *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; size_t buffer_size; int i; int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { err("Out of memory"); goto error; } kref_init(&dev->kref); sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES); init_usb_anchor(&dev->submitted); dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; if (le16_to_cpu(dev->udev->descriptor.idProduct) != 0x0001) { warn(KERN_INFO "USBLCD model not supported."); return -ENODEV; } /* set up the endpoint information */ /* use only the first bulk-in and bulk-out endpoints */ iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) { /* we found a bulk in endpoint */ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); dev->bulk_in_size = buffer_size; dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!dev->bulk_in_buffer) { err("Could not allocate bulk_in_buffer"); goto error; } } if (!dev->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(endpoint)) { /* we found a bulk out endpoint */ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; } } if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { err("Could not find both bulk-in and bulk-out endpoints"); goto error; } /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); /* we can register the device now, as it is ready */ retval = usb_register_dev(interface, &lcd_class); if (retval) { /* something prevented us from registering this driver */ err("Not able to get a minor for this device."); usb_set_intfdata(interface, NULL); goto error; } i = le16_to_cpu(dev->udev->descriptor.bcdDevice); info("USBLCD Version %1d%1d.%1d%1d found at address %d", (i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF), dev->udev->devnum); /* let the user know what node this device is now attached to */ info("USB LCD device now attached to USBLCD-%d", interface->minor); return 0; error: if (dev) kref_put(&dev->kref, lcd_delete); return retval; }
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, err,flag1,flag2; struct usb_device *udev; udev = interface_to_usbdev(intf); /* interface numbers are hardcoded in the spec */ if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; /*******************************/ flag1=device_can_wakeup(&udev->dev); flag2=device_may_wakeup(&udev->dev); RTKBT_DBG("btusb_probe 1==========can_wakeup=%x flag2=%x",flag1,flag2); //device_wakeup_enable(&udev->dev); /*device_wakeup_disable(&udev->dev); flag1=device_can_wakeup(&udev->dev); flag2=device_may_wakeup(&udev->dev); RTKBT_DBG("btusb_probe 2==========can_wakeup=%x flag2=%x",flag1,flag2); */ err = patch_add(intf); if (err < 0) return -1; /*******************************/ data = kzalloc(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) { kfree(data); 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) { kfree(data); return -ENOMEM; } HDEV_BUS = HCI_USB; 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 LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0) hci_set_drvdata(hdev, data); #else hdev->driver_data = data; hdev->destruct = btusb_destruct; hdev->owner = THIS_MODULE; #endif /* Interface numbers are hardcoded in the specification */ data->isoc = usb_ifnum_to_if(data->udev, 1); if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, data->isoc, data); if (err < 0) { hci_free_dev(hdev); kfree(data); return err; } } err = hci_register_dev(hdev); if (err < 0) { hci_free_dev(hdev); kfree(data); return err; } usb_set_intfdata(intf, data); return 0; }
/* * probe function for new CPC-USB devices */ static int ems_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct net_device *netdev; struct ems_usb *dev; int i, err = -ENOMEM; netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS); if (!netdev) { dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n"); return -ENOMEM; } dev = netdev_priv(netdev); dev->udev = interface_to_usbdev(intf); dev->netdev = netdev; dev->can.state = CAN_STATE_STOPPED; dev->can.clock.freq = EMS_USB_ARM7_CLOCK; dev->can.bittiming_const = &ems_usb_bittiming_const; dev->can.do_set_bittiming = ems_usb_set_bittiming; dev->can.do_set_mode = ems_usb_set_mode; dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; netdev->netdev_ops = &ems_usb_netdev_ops; netdev->flags |= IFF_ECHO; /* we support local echo */ init_usb_anchor(&dev->rx_submitted); init_usb_anchor(&dev->tx_submitted); atomic_set(&dev->active_tx_urbs, 0); for (i = 0; i < MAX_TX_URBS; i++) dev->tx_contexts[i].echo_index = MAX_TX_URBS; dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->intr_urb) { dev_err(&intf->dev, "Couldn't alloc intr URB\n"); goto cleanup_candev; } dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL); if (!dev->intr_in_buffer) goto cleanup_intr_urb; dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE + sizeof(struct ems_cpc_msg), GFP_KERNEL); if (!dev->tx_msg_buffer) goto cleanup_intr_in_buffer; usb_set_intfdata(intf, dev); SET_NETDEV_DEV(netdev, &intf->dev); init_params_sja1000(&dev->active_params); err = ems_usb_command_msg(dev, &dev->active_params); if (err) { netdev_err(netdev, "couldn't initialize controller: %d\n", err); goto cleanup_tx_msg_buffer; } err = register_candev(netdev); if (err) { netdev_err(netdev, "couldn't register CAN device: %d\n", err); goto cleanup_tx_msg_buffer; } return 0; cleanup_tx_msg_buffer: kfree(dev->tx_msg_buffer); cleanup_intr_in_buffer: kfree(dev->intr_in_buffer); cleanup_intr_urb: usb_free_urb(dev->intr_urb); cleanup_candev: free_candev(netdev); return err; }
int rmnet_usb_ctrl_init(void) { struct rmnet_ctrl_dev *dev; int n; int status; for (n = 0; n < NUM_CTRL_CHANNELS; ++n) { dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { status = -ENOMEM; goto error0; } /*for debug purpose*/ snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n); mutex_init(&dev->dev_lock); spin_lock_init(&dev->rx_lock); init_waitqueue_head(&dev->read_wait_queue); init_waitqueue_head(&dev->open_wait_queue); INIT_LIST_HEAD(&dev->rx_list); init_usb_anchor(&dev->tx_submitted); status = rmnet_usb_ctrl_alloc_rx(dev); if (status < 0) { kfree(dev); goto error0; } ctrl_dev[n] = dev; } status = alloc_chrdev_region(&ctrldev_num, 0, NUM_CTRL_CHANNELS, DEVICE_NAME); if (IS_ERR_VALUE(status)) { pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n", __func__, status); goto error0; } ctrldev_classp = class_create(THIS_MODULE, DEVICE_NAME); if (IS_ERR(ctrldev_classp)) { pr_err("ERROR:%s: class_create() ENOMEM\n", __func__); status = -ENOMEM; goto error1; } for (n = 0; n < NUM_CTRL_CHANNELS; ++n) { cdev_init(&ctrl_dev[n]->cdev, &ctrldev_fops); ctrl_dev[n]->cdev.owner = THIS_MODULE; status = cdev_add(&ctrl_dev[n]->cdev, (ctrldev_num + n), 1); if (IS_ERR_VALUE(status)) { pr_err("%s: cdev_add() ret %i\n", __func__, status); kfree(ctrl_dev[n]); goto error2; } ctrl_dev[n]->devicep = device_create(ctrldev_classp, NULL, (ctrldev_num + n), NULL, DEVICE_NAME "%d", n); if (IS_ERR(ctrl_dev[n]->devicep)) { pr_err("%s: device_create() ENOMEM\n", __func__); status = -ENOMEM; cdev_del(&ctrl_dev[n]->cdev); kfree(ctrl_dev[n]); goto error2; } /*create /sys/class/hsicctl/hsicctlx/modem_wait*/ status = device_create_file(ctrl_dev[n]->devicep, &dev_attr_modem_wait); if (status) { device_destroy(ctrldev_classp, MKDEV(MAJOR(ctrldev_num), n)); cdev_del(&ctrl_dev[n]->cdev); kfree(ctrl_dev[n]); goto error2; } dev_set_drvdata(ctrl_dev[n]->devicep, ctrl_dev[n]); } rmnet_usb_ctrl_debugfs_init(); pr_info("rmnet usb ctrl Initialized.\n"); return 0; error2: while (--n >= 0) { cdev_del(&ctrl_dev[n]->cdev); device_destroy(ctrldev_classp, MKDEV(MAJOR(ctrldev_num), n)); } class_destroy(ctrldev_classp); n = NUM_CTRL_CHANNELS; error1: unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS); error0: while (--n >= 0) kfree(ctrl_dev[n]); return status; }
static int synccom_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct synccom_port *port; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; size_t buffer_size; int i; int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ port = kzalloc(sizeof(*port), GFP_KERNEL); if (!port) { dev_err(&interface->dev, "Out of memory\n"); goto error; } kref_init(&port->kref); sema_init(&port->limit_sem, WRITES_IN_FLIGHT); mutex_init(&port->io_mutex); spin_lock_init(&port->err_lock); init_usb_anchor(&port->submitted); init_waitqueue_head(&port->bulk_in_wait); port->udev = usb_get_dev(interface_to_usbdev(interface)); port->interface = interface; /* set up the endpoint information */ /* use only the first bulk-in and bulk-out endpoints */ iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!port->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) { /* we found a bulk in endpoint */ buffer_size = endpoint->wMaxPacketSize; port->bulk_in_size = buffer_size; port->bulk_in_endpointAddr = endpoint->bEndpointAddress; port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!port->bulk_in_buffer) { dev_err(&interface->dev, "Could not allocate bulk_in_buffer\n"); goto error; } port->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!port->bulk_in_urb) { dev_err(&interface->dev, "Could not allocate bulk_in_urb\n"); goto error; } } if (!port->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(endpoint)) { /* we found a bulk out endpoint */ port->bulk_out_endpointAddr = endpoint->bEndpointAddress; } if (port->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(endpoint)) { /* we found a bulk out endpoint */ port->bulk_out_endpointAddr2 = endpoint->bEndpointAddress; } } if (!(port->bulk_in_endpointAddr && port->bulk_out_endpointAddr)) { dev_err(&interface->dev, "Could not find both bulk-in and bulk-out endpoints\n"); goto error; } /* save our data pointer in this interface device */ usb_set_intfdata(interface, port); /* we can register the device now, as it is ready */ retval = usb_register_dev(interface, &synccom_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&interface->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(interface, NULL); goto error; } /* let the user know what node this device is now attached to */ dev_info(&interface->dev, "USB synccom device now attached to synccom%d\n", interface->minor); initialize(port); return 0; error: if (port) /* this frees allocated memory */ kref_put(&port->kref, synccom_delete); return retval; }
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 sinosims_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_sinosims *dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; size_t buffer_size; int i; int retval = -ENOMEM; /* allocate memory for our device stat and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { dev_err(&interface->dev, "Out of memory\n"); goto error; } kref_init(&dev->kref); sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); mutex_init(&dev->io_mutex); spin_lock_init(&dev->err_lock); init_usb_anchor(&dev->submitted); init_waitqueue_head(&dev->bulk_in_wait); dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; /* set up the endpint information */ /* our device have only one configuration, in this configuration we have three interface. for each interface, there are tow endpints(one is bulk-in, and the other one is bulk-out) */ iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) { /* we found a bulk in endpoint */ buffer_size = usb_endpoint_maxp(endpoint); dev->bulk_in_size = buffer_size; dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!dev->bulk_in_buffer) { dev_err(&interface->dev, "Could not allocate bulk_in_buffer\n"); goto error; } dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->bulk_in_urb) { dev_err(&interface->dev, "Could not allocate bulk_in_urb\n"); goto error; } } if (!dev->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(endpoint)) { /* we found a bulk out endpoint */ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; } } if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { dev_err(&interface->dev, "Could not find both bulk-in and bulk-out endpoints\n"); goto error; } /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); /* we can register the device now, as it is ready */ retval = usb_register_dev(interface, &sinosims_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&interface->dev, "Not albe to get a minor for this device\n"); usb_set_intfdata(interface, NULL); goto error; } /* let the user know what node this device is now attached to */ dev_info(&interface->dev, "USB Sinosims device now attached to USBSino-%d", interface->minor); return 0; error: if (dev) { /* this frees allocated memory */ kref_put(&dev->kref, sinosims_delete); } return retval; }
static struct gs_can *gs_make_candev(unsigned int channel, struct usb_interface *intf, struct gs_device_config *dconf) { struct gs_can *dev; struct net_device *netdev; int rc; struct gs_device_bt_const *bt_const; bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL); if (!bt_const) return ERR_PTR(-ENOMEM); /* fetch bit timing constants */ rc = usb_control_msg(interface_to_usbdev(intf), usb_rcvctrlpipe(interface_to_usbdev(intf), 0), GS_USB_BREQ_BT_CONST, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, channel, 0, bt_const, sizeof(*bt_const), 1000); if (rc < 0) { dev_err(&intf->dev, "Couldn't get bit timing const for channel (err=%d)\n", rc); kfree(bt_const); return ERR_PTR(rc); } /* create netdev */ netdev = alloc_candev(sizeof(struct gs_can), GS_MAX_TX_URBS); if (!netdev) { dev_err(&intf->dev, "Couldn't allocate candev\n"); kfree(bt_const); return ERR_PTR(-ENOMEM); } dev = netdev_priv(netdev); netdev->netdev_ops = &gs_usb_netdev_ops; netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */ /* dev settup */ strcpy(dev->bt_const.name, "gs_usb"); dev->bt_const.tseg1_min = bt_const->tseg1_min; dev->bt_const.tseg1_max = bt_const->tseg1_max; dev->bt_const.tseg2_min = bt_const->tseg2_min; dev->bt_const.tseg2_max = bt_const->tseg2_max; dev->bt_const.sjw_max = bt_const->sjw_max; dev->bt_const.brp_min = bt_const->brp_min; dev->bt_const.brp_max = bt_const->brp_max; dev->bt_const.brp_inc = bt_const->brp_inc; dev->udev = interface_to_usbdev(intf); dev->iface = intf; dev->netdev = netdev; dev->channel = channel; init_usb_anchor(&dev->tx_submitted); atomic_set(&dev->active_tx_urbs, 0); spin_lock_init(&dev->tx_ctx_lock); for (rc = 0; rc < GS_MAX_TX_URBS; rc++) { dev->tx_context[rc].dev = dev; dev->tx_context[rc].echo_id = GS_MAX_TX_URBS; } /* can settup */ dev->can.state = CAN_STATE_STOPPED; dev->can.clock.freq = bt_const->fclk_can; dev->can.bittiming_const = &dev->bt_const; dev->can.do_set_bittiming = gs_usb_set_bittiming; dev->can.ctrlmode_supported = 0; if (bt_const->feature & GS_CAN_FEATURE_LISTEN_ONLY) dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; if (bt_const->feature & GS_CAN_FEATURE_LOOP_BACK) dev->can.ctrlmode_supported |= CAN_CTRLMODE_LOOPBACK; if (bt_const->feature & GS_CAN_FEATURE_TRIPLE_SAMPLE) dev->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; if (bt_const->feature & GS_CAN_FEATURE_ONE_SHOT) dev->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT; SET_NETDEV_DEV(netdev, &intf->dev); if (dconf->sw_version > 1) if (bt_const->feature & GS_CAN_FEATURE_IDENTIFY) netdev->ethtool_ops = &gs_usb_ethtool_ops; kfree(bt_const); rc = register_candev(dev->netdev); if (rc) { free_candev(dev->netdev); dev_err(&intf->dev, "Couldn't register candev (err=%d)\n", rc); return ERR_PTR(rc); } return dev; }
static int usb_net_raw_ip_init(void) { int i; int err; char name[32]; pr_debug("usb_net_raw_ip_init {\n"); /* create multiple raw-ip network devices */ for (i = 0; i < max_intfs; i++) { /* open baseband usb */ g_i = i; baseband_usb_net[i] = baseband_usb_open(i, usb_net_raw_ip_vid, usb_net_raw_ip_pid, usb_net_raw_ip_intf[i]); if (!baseband_usb_net[i]) { pr_err("cannot open baseband usb net\n"); err = -1; goto error_exit; } /* register network device */ usb_net_raw_ip_dev[i] = alloc_netdev(0, BASEBAND_USB_NET_DEV_NAME, ether_setup); if (!usb_net_raw_ip_dev[i]) { pr_err("alloc_netdev() failed\n"); err = -ENOMEM; goto error_exit; } usb_net_raw_ip_dev[i]->netdev_ops = &usb_net_raw_ip_ops; usb_net_raw_ip_dev[i]->watchdog_timeo = TX_TIMEOUT; random_ether_addr(usb_net_raw_ip_dev[i]->dev_addr); err = register_netdev(usb_net_raw_ip_dev[i]); if (err < 0) { pr_err("cannot register network device - %d\n", err); goto error_exit; } pr_debug("registered baseband usb network device" " - dev %p name %s\n", usb_net_raw_ip_dev[i], BASEBAND_USB_NET_DEV_NAME); /* start usb rx */ err = usb_net_raw_ip_setup_rx_urb(baseband_usb_net[i]); if (err < 0) { pr_err("setup reusable rx urb failed - err %d\n", err); goto error_exit; } err = usb_net_raw_ip_rx_urb_submit(baseband_usb_net[i]); if (err < 0) { pr_err("submit rx failed - err %d\n", err); goto error_exit; } /* start usb tx */ init_usb_anchor(&baseband_usb_net[i]->usb.tx_urb_deferred); sprintf(name, "raw_ip_tx_wq-%d", baseband_usb_net[i]->baseband_index); baseband_usb_net[i]->usb.tx_workqueue = create_singlethread_workqueue(name); if (!baseband_usb_net[i]->usb.tx_workqueue) { pr_err("cannot create workqueue\n"); goto error_exit; } INIT_WORK(&baseband_usb_net[i]->usb.tx_work, usb_net_raw_ip_tx_urb_work); } pr_debug("usb_net_raw_ip_init }\n"); return 0; error_exit: /* destroy multiple raw-ip network devices */ for (i = 0; i < max_intfs; i++) { /* unregister network device */ if (usb_net_raw_ip_dev[i]) { unregister_netdev(usb_net_raw_ip_dev[i]); free_netdev(usb_net_raw_ip_dev[i]); usb_net_raw_ip_dev[i] = (struct net_device *) 0; } /* close baseband usb */ if (baseband_usb_net[i]) { /* stop usb tx */ if (baseband_usb_net[i]->usb.tx_workqueue) { destroy_workqueue(baseband_usb_net[i] ->usb.tx_workqueue); baseband_usb_net[i]->usb.tx_workqueue = (struct workqueue_struct *) 0; } if (baseband_usb_net[i]->usb.tx_urb) { usb_kill_urb(baseband_usb_net[i]->usb.tx_urb); baseband_usb_net[i]->usb.tx_urb = (struct urb *) 0; } /* stop usb rx */ if (baseband_usb_net[i]->usb.rx_urb) { usb_kill_urb(baseband_usb_net[i]->usb.rx_urb); baseband_usb_net[i]->usb.rx_urb = (struct urb *) 0; } usb_net_raw_ip_free_rx_urb(baseband_usb_net[i]); /* close usb */ baseband_usb_close(baseband_usb_net[i]); baseband_usb_net[i] = (struct baseband_usb *) 0; } } return err; }
static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct gs_usb *dev; int rc = -ENOMEM; unsigned int icount, i; struct gs_host_config *hconf; struct gs_device_config *dconf; hconf = kmalloc(sizeof(*hconf), GFP_KERNEL); if (!hconf) return -ENOMEM; hconf->byte_order = 0x0000beef; /* send host config */ rc = usb_control_msg(interface_to_usbdev(intf), usb_sndctrlpipe(interface_to_usbdev(intf), 0), GS_USB_BREQ_HOST_FORMAT, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 1, intf->altsetting[0].desc.bInterfaceNumber, hconf, sizeof(*hconf), 1000); kfree(hconf); if (rc < 0) { dev_err(&intf->dev, "Couldn't send data format (err=%d)\n", rc); return rc; } dconf = kmalloc(sizeof(*dconf), GFP_KERNEL); if (!dconf) return -ENOMEM; /* read device config */ rc = usb_control_msg(interface_to_usbdev(intf), usb_rcvctrlpipe(interface_to_usbdev(intf), 0), GS_USB_BREQ_DEVICE_CONFIG, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 1, intf->altsetting[0].desc.bInterfaceNumber, dconf, sizeof(*dconf), 1000); if (rc < 0) { dev_err(&intf->dev, "Couldn't get device config: (err=%d)\n", rc); kfree(dconf); return rc; } icount = dconf->icount + 1; dev_info(&intf->dev, "Configuring for %d interfaces\n", icount); if (icount > GS_MAX_INTF) { dev_err(&intf->dev, "Driver cannot handle more that %d CAN interfaces\n", GS_MAX_INTF); kfree(dconf); return -EINVAL; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { kfree(dconf); return -ENOMEM; } init_usb_anchor(&dev->rx_submitted); atomic_set(&dev->active_channels, 0); usb_set_intfdata(intf, dev); dev->udev = interface_to_usbdev(intf); for (i = 0; i < icount; i++) { dev->canch[i] = gs_make_candev(i, intf, dconf); if (IS_ERR_OR_NULL(dev->canch[i])) { /* save error code to return later */ rc = PTR_ERR(dev->canch[i]); /* on failure destroy previously created candevs */ icount = i; for (i = 0; i < icount; i++) gs_destroy_candev(dev->canch[i]); usb_kill_anchored_urbs(&dev->rx_submitted); kfree(dconf); kfree(dev); return rc; } dev->canch[i]->parent = dev; } kfree(dconf); return 0; }
static int acm_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_cdc_union_desc *union_header = NULL; struct usb_cdc_country_functional_desc *cfd = NULL; unsigned char *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; struct usb_interface *control_interface; struct usb_interface *data_interface; struct usb_endpoint_descriptor *epctrl = NULL; struct usb_endpoint_descriptor *epread = NULL; struct usb_endpoint_descriptor *epwrite = NULL; struct usb_device *usb_dev = interface_to_usbdev(intf); struct acm *acm; int minor; int ctrlsize, readsize; u8 *buf; u8 ac_management_function = 0; u8 call_management_function = 0; int call_interface_num = -1; int data_interface_num = -1; unsigned long quirks; int num_rx_buf; int i; int combined_interfaces = 0; /* normal quirks */ quirks = (unsigned long)id->driver_info; num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; /* not a real CDC ACM device */ if (quirks & NOT_REAL_ACM) return -ENODEV; /* handle quirks deadly to normal probing*/ if (quirks & NO_UNION_NORMAL) { data_interface = usb_ifnum_to_if(usb_dev, 1); control_interface = usb_ifnum_to_if(usb_dev, 0); goto skip_normal_probe; } /* normal probing*/ if (!buffer) { dev_err(&intf->dev, "Weird descriptor references\n"); return -EINVAL; } if (!buflen) { if (intf->cur_altsetting->endpoint && intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { dev_dbg(&intf->dev, "Seeking extra descriptors on endpoint\n"); buflen = intf->cur_altsetting->endpoint->extralen; buffer = intf->cur_altsetting->endpoint->extra; } else { dev_err(&intf->dev, "Zero length descriptor references\n"); return -EINVAL; } } while (buflen > 0) { if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; } switch (buffer[2]) { case USB_CDC_UNION_TYPE: /* we've found it */ if (union_header) { dev_err(&intf->dev, "More than one " "union descriptor, skipping ...\n"); goto next_desc; } union_header = (struct usb_cdc_union_desc *)buffer; break; case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ cfd = (struct usb_cdc_country_functional_desc *)buffer; break; case USB_CDC_HEADER_TYPE: /* maybe check version */ break; /* for now we ignore it */ case USB_CDC_ACM_TYPE: ac_management_function = buffer[3]; break; case USB_CDC_CALL_MANAGEMENT_TYPE: call_management_function = buffer[3]; call_interface_num = buffer[4]; if ( (quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3) dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n"); break; default: /* there are LOTS more CDC descriptors that * could legitimately be found here. */ dev_dbg(&intf->dev, "Ignoring descriptor: " "type %02x, length %d\n", buffer[2], buffer[0]); break; } next_desc: buflen -= buffer[0]; buffer += buffer[0]; } if (!union_header) { if (call_interface_num > 0) { dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); /* quirks for Droids MuIn LCD */ if (quirks & NO_DATA_INTERFACE) data_interface = usb_ifnum_to_if(usb_dev, 0); else data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); control_interface = intf; } else { if (intf->cur_altsetting->desc.bNumEndpoints != 3) { dev_dbg(&intf->dev,"No union descriptor, giving up\n"); return -ENODEV; } else { dev_warn(&intf->dev,"No union descriptor, testing for castrated device\n"); combined_interfaces = 1; control_interface = data_interface = intf; goto look_for_collapsed_interface; } } } else { control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); if (!control_interface || !data_interface) { dev_dbg(&intf->dev, "no interfaces\n"); return -ENODEV; } } if (data_interface_num != call_interface_num) dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n"); if (control_interface == data_interface) { /* some broken devices designed for windows work this way */ dev_warn(&intf->dev,"Control and data interfaces are not separated!\n"); combined_interfaces = 1; /* a popular other OS doesn't use it */ quirks |= NO_CAP_LINE; if (data_interface->cur_altsetting->desc.bNumEndpoints != 3) { dev_err(&intf->dev, "This needs exactly 3 endpoints\n"); return -EINVAL; } look_for_collapsed_interface: for (i = 0; i < 3; i++) { struct usb_endpoint_descriptor *ep; ep = &data_interface->cur_altsetting->endpoint[i].desc; if (usb_endpoint_is_int_in(ep)) epctrl = ep; else if (usb_endpoint_is_bulk_out(ep)) epwrite = ep; else if (usb_endpoint_is_bulk_in(ep)) epread = ep; else return -EINVAL; } if (!epctrl || !epread || !epwrite) return -ENODEV; else goto made_compressed_probe; } skip_normal_probe: /*workaround for switched interfaces */ if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { struct usb_interface *t; dev_dbg(&intf->dev, "Your device has switched interfaces.\n"); t = control_interface; control_interface = data_interface; data_interface = t; } else { return -EINVAL; } } /* Accept probe requests only for the control interface */ if (!combined_interfaces && intf != control_interface) return -ENODEV; if (!combined_interfaces && usb_interface_claimed(data_interface)) { /* valid in this context */ dev_dbg(&intf->dev, "The data interface isn't available\n"); return -EBUSY; } if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) return -EINVAL; epctrl = &control_interface->cur_altsetting->endpoint[0].desc; epread = &data_interface->cur_altsetting->endpoint[0].desc; epwrite = &data_interface->cur_altsetting->endpoint[1].desc; /* workaround for switched endpoints */ if (!usb_endpoint_dir_in(epread)) { /* descriptors are swapped */ struct usb_endpoint_descriptor *t; dev_dbg(&intf->dev, "The data interface has switched endpoints\n"); t = epread; epread = epwrite; epwrite = t; } made_compressed_probe: dbg("interfaces are valid"); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (minor == ACM_TTY_MINORS) { dev_err(&intf->dev, "no more free acm devices\n"); return -ENODEV; } acm = kzalloc(sizeof(struct acm), GFP_KERNEL); if (acm == NULL) { dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); goto alloc_fail; } ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); readsize = le16_to_cpu(epread->wMaxPacketSize) * (quirks == SINGLE_RX_URB ? 1 : 2); acm->combined_interfaces = combined_interfaces; acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20; acm->control = control_interface; acm->data = data_interface; acm->minor = minor; acm->dev = usb_dev; acm->ctrl_caps = ac_management_function; if (quirks & NO_CAP_LINE) acm->ctrl_caps &= ~USB_CDC_CAP_LINE; acm->ctrlsize = ctrlsize; acm->readsize = readsize; acm->rx_buflimit = num_rx_buf; acm->urb_task.func = acm_rx_tasklet; acm->urb_task.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint); init_usb_anchor(&acm->deferred); init_waitqueue_head(&acm->drain_wait); spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); mutex_init(&acm->mutex); acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); acm->is_int_ep = usb_endpoint_xfer_int(epread); if (acm->is_int_ep) acm->bInterval = epread->bInterval; if (quirks & NO_HANGUP_IN_RESET_RESUME) acm->no_hangup_in_reset_resume = 1; tty_port_init(&acm->port); acm->port.ops = &acm_port_ops; buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); if (!buf) { dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); goto alloc_fail2; } acm->ctrl_buffer = buf; if (acm_write_buffers_alloc(acm) < 0) { dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); goto alloc_fail4; } acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->ctrlurb) { dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { struct acm_ru *rcv = &(acm->ru[i]); rcv->urb = usb_alloc_urb(0, GFP_KERNEL); if (rcv->urb == NULL) { dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); goto alloc_fail6; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = acm; } for (i = 0; i < num_rx_buf; i++) { struct acm_rb *rb = &(acm->rb[i]); rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, &rb->dma); if (!rb->base) { dev_dbg(&intf->dev, "out of memory (read bufs usb_alloc_coherent)\n"); goto alloc_fail7; } } for (i = 0; i < ACM_NW; i++) { struct acm_wb *snd = &(acm->wb[i]); snd->urb = usb_alloc_urb(0, GFP_KERNEL); if (snd->urb == NULL) { dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)"); goto alloc_fail8; } if (usb_endpoint_xfer_int(epwrite)) usb_fill_int_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); else usb_fill_bulk_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, snd); snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; snd->instance = acm; } usb_set_intfdata(intf, acm); i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); if (i < 0) goto alloc_fail8; if (cfd) { /* export the country data */ acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); if (!acm->country_codes) goto skip_countries; acm->country_code_size = cfd->bLength - 4; memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0, cfd->bLength - 4); acm->country_rel_date = cfd->iCountryCodeRelDate; i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); if (i < 0) { kfree(acm->country_codes); goto skip_countries; } i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate); if (i < 0) { device_remove_file(&intf->dev, &dev_attr_wCountryCodes); kfree(acm->country_codes); goto skip_countries; } } skip_countries: usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm, /* works around buggy devices */ epctrl->bInterval ? epctrl->bInterval : 0xff); acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; acm->ctrlurb->transfer_dma = acm->ctrl_dma; dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); acm_set_control(acm, acm->ctrlout); acm->line.dwDTERate = cpu_to_le32(9600); acm->line.bDataBits = 8; acm_set_line(acm, &acm->line); usb_driver_claim_interface(&acm_driver, data_interface, acm); usb_set_intfdata(data_interface, acm); usb_get_intf(control_interface); tty_register_device(acm_tty_driver, minor, &control_interface->dev); acm_table[minor] = acm; return 0; alloc_fail8: for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); alloc_fail7: acm_read_buffers_free(acm); alloc_fail6: for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->ru[i].urb); usb_free_urb(acm->ctrlurb); alloc_fail5: acm_write_buffers_free(acm); alloc_fail4: usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); alloc_fail2: kfree(acm); alloc_fail: return -ENOMEM; }
static int __init ksb_init(void) { struct ks_bridge *ksb; int num_instances = 0; int ret = 0; int i; dbg_dir = debugfs_create_dir("ks_bridge", NULL); if (IS_ERR(dbg_dir)) pr_err("unable to create debug dir"); for (i = 0; i < NO_BRIDGE_INSTANCES; i++) { ksb = kzalloc(sizeof(struct ks_bridge), GFP_KERNEL); if (!ksb) { pr_err("unable to allocat mem for ks_bridge"); ret = -ENOMEM; goto dev_free; } __ksb[i] = ksb; ksb->name = kasprintf(GFP_KERNEL, "ks_bridge:%i", i + 1); if (!ksb->name) { pr_info("unable to allocate name"); kfree(ksb); ret = -ENOMEM; goto dev_free; } spin_lock_init(&ksb->lock); INIT_LIST_HEAD(&ksb->to_mdm_list); INIT_LIST_HEAD(&ksb->to_ks_list); init_waitqueue_head(&ksb->ks_wait_q); ksb->wq = create_singlethread_workqueue(ksb->name); if (!ksb->wq) { pr_err("unable to allocate workqueue"); kfree(ksb->name); kfree(ksb); ret = -ENOMEM; goto dev_free; } INIT_WORK(&ksb->to_mdm_work, ksb_tomdm_work); INIT_WORK(&ksb->start_rx_work, ksb_start_rx_work); init_usb_anchor(&ksb->submitted); ksb->dbg_idx = 0; ksb->dbg_lock = __RW_LOCK_UNLOCKED(lck); if (!IS_ERR(dbg_dir)) debugfs_create_file(ksb->name, S_IRUGO, dbg_dir, ksb, &dbg_fops); num_instances++; } ret = usb_register(&ksb_usb_driver); if (ret) { pr_err("unable to register ks bridge driver"); goto dev_free; } pr_info("init done"); return 0; dev_free: if (!IS_ERR(dbg_dir)) debugfs_remove_recursive(dbg_dir); for (i = 0; i < num_instances; i++) { ksb = __ksb[i]; destroy_workqueue(ksb->wq); kfree(ksb->name); kfree(ksb); } return ret; }
static int usblp_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usblp *usblp; int protocol; int retval; /* Malloc and start initializing usblp structure so we can use it * directly. */ usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL); if (!usblp) { retval = -ENOMEM; goto abort_ret; } usblp->dev = dev; mutex_init(&usblp->wmut); mutex_init(&usblp->mut); spin_lock_init(&usblp->lock); init_waitqueue_head(&usblp->rwait); init_waitqueue_head(&usblp->wwait); init_usb_anchor(&usblp->urbs); usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; usblp->intf = intf; /* Malloc device ID string buffer to the largest expected length, * since we can re-query it on an ioctl and a dynamic string * could change in length. */ if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) { retval = -ENOMEM; goto abort; } /* * Allocate read buffer. We somewhat wastefully * malloc both regardless of bidirectionality, because the * alternate setting can be changed later via an ioctl. */ if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE_IN, GFP_KERNEL))) { retval = -ENOMEM; goto abort; } /* Allocate buffer for printer status */ usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL); if (!usblp->statusbuf) { retval = -ENOMEM; goto abort; } /* Lookup quirks for this printer. */ usblp->quirks = usblp_quirks( le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); /* Analyze and pick initial alternate settings and endpoints. */ protocol = usblp_select_alts(usblp); if (protocol < 0) { dev_dbg(&intf->dev, "incompatible printer-class device 0x%4.4X/0x%4.4X\n", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); retval = -ENODEV; goto abort; } /* Setup the selected alternate setting and endpoints. */ if (usblp_set_protocol(usblp, protocol) < 0) { retval = -ENODEV; /* ->probe isn't ->ioctl */ goto abort; } /* Retrieve and store the device ID string. */ usblp_cache_device_id_string(usblp); retval = device_create_file(&intf->dev, &dev_attr_ieee1284_id); if (retval) goto abort_intfdata; #ifdef DEBUG usblp_check_status(usblp, 0); #endif usb_set_intfdata(intf, usblp); usblp->present = 1; retval = usb_register_dev(intf, &usblp_class); if (retval) { dev_err(&intf->dev, "usblp: Not able to get a minor (base %u, slice default): %d\n", USBLP_MINOR_BASE, retval); goto abort_intfdata; } usblp->minor = intf->minor; dev_info(&intf->dev, "usblp%d: USB %sdirectional printer dev %d if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n", usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, usblp->ifnum, usblp->protocol[usblp->current_protocol].alt_setting, usblp->current_protocol, le16_to_cpu(usblp->dev->descriptor.idVendor), le16_to_cpu(usblp->dev->descriptor.idProduct)); return 0; abort_intfdata: usb_set_intfdata(intf, NULL); device_remove_file(&intf->dev, &dev_attr_ieee1284_id); abort: kfree(usblp->readbuf); kfree(usblp->statusbuf); kfree(usblp->device_id_string); kfree(usblp); abort_ret: return retval; }
static int carl9170_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_endpoint_descriptor *ep; struct ar9170 *ar; struct usb_device *udev; int i, err; err = usb_reset_device(interface_to_usbdev(intf)); if (err) return err; ar = carl9170_alloc(sizeof(*ar)); if (IS_ERR(ar)) return PTR_ERR(ar); udev = interface_to_usbdev(intf); usb_get_dev(udev); ar->udev = udev; ar->intf = intf; ar->features = id->driver_info; /* We need to remember the type of endpoint 4 because it differs * between high- and full-speed configuration. The high-speed * configuration specifies it as interrupt and the full-speed * configuration as bulk endpoint. This information is required * later when sending urbs to that endpoint. */ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; ++i) { ep = &intf->cur_altsetting->endpoint[i].desc; if (usb_endpoint_num(ep) == AR9170_USB_EP_CMD && usb_endpoint_dir_out(ep) && usb_endpoint_type(ep) == USB_ENDPOINT_XFER_BULK) ar->usb_ep_cmd_is_bulk = true; } usb_set_intfdata(intf, ar); SET_IEEE80211_DEV(ar->hw, &intf->dev); init_usb_anchor(&ar->rx_anch); init_usb_anchor(&ar->rx_pool); init_usb_anchor(&ar->rx_work); init_usb_anchor(&ar->tx_wait); init_usb_anchor(&ar->tx_anch); init_usb_anchor(&ar->tx_cmd); init_usb_anchor(&ar->tx_err); init_completion(&ar->cmd_wait); init_completion(&ar->fw_boot_wait); init_completion(&ar->fw_load_wait); tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet, (unsigned long)ar); atomic_set(&ar->tx_cmd_urbs, 0); atomic_set(&ar->tx_anch_urbs, 0); atomic_set(&ar->rx_work_urbs, 0); atomic_set(&ar->rx_anch_urbs, 0); atomic_set(&ar->rx_pool_urbs, 0); usb_get_dev(ar->udev); carl9170_set_state(ar, CARL9170_STOPPED); return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); }
int rmnet_usb_ctrl_init(int no_rmnet_devs, int no_rmnet_insts_per_dev) { struct rmnet_ctrl_dev *dev; int i, n; int status; num_devs = no_rmnet_devs; insts_per_dev = no_rmnet_insts_per_dev; ctrl_devs = kzalloc(num_devs * sizeof(*ctrl_devs), GFP_KERNEL); if (!ctrl_devs) return -ENOMEM; for (i = 0; i < num_devs; i++) { ctrl_devs[i] = kzalloc(insts_per_dev * sizeof(*ctrl_devs[i]), GFP_KERNEL); if (!ctrl_devs[i]) return -ENOMEM; status = alloc_chrdev_region(&ctrldev_num[i], 0, insts_per_dev, rmnet_dev_names[i]); if (IS_ERR_VALUE(status)) { pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n", __func__, status); return status; } ctrldev_classp[i] = class_create(THIS_MODULE, rmnet_dev_names[i]); if (IS_ERR(ctrldev_classp[i])) { pr_err("ERROR:%s: class_create() ENOMEM\n", __func__); status = PTR_ERR(ctrldev_classp[i]); return status; } for (n = 0; n < insts_per_dev; n++) { dev = &ctrl_devs[i][n]; /*for debug purpose*/ snprintf(dev->name, CTRL_DEV_MAX_LEN, "%s%d", rmnet_dev_names[i], n); dev->wq = create_singlethread_workqueue(dev->name); if (!dev->wq) { pr_err("unable to allocate workqueue"); kfree(dev); return -ENOMEM; } dev->ch_id = n; mutex_init(&dev->dev_lock); spin_lock_init(&dev->rx_lock); init_waitqueue_head(&dev->read_wait_queue); init_waitqueue_head(&dev->open_wait_queue); INIT_LIST_HEAD(&dev->rx_list); init_usb_anchor(&dev->tx_submitted); init_usb_anchor(&dev->rx_submitted); INIT_WORK(&dev->get_encap_work, get_encap_work); cdev_init(&dev->cdev, &ctrldev_fops); dev->cdev.owner = THIS_MODULE; status = cdev_add(&dev->cdev, (ctrldev_num[i] + n), 1); if (status) { pr_err("%s: cdev_add() ret %i\n", __func__, status); destroy_workqueue(dev->wq); kfree(dev); return status; } dev->devicep = device_create(ctrldev_classp[i], NULL, (ctrldev_num[i] + n), NULL, "%s%d", rmnet_dev_names[i], n); if (IS_ERR(dev->devicep)) { pr_err("%s: device_create() returned %ld\n", __func__, PTR_ERR(dev->devicep)); cdev_del(&dev->cdev); destroy_workqueue(dev->wq); kfree(dev); return PTR_ERR(dev->devicep); } /*create /sys/class/hsicctl/hsicctlx/modem_wait*/ status = device_create_file(dev->devicep, &dev_attr_modem_wait); if (status) { device_destroy(dev->devicep->class, dev->devicep->devt); cdev_del(&dev->cdev); destroy_workqueue(dev->wq); kfree(dev); return status; } dev_set_drvdata(dev->devicep, dev); status = rmnet_usb_ctrl_alloc_rx(dev); if (status) { device_remove_file(dev->devicep, &dev_attr_modem_wait); device_destroy(dev->devicep->class, dev->devicep->devt); cdev_del(&dev->cdev); destroy_workqueue(dev->wq); kfree(dev); return status; } } } rmnet_usb_ctrl_debugfs_init(); pr_info("rmnet usb ctrl Initialized.\n"); return 0; }
static int diag_bridge_probe(struct usb_interface *ifc, const struct usb_device_id *id) { struct diag_bridge *dev; struct usb_host_interface *ifc_desc; struct usb_endpoint_descriptor *ep_desc; int i, devid, ret = -ENOMEM; pr_debug("id:%lu", id->driver_info); devid = id->driver_info & 0xFF; if (devid < 0 || devid >= MAX_DIAG_BRIDGE_DEVS) return -ENODEV; /* already probed? */ if (__dev[devid]) { pr_err("Diag device already probed"); return -ENODEV; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { pr_err("unable to allocate dev"); return -ENOMEM; } __dev[devid] = dev; dev->id = devid; dev->udev = usb_get_dev(interface_to_usbdev(ifc)); dev->ifc = ifc; kref_init(&dev->kref); mutex_init(&dev->ifc_mutex); init_usb_anchor(&dev->submitted); ifc_desc = ifc->cur_altsetting; for (i = 0; i < ifc_desc->desc.bNumEndpoints; i++) { ep_desc = &ifc_desc->endpoint[i].desc; if (!dev->in_epAddr && usb_endpoint_is_bulk_in(ep_desc)) dev->in_epAddr = ep_desc->bEndpointAddress; if (!dev->out_epAddr && usb_endpoint_is_bulk_out(ep_desc)) dev->out_epAddr = ep_desc->bEndpointAddress; } if (!(dev->in_epAddr && dev->out_epAddr)) { pr_err("could not find bulk in and bulk out endpoints"); ret = -ENODEV; goto error; } usb_set_intfdata(ifc, dev); diag_bridge_debugfs_init(); dev->pdev = platform_device_register_simple("diag_bridge", devid, NULL, 0); if (IS_ERR(dev->pdev)) { pr_err("unable to allocate platform device"); ret = PTR_ERR(dev->pdev); goto error; } dev_dbg(&dev->ifc->dev, "%s: complete\n", __func__); return 0; error: if (dev) kref_put(&dev->kref, diag_bridge_delete); return ret; }
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, 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; data = kzalloc(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) { kfree(data); 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) { kfree(data); return -ENOMEM; } hdev->bus = HCI_USB; hdev->driver_data = 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->destruct = btusb_destruct; hdev->notify = btusb_notify; hdev->owner = THIS_MODULE; /* Interface numbers are hardcoded in the specification */ data->isoc = usb_ifnum_to_if(data->udev, 1); if (!reset) set_bit(HCI_QUIRK_NO_RESET, &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_NO_RESET, &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_NO_RESET, &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 (id->driver_info & BTUSB_BCM92035) { unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 }; struct sk_buff *skb; skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL); if (skb) { memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd)); skb_queue_tail(&hdev->driver_init, skb); } } if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, data->isoc, data); if (err < 0) { hci_free_dev(hdev); kfree(data); return err; } } err = hci_register_dev(hdev); if (err < 0) { hci_free_dev(hdev); kfree(data); return err; } usb_set_intfdata(intf, data); return 0; }
/* * probe function for usb devices */ static int sam4e_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *usb_hi; struct usb_interface_descriptor *usb_if_desc; struct usb_device *udev; int err = 0; u8 if_num; struct net_device *netdev; struct sam4e_usb *dev; struct sam4e_usb_handle *sam4e_usb_hnd; int cnt = 0; usb_hi = intf->cur_altsetting; usb_if_desc = &usb_hi->desc; if_num = usb_if_desc->bInterfaceNumber; if (DEBUG_SAM4E) { dev_info(&intf->dev, "probe %p %p if_num %d id if_num %d\n", intf, id, if_num, id->bInterfaceNumber); } if (if_num != 1) return -ENODEV; dev = kzalloc(sizeof(struct sam4e_usb), GFP_KERNEL); if (!dev) { dev_err(&intf->dev, "Couldn't alloc sam4e_usb\n"); err = -ENOMEM; goto cleanup_candev; } atomic_set(&dev->netif_queue_stop, 0); while (cnt < MAX_CAN_INTF) { netdev = alloc_candev(sizeof(struct sam4e_usb_handle), MAX_TX_URBS); if (!netdev) { dev_err(&intf->dev, "Couldn't alloc candev\n"); err = -ENOMEM; goto cleanup_candev; } sam4e_usb_hnd = netdev_priv(netdev); sam4e_usb_hnd->sam4e_dev = dev; sam4e_usb_hnd->owner_netdev_index = cnt; dev->udev = interface_to_usbdev(intf); if (cnt == 0) dev->netdev1 = netdev; else dev->netdev2 = netdev; dev->assembly_buffer = kzalloc(RX_ASSEMBLY_BUFFER_SIZE, GFP_KERNEL); netdev->netdev_ops = &sam4e_usb_netdev_ops; init_usb_anchor(&dev->rx_submitted); init_usb_anchor(&dev->tx_submitted); atomic_set(&dev->active_tx_urbs, 0); atomic_set(&dev->msg_seq, 0); usb_set_intfdata(intf, dev); SET_NETDEV_DEV(netdev, &intf->dev); err = register_candev(netdev); if (err) { pr_err("fail reg.CAN device: %d", err); goto cleanup_candev; } udev = interface_to_usbdev(intf); if (cnt == 0) { /*use mail box 7 and 6 for e/s frames on can0*/ setup_mailbox(7, 0, CAN_EFF_FLAG, CAN_EFF_FLAG, intf, udev, dev); setup_mailbox(6, 0, CAN_EFF_FLAG, 0, intf, udev, dev); } else { /*use mail box 5 and 4 for e/s frames on can1*/ setup_mailbox(5, 1, CAN_EFF_FLAG, CAN_EFF_FLAG, intf, udev, dev); setup_mailbox(4, 1, CAN_EFF_FLAG, 0, intf, udev, dev); } cnt++; } sam4e_read_fw_version(dev); err = sam4e_init_urbs(dev); if (err) { if (err == -ENODEV) { netif_device_detach(dev->netdev1); netif_device_detach(dev->netdev2); } pr_err("couldn't start device: %d\n", err); close_candev(dev->netdev1); close_candev(dev->netdev2); goto cleanup_candev; } return 0; /*ok. it's ours */ cleanup_candev: if (dev) { kfree(dev->assembly_buffer); if (dev->netdev1) free_candev(dev->netdev1); if (dev->netdev2) free_candev(dev->netdev2); kfree(dev); } return err; }