static int au0828_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { int ifnum, retval; struct au0828_dev *dev; struct usb_device *usbdev = interface_to_usbdev(interface); ifnum = interface->altsetting->desc.bInterfaceNumber; if (ifnum != 0) return -ENODEV; dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__, le16_to_cpu(usbdev->descriptor.idVendor), le16_to_cpu(usbdev->descriptor.idProduct), ifnum); /* * Make sure we have 480 Mbps of bandwidth, otherwise things like * video stream wouldn't likely work, since 12 Mbps is generally * not enough even for most Digital TV streams. */ if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { printk(KERN_ERR "au0828: Device initialization failed.\n"); printk(KERN_ERR "au0828: Device must be connected to a " "high-speed USB 2.0 port.\n"); return -ENODEV; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); return -ENOMEM; } mutex_init(&dev->mutex); mutex_init(&dev->dvb.lock); dev->usbdev = usbdev; dev->boardnr = id->driver_info; /* Create the v4l2_device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { printk(KERN_ERR "%s() v4l2_device_register failed\n", __func__); kfree(dev); return -EIO; } /* Power Up the bridge */ au0828_write(dev, REG_600, 1 << 4); /* Bring up the GPIO's and supporting devices */ au0828_gpio_setup(dev); /* I2C */ au0828_i2c_register(dev); /* Setup */ au0828_card_setup(dev); /* Analog TV */ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) au0828_analog_register(dev, interface); /* Digital TV */ au0828_dvb_register(dev); /* Store the pointer to the au0828_dev so it can be accessed in au0828_usb_disconnect */ usb_set_intfdata(interface, dev); printk(KERN_INFO "Registered device AU0828 [%s]\n", dev->board.name == NULL ? "Unset" : dev->board.name); return 0; }
/* * drv_init() - a device potentially for us * * notes: drv_init() is called when the bus driver has located a card for us * to support. We accept the new device by returning 0. */ static int r871xu_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid) { uint status; struct _adapter *padapter = NULL; struct dvobj_priv *pdvobjpriv; struct net_device *pnetdev; printk(KERN_INFO "r8712u: DriverVersion: %s\n", DRVER); /* In this probe function, O.S. will provide the usb interface pointer * to driver. We have to increase the reference count of the usb device * structure by using the usb_get_dev function. */ usb_get_dev(interface_to_usbdev(pusb_intf)); pintf = pusb_intf; /* step 1. */ pnetdev = r8712_init_netdev(); if (!pnetdev) goto error; padapter = (struct _adapter *)_netdev_priv(pnetdev); disable_ht_for_spec_devid(pdid, padapter); pdvobjpriv = &padapter->dvobjpriv; pdvobjpriv->padapter = padapter; padapter->dvobjpriv.pusbdev = interface_to_usbdev(pusb_intf); usb_set_intfdata(pusb_intf, pnetdev); SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); /* step 2. */ padapter->dvobj_init = &r8712_usb_dvobj_init; padapter->dvobj_deinit = &r8712_usb_dvobj_deinit; padapter->halpriv.hal_bus_init = &r8712_usb_hal_bus_init; padapter->dvobjpriv.inirp_init = &r8712_usb_inirp_init; padapter->dvobjpriv.inirp_deinit = &r8712_usb_inirp_deinit; /* step 3. * initialize the dvobj_priv */ if (padapter->dvobj_init == NULL) goto error; else { status = padapter->dvobj_init(padapter); if (status != _SUCCESS) goto error; } /* step 4. */ status = r8712_init_drv_sw(padapter); if (status == _FAIL) goto error; /* step 5. read efuse/eeprom data and get mac_addr */ { int i, offset; u8 mac[6]; u8 tmpU1b, AutoloadFail, eeprom_CustomerID; u8 *pdata = padapter->eeprompriv.efuse_eeprom_data; tmpU1b = r8712_read8(padapter, EE_9346CR);/*CR9346*/ /* To check system boot selection.*/ printk(KERN_INFO "r8712u: Boot from %s: Autoload %s\n", (tmpU1b & _9356SEL) ? "EEPROM" : "EFUSE", (tmpU1b & _EEPROM_EN) ? "OK" : "Failed"); /* To check autoload success or not.*/ if (tmpU1b & _EEPROM_EN) { AutoloadFail = true; /* The following operations prevent Efuse leakage by * turning on 2.5V. */ tmpU1b = r8712_read8(padapter, EFUSE_TEST+3); r8712_write8(padapter, EFUSE_TEST + 3, tmpU1b | 0x80); msleep(20); r8712_write8(padapter, EFUSE_TEST + 3, (tmpU1b & (~BIT(7)))); /* Retrieve Chip version. * Recognize IC version by Reg0x4 BIT15. */ tmpU1b = (u8)((r8712_read32(padapter, PMC_FSM) >> 15) & 0x1F); if (tmpU1b == 0x3) padapter->registrypriv.chip_version = RTL8712_3rdCUT; else padapter->registrypriv.chip_version = (tmpU1b >> 1) + 1; switch (padapter->registrypriv.chip_version) { case RTL8712_1stCUT: case RTL8712_2ndCUT: case RTL8712_3rdCUT: break; default: padapter->registrypriv.chip_version = RTL8712_2ndCUT; break; } for (i = 0, offset = 0; i < 128; i += 8, offset++) r8712_efuse_pg_packet_read(padapter, offset, &pdata[i]); if (r8712_initmac) { /* Users specify the mac address */ int jj, kk; for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) mac[jj] = key_2char2num(r8712_initmac[kk], r8712_initmac[kk + 1]); } else { /* Use the mac address stored in the Efuse * offset = 0x12 for usb in efuse */ memcpy(mac, &pdata[0x12], ETH_ALEN); } eeprom_CustomerID = pdata[0x52]; switch (eeprom_CustomerID) { case EEPROM_CID_ALPHA: padapter->eeprompriv.CustomerID = RT_CID_819x_ALPHA; break; case EEPROM_CID_CAMEO: padapter->eeprompriv.CustomerID = RT_CID_819x_CAMEO; break; case EEPROM_CID_SITECOM: padapter->eeprompriv.CustomerID = RT_CID_819x_Sitecom; break; case EEPROM_CID_COREGA: padapter->eeprompriv.CustomerID = RT_CID_COREGA; break; case EEPROM_CID_Senao: padapter->eeprompriv.CustomerID = RT_CID_819x_Senao; break; case EEPROM_CID_EDIMAX_BELKIN: padapter->eeprompriv.CustomerID = RT_CID_819x_Edimax_Belkin; break; case EEPROM_CID_SERCOMM_BELKIN: padapter->eeprompriv.CustomerID = RT_CID_819x_Sercomm_Belkin; break; case EEPROM_CID_WNC_COREGA: padapter->eeprompriv.CustomerID = RT_CID_819x_WNC_COREGA; break; case EEPROM_CID_WHQL: break; case EEPROM_CID_NetCore: padapter->eeprompriv.CustomerID = RT_CID_819x_Netcore; break; case EEPROM_CID_CAMEO1: padapter->eeprompriv.CustomerID = RT_CID_819x_CAMEO1; break; case EEPROM_CID_CLEVO: padapter->eeprompriv.CustomerID = RT_CID_819x_CLEVO; break; default: padapter->eeprompriv.CustomerID = RT_CID_DEFAULT; break; } printk(KERN_INFO "r8712u: CustomerID = 0x%.4x\n", padapter->eeprompriv.CustomerID); /* Led mode */ switch (padapter->eeprompriv.CustomerID) { case RT_CID_DEFAULT: case RT_CID_819x_ALPHA: case RT_CID_819x_CAMEO: padapter->ledpriv.LedStrategy = SW_LED_MODE1; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_Sitecom: padapter->ledpriv.LedStrategy = SW_LED_MODE2; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_COREGA: case RT_CID_819x_Senao: padapter->ledpriv.LedStrategy = SW_LED_MODE3; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_Edimax_Belkin: padapter->ledpriv.LedStrategy = SW_LED_MODE4; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_Sercomm_Belkin: padapter->ledpriv.LedStrategy = SW_LED_MODE5; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_WNC_COREGA: padapter->ledpriv.LedStrategy = SW_LED_MODE6; padapter->ledpriv.bRegUseLed = true; break; default: padapter->ledpriv.LedStrategy = SW_LED_MODE0; padapter->ledpriv.bRegUseLed = false; break; } } else
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; 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; /* 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 ((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"); 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_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; tty_port_init(&acm->port); acm->port.ops = &acm_port_ops; buf = usb_buffer_alloc(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_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &rb->dma); if (!rb->base) { dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\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_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); alloc_fail2: kfree(acm); alloc_fail: return -ENOMEM; }
static int s2250loader_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *usbdev; int minor, ret; pdevice_extension_t s = NULL; const struct firmware *fw; usbdev = usb_get_dev(interface_to_usbdev(interface)); if (!usbdev) { printk(KERN_ERR "Enter s2250loader_probe failed\n"); return -1; } printk(KERN_INFO "Enter s2250loader_probe 2.6 kernel\n"); printk(KERN_INFO "vendor id 0x%x, device id 0x%x devnum:%d\n", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, usbdev->devnum); if (usbdev->descriptor.bNumConfigurations != 1) { printk(KERN_ERR "can't handle multiple config\n"); return -1; } mutex_lock(&s2250_dev_table_mutex); for (minor = 0; minor < MAX_DEVICES; minor++) { if (s2250_dev_table[minor] == NULL) break; } if (minor < 0 || minor >= MAX_DEVICES) { printk(KERN_ERR "Invalid minor: %d\n", minor); goto failed; } /* Allocate dev data structure */ s = kmalloc(sizeof(device_extension_t), GFP_KERNEL); if (s == NULL) { printk(KERN_ERR "Out of memory\n"); goto failed; } s2250_dev_table[minor] = s; printk(KERN_INFO "s2250loader_probe: Device %d on Bus %d Minor %d\n", usbdev->devnum, usbdev->bus->busnum, minor); memset(s, 0, sizeof(device_extension_t)); s->usbdev = usbdev; printk(KERN_INFO "loading 2250 loader\n"); kref_init(&(s->kref)); mutex_unlock(&s2250_dev_table_mutex); if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) goto failed2; ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); release_firmware(fw); if (0 != ret) { printk(KERN_ERR "loader download failed\n"); goto failed2; } if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) goto failed2; ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); release_firmware(fw); if (0 != ret) { printk(KERN_ERR "firmware_s2250 download failed\n"); goto failed2; } usb_set_intfdata(interface, s); return 0; failed: mutex_unlock(&s2250_dev_table_mutex); failed2: if (s) kref_put(&(s->kref), s2250loader_delete); printk(KERN_ERR "probe failed\n"); return -1; }
static BOOLEAN USBDevConfigInit( IN struct usb_device *dev, IN struct usb_interface *intf, IN VOID *pAd) { struct usb_host_interface *iface_desc; ULONG BulkOutIdx; ULONG BulkInIdx; UINT32 i; RT_CMD_USB_DEV_CONFIG Config, *pConfig = &Config; /* get the active interface descriptor */ iface_desc = intf->cur_altsetting; /* get # of enpoints */ pConfig->NumberOfPipes = iface_desc->desc.bNumEndpoints; DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints)); /* Configure Pipes */ BulkOutIdx = 0; BulkInIdx = 0; for (i = 0; i < pConfig->NumberOfPipes; i++) { if ((iface_desc->endpoint[i].desc.bmAttributes == USB_ENDPOINT_XFER_BULK) && ((iface_desc->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) { if (BulkInIdx < 2) { pConfig->BulkInEpAddr[BulkInIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) pConfig->BulkInMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize); #else pConfig->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize; #endif /* LINUX_VERSION_CODE */ DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK IN MaxPacketSize = %d\n", pConfig->BulkInMaxPacketSize)); DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress)); } else { DBGPRINT(RT_DEBUG_ERROR, ("Bulk IN endpoint nums large than 2\n")); } } else if ((iface_desc->endpoint[i].desc.bmAttributes == USB_ENDPOINT_XFER_BULK) && ((iface_desc->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)) { if (BulkOutIdx < 6) { /* there are 6 bulk out EP. EP6 highest priority. */ /* EP1-4 is EDCA. EP5 is HCCA. */ pConfig->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) pConfig->BulkOutMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize); #else pConfig->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize; #endif DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK OUT MaxPacketSize = %d\n", pConfig->BulkOutMaxPacketSize)); DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress)); } else { DBGPRINT(RT_DEBUG_ERROR, ("Bulk Out endpoint nums large than 6\n")); } } } if (!(pConfig->BulkInEpAddr && pConfig->BulkOutEpAddr[0])) { printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__); return FALSE; } pConfig->pConfig = &dev->config->desc; usb_set_intfdata(intf, pAd); RTMP_DRIVER_USB_CONFIG_INIT(pAd, pConfig); RT28XXVendorSpecificCheck(dev, pAd); return TRUE; }
int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) { int retval; struct net_device *net = dev->net; struct cdc_state *info = (void *) &dev->data; union { void *buf; struct rndis_msg_hdr *header; struct rndis_init *init; struct rndis_init_c *init_c; struct rndis_query *get; struct rndis_query_c *get_c; struct rndis_set *set; struct rndis_set_c *set_c; struct rndis_halt *halt; } u; u32 tmp; __le32 phym_unspec, *phym; int reply_len; unsigned char *bp; u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); if (!u.buf) return -ENOMEM; retval = usbnet_generic_cdc_bind(dev, intf); if (retval < 0) goto fail; u.init->msg_type = RNDIS_MSG_INIT; u.init->msg_len = cpu_to_le32(sizeof *u.init); u.init->major_version = cpu_to_le32(1); u.init->minor_version = cpu_to_le32(0); net->hard_header_len += sizeof (struct rndis_data_hdr); dev->hard_mtu = net->mtu + net->hard_header_len; dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); if (dev->maxpacket == 0) { if (netif_msg_probe(dev)) dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n"); retval = -EINVAL; goto fail_and_release; } dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); dev->rx_urb_size &= ~(dev->maxpacket - 1); u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); net->netdev_ops = &rndis_netdev_ops; retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); if (unlikely(retval < 0)) { dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); goto fail_and_release; } tmp = le32_to_cpu(u.init_c->max_transfer_size); if (tmp < dev->hard_mtu) { if (tmp <= net->hard_header_len) { dev_err(&intf->dev, "dev can't take %u byte packets (max %u)\n", dev->hard_mtu, tmp); retval = -EINVAL; goto halt_fail_and_release; } dev_warn(&intf->dev, "dev can't take %u byte packets (max %u), " "adjusting MTU to %u\n", dev->hard_mtu, tmp, tmp - net->hard_header_len); dev->hard_mtu = tmp; net->mtu = dev->hard_mtu - net->hard_header_len; } dev_dbg(&intf->dev, "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n", dev->hard_mtu, tmp, dev->rx_urb_size, 1 << le32_to_cpu(u.init_c->packet_alignment)); if (dev->driver_info->early_init && dev->driver_info->early_init(dev) != 0) goto halt_fail_and_release; phym = NULL; reply_len = sizeof *phym; retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, 0, (void **) &phym, &reply_len); if (retval != 0 || !phym) { phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; phym = &phym_unspec; } if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { if (netif_msg_probe(dev)) dev_dbg(&intf->dev, "driver requires wireless " "physical medium, but device is not.\n"); retval = -ENODEV; goto halt_fail_and_release; } if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { if (netif_msg_probe(dev)) dev_dbg(&intf->dev, "driver requires non-wireless " "physical medium, but device is wireless.\n"); retval = -ENODEV; goto halt_fail_and_release; } reply_len = ETH_ALEN; retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, 48, (void **) &bp, &reply_len); if (unlikely(retval< 0)) { dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); goto halt_fail_and_release; } memcpy(net->dev_addr, bp, ETH_ALEN); memcpy(net->perm_addr, bp, ETH_ALEN); memset(u.set, 0, sizeof *u.set); u.set->msg_type = RNDIS_MSG_SET; u.set->msg_len = cpu_to_le32(4 + sizeof *u.set); u.set->oid = OID_GEN_CURRENT_PACKET_FILTER; u.set->len = cpu_to_le32(4); u.set->offset = cpu_to_le32((sizeof *u.set) - 8); *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER; retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); if (unlikely(retval < 0)) { dev_err(&intf->dev, "rndis set packet filter, %d\n", retval); goto halt_fail_and_release; } retval = 0; kfree(u.buf); return retval; halt_fail_and_release: memset(u.halt, 0, sizeof *u.halt); u.halt->msg_type = RNDIS_MSG_HALT; u.halt->msg_len = cpu_to_le32(sizeof *u.halt); (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE); fail_and_release: usb_set_intfdata(info->data, NULL); usb_driver_release_interface(driver_of(intf), info->data); info->data = NULL; fail: kfree(u.buf); return retval; }
/** * ld_usb_probe * * Called by the usb core when a new device is connected that it thinks * this driver might be interested in. */ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct ld_usb *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; char *buffer; int i; int retval = -ENOMEM; /* allocate memory for our device state and intialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { dev_err(&intf->dev, "Out of memory\n"); goto exit; } mutex_init(&dev->mutex); spin_lock_init(&dev->rbsl); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); /* workaround for early firmware versions on fast computers */ if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) && ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_CASSY) || (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) && (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { buffer = kmalloc(256, GFP_KERNEL); if (buffer == NULL) { dev_err(&intf->dev, "Couldn't allocate string buffer\n"); goto error; } /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ usb_string(udev, 255, buffer, 256); kfree(buffer); } iface_desc = intf->cur_altsetting; /* set up the endpoint information */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) dev->interrupt_in_endpoint = endpoint; if (usb_endpoint_is_int_out(endpoint)) dev->interrupt_out_endpoint = endpoint; } if (dev->interrupt_in_endpoint == NULL) { dev_err(&intf->dev, "Interrupt in endpoint not found\n"); goto error; } if (dev->interrupt_out_endpoint == NULL) dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize); dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL); if (!dev->ring_buffer) { dev_err(&intf->dev, "Couldn't allocate ring_buffer\n"); goto error; } dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); if (!dev->interrupt_in_buffer) { dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n"); goto error; } dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_in_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n"); goto error; } dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) : udev->descriptor.bMaxPacketSize0; dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL); if (!dev->interrupt_out_buffer) { dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n"); goto error; } dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->interrupt_out_urb) { dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n"); goto error; } dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; if (dev->interrupt_out_endpoint) dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; /* we can register the device now, as it is ready */ usb_set_intfdata(intf, dev); retval = usb_register_dev(intf, &ld_usb_class); if (retval) { /* something prevented us from registering this driver */ dev_err(&intf->dev, "Not able to get a minor for this device.\n"); usb_set_intfdata(intf, NULL); goto error; } /* let the user know what node this device is now attached to */ dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n", (intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor); exit: return retval; error: ld_usb_delete(dev); return retval; }
static int qcnmea_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); struct usb_host_interface *cur_intf = intf->cur_altsetting; int epnum, minor; struct usb_endpoint_descriptor *epread, *epwrite, *eptmp; struct qcnmea *nmea; int i, num_rx_buf = QCNMEA_NR; if(cur_intf->desc.bInterfaceNumber != 1) { /*not the right interface*/ return -ENODEV; } printk(KERN_ALERT "this is qct nmea interface!\n"); epnum = cur_intf->desc.bNumEndpoints; if(epnum != 2) {/*endpoint number error*/ printk(KERN_ALERT "epnum[%d] is wrong!\n", epnum); return -EINVAL; } while(epnum > 0) { eptmp = &cur_intf->endpoint[epnum - 1].desc; if(!eptmp) return -EINVAL; if(usb_endpoint_dir_in(eptmp)) epread = eptmp; else if(usb_endpoint_dir_out(eptmp)) epwrite = eptmp; epnum--; } if(!epwrite || !epread) { printk(KERN_ALERT "epwrite[%d], epread[%d]\n", epwrite, epread); return -EINVAL; } for(minor = 0; (minor < QC_NMEA_MINORS) && qcnmea_tab[minor]; minor++) ; if(minor == QC_NMEA_MINORS) { printk(KERN_ALERT "minor is wrong!\n"); return -ENODEV; } nmea = kzalloc(sizeof(struct qcnmea), GFP_KERNEL); if(!nmea) { printk(KERN_ALERT "in alloc_fail1\n"); goto alloc_fail1; } nmea->usb_dev = usb_dev; nmea->read_size = le16_to_cpu(epread->wMaxPacketSize); nmea->write_size = le16_to_cpu(epwrite->wMaxPacketSize); nmea->intf = intf; spin_lock_init(&nmea->throttle_lock); spin_lock_init(&nmea->write_lock); spin_lock_init(&nmea->read_lock); INIT_WORK(&nmea->write_work, qcnmea_write_work, nmea); nmea->write_ready = 1; nmea->read_pipe = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); if(qcnmea_write_buf_alloc(nmea) < 0) { printk(KERN_ALERT "in alloc_fail4\n"); goto alloc_fail4; } nmea->write_urb = usb_alloc_urb(0, GFP_KERNEL); if(!nmea->write_urb) { printk(KERN_ALERT "in alloc_fail5\n"); goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { struct qcnmea_ru *rcv = &(nmea->ru[i]); if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { //dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)"); printk(KERN_ALERT "in alloc_fail7\n"); goto alloc_fail7; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = nmea; } for (i = 0; i < num_rx_buf; i++) { struct qcnmea_rb *buf = &(nmea->rb[i]); if (!(buf->base = usb_buffer_alloc(nmea->usb_dev, nmea->read_size, GFP_KERNEL, &buf->dma))) { //dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)"); printk(KERN_ALERT "in alloc_fail7,1\n"); goto alloc_fail7; } } tasklet_init(&nmea->rx_tasklet, qcnmea_rx_tasklet, nmea); usb_set_intfdata(intf, nmea); //if(device_create_file(&intf->dev, &dev_attr_bmCapabilities)) // goto alloc_fail7; usb_fill_bulk_urb(nmea->write_urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), nmea->write_buf, nmea->write_size, qcnmea_write_bulk, nmea); nmea->write_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; nmea->line.dwDTERate = cpu_to_le32(9600); nmea->line.bDataBits = 8; qcnmea_set_line(nmea, &nmea->line); qcnmea_set_control(nmea, nmea->seria_out); usb_get_intf(intf); tty_register_device(qcnmea_tty_driver, minor, &intf->dev); nmea->minor = minor; qcnmea_tab[minor] = nmea; printk(KERN_ALERT "qct nmea probe ok!, read_size :%d, write_size :%d\n",nmea->read_size, nmea->write_size); return 0; alloc_fail7: for (i = 0; i < num_rx_buf; i++) usb_buffer_free(usb_dev, nmea->read_size, nmea->rb[i].base, nmea->rb[i].dma); for (i = 0; i < num_rx_buf; i++) usb_free_urb(nmea->ru[i].urb); alloc_fail6: usb_free_urb(nmea->write_urb); alloc_fail5: qcnmea_write_buf_free(nmea); alloc_fail4: alloc_fail3: alloc_fail2: kfree(nmea); alloc_fail1:
static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) { int status = -1; u8 *buf = intf->cur_altsetting->extra; int len = intf->cur_altsetting->extralen; struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; struct usb_cdc_union_desc *cdc_union; struct usb_cdc_ether_desc *cdc_ether; struct usb_driver *driver = driver_of(intf); struct qmi_wwan_state *info = (void *)&dev->data; struct usb_cdc_parsed_header hdr; BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state))); /* set up initial state */ info->control = intf; info->data = intf; /* and a number of CDC descriptors */ cdc_parse_cdc_header(&hdr, intf, buf, len); cdc_union = hdr.usb_cdc_union_desc; cdc_ether = hdr.usb_cdc_ether_desc; /* Use separate control and data interfaces if we found a CDC Union */ if (cdc_union) { info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0); if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) { dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n", cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0); /* ignore and continue... */ cdc_union = NULL; info->data = intf; } } /* errors aren't fatal - we can live with the dynamic address */ if (cdc_ether) { dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize); usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress); } /* claim data interface and set it up */ if (info->control != info->data) { status = usb_driver_claim_interface(driver, info->data, dev); if (status < 0) goto err; } status = qmi_wwan_register_subdriver(dev); if (status < 0 && info->control != info->data) { usb_set_intfdata(info->data, NULL); usb_driver_release_interface(driver, info->data); } /* disabling remote wakeup on MDM9x30 devices has the same * effect as clearing DTR. The device will not respond to QMI * requests until we set DTR again. This is similar to a * QMI_CTL SYNC request, clearing a lot of firmware state * including the client ID allocations. * * Our usage model allows a session to span multiple * open/close events, so we must prevent the firmware from * clearing out state the clients might need. * * MDM9x30 is the first QMI chipset with USB3 support. Abuse * this fact to enable the quirk. */ if (le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) { qmi_wwan_manage_power(dev, 1); qmi_wwan_change_dtr(dev, true); } /* Never use the same address on both ends of the link, even if the * buggy firmware told us to. Or, if device is assigned the well-known * buggy firmware MAC address, replace it with a random address, */ if (ether_addr_equal(dev->net->dev_addr, default_modem_addr) || ether_addr_equal(dev->net->dev_addr, buggy_fw_addr)) eth_hw_addr_random(dev->net); /* make MAC addr easily distinguishable from an IP header */ if (possibly_iphdr(dev->net->dev_addr)) { dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */ dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */ } dev->net->netdev_ops = &qmi_wwan_netdev_ops; dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group; err: return status; }
static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct asus_oled_dev *odev = NULL; int retval = -ENOMEM; uint16_t dev_width = 0; oled_pack_mode_t pack_mode = PACK_MODE_LAST; const struct oled_dev_desc_str * dev_desc = oled_dev_desc_table; const char *desc = 0; if (id == 0) { // Even possible? Just to make sure... dev_err(&interface->dev, "No usb_device_id provided!\n"); return -ENODEV; } for (; dev_desc->idVendor; dev_desc++) { if (dev_desc->idVendor == id->idVendor && dev_desc->idProduct == id->idProduct) { dev_width = dev_desc->devWidth; desc = dev_desc->devDesc; pack_mode = dev_desc->packMode; break; } } if ( !desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) { dev_err(&interface->dev, "Missing or incomplete device description!\n"); return -ENODEV; } odev = kzalloc(sizeof(struct asus_oled_dev), GFP_KERNEL); if (odev == NULL) { dev_err(&interface->dev, "Out of memory\n"); return -ENOMEM; } odev->udev = usb_get_dev(udev); odev->pic_mode = ASUS_OLED_STATIC; odev->dev_width = dev_width; odev->pack_mode = pack_mode; odev->height = 0; odev->width = 0; odev->x_shift = 0; odev->y_shift = 0; odev->buf_offs = 0; odev->buf_size = 0; odev->last_val = 0; odev->buf = NULL; odev->enabled = 1; odev->dev = 0; usb_set_intfdata (interface, odev); if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)))) { goto err_files; } if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)))) { goto err_files; } odev->dev = device_create(oled_class, &interface->dev, MKDEV(0,0), NULL,"oled_%d", ++oled_num); if (IS_ERR(odev->dev)) { retval = PTR_ERR(odev->dev); goto err_files; } dev_set_drvdata(odev->dev, odev); if ( (retval = device_create_file(odev->dev, &dev_attr_enabled))) { goto err_class_enabled; } if ( (retval = device_create_file(odev->dev, &dev_attr_picture))) { goto err_class_picture; } dev_info(&interface->dev, "Attached Asus OLED device: %s [width %u, pack_mode %d]\n", desc, odev->dev_width, odev->pack_mode); if (start_off) enable_oled(odev, 0); return 0; err_class_picture: device_remove_file(odev->dev, &dev_attr_picture); err_class_enabled: device_remove_file(odev->dev, &dev_attr_enabled); device_unregister(odev->dev); err_files: device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)); device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)); usb_set_intfdata (interface, NULL); usb_put_dev(odev->udev); kfree(odev); return retval; }
static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id *id) { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); struct bcm203x_data *data; int size; BT_DBG("intf %p id %p", intf, id); if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { BT_ERR("Can't allocate memory for data structure"); return -ENOMEM; } data->udev = udev; data->state = BCM203X_LOAD_MINIDRV; data->urb = usb_alloc_urb(0, GFP_KERNEL); if (!data->urb) { BT_ERR("Can't allocate URB"); kfree(data); return -ENOMEM; } if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { BT_ERR("Mini driver request failed"); usb_free_urb(data->urb); kfree(data); return -EIO; } BT_DBG("minidrv data %p size %zu", firmware->data, firmware->size); size = max_t(uint, firmware->size, 4096); data->buffer = kmalloc(size, GFP_KERNEL); if (!data->buffer) { BT_ERR("Can't allocate memory for mini driver"); release_firmware(firmware); usb_free_urb(data->urb); kfree(data); return -ENOMEM; } memcpy(data->buffer, firmware->data, firmware->size); usb_fill_bulk_urb(data->urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->buffer, firmware->size, bcm203x_complete, data); release_firmware(firmware); if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) { BT_ERR("Firmware request failed"); usb_free_urb(data->urb); kfree(data->buffer); kfree(data); return -EIO; } BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); data->fw_data = kmalloc(firmware->size, GFP_KERNEL); if (!data->fw_data) { BT_ERR("Can't allocate memory for firmware image"); release_firmware(firmware); usb_free_urb(data->urb); kfree(data->buffer); kfree(data); return -ENOMEM; } memcpy(data->fw_data, firmware->data, firmware->size); data->fw_size = firmware->size; data->fw_sent = 0; release_firmware(firmware); INIT_WORK(&data->work, bcm203x_work); usb_set_intfdata(intf, data); schedule_work(&data->work); return 0; }
/* * probes control interface, claims data interface, collects the bulk * endpoints, activates data interface (if needed), maybe sets MTU. * all pure cdc, except for certain firmware workarounds, and knowing * that rndis uses one different rule. */ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) { u8 *buf = intf->cur_altsetting->extra; int len = intf->cur_altsetting->extralen; struct usb_interface_descriptor *d; struct cdc_state *info = (void *) &dev->data; int status; int rndis; struct usb_driver *driver = driver_of(intf); if (sizeof dev->data < sizeof *info) return -EDOM; /* expect strict spec conformance for the descriptors, but * cope with firmware which stores them in the wrong place */ if (len == 0 && dev->udev->actconfig->extralen) { /* Motorola SB4100 (and others: Brad Hards says it's * from a Broadcom design) put CDC descriptors here */ buf = dev->udev->actconfig->extra; len = dev->udev->actconfig->extralen; if (len) dev_dbg(&intf->dev, "CDC descriptors on config\n"); } /* Maybe CDC descriptors are after the endpoint? This bug has * been seen on some 2Wire Inc RNDIS-ish products. */ if (len == 0) { struct usb_host_endpoint *hep; hep = intf->cur_altsetting->endpoint; if (hep) { buf = hep->extra; len = hep->extralen; } if (len) dev_dbg(&intf->dev, "CDC descriptors on endpoint\n"); } /* this assumes that if there's a non-RNDIS vendor variant * of cdc-acm, it'll fail RNDIS requests cleanly. */ rndis = is_rndis(&intf->cur_altsetting->desc) || is_activesync(&intf->cur_altsetting->desc); memset(info, 0, sizeof *info); info->control = intf; while (len > 3) { if (buf [1] != USB_DT_CS_INTERFACE) goto next_desc; /* use bDescriptorSubType to identify the CDC descriptors. * We expect devices with CDC header and union descriptors. * For CDC Ethernet we need the ethernet descriptor. * For RNDIS, ignore two (pointless) CDC modem descriptors * in favor of a complicated OID-based RPC scheme doing what * CDC Ethernet achieves with a simple descriptor. */ switch (buf [2]) { case USB_CDC_HEADER_TYPE: if (info->header) { dev_dbg(&intf->dev, "extra CDC header\n"); goto bad_desc; } info->header = (void *) buf; if (info->header->bLength != sizeof *info->header) { dev_dbg(&intf->dev, "CDC header len %u\n", info->header->bLength); goto bad_desc; } break; case USB_CDC_ACM_TYPE: /* paranoia: disambiguate a "real" vendor-specific * modem interface from an RNDIS non-modem. */ if (rndis) { struct usb_cdc_acm_descriptor *acm; acm = (void *) buf; if (acm->bmCapabilities) { dev_dbg(&intf->dev, "ACM capabilities %02x, " "not really RNDIS?\n", acm->bmCapabilities); goto bad_desc; } } break; case USB_CDC_UNION_TYPE: if (info->u) { dev_dbg(&intf->dev, "extra CDC union\n"); goto bad_desc; } info->u = (void *) buf; if (info->u->bLength != sizeof *info->u) { dev_dbg(&intf->dev, "CDC union len %u\n", info->u->bLength); goto bad_desc; } /* we need a master/control interface (what we're * probed with) and a slave/data interface; union * descriptors sort this all out. */ info->control = usb_ifnum_to_if(dev->udev, info->u->bMasterInterface0); info->data = usb_ifnum_to_if(dev->udev, info->u->bSlaveInterface0); if (!info->control || !info->data) { dev_dbg(&intf->dev, "master #%u/%p slave #%u/%p\n", info->u->bMasterInterface0, info->control, info->u->bSlaveInterface0, info->data); goto bad_desc; } if (info->control != intf) { dev_dbg(&intf->dev, "bogus CDC Union\n"); /* Ambit USB Cable Modem (and maybe others) * interchanges master and slave interface. */ if (info->data == intf) { info->data = info->control; info->control = intf; } else goto bad_desc; } /* a data interface altsetting does the real i/o */ d = &info->data->cur_altsetting->desc; if (d->bInterfaceClass != USB_CLASS_CDC_DATA) { dev_dbg(&intf->dev, "slave class %u\n", d->bInterfaceClass); goto bad_desc; } break; case USB_CDC_ETHERNET_TYPE: if (info->ether) { dev_dbg(&intf->dev, "extra CDC ether\n"); goto bad_desc; } info->ether = (void *) buf; if (info->ether->bLength != sizeof *info->ether) { dev_dbg(&intf->dev, "CDC ether len %u\n", info->ether->bLength); goto bad_desc; } dev->hard_mtu = le16_to_cpu( info->ether->wMaxSegmentSize); /* because of Zaurus, we may be ignoring the host * side link address we were given. */ break; } next_desc: len -= buf [0]; /* bLength */ buf += buf [0]; } /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors, * so we'll hard-wire the interfaces and not check for descriptors. */ if (is_activesync(&intf->cur_altsetting->desc) && !info->u) { info->control = usb_ifnum_to_if(dev->udev, 0); info->data = usb_ifnum_to_if(dev->udev, 1); if (!info->control || !info->data) { dev_dbg(&intf->dev, "activesync: master #0/%p slave #1/%p\n", info->control, info->data); goto bad_desc; } } else if (!info->header || !info->u || (!rndis && !info->ether)) { dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", info->header ? "" : "header ", info->u ? "" : "union ", info->ether ? "" : "ether "); goto bad_desc; } /* claim data interface and set it up ... with side effects. * network traffic can't flow until an altsetting is enabled. */ status = usb_driver_claim_interface(driver, info->data, dev); if (status < 0) return status; status = usbnet_get_endpoints(dev, info->data); if (status < 0) { /* ensure immediate exit from usbnet_disconnect */ usb_set_intfdata(info->data, NULL); usb_driver_release_interface(driver, info->data); return status; } /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */ dev->status = NULL; if (info->control->cur_altsetting->desc.bNumEndpoints == 1) { struct usb_endpoint_descriptor *desc; dev->status = &info->control->cur_altsetting->endpoint [0]; desc = &dev->status->desc; if (!usb_endpoint_is_int_in(desc) || (le16_to_cpu(desc->wMaxPacketSize) < sizeof(struct usb_cdc_notification)) || !desc->bInterval) { dev_dbg(&intf->dev, "bad notification endpoint\n"); dev->status = NULL; } } if (rndis && !dev->status) { dev_dbg(&intf->dev, "missing RNDIS status endpoint\n"); usb_set_intfdata(info->data, NULL); usb_driver_release_interface(driver, info->data); return -ENODEV; } return 0; bad_desc: dev_info(&dev->udev->dev, "bad CDC descriptors\n"); return -ENODEV; }
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) //探针函数 相当于设备驱动的主函数 { struct usb_device *udev = interface_to_usbdev(intf); //根据usb设备接口获取到usb设备 实际 返回的是 intf->dev.parent 即设备的父亲 struct usb_xpad *xpad; //自己的定义的手柄设备类型 struct input_dev *input_dev;//输入设备 struct usb_endpoint_descriptor *ep_irq_in; //in endpoint 的描述 int ep_irq_in_idx; int i, error; for (i = 0; xpad_device[i].idVendor; i++) //根据实际插入的设备的生产商id和产品id 找到匹配的设备 { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); //在内核空间为手柄设备申请内存空间 input_dev = input_allocate_device(); //为输入设备在内核空间申请内存空间 input_allocate_device()这个函数是用kzalloc函数申请了空间后 然后对该内存进行了初始化 if (!xpad || !input_dev) //申请空间失败 { error = -ENOMEM; goto fail1; } //usb_alloc_coherent (struct usb_device *dev,size_t size,gfp_t mem_flags,dma_addr_t *dma)--allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP //分配DMA接口的缓冲区 返回 idata_dma 和 idata(raw packet,原始数据包) xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) //返回raw packet(原始数据包)失败 { error = -ENOMEM; goto fail1; } //usb_alloc_urb (int iso_packets,gfp_t mem_flags) create a new urb for a USB driver to use iso_packets = 0 when use interrupt endpoints //创建新的urb给设备使用 xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) //urb创建失败 { error = -ENOMEM; goto fail2; } xpad->udev = udev; //保存usb设备信息 xpad->intf = intf; //保存usb接口信息 xpad->dev = input_dev; //保存输入设备信息 //创建物理路径 usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); //input0类型的 input_dev->name = xpad_device[i].name; //保存输入设备名字 input_dev->phys = xpad->phys; //保存输入设备的物理路径 usb_to_input_id(udev, &input_dev->id); //保存输入设备ID input_dev->dev.parent = &intf->dev; //保存输入设备的设备 输入设备的父亲是usb接口 , usb接口的父亲 usb设备 input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; //输入设备的打开函数 input_dev->close = xpad_close; //输入设备的关闭函数 //BIT_MASK(nr) (1UL<<((nr)%BITS_PER_LONG)) input_dev->evbit[0] = BIT_MASK(EV_KEY); //注册键盘事件 input_dev->evbit[0] |= BIT_MASK(EV_REL); //注册相对轴事件 input_dev->evbit[0] |= BIT_MASK(EV_ABS); //注册绝对轴事件 /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) ///注册对应的绝对轴 xpad_set_up_abs(input_dev, xpad_abs[i]); xpad_set_up_rel(input_dev, REL_WHEEL); //注册对应的相对轴 for (i = 0 ; key_need_register[i] >= 0; i++) __set_bit(key_need_register[i], input_dev->keybit); //注册按键 for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); //注册游戏手柄按键 for (i = 0; xpad360_btn[i] >= 0; i++) __set_bit(xpad360_btn[i], input_dev->keybit); //注册LT RT按键 for (i = 0; xpad_abs_triggers[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); //初始化设备输出 error = xpad_init_output(intf, xpad); if (error) goto fail3; ep_irq_in_idx = 0; ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc; //根据usb接口得到 in endpoint口的描述信息 //函数结构 usb_fill_int_urb(struct urb* urb,struct usb_device * dev,unsigned int pipe,void * transfer_buffer,int buffer_length,usb_complete_t complete,void * context,int interval) //根据 usb设备,usb管道,输入缓冲区的首地址,缓冲区长度,urb入口函数,手柄设备数据信息,in endpoint口的轮换间隔信息 得到 输入的urb usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad, ep_irq_in->bInterval); xpad->irq_in->transfer_dma = xpad->idata_dma; //传输的DMA接口地址 xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; //传输标志(允许DMA方式传输) urb->transfer_dma valid on submit //根据输入设备信息 注册设备 error = input_register_device(xpad->dev); if (error) goto fail5; usb_set_intfdata(intf, xpad); return 0; fail5: if (input_dev) input_ff_destroy(input_dev); //free force feedback structures fail4: xpad_deinit_output(xpad); //free out urb and out dma fail3: usb_free_urb(xpad->irq_in); //free in urb fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); //free in dma fail1: input_free_device(input_dev); //free input_dev kfree(xpad); //free xpad return error; }
static int __devinit bridge_probe(struct usb_interface *iface, const struct usb_device_id *id) { struct usb_host_endpoint *endpoint = NULL; struct usb_host_endpoint *bulk_in = NULL; struct usb_host_endpoint *bulk_out = NULL; struct usb_host_endpoint *int_in = NULL; struct usb_device *udev; int i; int status = 0; int numends; int ch_id; char **bname = (char **)id->driver_info; unsigned int iface_num; iface_num = iface->cur_altsetting->desc.bInterfaceNumber; if (iface->num_altsetting != 1) { err("%s invalid num_altsetting %u\n", __func__, iface->num_altsetting); return -EINVAL; } udev = interface_to_usbdev(iface); usb_get_dev(udev); printk(KERN_INFO "%s: iface_num:%d\n", __func__, iface_num); if (!usb_diag_enable && iface_num == DUN_IFC_NUM && (board_mfg_mode() == 8 || board_mfg_mode() == 6 || board_mfg_mode() == 2)) { printk(KERN_INFO "%s DUN channel is NOT enumed as bridge interface!!! MAY be switched to TTY interface!!!", __func__); return -ENODEV; } numends = iface->cur_altsetting->desc.bNumEndpoints; for (i = 0; i < numends; i++) { endpoint = iface->cur_altsetting->endpoint + i; if (!endpoint) { dev_err(&iface->dev, "%s: invalid endpoint %u\n", __func__, i); status = -EINVAL; goto out; } if (usb_endpoint_is_bulk_in(&endpoint->desc)) bulk_in = endpoint; else if (usb_endpoint_is_bulk_out(&endpoint->desc)) bulk_out = endpoint; else if (usb_endpoint_is_int_in(&endpoint->desc)) int_in = endpoint; } if (!bulk_in || !bulk_out || !int_in) { dev_err(&iface->dev, "%s: invalid endpoints\n", __func__); status = -EINVAL; goto out; } ch_id = get_bridge_dev_idx(); if (ch_id < 0) { err("%s all bridge channels claimed. Probe failed\n", __func__); return -ENODEV; } status = data_bridge_probe(iface, bulk_in, bulk_out, bname[BRIDGE_DATA_IDX], ch_id); if (status < 0) { dev_err(&iface->dev, "data_bridge_probe failed %d\n", status); goto out; } status = ctrl_bridge_probe(iface, int_in, bname[BRIDGE_CTRL_IDX], ch_id); if (status < 0) { dev_err(&iface->dev, "ctrl_bridge_probe failed %d\n", status); goto error; } return 0; error: platform_device_unregister(__dev[ch_id]->pdev); free_rx_urbs(__dev[ch_id]); usb_set_intfdata(iface, NULL); out: usb_put_dev(udev); return status; }
static int pcan_usb_plugin(struct usb_interface *interface, const struct usb_device_id *id) { int err; int i, dev_ctrl_count, sizeof_if; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; struct usb_device *usb_dev = interface_to_usbdev(interface); struct pcan_usb_interface *usb_if; int (*device_init)(struct pcan_usb_interface *); DPRINTK(KERN_DEBUG "%s: %s(0x%04x, 0x%04x, 0x%04x)\n", DEVICE_NAME, __FUNCTION__, usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct, usb_dev->descriptor.bcdDevice); /* check endpoint addresses (numbers) and associated max data length */ /* (only from setting 0) */ /* Since USB-PRO defines also a LIN interface, should reject it when */ /* adapter plugged: make use of endpoint addresses (no other way...) */ iface_desc = &interface->altsetting[0]; DPRINTK(KERN_DEBUG "%s: %s(): bNumEndpoints=%d\n", DEVICE_NAME, __FUNCTION__, iface_desc->desc.bNumEndpoints); for (i=0; i < iface_desc->desc.bNumEndpoints; i++) { struct usb_endpoint_descriptor *endpoint = &iface_desc->endpoint[i].desc; /* Below is the list of valid ep addreses. All other ep address */ /* is considered as not-CAN interface address => no dev created */ switch (endpoint->bEndpointAddress) { case 0x01: case 0x81: case 0x02: case 0x82: case 0x03: case 0x83: break; default: #ifdef DEBUG printk(KERN_INFO "%s: %s(): EP address %02x not in CAN range.\n", DEVICE_NAME, __FUNCTION__, endpoint->bEndpointAddress); printk(KERN_INFO "%s: %s(): ignoring the whole USB interface\n", DEVICE_NAME, __FUNCTION__); #endif return -ENODEV; } } // take the 1st configuration (it's default) if ((err = usb_reset_configuration(usb_dev)) < 0) { printk(KERN_ERR "%s: usb_set_configuration() failed!\n", DEVICE_NAME); return err; } // only 1 interface is supported // Note: HW_USB_PRO: interface#0 for CAN, #1 for LIN if ((err = usb_set_interface(usb_dev, 0, 0)) < 0) { printk(KERN_ERR "%s: usb_set_interface() failed!\n", DEVICE_NAME); return err; } /* Now, according to device id, create as many device as CAN controllers */ switch (usb_dev->descriptor.idProduct) { #ifdef HW_USB_PRO case PCAN_USBPRO_PRODUCT_ID: dev_ctrl_count = 2; device_init = pcan_usbpro_init; break; #endif case PCAN_USB_PRODUCT_ID: default: dev_ctrl_count = 1; device_init = pcan_usb_init; break; } printk(KERN_INFO "%s: new ", DEVICE_NAME); if (usb_dev->speed == USB_SPEED_HIGH) printk("high speed "); printk("usb adapter with %u CAN controller(s) detected\n", dev_ctrl_count); /* create our interface object for the USB device */ sizeof_if = sizeof(struct pcan_usb_interface) + \ sizeof(struct pcandev) * (dev_ctrl_count-1); usb_if = (struct pcan_usb_interface *)kmalloc(sizeof_if, GFP_KERNEL); if (usb_if == NULL) { printk(KERN_ERR "%s: kmalloc(%d) failed!\n", DEVICE_NAME, sizeof_if); return err; } memset(usb_if, '\0', sizeof_if); // store pointer to kernel supplied usb_dev usb_if->usb_dev = usb_dev; usb_if->usb_intf = interface; usb_if->dev_ctrl_count = dev_ctrl_count; // preset finish flags atomic_set(&usb_if->cmd_sync_complete, 0); atomic_set(&usb_if->cmd_async_complete, 1); // preset active URB counter atomic_set(&usb_if->active_urbs, 0); init_waitqueue_head(&usb_if->usb_wait_queue); /* get endpoint addresses (numbers) and associated max data length */ /* (only from setting 0) */ #ifdef HW_USB_PRO /* * Function Interface Endpoints DeviceId * --------- --------- ----------------------------------------- * Control 0 * CAN 0 "CAN-Device", * USB\VID_0c72&PID_000d&MI_00 * 1=Command, bidi for both CAN_Ctrller * 2=CAN-Controller 0, rcv (IN) both CAN-Ctrller, * transmit (OUT) CAN-Ctrl#0, * 3=CAN-Controller 1 transmit (OUT) CAN-Ctrl#1 * LIN 1 "LIN-Device", * USB\VID_0c72&PID_000d&MI_01 * 4=Command, * 5=Controller 0, * 6=Controller 1 */ #endif for (i=0; i < iface_desc->desc.bNumEndpoints; i++) { PCAN_ENDPOINT *pipe_addr = NULL; endpoint = &iface_desc->endpoint[i].desc; DPRINTK(KERN_DEBUG "%s: %s(): EP[%d]={addr=%d max=%d}\n", DEVICE_NAME, __FUNCTION__, i, endpoint->bEndpointAddress, endpoint->wMaxPacketSize); switch (endpoint->bEndpointAddress) { case 0x01: pipe_addr = &usb_if->pipe_cmd_out; break; case 0x81: pipe_addr = &usb_if->pipe_cmd_in; break; case 0x02: switch (usb_dev->descriptor.idProduct) { #ifdef HW_USB_PRO case PCAN_USBPRO_PRODUCT_ID: #endif case PCAN_USB_PRODUCT_ID: default: pipe_addr = &usb_if->dev[0].port.usb.pipe_write; break; } break; case 0x82: pipe_addr = &usb_if->pipe_read; break; #ifdef HW_USB_PRO case 0x03: switch (usb_dev->descriptor.idProduct) { case PCAN_USBPRO_PRODUCT_ID: pipe_addr = &usb_if->dev[1].port.usb.pipe_write; break; } #endif case 0x83: /* Unused pipe for PCAN-USB-PRO */ /* But seems that need to be reset too... */ /* TBD */ break; default: continue; } if (pipe_addr) { pipe_addr->ucNumber = endpoint->bEndpointAddress; pipe_addr->wDataSz = le16_to_cpu(endpoint->wMaxPacketSize); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) usb_reset_endpoint(usb_dev, endpoint->bEndpointAddress); #endif } /* ucRevision needs to be defined before allocating resources (PCAN-USB) */ #if defined(__LITTLE_ENDIAN) usb_if->ucHardcodedDevNr = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice & 0xff); usb_if->ucRevision = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice >> 8); #elif defined(__BIG_ENDIAN) usb_if->ucHardcodedDevNr = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice >> 8); usb_if->ucRevision = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice & 0xff); #else #error "Please fix the endianness defines in <asm/byteorder.h>" #endif DPRINTK(KERN_DEBUG "%s(): ucHardcodedDevNr=0x%02x ucRevision=0x%02X\n", __func__, usb_if->ucHardcodedDevNr, usb_if->ucRevision); if ((err = pcan_usb_allocate_resources(usb_if))) goto reject; usb_set_intfdata(interface, usb_if); /* call initialisation callback for entire device */ device_init(usb_if); /* install the reception part for the interface */ if (!atomic_read(&usb_if->read_data.use_count)) { FILL_BULK_URB(&usb_if->read_data, usb_if->usb_dev, usb_rcvbulkpipe(usb_if->usb_dev, usb_if->pipe_read.ucNumber), usb_if->read_buffer_addr[0], usb_if->read_buffer_size, pcan_usb_read_notify, usb_if); // submit urb if ((err = __usb_submit_urb(&usb_if->read_data))) { printk(KERN_ERR "%s: %s() can't submit! (%d)\n", DEVICE_NAME, __FUNCTION__, err); goto reject; } atomic_inc(&usb_if->active_urbs); } /* next, initialize each controller */ for (i=0; i < usb_if->dev_ctrl_count; i++) { err = pcan_usb_create_dev(usb_if, i); if (err != 0) { for (; i > 0; i--) { // TBD pcan_usb_delete_dev(); } break; } } reject: return err; }
/* * probe function for new CPC-USB devices */ static int cpcusb_probe(struct usb_interface *interface, const struct usb_device_id *id) { CPC_USB_T *card = NULL; CPC_CHAN_T *chan = NULL; struct usb_device *udev = interface_to_usbdev(interface); struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int i, j, retval = -ENOMEM, slot; slot = cpcusb_get_free_slot(); if (slot < 0) { info("No more devices supported"); return -ENOMEM; } /* allocate memory for our device state and initialize it */ card = kzalloc(sizeof(CPC_USB_T), GFP_KERNEL); if (!card) { err("Out of memory"); return -ENOMEM; } CPCUSB_Table[slot] = card; /* allocate and initialize the channel struct */ card->chan = kmalloc(sizeof(CPC_CHAN_T), GFP_KERNEL); if (!card->chan) { kfree(card); err("Out of memory"); return -ENOMEM; } chan = card->chan; memset(chan, 0, sizeof(CPC_CHAN_T)); ResetBuffer(chan); init_MUTEX(&card->sem); spin_lock_init(&card->slock); card->udev = udev; card->interface = interface; if (udev->descriptor.iSerialNumber) { usb_string(udev, udev->descriptor.iSerialNumber, card->serialNumber, 128); info("Serial %s", card->serialNumber); } card->productId = udev->descriptor.idProduct; info("Product %s", card->productId == USB_CPCUSB_LPC2119_PRODUCT_ID ? "CPC-USB/ARM7" : "CPC-USB/M16C"); /* set up the endpoint information */ /* check out the endpoints */ /* use only the first bulk-in and bulk-out endpoints */ iface_desc = &interface->altsetting[0]; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!card->num_intr_in && (endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { card->intr_in_urb = usb_alloc_urb(0, GFP_KERNEL); card->num_intr_in = 1; if (!card->intr_in_urb) { err("No free urbs available"); goto error; } dbg("intr_in urb %d", card->num_intr_in); } if (!card->num_bulk_in && (endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { card->num_bulk_in = 2; for (j = 0; j < CPC_USB_URB_CNT; j++) { card->urbs[j].size = endpoint->wMaxPacketSize; card->urbs[j].urb = usb_alloc_urb(0, GFP_KERNEL); if (!card->urbs[j].urb) { err("No free urbs available"); goto error; } card->urbs[j].buffer = usb_buffer_alloc(udev, card->urbs[j].size, GFP_KERNEL, &card->urbs[j].urb->transfer_dma); if (!card->urbs[j].buffer) { err("Couldn't allocate bulk_in_buffer"); goto error; } } info("%s - %d reading URB's allocated", __func__, CPC_USB_URB_CNT); } if (!card->num_bulk_out && !(endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { card->num_bulk_out = 2; for (j = 0; j < CPC_USB_URB_CNT; j++) { card->wrUrbs[j].size = endpoint->wMaxPacketSize; card->wrUrbs[j].urb = usb_alloc_urb(0, GFP_KERNEL); if (!card->wrUrbs[j].urb) { err("No free urbs available"); goto error; } card->wrUrbs[j].buffer = usb_buffer_alloc(udev, card->wrUrbs[j].size, GFP_KERNEL, &card->wrUrbs[j].urb->transfer_dma); if (!card->wrUrbs[j].buffer) { err("Couldn't allocate bulk_out_buffer"); goto error; } usb_fill_bulk_urb(card->wrUrbs[j].urb, udev, usb_sndbulkpipe(udev, endpoint->bEndpointAddress), card->wrUrbs[j].buffer, card->wrUrbs[j].size, cpcusb_write_bulk_callback, card); } info("%s - %d writing URB's allocated", __func__, CPC_USB_URB_CNT); } } if (!(card->num_bulk_in && card->num_bulk_out)) { err("Couldn't find both bulk-in and bulk-out endpoints"); goto error; } /* allow device read, write and ioctl */ card->present = 1; /* we can register the device now, as it is ready */ usb_set_intfdata(interface, card); retval = usb_register_dev(interface, &cpcusb_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; } card->chan->minor = card->minor = interface->minor; chan->buf = vmalloc(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT); if (chan->buf == NULL) { err("Out of memory"); retval = -ENOMEM; goto error; } info("Allocated memory for %d messages (%lu kbytes)", CPC_MSG_BUF_CNT, (long unsigned int)(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT) / 1000); memset(chan->buf, 0, sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT); ResetBuffer(chan); card->chan->CPCWait_q = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL); if (!card->chan->CPCWait_q) { err("Out of memory"); retval = -ENOMEM; goto error; } init_waitqueue_head(card->chan->CPCWait_q); CPCUSB_Table[slot] = card; card->idx = slot; CPCUsbCnt++; /* let the user know what node this device is now attached to */ info("Device now attached to USB-%d", card->minor); return 0; error: for (j = 0; j < CPC_USB_URB_CNT; j++) { if (card->urbs[j].buffer) { usb_buffer_free(card->udev, card->urbs[j].size, card->urbs[j].buffer, card->urbs[j].urb->transfer_dma); card->urbs[j].buffer = NULL; } if (card->urbs[j].urb) { usb_free_urb(card->urbs[j].urb); card->urbs[j].urb = NULL; } } cpcusb_delete(card); return retval; }
static int ar5523_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct ieee80211_hw *hw; struct ar5523 *ar; int error = -ENOMEM; /* * Load firmware if the device requires it. This will return * -ENXIO on success and we'll get called back afer the usb * id changes to indicate that the firmware is present. */ if (id->driver_info & AR5523_FLAG_PRE_FIRMWARE) return ar5523_load_firmware(dev); hw = ieee80211_alloc_hw(sizeof(*ar), &ar5523_ops); if (!hw) goto out; SET_IEEE80211_DEV(hw, &intf->dev); ar = hw->priv; ar->hw = hw; ar->dev = dev; mutex_init(&ar->mutex); INIT_DELAYED_WORK(&ar->stat_work, ar5523_stat_work); init_timer(&ar->tx_wd_timer); setup_timer(&ar->tx_wd_timer, ar5523_tx_wd_timer, (unsigned long) ar); INIT_WORK(&ar->tx_wd_work, ar5523_tx_wd_work); INIT_WORK(&ar->tx_work, ar5523_tx_work); INIT_LIST_HEAD(&ar->tx_queue_pending); INIT_LIST_HEAD(&ar->tx_queue_submitted); spin_lock_init(&ar->tx_data_list_lock); atomic_set(&ar->tx_nr_total, 0); atomic_set(&ar->tx_nr_pending, 0); init_waitqueue_head(&ar->tx_flush_waitq); atomic_set(&ar->rx_data_free_cnt, 0); INIT_WORK(&ar->rx_refill_work, ar5523_rx_refill_work); INIT_LIST_HEAD(&ar->rx_data_free); INIT_LIST_HEAD(&ar->rx_data_used); spin_lock_init(&ar->rx_data_list_lock); ar->wq = create_singlethread_workqueue("ar5523"); if (!ar->wq) { ar5523_err(ar, "Could not create wq\n"); goto out_free_ar; } error = ar5523_alloc_rx_bufs(ar); if (error) { ar5523_err(ar, "Could not allocate rx buffers\n"); goto out_free_wq; } error = ar5523_alloc_rx_cmd(ar); if (error) { ar5523_err(ar, "Could not allocate rx command buffers\n"); goto out_free_rx_bufs; } error = ar5523_alloc_tx_cmd(ar); if (error) { ar5523_err(ar, "Could not allocate tx command buffers\n"); goto out_free_rx_cmd; } error = ar5523_submit_rx_cmd(ar); if (error) { ar5523_err(ar, "Failed to submit rx cmd\n"); goto out_free_tx_cmd; } /* * We're now ready to send/receive firmware commands. */ error = ar5523_host_available(ar); if (error) { ar5523_err(ar, "could not initialize adapter\n"); goto out_cancel_rx_cmd; } error = ar5523_get_max_rxsz(ar); if (error) { ar5523_err(ar, "could not get caps from adapter\n"); goto out_cancel_rx_cmd; } error = ar5523_get_devcap(ar); if (error) { ar5523_err(ar, "could not get caps from adapter\n"); goto out_cancel_rx_cmd; } error = ar5523_get_devstatus(ar); if (error != 0) { ar5523_err(ar, "could not get device status\n"); goto out_cancel_rx_cmd; } ar5523_info(ar, "MAC/BBP AR5523, RF AR%c112\n", (id->driver_info & AR5523_FLAG_ABG) ? '5' : '2'); ar->vif = NULL; hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; hw->extra_tx_headroom = sizeof(struct ar5523_tx_desc) + sizeof(struct ar5523_chunk); hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); hw->queues = 1; error = ar5523_init_modes(ar); if (error) goto out_cancel_rx_cmd; usb_set_intfdata(intf, hw); error = ieee80211_register_hw(hw); if (error) { ar5523_err(ar, "could not register device\n"); goto out_cancel_rx_cmd; } ar5523_info(ar, "Found and initialized AR5523 device\n"); return 0; out_cancel_rx_cmd: ar5523_cancel_rx_cmd(ar); out_free_tx_cmd: ar5523_free_tx_cmd(ar); out_free_rx_cmd: ar5523_free_rx_cmd(ar); out_free_rx_bufs: ar5523_free_rx_bufs(ar); out_free_wq: destroy_workqueue(ar->wq); out_free_ar: ieee80211_free_hw(hw); out: return error; }
static int pegasus_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct net_device *net; pegasus_t *pegasus; int dev_index = id - pegasus_ids; int res = -ENOMEM; usb_get_dev(dev); net = alloc_etherdev(sizeof(struct pegasus)); if (!net) { err("out of memory allocating device structure"); goto out; } pegasus = netdev_priv(net); memset(pegasus, 0, sizeof (struct pegasus)); pegasus->dev_index = dev_index; init_waitqueue_head(&pegasus->ctrl_wait); if (!alloc_urbs(pegasus)) goto out1; tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); pegasus->usb = dev; pegasus->net = net; SET_MODULE_OWNER(net); net->open = pegasus_open; net->stop = pegasus_close; net->watchdog_timeo = PEGASUS_TX_TIMEOUT; net->tx_timeout = pegasus_tx_timeout; net->do_ioctl = pegasus_ioctl; net->hard_start_xmit = pegasus_start_xmit; net->set_multicast_list = pegasus_set_multicast; net->get_stats = pegasus_netdev_stats; net->mtu = PEGASUS_MTU; SET_ETHTOOL_OPS(net, &ops); pegasus->mii.dev = net; pegasus->mii.mdio_read = mdio_read; pegasus->mii.mdio_write = mdio_write; pegasus->mii.phy_id_mask = 0x1f; pegasus->mii.reg_num_mask = 0x1f; spin_lock_init(&pegasus->rx_pool_lock); pegasus->features = usb_dev_id[dev_index].private; get_interrupt_interval(pegasus); if (reset_mac(pegasus)) { err("can't reset MAC"); res = -EIO; goto out2; } set_ethernet_addr(pegasus); fill_skb_pool(pegasus); if (pegasus->features & PEGASUS_II) { info("setup Pegasus II specific registers"); setup_pegasus_II(pegasus); } pegasus->phy = mii_phy_probe(pegasus); if (pegasus->phy == 0xff) { warn("can't locate MII phy, using default"); pegasus->phy = 1; } usb_set_intfdata(intf, pegasus); SET_NETDEV_DEV(net, &intf->dev); res = register_netdev(net); if (res) goto out3; printk("%s: %s\n", net->name, usb_dev_id[dev_index].name); return 0; out3: usb_set_intfdata(intf, NULL); free_skb_pool(pegasus); out2: free_all_urbs(pegasus); out1: free_netdev(net); out: usb_put_dev(dev); return res; }
static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_mouse *mouse; struct input_dev *input_dev; int pipe, maxp; int error = -ENOMEM; interface = intf->cur_altsetting; if (interface->desc.bNumEndpoints != 1) return -ENODEV; endpoint = &interface->endpoint[0].desc; if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!mouse || !input_dev) goto fail1; mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma); if (!mouse->data) goto fail1; mouse->irq = usb_alloc_urb(0, GFP_KERNEL); if (!mouse->irq) goto fail2; mouse->usbdev = dev; mouse->dev = input_dev; if (dev->manufacturer) strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name)); if (dev->product) { if (dev->manufacturer) strlcat(mouse->name, " ", sizeof(mouse->name)); strlcat(mouse->name, dev->product, sizeof(mouse->name)); } if (!strlen(mouse->name)) snprintf(mouse->name, sizeof(mouse->name), "USB HIDBP Mouse %04x:%04x", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); usb_make_path(dev, mouse->phys, sizeof(mouse->phys)); strlcat(mouse->phys, "/input0", sizeof(mouse->phys)); input_dev->name = mouse->name; input_dev->phys = mouse->phys; usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); input_set_drvdata(input_dev, mouse); input_dev->open = usb_mouse_open; input_dev->close = usb_mouse_close; usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data, (maxp > 8 ? 8 : maxp), usb_mouse_irq, mouse, endpoint->bInterval); mouse->irq->transfer_dma = mouse->data_dma; mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(mouse->dev); if (error) goto fail3; usb_set_intfdata(intf, mouse); return 0; fail3: usb_free_urb(mouse->irq); fail2: usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); fail1: input_free_device(input_dev); kfree(mouse); return error; }
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; kfree(dconf); 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); return -EINVAL; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); 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); if (IS_ERR_OR_NULL(dev->canch[i])) { /* on failure destroy previously created candevs */ icount = i; for (i = 0; i < icount; i++) { gs_destroy_candev(dev->canch[i]); dev->canch[i] = NULL; } kfree(dev); return rc; } dev->canch[i]->parent = dev; } return 0; }
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_xpad *xpad; struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int i; int error = -ENOMEM; for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); input_dev = input_allocate_device(); if (!xpad || !input_dev) goto fail1; xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) goto fail1; xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) goto fail2; xpad->udev = udev; xpad->mapping = xpad_device[i].mapping; xpad->xtype = xpad_device[i].xtype; if (xpad->xtype == XTYPE_UNKNOWN) { if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) xpad->xtype = XTYPE_XBOX360W; else xpad->xtype = XTYPE_XBOX360; } else xpad->xtype = XTYPE_XBOX; if (dpad_to_buttons) xpad->mapping |= MAP_DPAD_TO_BUTTONS; if (triggers_to_buttons) xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; } xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); input_dev->name = xpad_device[i].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; input_dev->close = xpad_close; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); /* set up standard buttons and axes */ for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); /* Now set up model-specific ones */ if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { for (i = 0; xpad360_btn[i] >= 0; i++) __set_bit(xpad360_btn[i], input_dev->keybit); } else { for (i = 0; xpad_btn[i] >= 0; i++) __set_bit(xpad_btn[i], input_dev->keybit); } if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { for (i = 0; xpad_btn_pad[i] >= 0; i++) __set_bit(xpad_btn_pad[i], input_dev->keybit); } else { for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); } if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { for (i = 0; xpad_btn_triggers[i] >= 0; i++) __set_bit(xpad_btn_triggers[i], input_dev->keybit); } else { for (i = 0; xpad_abs_triggers[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); } error = xpad_init_output(intf, xpad); if (error) goto fail2; error = xpad_init_ff(xpad); if (error) goto fail3; error = xpad_led_probe(xpad); if (error) goto fail3; ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad, ep_irq_in->bInterval); xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; INIT_WORK(&xpad->submit_urb, xpad_do_submit_urb); error = input_register_device(xpad->dev); if (error) goto fail4; usb_set_intfdata(intf, xpad); xpad->interface_number = intf->cur_altsetting->desc.bInterfaceNumber; /* * Submit the int URB immediatly rather than waiting for open * because we get status messages from the device whether * or not any controllers are attached. In fact, it's * exactly the message that a controller has arrived that * we're waiting for. */ if (xpad->xtype == XTYPE_XBOX360W) { xpad->irq_in->dev = xpad->udev; error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); if (error) goto fail4; } return 0; fail4: cancel_work_sync(&xpad->submit_urb); usb_free_urb(xpad->irq_in); fail3: xpad_deinit_output(xpad); fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); return error; }
static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); struct usb_host_endpoint *bulk_out_ep; struct usb_host_endpoint *bulk_in_ep; struct hci_dev *hdev; struct bfusb *bfusb; BT_DBG("intf %p id %p", intf, id); if (ignore) return -ENODEV; /* Check number of endpoints */ if (intf->cur_altsetting->desc.bNumEndpoints < 2) return -EIO; bulk_out_ep = &intf->cur_altsetting->endpoint[0]; bulk_in_ep = &intf->cur_altsetting->endpoint[1]; if (!bulk_out_ep || !bulk_in_ep) { BT_ERR("Bulk endpoints not found"); goto done; } /* Initialize control structure and load firmware */ if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) { BT_ERR("Can't allocate memory for control structure"); goto done; } bfusb->udev = udev; bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress; bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); rwlock_init(&bfusb->lock); bfusb->reassembly = NULL; skb_queue_head_init(&bfusb->transmit_q); skb_queue_head_init(&bfusb->pending_q); skb_queue_head_init(&bfusb->completed_q); if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) { BT_ERR("Firmware request failed"); goto error; } BT_DBG("firmware data %p size %d", firmware->data, firmware->size); if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) { BT_ERR("Firmware loading failed"); goto release; } release_firmware(firmware); /* Initialize and register HCI device */ hdev = hci_alloc_dev(); if (!hdev) { BT_ERR("Can't allocate HCI device"); goto error; } bfusb->hdev = hdev; hdev->type = HCI_USB; hdev->driver_data = bfusb; SET_HCIDEV_DEV(hdev, &intf->dev); hdev->open = bfusb_open; hdev->close = bfusb_close; hdev->flush = bfusb_flush; hdev->send = bfusb_send_frame; hdev->destruct = bfusb_destruct; hdev->ioctl = bfusb_ioctl; hdev->owner = THIS_MODULE; if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); hci_free_dev(hdev); goto error; } usb_set_intfdata(intf, bfusb); return 0; release: release_firmware(firmware); error: kfree(bfusb); done: return -EIO; }
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; }
/** * fx2_probe - Called when USB core finds our device * * @intf: USB interface * @id: not used */ static int fx2_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_host_interface *host_interface; struct osr_usb_fx2_dev *dev_priv = NULL; int int_end_size; int ret = 0, i; printk("fx2_probe: Calling fx_probe\n"); if (!udev) { printk(KERN_ERR "No USB device\n"); return -EINVAL; } host_interface = intf->cur_altsetting; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (!dev_priv) { printk(KERN_ERR "Cannot allocate device private structure\n"); return -ENOMEM; } /* Initialize our private structure */ dev_priv->udev = udev; spin_lock_init(&dev_priv->isr_lock); /* Initialize Attributes */ osr_usb_attrib_init(&intf->dev); /* Set up interrupt and bulk endpoints */ for (i = 0; i < host_interface->desc.bNumEndpoints; i++) { struct usb_endpoint_descriptor *endpoint; endpoint = &host_interface->endpoint[i].desc; if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN && (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { printk("fx2_probe: Added Endpoint Number: %d, " "Interrupt\n", endpoint->bEndpointAddress & ENDPOINT_NUMBER_MASK); if (dev_priv->int_endpoint) printk(KERN_ERR "More than one INT endpoint\n"); dev_priv->int_endpoint = endpoint; } else if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { if (endpoint->bEndpointAddress & USB_DIR_IN) { printk("fx2_probe: Added Endpoint Number: %d, " "Bulk In\n", endpoint->bEndpointAddress & ENDPOINT_NUMBER_MASK); dev_priv->bulk_in_endpoint = endpoint; } else { printk("fx2_probe: Added Endpoint Number: %d, " "Bulk Out\n", endpoint->bEndpointAddress & ENDPOINT_NUMBER_MASK); dev_priv->bulk_out_endpoint = endpoint; } } } if (!dev_priv->int_endpoint) { printk(KERN_ERR "No interrupt endpoint found\n"); ret = -EINVAL; goto error; } /* Debounce work */ INIT_DELAYED_WORK(&dev_priv->debounce_work, fx2_debounce_work); /** * Initialize ISR */ /* 0 ISO packets because this is an interrupt EP */ dev_priv->int_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev_priv->int_urb) { printk(KERN_ERR "Cannot allocate interrupt URB\n"); ret = -ENOMEM; goto error; } /* Set up buffer to handle input from the board */ int_end_size = le16_to_cpu(dev_priv->int_endpoint->wMaxPacketSize); dev_priv->int_buffer = kmalloc(int_end_size, int_end_size); if (!dev_priv->int_buffer) { printk(KERN_ERR "Cannot allocate interrupt buffer\n"); ret = -ENOMEM; goto error; } usb_fill_int_urb(dev_priv->int_urb, dev_priv->udev, usb_rcvintpipe(dev_priv->udev, dev_priv->int_endpoint->bEndpointAddress), dev_priv->int_buffer, int_end_size, fx2_isr, dev_priv, dev_priv->int_endpoint->bInterval); mb(); ret = usb_submit_urb(dev_priv->int_urb, GFP_KERNEL); if (ret) { printk(KERN_ERR "Failed to submit interrupt URB\n"); goto error; } /* Associate dev_priv with intf */ usb_set_intfdata(intf, dev_priv); /* Register the device */ ret = usb_register_dev(intf, &osr_usb_fx2_class); if (ret) { printk(KERN_ERR "Failed to register OSR FX2 device\n"); goto error; } dev_priv->minor = intf->minor; printk("fx2_probe: /dev/osr_usb%d\n", dev_priv->minor - FX2_MINOR_BASE); return ret; error: fx2_disconnect(intf); return ret; }
/* * Called whenever the USB subsystem thinks we could be the right driver * to handle this device */ static int probe(struct usb_interface *intf, const struct usb_device_id *id) { int alt_set, endp; int found = 0; int i, j; int struct_size; struct usb_host_interface *host_interf; struct usb_interface_descriptor *interf_desc; struct usb_host_endpoint *host_endpoint; struct ttusbir_device *ttusbir; DPRINTK("Module ttusbir probe\n"); /* To reduce memory fragmentation we use only one allocation */ struct_size = sizeof(struct ttusbir_device) + (sizeof(struct urb *) * num_urbs) + (sizeof(char *) * num_urbs) + (num_urbs * 128); ttusbir = kzalloc(struct_size, GFP_KERNEL); if (!ttusbir) return -ENOMEM; ttusbir->urb = (struct urb **)((char *)ttusbir + sizeof(struct ttusbir_device)); ttusbir->buffer = (char **)((char *)ttusbir->urb + (sizeof(struct urb *) * num_urbs)); for (i = 0; i < num_urbs; i++) ttusbir->buffer[i] = (char *)ttusbir->buffer + (sizeof(char *)*num_urbs) + (i * 128); ttusbir->usb_driver = &usb_driver; ttusbir->alt_setting = -1; /* @TODO check if error can be returned */ ttusbir->udev = usb_get_dev(interface_to_usbdev(intf)); ttusbir->interf = intf; ttusbir->last_pulse = 0x00; ttusbir->last_num = 0; /* * Now look for interface setting we can handle * We are searching for the alt setting where end point * 0x82 has max packet size 16 */ for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) { host_interf = &intf->altsetting[alt_set]; interf_desc = &host_interf->desc; for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) { host_endpoint = &host_interf->endpoint[endp]; if ((host_endpoint->desc.bEndpointAddress == 0x82) && (host_endpoint->desc.wMaxPacketSize == 0x10)) { ttusbir->alt_setting = alt_set; ttusbir->endpoint = endp; found = 1; break; } } } if (ttusbir->alt_setting != -1) DPRINTK("alt setting: %d\n", ttusbir->alt_setting); else { err("Could not find alternate setting\n"); kfree(ttusbir); return -EINVAL; } /* OK lets setup this interface setting */ usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting); /* Store device info in interface structure */ usb_set_intfdata(intf, ttusbir); /* Register as a LIRC driver */ if (lirc_buffer_init(&ttusbir->rbuf, sizeof(lirc_t), 256) < 0) { err("Could not get memory for LIRC data buffer\n"); usb_set_intfdata(intf, NULL); kfree(ttusbir); return -ENOMEM; } strcpy(ttusbir->driver.name, "TTUSBIR"); ttusbir->driver.minor = -1; ttusbir->driver.code_length = 1; ttusbir->driver.sample_rate = 0; ttusbir->driver.data = ttusbir; ttusbir->driver.add_to_buf = NULL; ttusbir->driver.rbuf = &ttusbir->rbuf; ttusbir->driver.set_use_inc = set_use_inc; ttusbir->driver.set_use_dec = set_use_dec; ttusbir->driver.fops = NULL; ttusbir->driver.dev = &intf->dev; ttusbir->driver.owner = THIS_MODULE; ttusbir->driver.features = LIRC_CAN_REC_MODE2; ttusbir->minor = lirc_register_driver(&ttusbir->driver); if (ttusbir->minor < 0) { err("Error registering as LIRC driver\n"); usb_set_intfdata(intf, NULL); lirc_buffer_free(&ttusbir->rbuf); kfree(ttusbir); return -EIO; } /* Allocate and setup the URB that we will use to talk to the device */ for (i = 0; i < num_urbs; i++) { ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL); if (!ttusbir->urb[i]) { err("Could not allocate memory for the URB\n"); for (j = i - 1; j >= 0; j--) kfree(ttusbir->urb[j]); lirc_buffer_free(&ttusbir->rbuf); lirc_unregister_driver(ttusbir->minor); kfree(ttusbir); usb_set_intfdata(intf, NULL); return -ENOMEM; } ttusbir->urb[i]->dev = ttusbir->udev; ttusbir->urb[i]->context = ttusbir; ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev, ttusbir->endpoint); ttusbir->urb[i]->interval = 1; ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP; ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0]; ttusbir->urb[i]->complete = urb_complete; ttusbir->urb[i]->number_of_packets = 8; ttusbir->urb[i]->transfer_buffer_length = 128; for (j = 0; j < 8; j++) { ttusbir->urb[i]->iso_frame_desc[j].offset = j*16; ttusbir->urb[i]->iso_frame_desc[j].length = 16; } } return 0; }
/* * This routine is called by the USB subsystem for each new device * in the system. We need to check if the device is ours, and in * this case start handling it. */ static int kingsun_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_device *dev = interface_to_usbdev(intf); struct kingsun_cb *kingsun = NULL; struct net_device *net = NULL; int ret = -ENOMEM; int pipe, maxp_in, maxp_out; __u8 ep_in; __u8 ep_out; /* Check that there really are two interrupt endpoints. Check based on the one in drivers/usb/input/usbmouse.c */ interface = intf->cur_altsetting; if (interface->desc.bNumEndpoints != 2) { err("kingsun-sir: expected 2 endpoints, found %d", interface->desc.bNumEndpoints); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_IN].desc; if (!usb_endpoint_is_int_in(endpoint)) { err("kingsun-sir: endpoint 0 is not interrupt IN"); return -ENODEV; } ep_in = endpoint->bEndpointAddress; pipe = usb_rcvintpipe(dev, ep_in); maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); if (maxp_in > 255 || maxp_in <= 1) { err("%s: endpoint 0 has max packet size %d not in range", __FILE__, maxp_in); return -ENODEV; } endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc; if (!usb_endpoint_is_int_out(endpoint)) { err("kingsun-sir: endpoint 1 is not interrupt OUT"); return -ENODEV; } ep_out = endpoint->bEndpointAddress; pipe = usb_sndintpipe(dev, ep_out); maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); /* Allocate network device container. */ net = alloc_irdadev(sizeof(*kingsun)); if(!net) goto err_out1; SET_NETDEV_DEV(net, &intf->dev); kingsun = netdev_priv(net); kingsun->irlap = NULL; kingsun->tx_urb = NULL; kingsun->rx_urb = NULL; kingsun->ep_in = ep_in; kingsun->ep_out = ep_out; kingsun->in_buf = NULL; kingsun->out_buf = NULL; kingsun->max_rx = (__u8)maxp_in; kingsun->max_tx = (__u8)maxp_out; kingsun->netdev = net; kingsun->usbdev = dev; kingsun->rx_buff.in_frame = FALSE; kingsun->rx_buff.state = OUTSIDE_FRAME; kingsun->rx_buff.skb = NULL; kingsun->receiving = 0; spin_lock_init(&kingsun->lock); /* Allocate input buffer */ kingsun->in_buf = kmalloc(kingsun->max_rx, GFP_KERNEL); if (!kingsun->in_buf) goto free_mem; /* Allocate output buffer */ kingsun->out_buf = kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); if (!kingsun->out_buf) goto free_mem; printk(KERN_INFO "KingSun/DonShine IRDA/USB found at address %d, " "Vendor: %x, Product: %x\n", dev->devnum, le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); /* Initialize QoS for this device */ irda_init_max_qos_capabilies(&kingsun->qos); /* That's the Rx capability. */ kingsun->qos.baud_rate.bits &= IR_9600; kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; irda_qos_bits_to_value(&kingsun->qos); /* Override the network functions we need to use */ net->hard_start_xmit = kingsun_hard_xmit; net->open = kingsun_net_open; net->stop = kingsun_net_close; net->get_stats = kingsun_net_get_stats; net->do_ioctl = kingsun_net_ioctl; ret = register_netdev(net); if (ret != 0) goto free_mem; info("IrDA: Registered KingSun/DonShine device %s", net->name); usb_set_intfdata(intf, kingsun); /* Situation at this point: - all work buffers allocated - urbs not allocated, set to NULL - max rx packet known (in max_rx) - unwrap state machine (partially) initialized, but skb == NULL */ return 0; free_mem: if (kingsun->out_buf) kfree(kingsun->out_buf); if (kingsun->in_buf) kfree(kingsun->in_buf); free_netdev(net); err_out1: 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; if (id->driver_info & BTUSB_ATH3012) { struct usb_device *udev = interface_to_usbdev(intf); /* Old firmware would otherwise let ath3k driver load * patch and sysconfig files */ if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) 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; }
static int pcan_usb_create_dev(struct pcan_usb_interface *usb_if, int ctrl_index) { int err, retry; struct pcandev *dev; struct usb_device *usb_dev = usb_if->usb_dev; USB_PORT *u; void *h; dev = (struct pcandev *)&usb_if->dev[ctrl_index]; u = &dev->port.usb; u->usb_if = usb_if; u->dev_ctrl_index = ctrl_index; switch (usb_dev->descriptor.idProduct) { #ifdef HW_USB_PRO case PCAN_USBPRO_PRODUCT_ID: /* init structure elements to defaults */ pcan_soft_init(dev, "usbpro", HW_USB_PRO); break; #endif case PCAN_USB_PRODUCT_ID: default: // init structure elements to defaults pcan_soft_init(dev, "usb", HW_USB); break; } // override standard device access functions dev->device_open = pcan_usb_device_open; dev->device_write = pcan_usb_write; dev->device_release = pcan_usb_device_release; // init process wait queues init_waitqueue_head(&dev->read_queue); init_waitqueue_head(&dev->write_queue); // set this before any instructions, fill struct pcandev, part 1 dev->readreg = NULL; dev->writereg = NULL; dev->cleanup = pcan_usb_cleanup; dev->req_irq = pcan_usb_req_irq; dev->free_irq = pcan_usb_free_irq; dev->open = pcan_usb_open; dev->release = pcan_usb_release; dev->filter = pcan_create_filter_chain(); dev->device_params = pcan_usb_device_params; printk(KERN_INFO "%s: usb hardware revision = %d\n", DEVICE_NAME, usb_if->ucRevision); dev->wInitStep = 1; // add into list of devices list_add_tail(&dev->list, &pcan_drv.devices); // add this device to the list dev->wInitStep = 2; // assign the device as plugged in dev->ucPhysicallyInstalled = 1; pcan_drv.wDeviceCount++; usb_devices++; dev->wInitStep = 3; /* Handle controller list per interface */ h = usb_get_intfdata(usb_if->usb_intf); /* must tell that this interface is not in use for all controllers, */ /* especially for controllers > 0 (kernel>2.6.26) */ usb_if->usb_intf->minor = -1; if ((err = usb_register_dev(usb_if->usb_intf, &pcan_class)) < 0) { printk(KERN_ERR "%s: unable to register usb device for CAN#%u (err=%d)\n", DEVICE_NAME, ctrl_index, err); usb_set_intfdata(usb_if->usb_intf, h); goto reject; } dev->nMinor = usb_if->usb_intf->minor; dev->nMajor = USB_MAJOR; // set device in inactive state to prevent violating the bus usb_if->device_ctrl_set_bus_off(dev); // get serial number early usb_if->device_get_snr(usb_if, &usb_if->dwSerialNumber); /* Get device number early too */ /* sometimes, need to retry... */ for (retry=3; retry; retry--) { uint32_t device_nr32; err = usb_if->device_ctrl_get_dnr(dev, &device_nr32); if (!err) { u->ucHardcodedDevNr = (uint8_t )device_nr32; break; } } /* Call hardware supplied own callback to do some private init */ if (usb_if->device_ctrl_init) { err = usb_if->device_ctrl_init(dev); if (err) printk(KERN_ERR "%s: CAN#%u initialization not complete (err=%d)\n", DEVICE_NAME, ctrl_index, err); } #ifdef NETDEV_SUPPORT pcan_netdev_register(dev); #endif dev->wInitStep = 4; printk(KERN_INFO "%s: usb device minor %d found\n", DEVICE_NAME, dev->nMinor); return 0; reject: pcan_usb_cleanup(dev); printk(KERN_ERR "%s: %s() failed! (%d)\n", DEVICE_NAME, __FUNCTION__, err); return err; }
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 ipheth_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_host_interface *hintf; struct usb_endpoint_descriptor *endp; struct ipheth_device *dev; struct net_device *netdev; int i; int retval; netdev = alloc_etherdev(sizeof(struct ipheth_device)); if (!netdev) return -ENOMEM; netdev->netdev_ops = &ipheth_netdev_ops; netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; strcpy(netdev->name, "eth%d"); dev = netdev_priv(netdev); dev->udev = udev; dev->net = netdev; dev->intf = intf; hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); if (hintf == NULL) { retval = -ENODEV; err("Unable to find alternate settings interface"); goto err_endpoints; } for (i = 0; i < hintf->desc.bNumEndpoints; i++) { endp = &hintf->endpoint[i].desc; if (usb_endpoint_is_bulk_in(endp)) dev->bulk_in = endp->bEndpointAddress; else if (usb_endpoint_is_bulk_out(endp)) dev->bulk_out = endp->bEndpointAddress; } if (!(dev->bulk_in && dev->bulk_out)) { retval = -ENODEV; err("Unable to find endpoints"); goto err_endpoints; } dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL); if (dev->ctrl_buf == NULL) { retval = -ENOMEM; goto err_alloc_ctrl_buf; } retval = ipheth_get_macaddr(dev); if (retval) goto err_get_macaddr; INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work); retval = ipheth_alloc_urbs(dev); if (retval) { err("error allocating urbs: %d", retval); goto err_alloc_urbs; } usb_set_intfdata(intf, dev); SET_NETDEV_DEV(netdev, &intf->dev); SET_ETHTOOL_OPS(netdev, &ops); retval = register_netdev(netdev); if (retval) { err("error registering netdev: %d", retval); retval = -EIO; goto err_register_netdev; } dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n"); return 0; err_register_netdev: ipheth_free_urbs(dev); err_alloc_urbs: err_get_macaddr: err_alloc_ctrl_buf: kfree(dev->ctrl_buf); err_endpoints: free_netdev(netdev); return retval; }