int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) { static const char ifname[] = "usbpn%d"; const struct usb_cdc_union_desc *union_header = NULL; const struct usb_host_interface *data_desc; struct usb_interface *data_intf; struct usb_device *usbdev = interface_to_usbdev(intf); struct net_device *dev; struct usbpn_dev *pnd; u8 *data; int phonet = 0; int len, err; data = intf->altsetting->extra; len = intf->altsetting->extralen; while (len >= 3) { u8 dlen = data[0]; if (dlen < 3) return -EINVAL; /* bDescriptorType */ if (data[1] == USB_DT_CS_INTERFACE) { /* bDescriptorSubType */ switch (data[2]) { case USB_CDC_UNION_TYPE: if (union_header || dlen < 5) break; union_header = (struct usb_cdc_union_desc *)data; break; case 0xAB: phonet = 1; break; } } data += dlen; len -= dlen; } if (!union_header || !phonet) return -EINVAL; data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); if (data_intf == NULL) return -ENODEV; /* Data interface has one inactive and one active setting */ if (data_intf->num_altsetting != 2) return -EINVAL; if (data_intf->altsetting[0].desc.bNumEndpoints == 0 && data_intf->altsetting[1].desc.bNumEndpoints == 2) data_desc = data_intf->altsetting + 1; else if (data_intf->altsetting[0].desc.bNumEndpoints == 2 && data_intf->altsetting[1].desc.bNumEndpoints == 0) data_desc = data_intf->altsetting; else return -EINVAL; dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size, ifname, usbpn_setup); if (!dev) return -ENOMEM; pnd = netdev_priv(dev); SET_NETDEV_DEV(dev, &intf->dev); netif_stop_queue(dev); pnd->dev = dev; pnd->usb = usb_get_dev(usbdev); pnd->intf = intf; pnd->data_intf = data_intf; spin_lock_init(&pnd->tx_lock); spin_lock_init(&pnd->rx_lock); /* Endpoints */ if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { pnd->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); pnd->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); } else { pnd->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); pnd->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); } pnd->active_setting = data_desc - data_intf->altsetting; err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd); if (err) goto out; /* Force inactive mode until the network device is brought UP */ usb_set_interface(usbdev, union_header->bSlaveInterface0, !pnd->active_setting); usb_set_intfdata(intf, pnd); err = register_netdev(dev); if (err) { usb_driver_release_interface(&usbpn_driver, data_intf); goto out; } dev_dbg(&dev->dev, "USB CDC Phonet device found\n"); return 0; out: usb_set_intfdata(intf, NULL); free_netdev(dev); return err; }
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; 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; struct usb_endpoint_descriptor *epread; struct usb_endpoint_descriptor *epwrite; 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; /* 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) { err("Weird descriptor references\n"); return -EINVAL; } if (!buflen) { if (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 { err("Zero length descriptor references\n"); return -EINVAL; } } while (buflen > 0) { if (buffer [1] != USB_DT_CS_INTERFACE) { err("skipping garbage\n"); goto next_desc; } switch (buffer [2]) { case USB_CDC_UNION_TYPE: /* we've found it */ if (union_header) { err("More than one union descriptor, skipping ..."); 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) err("This device cannot do calls on its own. It is no modem."); break; default: err("Ignoring extra header, type %d, length %d", 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 { dev_dbg(&intf->dev,"No union descriptor, giving up\n"); return -ENODEV; } } 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"); 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 (intf != control_interface) return -ENODEV; if (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; } dbg("interfaces are valid"); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (minor == ACM_TTY_MINORS) { err("no more free acm devices"); return -ENODEV; } if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { 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->writesize = le16_to_cpu(epwrite->wMaxPacketSize); acm->control = control_interface; acm->data = data_interface; acm->minor = minor; acm->dev = usb_dev; acm->ctrl_caps = ac_management_function; 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); spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); mutex_init(&acm->mutex); acm->write_ready = 1; acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); 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]); if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); goto alloc_fail7; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = acm; } for (i = 0; i < num_rx_buf; i++) { struct acm_rb *buf = &(acm->rb[i]); if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); goto alloc_fail7; } } acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->writeurb) { dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n"); goto alloc_fail7; } 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) { 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, epctrl->bInterval); acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; acm->ctrlurb->transfer_dma = acm->ctrl_dma; usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, acm); acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; 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_get_intf(control_interface); tty_register_device(acm_tty_driver, minor, &control_interface->dev); acm_table[minor] = acm; return 0; alloc_fail8: usb_free_urb(acm->writeurb); alloc_fail7: for (i = 0; i < num_rx_buf; i++) usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); 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; }
/* handles CDC Ethernet and many other network "bulk data" interfaces */ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) { int tmp; struct usb_host_interface *alt = NULL; struct usb_host_endpoint *in = NULL, *out = NULL; struct usb_host_endpoint *status = NULL; for (tmp = 0; tmp < intf->num_altsetting; tmp++) { unsigned ep; in = out = status = NULL; alt = intf->altsetting + tmp; /* take the first altsetting with in-bulk + out-bulk; * remember any status endpoint, just in case; * ignore other endpoints and altsettings. */ for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { struct usb_host_endpoint *e; int intr = 0; e = alt->endpoint + ep; switch (e->desc.bmAttributes) { case USB_ENDPOINT_XFER_INT: if (!usb_endpoint_dir_in(&e->desc)) continue; intr = 1; /* FALLTHROUGH */ case USB_ENDPOINT_XFER_BULK: break; default: continue; } if (usb_endpoint_dir_in(&e->desc)) { if (!intr && !in) in = e; else if (intr && !status) status = e; } else { if (!out) out = e; } } if (in && out) break; } if (!alt || !in || !out) return -EINVAL; if (alt->desc.bAlternateSetting != 0 || !(dev->driver_info->flags & FLAG_NO_SETINT)) { tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); if (tmp < 0) return tmp; } dev->in = usb_rcvbulkpipe (dev->udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->out = usb_sndbulkpipe (dev->udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->status = status; return 0; }
static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { struct usb_skel *dev; int retval = 0; struct urb *urb = NULL; char *buf = NULL; size_t writesize = min(count, (size_t)MAX_TRANSFER); dev = (struct usb_skel *)file->private_data; /* verify that we actually have some data to write */ if (count == 0) goto exit; /* limit the number of URBs in flight to stop a user from using up all RAM */ if (down_interruptible(&dev->limit_sem)) { retval = -ERESTARTSYS; goto exit; } spin_lock_irq(&dev->err_lock); if ((retval = dev->errors) < 0) { /* any error is reported once */ dev->errors = 0; /* to preserve notifications about reset */ retval = (retval == -EPIPE) ? retval : -EIO; } spin_unlock_irq(&dev->err_lock); if (retval < 0) goto error; /* create a urb, and a buffer for it, and copy the data to the urb */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { retval = -ENOMEM; goto error; } buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); if (!buf) { retval = -ENOMEM; goto error; } if (copy_from_user(buf, user_buffer, writesize)) { retval = -EFAULT; goto error; } /* this lock makes sure we don't submit URBs to gone devices */ mutex_lock(&dev->io_mutex); if (!dev->interface) { /* disconnect() was called */ mutex_unlock(&dev->io_mutex); retval = -ENODEV; goto error; } /* initialize the urb properly */ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, writesize, skel_write_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->submitted); /* send the data out the bulk port */ retval = usb_submit_urb(urb, GFP_KERNEL); mutex_unlock(&dev->io_mutex); if (retval) { err("%s - failed submitting write urb, error %d", __func__, retval); goto error_unanchor; } /* release our reference to this urb, the USB core will eventually free it entirely */ usb_free_urb(urb); return writesize; error_unanchor: usb_unanchor_urb(urb); error: if (urb) { usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma); usb_free_urb(urb); } up(&dev->limit_sem); exit: return retval; }
static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, int count) { struct usb_serial *serial = port->serial; struct urb *urb; const unsigned char *current_position = buf; unsigned long flags; int status; int i; int bytes_sent = 0; int transfer_size; dbg("%s - port %d", __FUNCTION__, port->number); while (count > 0) { /* try to find a free urb in our list of them */ urb = NULL; spin_lock_irqsave (&write_urb_pool_lock, flags); for (i = 0; i < NUM_URBS; ++i) { if (write_urb_pool[i]->status != -EINPROGRESS) { urb = write_urb_pool[i]; break; } } spin_unlock_irqrestore (&write_urb_pool_lock, flags); if (urb == NULL) { dbg("%s - no more free urbs", __FUNCTION__); goto exit; } if (urb->transfer_buffer == NULL) { urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); if (urb->transfer_buffer == NULL) { dev_err(&port->dev, "%s no more kernel memory...\n", __FUNCTION__); goto exit; } } transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE); memcpy (urb->transfer_buffer, current_position, transfer_size); usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, urb->transfer_buffer); /* build up our urb */ usb_fill_bulk_urb ( urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), urb->transfer_buffer, transfer_size, empeg_write_bulk_callback, port); /* send it down the pipe */ status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __FUNCTION__, status); bytes_sent = status; break; } current_position += transfer_size; bytes_sent += transfer_size; count -= transfer_size; bytes_out += transfer_size; } exit: return bytes_sent; }
static int init_card(struct snd_usb_caiaqdev *dev) { char *c; struct usb_device *usb_dev = dev->chip.dev; struct snd_card *card = dev->chip.card; int err, len; if (usb_set_interface(usb_dev, 0, 1) != 0) { log("can't set alt interface.\n"); return -EIO; } usb_init_urb(&dev->ep1_in_urb); usb_init_urb(&dev->midi_out_urb); usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, usb_rcvbulkpipe(usb_dev, 0x1), dev->ep1_in_buf, EP1_BUFSIZE, usb_ep1_command_reply_dispatch, dev); usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, usb_sndbulkpipe(usb_dev, 0x1), dev->midi_out_buf, EP1_BUFSIZE, snd_usb_caiaq_midi_output_done, dev); init_waitqueue_head(&dev->ep1_wait_queue); init_waitqueue_head(&dev->prepare_wait_queue); if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) return -EIO; err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); if (err) return err; if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ)) return -ENODEV; usb_string(usb_dev, usb_dev->descriptor.iManufacturer, dev->vendor_name, CAIAQ_USB_STR_LEN); usb_string(usb_dev, usb_dev->descriptor.iProduct, dev->product_name, CAIAQ_USB_STR_LEN); usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, dev->serial, CAIAQ_USB_STR_LEN); /* terminate serial string at first white space occurence */ c = strchr(dev->serial, ' '); if (c) *c = '\0'; strcpy(card->driver, MODNAME); strcpy(card->shortname, dev->product_name); len = snprintf(card->longname, sizeof(card->longname), "%s %s (serial %s, ", dev->vendor_name, dev->product_name, dev->serial); if (len < sizeof(card->longname) - 2) len += usb_make_path(usb_dev, card->longname + len, sizeof(card->longname) - len); card->longname[len++] = ')'; card->longname[len] = '\0'; setup_card(dev); return 0; }
/** * hdm_enqueue - receive a buffer to be used for data transfer * @iface: interface to enqueue to * @channel: ID of the channel * @mbo: pointer to the buffer object * * This allocates a new URB and fills it according to the channel * that is being used for transmission of data. Before the URB is * submitted it is stored in the private anchor list. * * Returns 0 on success. On any error the URB is freed and a error code * is returned. * * Context: Could in _some_ cases be interrupt! */ static int hdm_enqueue(struct most_interface *iface, int channel, struct mbo *mbo) { struct most_dev *mdev; struct most_channel_config *conf; struct device *dev; int retval = 0; struct urb *urb; unsigned long length; void *virt_address; if (unlikely(!iface || !mbo)) return -EIO; if (unlikely(iface->num_channels <= channel || channel < 0)) return -ECHRNG; mdev = to_mdev(iface); conf = &mdev->conf[channel]; dev = &mdev->usb_device->dev; if (!mdev->usb_device) return -ENODEV; urb = usb_alloc_urb(NO_ISOCHRONOUS_URB, GFP_ATOMIC); if (!urb) return -ENOMEM; if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] && hdm_add_padding(mdev, channel, mbo)) { retval = -EIO; goto _error; } urb->transfer_dma = mbo->bus_address; virt_address = mbo->virt_address; length = mbo->buffer_length; if (conf->direction & MOST_CH_TX) { usb_fill_bulk_urb(urb, mdev->usb_device, usb_sndbulkpipe(mdev->usb_device, mdev->ep_address[channel]), virt_address, length, hdm_write_completion, mbo); if (conf->data_type != MOST_CH_ISOC) urb->transfer_flags |= URB_ZERO_PACKET; } else { usb_fill_bulk_urb(urb, mdev->usb_device, usb_rcvbulkpipe(mdev->usb_device, mdev->ep_address[channel]), virt_address, length + conf->extra_len, hdm_read_completion, mbo); } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &mdev->busy_urbs[channel]); retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { dev_err(dev, "URB submit failed with error %d.\n", retval); goto _error_1; } return 0; _error_1: usb_unanchor_urb(urb); _error: usb_free_urb(urb); return retval; }
static int whiteheat_attach(struct usb_serial *serial) { struct usb_serial_port *command_port; struct whiteheat_command_private *command_info; struct whiteheat_hw_info *hw_info; int pipe; int ret; int alen; __u8 *command; __u8 *result; command_port = serial->port[COMMAND_PORT]; pipe = usb_sndbulkpipe(serial->dev, command_port->bulk_out_endpointAddress); command = kmalloc(2, GFP_KERNEL); if (!command) goto no_command_buffer; command[0] = WHITEHEAT_GET_HW_INFO; command[1] = 0; result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL); if (!result) goto no_result_buffer; /* * When the module is reloaded the firmware is still there and * the endpoints are still in the usb core unchanged. This is the * unlinking bug in disguise. Same for the call below. */ usb_clear_halt(serial->dev, pipe); ret = usb_bulk_msg(serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS); if (ret) { dev_err(&serial->dev->dev, "%s: Couldn't send command [%d]\n", serial->type->description, ret); goto no_firmware; } else if (alen != 2) { dev_err(&serial->dev->dev, "%s: Send command incomplete [%d]\n", serial->type->description, alen); goto no_firmware; } pipe = usb_rcvbulkpipe(serial->dev, command_port->bulk_in_endpointAddress); /* See the comment on the usb_clear_halt() above */ usb_clear_halt(serial->dev, pipe); ret = usb_bulk_msg(serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS); if (ret) { dev_err(&serial->dev->dev, "%s: Couldn't get results [%d]\n", serial->type->description, ret); goto no_firmware; } else if (alen != sizeof(*hw_info) + 1) { dev_err(&serial->dev->dev, "%s: Get results incomplete [%d]\n", serial->type->description, alen); goto no_firmware; } else if (result[0] != command[0]) { dev_err(&serial->dev->dev, "%s: Command failed [%d]\n", serial->type->description, result[0]); goto no_firmware; } hw_info = (struct whiteheat_hw_info *)&result[1]; dev_info(&serial->dev->dev, "%s: Firmware v%d.%02d\n", serial->type->description, hw_info->sw_major_rev, hw_info->sw_minor_rev); command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); if (command_info == NULL) { dev_err(&serial->dev->dev, "%s: Out of memory for port structures\n", serial->type->description); goto no_command_private; } mutex_init(&command_info->mutex); command_info->port_running = 0; init_waitqueue_head(&command_info->wait_command); usb_set_serial_port_data(command_port, command_info); command_port->write_urb->complete = command_port_write_callback; command_port->read_urb->complete = command_port_read_callback; kfree(result); kfree(command); return 0; no_firmware: /* Firmware likely not running */ dev_err(&serial->dev->dev, "%s: Unable to retrieve firmware version, try replugging\n", serial->type->description); dev_err(&serial->dev->dev, "%s: If the firmware is not running (status led not blinking)\n", serial->type->description); dev_err(&serial->dev->dev, "%s: please contact [email protected]\n", serial->type->description); kfree(result); kfree(command); return -ENODEV; no_command_private: kfree(result); no_result_buffer: kfree(command); no_command_buffer: return -ENOMEM; }
static int sddr55_raw_bulk(struct us_data *us, int direction, unsigned char *data, unsigned int len) { int result; int act_len; int pipe; if (direction == SCSI_DATA_READ) pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in); else pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out); result = usb_stor_bulk_msg(us, data, pipe, len, &act_len); /* if we stall, we need to clear it before we go on */ if (result == -EPIPE) { US_DEBUGP("EPIPE: clearing endpoint halt for" " pipe 0x%x, stalled at %d bytes\n", pipe, act_len); usb_clear_halt(us->pusb_dev, pipe); } if (result) { /* NAK - that means we've retried a few times already */ if (result == -ETIMEDOUT) { US_DEBUGP("usbat_raw_bulk():" " device NAKed\n"); return US_BULK_TRANSFER_FAILED; } /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { US_DEBUGP("usbat_raw_bulk():" " transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } if (result == -EPIPE) { US_DEBUGP("usbat_raw_bulk():" " output pipe stalled\n"); return US_BULK_TRANSFER_FAILED; } /* the catch-all case */ US_DEBUGP("us_transfer_partial(): unknown error\n"); return US_BULK_TRANSFER_FAILED; } if (act_len != len) { US_DEBUGP("Warning: Transferred only %d bytes\n", act_len); return US_BULK_TRANSFER_SHORT; } US_DEBUGP("Transferred %d of %d bytes\n", act_len, len); return US_BULK_TRANSFER_GOOD; }
/* * Synchronous write to the device * * Takes care of updating EDC counts and thus, handle device errors. */ static ssize_t i2400mu_tx_bulk_out(struct i2400mu *i2400mu, void *buf, size_t buf_size) { int result; struct device *dev = &i2400mu->usb_iface->dev; int len; struct usb_endpoint_descriptor *epd; int pipe, do_autopm = 1; result = usb_autopm_get_interface(i2400mu->usb_iface); if (result < 0) { dev_err(dev, "BM-CMD: can't get autopm: %d\n", result); do_autopm = 0; } epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_out); pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); retry: result = usb_bulk_msg(i2400mu->usb_dev, pipe, buf, buf_size, &len, 200); switch (result) { case 0: if (len != buf_size) { dev_err(dev, "BM-CMD: short write (%u B vs %zu " "expected)\n", len, buf_size); result = -EIO; break; } result = len; break; case -EPIPE: /* * Stall -- maybe the device is choking with our * requests. Clear it and give it some time. If they * happen to often, it might be another symptom, so we * reset. * * No error handling for usb_clear_halt(0; if it * works, the retry works; if it fails, this switch * does the error handling for us. */ if (edc_inc(&i2400mu->urb_edc, 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { dev_err(dev, "BM-CMD: too many stalls in " "URB; resetting device\n"); usb_queue_reset_device(i2400mu->usb_iface); /* fallthrough */ } else { usb_clear_halt(i2400mu->usb_dev, pipe); msleep(10); /* give the device some time */ goto retry; } case -EINVAL: /* while removing driver */ case -ENODEV: /* dev disconnect ... */ case -ENOENT: /* just ignore it */ case -ESHUTDOWN: /* and exit */ case -ECONNRESET: result = -ESHUTDOWN; break; case -ETIMEDOUT: /* bah... */ break; default: /* any other? */ if (edc_inc(&i2400mu->urb_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { dev_err(dev, "BM-CMD: maximum errors in " "URB exceeded; resetting device\n"); usb_queue_reset_device(i2400mu->usb_iface); result = -ENODEV; break; } dev_err(dev, "BM-CMD: URB error %d, retrying\n", result); goto retry; } if (do_autopm) usb_autopm_put_interface(i2400mu->usb_iface); return result; }
static int speedtch_upload_firmware(struct speedtch_instance_data *instance, const struct firmware *fw1, const struct firmware *fw2) { unsigned char *buffer; struct usbatm_data *usbatm = instance->usbatm; struct usb_device *usb_dev = usbatm->usb_dev; int actual_length; int ret = 0; int offset; usb_dbg(usbatm, "%s entered\n", __func__); if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) { ret = -ENOMEM; usb_dbg(usbatm, "%s: no memory for buffer!\n", __func__); goto out; } if (!usb_ifnum_to_if(usb_dev, 2)) { ret = -ENODEV; usb_dbg(usbatm, "%s: interface not found!\n", __func__); goto out_free; } /* URB 7 */ if (dl_512_first) { /* some modems need a read before writing the firmware */ ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, 0x200, &actual_length, 2000); if (ret < 0 && ret != -ETIMEDOUT) usb_warn(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret); else usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret); } /* URB 8 : both leds are static green */ for (offset = 0; offset < fw1->size; offset += PAGE_SIZE) { int thislen = min_t(int, PAGE_SIZE, fw1->size - offset); memcpy(buffer, fw1->data + offset, thislen); ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, thislen, &actual_length, DATA_TIMEOUT); if (ret < 0) { usb_err(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret); goto out_free; } usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size); } /* USB led blinking green, ADSL led off */ /* URB 11 */ ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, 0x200, &actual_length, DATA_TIMEOUT); if (ret < 0) { usb_err(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret); goto out_free; } usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length); /* URBs 12 to 139 - USB led blinking green, ADSL led off */ for (offset = 0; offset < fw2->size; offset += PAGE_SIZE) { int thislen = min_t(int, PAGE_SIZE, fw2->size - offset); memcpy(buffer, fw2->data + offset, thislen); ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, thislen, &actual_length, DATA_TIMEOUT); if (ret < 0) { usb_err(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret); goto out_free; } } usb_dbg(usbatm, "%s: BLOCK3 uploaded (%zu bytes)\n", __func__, fw2->size); /* USB led static green, ADSL led static red */ /* URB 142 */ ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), buffer, 0x200, &actual_length, DATA_TIMEOUT); if (ret < 0) { usb_err(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret); goto out_free; } /* success */ usb_dbg(usbatm, "%s: BLOCK4 downloaded (%d bytes)\n", __func__, actual_length); /* Delay to allow firmware to start up. We can do this here because we're in our own kernel thread anyway. */ msleep_interruptible(1000); if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) { usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->params.altsetting, ret); goto out_free; } /* Enable software buffering, if requested */ if (sw_buffering) speedtch_set_swbuff(instance, 1); /* Magic spell; don't ask us what this does */ speedtch_test_sequence(instance); ret = 0; out_free: free_page((unsigned long)buffer); out: return ret; }
s32 rtl8188eu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt) { #ifdef PLATFORM_LINUX u16 fc; int rc, len, pipe; unsigned int bmcst, tid, qsel; struct sk_buff *skb, *pxmit_skb; struct urb *urb; unsigned char *pxmitbuf; struct tx_desc *ptxdesc; struct rtw_ieee80211_hdr *tx_hdr; struct hostapd_priv *phostapdpriv = padapter->phostapdpriv; struct net_device *pnetdev = padapter->pnetdev; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); //DBG_8192C("%s\n", __FUNCTION__); skb = pkt; len = skb->len; tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data); fc = le16_to_cpu(tx_hdr->frame_ctl); bmcst = IS_MCAST(tx_hdr->addr1); if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT) goto _exit; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/[email protected]/msg17214.html pxmit_skb = dev_alloc_skb(len + TXDESC_SIZE); #else pxmit_skb = netdev_alloc_skb(pnetdev, len + TXDESC_SIZE); #endif if(!pxmit_skb) goto _exit; pxmitbuf = pxmit_skb->data; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { goto _exit; } // ----- fill tx desc ----- ptxdesc = (struct tx_desc *)pxmitbuf; _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc)); //offset 0 ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff); ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); if(bmcst) { ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); } //offset 4 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000); //offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //offset 20 //HW append seq ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29. rtl8188eu_cal_txdesc_chksum(ptxdesc); // ----- end of fill tx desc ----- // skb_put(pxmit_skb, len + TXDESC_SIZE); pxmitbuf = pxmitbuf + TXDESC_SIZE; _rtw_memcpy(pxmitbuf, skb->data, len); //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len); // ----- prepare urb for submit ----- //translate DMA FIFO addr to pipehandle //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX); pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f); usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe, pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb); urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(urb, &phostapdpriv->anchored); rc = usb_submit_urb(urb, GFP_ATOMIC); if (rc < 0) { usb_unanchor_urb(urb); kfree_skb(skb); } usb_free_urb(urb); _exit: dev_kfree_skb_any(skb); #endif return 0; }
int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) { struct bulk_cb_wrap *bcb; struct bulk_cs_wrap *bcs; int result; int pipe; int partial; int ret = USB_STOR_TRANSPORT_ERROR; bcb = kmalloc(sizeof *bcb, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); if (!bcb) { return USB_STOR_TRANSPORT_ERROR; } bcs = kmalloc(sizeof *bcs, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); if (!bcs) { kfree(bcb); return USB_STOR_TRANSPORT_ERROR; } /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb)); bcb->Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0; bcb->Tag = ++(us->tag); bcb->Lun = srb->cmnd[1] >> 5; if (us->flags & US_FL_SCM_MULT_TARG) bcb->Lun |= srb->target << 4; bcb->Length = srb->cmd_len; /* construct the pipe handle */ pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out); /* copy the command payload */ memset(bcb->CDB, 0, sizeof(bcb->CDB)); memcpy(bcb->CDB, srb->cmnd, bcb->Length); /* send it to out endpoint */ US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n", le32_to_cpu(bcb->Signature), bcb->Tag, (bcb->Lun >> 4), (bcb->Lun & 0x0F), le32_to_cpu(bcb->DataTransferLength), bcb->Flags, bcb->Length); result = usb_stor_bulk_msg(us, bcb, pipe, US_BULK_CB_WRAP_LEN, &partial); US_DEBUGP("Bulk command transfer result=%d\n", result); /* if the command was aborted, indicate that */ if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } /* if we stall, we need to clear it before we go on */ if (result == -EPIPE) { US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); result = usb_stor_clear_halt(us, pipe); /* if the command was aborted, indicate that */ if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } result = -EPIPE; } else if (result) { /* unknown error -- we've got a problem */ ret = USB_STOR_TRANSPORT_ERROR; goto out; } /* if the command transfered well, then we go to the data stage */ if (result == 0) { /* send/receive data payload, if there is any */ if (bcb->DataTransferLength) { usb_stor_transfer(srb, us); result = srb->result; US_DEBUGP("Bulk data transfer result 0x%x\n", result); /* if it was aborted, we need to indicate that */ if (result == US_BULK_TRANSFER_ABORTED) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } } } /* See flow chart on pg 15 of the Bulk Only Transport spec for * an explanation of how this code works. */ /* construct the pipe handle */ pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in); /* get CSW for device status */ US_DEBUGP("Attempting to get CSW...\n"); result = usb_stor_bulk_msg(us, bcs, pipe, US_BULK_CS_WRAP_LEN, &partial); /* if the command was aborted, indicate that */ if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } /* did the attempt to read the CSW fail? */ if (result == -EPIPE) { US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); result = usb_stor_clear_halt(us, pipe); /* if the command was aborted, indicate that */ if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } /* get the status again */ US_DEBUGP("Attempting to get CSW (2nd try)...\n"); result = usb_stor_bulk_msg(us, bcs, pipe, US_BULK_CS_WRAP_LEN, &partial); /* if the command was aborted, indicate that */ if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; goto out; } /* if it fails again, we need a reset and return an error*/ if (result == -EPIPE) { US_DEBUGP("clearing halt for pipe 0x%x\n", pipe); result = usb_stor_clear_halt(us, pipe); /* if the command was aborted, indicate that */ if (result == -ECONNRESET) { ret = USB_STOR_TRANSPORT_ABORTED; } else { ret = USB_STOR_TRANSPORT_ERROR; } goto out; } } /* if we still have a failure at this point, we're in trouble */ US_DEBUGP("Bulk status result = %d\n", result); if (result) { ret = USB_STOR_TRANSPORT_ERROR; goto out; } /* check bulk status */ US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n", le32_to_cpu(bcs->Signature), bcs->Tag, bcs->Residue, bcs->Status); if ((bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) && bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) || bcs->Tag != bcb->Tag || bcs->Status > US_BULK_STAT_PHASE || partial != 13) { US_DEBUGP("Bulk logical error\n"); ret = USB_STOR_TRANSPORT_ERROR; goto out; } /* based on the status code, we report good or bad */ switch (bcs->Status) { case US_BULK_STAT_OK: /* command good -- note that data could be short */ ret = USB_STOR_TRANSPORT_GOOD; goto out; case US_BULK_STAT_FAIL: /* command failed */ ret = USB_STOR_TRANSPORT_FAILED; goto out; case US_BULK_STAT_PHASE: /* phase error -- note that a transport reset will be * invoked by the invoke_transport() function */ ret = USB_STOR_TRANSPORT_ERROR; goto out; } /* we should never get here, but if we do, we're in trouble */ out: kfree(bcb); kfree(bcs); return ret; }
static void ir_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { struct urb *urb; unsigned char *transfer_buffer; int result; speed_t baud; int ir_baud; dbg("%s - port %d", __func__, port->number); baud = tty_get_baud_rate(tty); /* * FIXME, we should compare the baud request against the * capability stated in the IR header that we got in the * startup function. */ switch (baud) { case 2400: ir_baud = USB_IRDA_BR_2400; break; case 9600: ir_baud = USB_IRDA_BR_9600; break; case 19200: ir_baud = USB_IRDA_BR_19200; break; case 38400: ir_baud = USB_IRDA_BR_38400; break; case 57600: ir_baud = USB_IRDA_BR_57600; break; case 115200: ir_baud = USB_IRDA_BR_115200; break; case 576000: ir_baud = USB_IRDA_BR_576000; break; case 1152000: ir_baud = USB_IRDA_BR_1152000; break; case 4000000: ir_baud = USB_IRDA_BR_4000000; break; default: ir_baud = USB_IRDA_BR_9600; baud = 9600; } if (xbof == -1) ir_xbof = ir_xbof_change(ir_add_bof); else ir_xbof = ir_xbof_change(xbof) ; /* Only speed changes are supported */ tty_termios_copy_hw(tty->termios, old_termios); tty_encode_baud_rate(tty, baud, baud); /* * send the baud change out on an "empty" data packet */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { dev_err(&port->dev, "%s - no more urbs\n", __func__); return; } transfer_buffer = kmalloc(1, GFP_KERNEL); if (!transfer_buffer) { dev_err(&port->dev, "%s - out of memory\n", __func__); goto err_buf; } *transfer_buffer = ir_xbof | ir_baud; usb_fill_bulk_urb( urb, port->serial->dev, usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), transfer_buffer, 1, ir_set_termios_callback, port); urb->transfer_flags = URB_ZERO_PACKET; result = usb_submit_urb(urb, GFP_KERNEL); if (result) { dev_err(&port->dev, "%s - failed to submit urb: %d\n", __func__, result); goto err_subm; } usb_free_urb(urb); return; err_subm: kfree(transfer_buffer); err_buf: usb_free_urb(urb); }
static ssize_t camera_write (struct file *file, const char *buf, size_t len, loff_t *ppos) { struct camera_state *camera; ssize_t bytes_written = 0; if (len > MAX_PACKET_SIZE) return -EINVAL; camera = (struct camera_state *) file->private_data; down (&camera->sem); if (!camera->dev) { up (&camera->sem); return -ENODEV; } /* most writes will be small: simple commands, sometimes with * parameters. putting images (like borders) into the camera * would be the main use of big writes. */ while (len > 0) { char *obuf = camera->buf; int maxretry = MAX_WRITE_RETRY; unsigned long copy_size, thistime; /* it's not clear that retrying can do any good ... or that * fragmenting application packets into N writes is correct. */ thistime = copy_size = len; if (copy_from_user (obuf, buf, copy_size)) { bytes_written = -EFAULT; break; } while (thistime) { int result; int count; if (signal_pending (current)) { if (!bytes_written) bytes_written = -EINTR; goto done; } result = usb_bulk_msg (camera->dev, usb_sndbulkpipe (camera->dev, camera->outEP), obuf, thistime, &count, HZ*10); if (result) dbg ("write USB err - %d", result); if (count) { obuf += count; thistime -= count; maxretry = MAX_WRITE_RETRY; continue; } else if (!result) break; if (result == -ETIMEDOUT) { /* NAK - delay a bit */ if (!maxretry--) { if (!bytes_written) bytes_written = -ETIME; goto done; } interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT); continue; } if (!bytes_written) bytes_written = -EIO; goto done; } bytes_written += copy_size; len -= copy_size; buf += copy_size; } done: up (&camera->sem); dbg ("wrote %Zd", bytes_written); return bytes_written; }
int usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) { struct usbnet *dev; struct net_device *net; struct usb_host_interface *interface; struct driver_info *info; struct usb_device *xdev; int status; const char *name; name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; if (!info) { dev_dbg (&udev->dev, "blacklisted by %s\n", name); return -ENODEV; } xdev = interface_to_usbdev (udev); interface = udev->cur_altsetting; usb_get_dev (xdev); status = -ENOMEM; // set up our own records net = alloc_etherdev(sizeof(*dev)); if (!net) { dbg ("can't kmalloc dev"); goto out; } dev = netdev_priv(net); dev->udev = xdev; dev->intf = udev; dev->driver_info = info; dev->driver_name = name; dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK); skb_queue_head_init (&dev->rxq); skb_queue_head_init (&dev->txq); skb_queue_head_init (&dev->done); skb_queue_head_init(&dev->rxq_pause); dev->bh.func = usbnet_bh; dev->bh.data = (unsigned long) dev; INIT_WORK (&dev->kevent, kevent); dev->delay.function = usbnet_bh; dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); mutex_init (&dev->phy_mutex); dev->net = net; strcpy (net->name, "usb%d"); memcpy (net->dev_addr, node_id, sizeof node_id); /* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case. */ dev->hard_mtu = net->mtu + net->hard_header_len; #if 0 // dma_supported() is deeply broken on almost all architectures // possible with some EHCI controllers if (dma_supported (&udev->dev, DMA_BIT_MASK(64))) net->features |= NETIF_F_HIGHDMA; #endif net->netdev_ops = &usbnet_netdev_ops; net->watchdog_timeo = TX_TIMEOUT_JIFFIES; net->ethtool_ops = &usbnet_ethtool_ops; // allow device-specific bind/init procedures // NOTE net->name still not usable ... if (info->bind) { status = info->bind (dev, udev); if (status < 0) goto out1; // heuristic: "usb%d" for links we know are two-host, // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better. if ((dev->driver_info->flags & FLAG_ETHER) != 0 && (net->dev_addr [0] & 0x02) == 0) strcpy (net->name, "eth%d"); /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) strcpy(net->name, "wlan%d"); /* maybe the remote can't receive an Ethernet MTU */ if (net->mtu > (dev->hard_mtu - net->hard_header_len)) net->mtu = dev->hard_mtu - net->hard_header_len; } else if (!info->in || !info->out) status = usbnet_get_endpoints (dev, udev); else { dev->in = usb_rcvbulkpipe (xdev, info->in); dev->out = usb_sndbulkpipe (xdev, info->out); if (!(info->flags & FLAG_NO_SETINT)) status = usb_set_interface (xdev, interface->desc.bInterfaceNumber, interface->desc.bAlternateSetting); else status = 0; } if (status >= 0 && dev->status) status = init_status (dev, udev); if (status < 0) goto out3; if (!dev->rx_urb_size) dev->rx_urb_size = dev->hard_mtu; dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); SET_NETDEV_DEV(net, &udev->dev); status = register_netdev (net); if (status) goto out3; if (netif_msg_probe (dev)) devinfo (dev, "register '%s' at usb-%s-%s, %s, %pM", udev->dev.driver->name, xdev->bus->bus_name, xdev->devpath, dev->driver_info->description, net->dev_addr); // ok, it's ready to go. usb_set_intfdata (udev, dev); // start as if the link is up netif_device_attach (net); return 0; out3: if (info->unbind) info->unbind (dev, udev); out1: free_netdev(net); out: usb_put_dev(xdev); return status; }
/* * Callback to search the Mustek MDC800 on the USB Bus */ static int mdc800_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) { int i,j; struct usb_host_interface *intf_desc; struct usb_device *dev = interface_to_usbdev (intf); int irq_interval=0; int retval; dbg ("(mdc800_usb_probe) called."); if (mdc800->dev != 0) { warn ("only one Mustek MDC800 is supported."); return -ENODEV; } if (dev->descriptor.bNumConfigurations != 1) { err ("probe fails -> wrong Number of Configuration"); return -ENODEV; } intf_desc = intf->cur_altsetting; if ( ( intf_desc->desc.bInterfaceClass != 0xff ) || ( intf_desc->desc.bInterfaceSubClass != 0 ) || ( intf_desc->desc.bInterfaceProtocol != 0 ) || ( intf_desc->desc.bNumEndpoints != 4) ) { err ("probe fails -> wrong Interface"); return -ENODEV; } /* Check the Endpoints */ for (i=0; i<4; i++) { mdc800->endpoint[i]=-1; for (j=0; j<4; j++) { if (mdc800_endpoint_equals (&intf_desc->endpoint [j].desc,&mdc800_ed [i])) { mdc800->endpoint[i]=intf_desc->endpoint [j].desc.bEndpointAddress ; if (i==1) { irq_interval=intf_desc->endpoint [j].desc.bInterval; } continue; } } if (mdc800->endpoint[i] == -1) { err ("probe fails -> Wrong Endpoints."); return -ENODEV; } } info ("Found Mustek MDC800 on USB."); down (&mdc800->io_lock); retval = usb_register_dev(intf, &mdc800_class); if (retval) { err ("Not able to get a minor for this device."); return -ENODEV; } mdc800->dev=dev; mdc800->open=0; /* Setup URB Structs */ usb_fill_int_urb ( mdc800->irq_urb, mdc800->dev, usb_rcvintpipe (mdc800->dev,mdc800->endpoint [1]), mdc800->irq_urb_buffer, 8, mdc800_usb_irq, mdc800, irq_interval ); usb_fill_bulk_urb ( mdc800->write_urb, mdc800->dev, usb_sndbulkpipe (mdc800->dev, mdc800->endpoint[0]), mdc800->write_urb_buffer, 8, mdc800_usb_write_notify, mdc800 ); usb_fill_bulk_urb ( mdc800->download_urb, mdc800->dev, usb_rcvbulkpipe (mdc800->dev, mdc800->endpoint [3]), mdc800->download_urb_buffer, 64, mdc800_usb_download_notify, mdc800 ); mdc800->state=READY; up (&mdc800->io_lock); usb_set_intfdata(intf, mdc800); return 0; }
int UMAS_BulkTransport(SCSI_CMD_T *srb, UMAS_DATA_T *umas) { int result, status = 0; int pipe; uint32_t partial; struct bulk_cb_wrap bcb; struct bulk_cs_wrap bcs; /* if the device was removed, then we're already reset */ if(!umas->pusb_dev) return SUCCESS; /* set up the command wrapper */ bcb.Signature = UMAS_BULK_CB_SIGN; bcb.DataTransferLength = usb_stor_transfer_length(srb); bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0; bcb.Tag = srb->serial_number; bcb.Lun = srb->cmnd[1] >> 5; if(umas->flags & UMAS_FL_SCM_MULT_TARG) bcb.Lun |= srb->target << 4; bcb.Length = srb->cmd_len; /* construct the pipe handle */ pipe = usb_sndbulkpipe(umas->pusb_dev, umas->ep_out); /* copy the command payload */ memset(bcb.CDB, 0, sizeof(bcb.CDB)); memcpy(bcb.CDB, srb->cmnd, bcb.Length); /* send it to out endpoint */ UMAS_VDEBUG("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n", bcb.Signature, bcb.Tag, (bcb.Lun >> 4), (bcb.Lun & 0x0F), bcb.DataTransferLength, bcb.Flags, bcb.Length); result = usb_stor_bulk_msg(umas, &bcb, pipe, UMAS_BULK_CB_WRAP_LEN, &partial); UMAS_VDEBUG("Bulk command transfer result=%d\n", result); /* if the command was aborted, indicate that */ if(result == USB_ERR_NOENT) return USB_STOR_TRANSPORT_ABORTED; /* if we stall, we need to clear it before we go on */ if(result == USB_ERR_PIPE) { UMAS_DEBUG("UMAS_BulkTransport - 1 clearing endpoint halt for pipe 0x%x\n", pipe); clear_halt(umas->pusb_dev, pipe); } else if(result) { /* unknown error -- we've got a problem */ status = USB_STOR_TRANSPORT_ERROR; goto bulk_error; } /* if the command transferred well, then we go to the data stage */ if(result == 0) { /* send/receive data payload, if there is any */ if(bcb.DataTransferLength) { us_transfer(srb, umas); /* if it was aborted, we need to indicate that */ if(srb->result == USB_STOR_TRANSPORT_ABORTED) { status = USB_STOR_TRANSPORT_ABORTED; goto bulk_error; } } } /* * See flow chart on pg 15 of the Bulk Only Transport spec for * an explanation of how this code works. */ /* construct the pipe handle */ pipe = usb_rcvbulkpipe(umas->pusb_dev, umas->ep_in); /* get CSW for device status */ UMAS_VDEBUG("Attempting to get CSW...\n"); result = usb_stor_bulk_msg(umas, (char *)&bcs, pipe, UMAS_BULK_CS_WRAP_LEN, &partial); /* if the command was aborted, indicate that */ if(result == USB_ERR_NOENT) { status = USB_STOR_TRANSPORT_ABORTED; goto bulk_error; } /* did the attempt to read the CSW fail? */ if(result == USB_ERR_PIPE) { UMAS_DEBUG("get CSW failed - clearing endpoint halt for pipe 0x%x\n", pipe); clear_halt(umas->pusb_dev, pipe); /* get the status again */ UMAS_DEBUG("Attempting to get CSW (2nd try)...\n"); result = usb_stor_bulk_msg(umas, &bcs, pipe, UMAS_BULK_CS_WRAP_LEN, &partial); /* if the command was aborted, indicate that */ if(result == USB_ERR_NOENT) { UMAS_DEBUG("get CSW Command was aborted!\n"); status = USB_STOR_TRANSPORT_ABORTED; goto bulk_error; } /* if it fails again, we need a reset and return an error*/ if(result == USB_ERR_PIPE) { UMAS_DEBUG("get CSW command 2nd try failed - clearing halt for pipe 0x%x\n", pipe); clear_halt(umas->pusb_dev, pipe); status = USB_STOR_TRANSPORT_ERROR; goto bulk_error; } } /* if we still have a failure at this point, we're in trouble */ UMAS_VDEBUG("Bulk status result = %d\n", result); if(result) { status = USB_STOR_TRANSPORT_ERROR; goto bulk_error; } /* check bulk status */ UMAS_VDEBUG("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n", USB_SWAP32(bcs.Signature), bcs.Tag, bcs.Residue, bcs.Status); if((bcs.Signature != UMAS_BULK_CS_SIGN) || (bcs.Tag != bcb.Tag) || (bcs.Status > UMAS_BULK_STAT_PHASE) || (partial != 13)) { UMAS_DEBUG("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n", USB_SWAP32(bcs.Signature), bcs.Tag, bcs.Residue, bcs.Status); status = USB_STOR_TRANSPORT_ERROR; goto bulk_error; } /* based on the status code, we report good or bad */ switch(bcs.Status) { case UMAS_BULK_STAT_OK: /* command good -- note that data could be short */ return USB_STOR_TRANSPORT_GOOD; case UMAS_BULK_STAT_FAIL: /* command failed */ status = USB_STOR_TRANSPORT_FAILED; goto bulk_error; case UMAS_BULK_STAT_PHASE: /* phase error -- note that a transport reset will be * invoked by the invoke_transport() function */ status = USB_STOR_TRANSPORT_ERROR; goto bulk_error; } /* we should never get here, but if we do, we're in trouble */ bulk_error: return status; }
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, error; 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) { error = -ENOMEM; goto fail1; } xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) { error = -ENOMEM; goto fail1; } xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) { error = -ENOMEM; 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; if (sticks_to_null) xpad->mapping |= MAP_STICKS_TO_NULL; } 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); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { input_dev->evbit[0] |= BIT_MASK(EV_ABS); /* */ for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); } /* */ for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); /* */ 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 fail3; error = xpad_init_ff(xpad); if (error) goto fail4; error = xpad_led_probe(xpad); if (error) goto fail5; 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; error = input_register_device(xpad->dev); if (error) goto fail6; usb_set_intfdata(intf, xpad); if (xpad->xtype == XTYPE_XBOX360W) { /* */ xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->bulk_out) { error = -ENOMEM; goto fail7; } xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); if (!xpad->bdata) { error = -ENOMEM; goto fail8; } xpad->bdata[2] = 0x08; switch (intf->cur_altsetting->desc.bInterfaceNumber) { case 0: xpad->bdata[3] = 0x42; break; case 2: xpad->bdata[3] = 0x43; break; case 4: xpad->bdata[3] = 0x44; break; case 6: xpad->bdata[3] = 0x45; } ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; usb_fill_bulk_urb(xpad->bulk_out, udev, usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); /* */ xpad->irq_in->dev = xpad->udev; error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); if (error) goto fail9; } return 0; fail9: kfree(xpad->bdata); fail8: usb_free_urb(xpad->bulk_out); fail7: input_unregister_device(input_dev); input_dev = NULL; fail6: xpad_led_disconnect(xpad); fail5: if (input_dev) input_ff_destroy(input_dev); fail4: xpad_deinit_output(xpad); fail3: usb_free_urb(xpad->irq_in); fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); return error; }
static ssize_t write_rio(struct file *file, const char __user *buffer, size_t count, loff_t * ppos) { DEFINE_WAIT(wait); struct rio_usb_data *rio = &rio_instance; unsigned long copy_size; unsigned long bytes_written = 0; unsigned int partial; int result = 0; int maxretry; int errn = 0; int intr; intr = mutex_lock_interruptible(&(rio->lock)); if (intr) return -EINTR; /* Sanity check to make sure rio is connected, powered, etc */ if (rio->present == 0 || rio->rio_dev == NULL) { mutex_unlock(&(rio->lock)); return -ENODEV; } do { unsigned long thistime; char *obuf = rio->obuf; thistime = copy_size = (count >= OBUF_SIZE) ? OBUF_SIZE : count; if (copy_from_user(rio->obuf, buffer, copy_size)) { errn = -EFAULT; goto error; } maxretry = 5; while (thistime) { if (!rio->rio_dev) { errn = -ENODEV; goto error; } if (signal_pending(current)) { mutex_unlock(&(rio->lock)); return bytes_written ? bytes_written : -EINTR; } result = usb_bulk_msg(rio->rio_dev, usb_sndbulkpipe(rio->rio_dev, 2), obuf, thistime, &partial, 5000); dbg("write stats: result:%d thistime:%lu partial:%u", result, thistime, partial); if (result == -ETIMEDOUT) { /* NAK - so hold for a while */ if (!maxretry--) { errn = -ETIME; goto error; } prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE); schedule_timeout(NAK_TIMEOUT); finish_wait(&rio->wait_q, &wait); continue; } else if (!result && partial) { obuf += partial; thistime -= partial; } else break; }; if (result) { err("Write Whoops - %x", result); errn = -EIO; goto error; } bytes_written += copy_size; count -= copy_size; buffer += copy_size; } while (count > 0); mutex_unlock(&(rio->lock)); return bytes_written ? bytes_written : -EIO; error: mutex_unlock(&(rio->lock)); return errn; }
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_buffer_alloc(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->dpad_mapping = xpad_device[i].dpad_mapping; xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = !dpad_to_buttons; 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; } 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 buttons */ for (i = 0; xpad_common_btn[i] >= 0; i++) set_bit(xpad_common_btn[i], input_dev->keybit); 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->dpad_mapping == MAP_DPAD_TO_BUTTONS) for (i = 0; xpad_btn_pad[i] >= 0; i++) set_bit(xpad_btn_pad[i], input_dev->keybit); /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[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; error = input_register_device(xpad->dev); if (error) goto fail4; usb_set_intfdata(intf, xpad); /* * 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; /* * Setup the message to set the LEDs on the * controller when it shows up */ xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); if(!xpad->bulk_out) goto fail5; xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); if(!xpad->bdata) goto fail6; xpad->bdata[2] = 0x08; switch (intf->cur_altsetting->desc.bInterfaceNumber) { case 0: xpad->bdata[3] = 0x42; break; case 2: xpad->bdata[3] = 0x43; break; case 4: xpad->bdata[3] = 0x44; break; case 6: xpad->bdata[3] = 0x45; } ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; usb_fill_bulk_urb(xpad->bulk_out, udev, usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); } return 0; fail6: usb_free_urb(xpad->bulk_out); fail5: usb_kill_urb(xpad->irq_in); fail4: usb_free_urb(xpad->irq_in); fail3: xpad_deinit_output(xpad); fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); return error; }
static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, unsigned int plen, void *payload, unsigned int outlen, void *out) { struct ar9170_usb *aru = (void *) ar; struct urb *urb = NULL; unsigned long flags; int err = -ENOMEM; if (unlikely(!IS_ACCEPTING_CMD(ar))) return -EPERM; if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4)) return -EINVAL; urb = usb_alloc_urb(0, GFP_ATOMIC); if (unlikely(!urb)) goto err_free; ar->cmdbuf[0] = cpu_to_le32(plen); ar->cmdbuf[0] |= cpu_to_le32(cmd << 8); /* writing multiple regs fills this buffer already */ if (plen && payload != (u8 *)(&ar->cmdbuf[1])) memcpy(&ar->cmdbuf[1], payload, plen); spin_lock_irqsave(&aru->common.cmdlock, flags); aru->readbuf = (u8 *)out; aru->readlen = outlen; spin_unlock_irqrestore(&aru->common.cmdlock, flags); usb_fill_int_urb(urb, aru->udev, usb_sndbulkpipe(aru->udev, AR9170_EP_CMD), aru->common.cmdbuf, plen + 4, ar9170_usb_tx_urb_complete, NULL, 1); usb_anchor_urb(urb, &aru->tx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) { usb_unanchor_urb(urb); usb_free_urb(urb); goto err_unbuf; } usb_free_urb(urb); err = wait_for_completion_timeout(&aru->cmd_wait, HZ); if (err == 0) { err = -ETIMEDOUT; goto err_unbuf; } if (aru->readlen != outlen) { err = -EMSGSIZE; goto err_unbuf; } return 0; err_unbuf: /* Maybe the device was removed in the second we were waiting? */ if (IS_STARTED(ar)) { dev_err(&aru->udev->dev, "no command feedback " "received (%d).\n", err); /* provide some maybe useful debug information */ print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE, aru->common.cmdbuf, plen + 4); dump_stack(); } /* invalidate to avoid completing the next prematurely */ spin_lock_irqsave(&aru->common.cmdlock, flags); aru->readbuf = NULL; aru->readlen = 0; spin_unlock_irqrestore(&aru->common.cmdlock, flags); err_free: return err; }
static int acm_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_cdc_union_desc *union_header = NULL; struct usb_cdc_country_functional_desc *cfd = NULL; unsigned char *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; struct usb_interface *control_interface; struct usb_interface *data_interface; struct usb_endpoint_descriptor *epctrl = NULL; struct usb_endpoint_descriptor *epread = NULL; struct usb_endpoint_descriptor *epwrite = NULL; struct usb_device *usb_dev = interface_to_usbdev(intf); struct acm *acm; int minor; int ctrlsize, readsize; u8 *buf; u8 ac_management_function = 0; u8 call_management_function = 0; int call_interface_num = -1; int data_interface_num = -1; unsigned long quirks; int num_rx_buf; int i; int combined_interfaces = 0; /* normal quirks */ quirks = (unsigned long)id->driver_info; num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; /* not a real CDC ACM device */ if (quirks & NOT_REAL_ACM) return -ENODEV; if (max_intfs == 1) { /* XMM HACK - use ACM for interfaces 0/1 only */ switch (intf->cur_altsetting->desc.bInterfaceNumber) { case 0: case 1: I("XMM HACK -" " interface #%d create for ttyACM device\n", intf->cur_altsetting->desc.bInterfaceNumber); break; default: D("XMM HACK -" " interface #%d reserved for RAW-IP network driver\n", intf->cur_altsetting->desc.bInterfaceNumber); return -EINVAL; } } else if (max_intfs == 2) { /* XMM HACK - use ACM for interfaces 0/1 & 6/7 only */ switch (intf->cur_altsetting->desc.bInterfaceNumber) { case 0: case 1: case 6: case 7: I("XMM HACK -" " interface #%d create for ttyACM device\n", intf->cur_altsetting->desc.bInterfaceNumber); break; default: D("XMM HACK -" " interface #%d reserved for RAW-IP network driver\n", intf->cur_altsetting->desc.bInterfaceNumber); return -EINVAL; } } /* 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); if (!control_interface || !data_interface) { E("no ctrl or data interfaces\n"); return -ENODEV; } goto skip_normal_probe; } /* normal probing*/ if (!buffer) { E("Weird descriptor references\n"); return -EINVAL; } if (!buflen) { if (intf->cur_altsetting->endpoint && intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { D("Seeking extra descriptors on endpoint\n"); buflen = intf->cur_altsetting->endpoint->extralen; buffer = intf->cur_altsetting->endpoint->extra; } else { E("Zero length descriptor references\n"); return -EINVAL; } } while (buflen > 0) { if (buffer[1] != USB_DT_CS_INTERFACE) { E("skipping garbage\n"); goto next_desc; } switch (buffer[2]) { case USB_CDC_UNION_TYPE: /* we've found it */ if (union_header) { E("More than one " "union descriptor, skipping ...\n"); goto next_desc; } union_header = (struct usb_cdc_union_desc *)buffer; break; case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ cfd = (struct usb_cdc_country_functional_desc *)buffer; break; case USB_CDC_HEADER_TYPE: /* maybe check version */ break; /* for now we ignore it */ case USB_CDC_ACM_TYPE: ac_management_function = buffer[3]; break; case USB_CDC_CALL_MANAGEMENT_TYPE: call_management_function = buffer[3]; call_interface_num = buffer[4]; if ( (quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3) D("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. */ D("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) { D("No union descriptor, using call management descriptor\n"); /* quirks for Droids MuIn LCD */ if (quirks & NO_DATA_INTERFACE) data_interface = usb_ifnum_to_if(usb_dev, 0); else data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); control_interface = intf; if (!data_interface) { D("no data interfaces\n"); return -ENODEV; } } else { if (intf->cur_altsetting->desc.bNumEndpoints != 3) { D("No union descriptor, giving up\n"); return -ENODEV; } else { D("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) { D("no interfaces\n"); return -ENODEV; } } if (data_interface_num != call_interface_num) D("Separate call control interface. That is not fully supported.\n"); if (control_interface == data_interface) { /* some broken devices designed for windows work this way */ D("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) { E("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; D("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 */ D("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; D("The data interface has switched endpoints\n"); t = epread; epread = epwrite; epwrite = t; } made_compressed_probe: D( "interfaces are valid\n"); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (minor == ACM_TTY_MINORS) { E("no more free acm devices\n"); return -ENODEV; } acm = kzalloc(sizeof(struct acm), GFP_KERNEL); if (acm == NULL) { E("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; INIT_WORK(&acm->work, acm_softint); init_usb_anchor(&acm->deferred); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); mutex_init(&acm->mutex); acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); acm->is_int_ep = usb_endpoint_xfer_int(epread); if (acm->is_int_ep) acm->bInterval = epread->bInterval; if (quirks & NO_HANGUP_IN_RESET_RESUME) acm->no_hangup_in_reset_resume = 1; tty_port_init(&acm->port); acm->port.ops = &acm_port_ops; buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); if (!buf) { E("out of memory (ctrl buffer alloc)\n"); goto alloc_fail2; } acm->ctrl_buffer = buf; if (acm_write_buffers_alloc(acm) < 0) { E("out of memory (write buffer alloc)\n"); goto alloc_fail4; } acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->ctrlurb) { E("out of memory (ctrlurb kmalloc)\n"); goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { struct acm_rb *rb = &(acm->read_buffers[i]); struct urb *urb; rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, &rb->dma); if (!rb->base) { E("out of memory " "(read bufs usb_alloc_coherent)\n"); goto alloc_fail6; } rb->index = i; rb->instance = acm; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { E("out of memory (read urbs usb_alloc_urb)\n"); goto alloc_fail6; } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; urb->transfer_dma = rb->dma; if (acm->is_int_ep) { usb_fill_int_urb(urb, acm->dev, acm->rx_endpoint, rb->base, acm->readsize, acm_read_bulk_callback, rb, acm->bInterval); } else { usb_fill_bulk_urb(urb, acm->dev, acm->rx_endpoint, rb->base, acm->readsize, acm_read_bulk_callback, rb); } acm->read_urbs[i] = urb; __set_bit(i, &acm->read_urbs_free); } 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) { E("out of memory (write urbs usb_alloc_urb)\n"); goto alloc_fail7; } 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+URB_ZERO_PACKET); snd->instance = acm; } usb_set_intfdata(intf, acm); i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); if (i < 0) goto alloc_fail7; 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); acm->country_codes = NULL; acm->country_code_size = 0; 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); acm->country_codes = NULL; acm->country_code_size = 0; 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; I("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_fail7: for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); alloc_fail6: for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->read_urbs[i]); acm_read_buffers_free(acm); usb_free_urb(acm->ctrlurb); alloc_fail5: acm_write_buffers_free(acm); alloc_fail4: usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); alloc_fail2: kfree(acm); alloc_fail: return -ENOMEM; }
static int __devinit if_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *data_desc; struct usb_link_device *usb_ld = (struct usb_link_device *)id->driver_info; struct link_device *ld = &usb_ld->ld; struct usb_interface *data_intf; struct usb_device *usbdev = interface_to_usbdev(intf); struct device *dev, *ehci_dev, *root_hub; struct if_usb_devdata *pipe; struct urb *urb; int i; int j; int dev_id; int err; /* To detect usb device order probed */ dev_id = intf->cur_altsetting->desc.bInterfaceNumber; if (dev_id >= IF_USB_DEVNUM_MAX) { dev_err(&intf->dev, "Device id %d cannot support\n", dev_id); return -EINVAL; } if (!usb_ld) { dev_err(&intf->dev, "if_usb device doesn't be allocated\n"); err = ENOMEM; goto out; } mif_info("probe dev_id=%d usb_device_id(0x%p), usb_ld (0x%p)\n", dev_id, id, usb_ld); usb_ld->usbdev = usbdev; usb_get_dev(usbdev); for (i = 0; i < IF_USB_DEVNUM_MAX; i++) { data_intf = usb_ifnum_to_if(usbdev, i); /* remap endpoint of RAW to no.1 for LTE modem */ if (i == 0) pipe = &usb_ld->devdata[1]; else if (i == 1) pipe = &usb_ld->devdata[0]; else pipe = &usb_ld->devdata[i]; pipe->disconnected = 0; pipe->data_intf = data_intf; data_desc = data_intf->cur_altsetting; /* Endpoints */ if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { pipe->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); pipe->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); pipe->rx_buf_size = 1024*4; } else { pipe->rx_pipe = usb_rcvbulkpipe(usbdev, data_desc->endpoint[1].desc.bEndpointAddress); pipe->tx_pipe = usb_sndbulkpipe(usbdev, data_desc->endpoint[0].desc.bEndpointAddress); pipe->rx_buf_size = 1024*4; } if (i == 0) { dev_info(&usbdev->dev, "USB IF USB device found\n"); } else { err = usb_driver_claim_interface(&if_usb_driver, data_intf, usb_ld); if (err < 0) { mif_err("failed to cliam usb interface\n"); goto out; } } usb_set_intfdata(data_intf, usb_ld); usb_ld->dev_count++; pm_suspend_ignore_children(&data_intf->dev, true); for (j = 0; j < URB_COUNT; j++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { mif_err("alloc urb fail\n"); err = -ENOMEM; goto out2; } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer = usb_alloc_coherent(usbdev, pipe->rx_buf_size, GFP_KERNEL, &urb->transfer_dma); if (!urb->transfer_buffer) { mif_err( "Failed to allocate transfer buffer\n"); usb_free_urb(urb); err = -ENOMEM; goto out2; } usb_fill_bulk_urb(urb, usbdev, pipe->rx_pipe, urb->transfer_buffer, pipe->rx_buf_size, usb_rx_complete, pipe); usb_anchor_urb(urb, &pipe->urbs); } } /* temporary call reset_resume */ atomic_set(&usb_ld->suspend_count, 1); if_usb_reset_resume(data_intf); atomic_set(&usb_ld->suspend_count, 0); SET_HOST_ACTIVE(usb_ld->pdata, 1); usb_ld->host_wake_timeout_flag = 0; if (gpio_get_value(usb_ld->pdata->gpio_phone_active)) { struct link_pm_data *pm_data = usb_ld->link_pm_data; int delay = pm_data->autosuspend_delay_ms ?: DEFAULT_AUTOSUSPEND_DELAY_MS; pm_runtime_set_autosuspend_delay(&usbdev->dev, delay); dev = &usbdev->dev; if (dev->parent) { dev_dbg(&usbdev->dev, "if_usb Runtime PM Start!!\n"); usb_enable_autosuspend(usb_ld->usbdev); /* s5p-ehci runtime pm allow - usb phy suspend mode */ root_hub = &usbdev->bus->root_hub->dev; ehci_dev = root_hub->parent; mif_debug("ehci device = %s, %s\n", dev_driver_string(ehci_dev), dev_name(ehci_dev)); pm_runtime_allow(ehci_dev); if (!pm_data->autosuspend) pm_runtime_forbid(dev); if (has_hub(usb_ld)) link_pm_preactive(pm_data); pm_data->root_hub = root_hub; } usb_ld->flow_suspend = 0; /* Queue work if skbs were pending before a disconnect/probe */ if (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0); usb_ld->if_usb_connected = 1; /*USB3503*/ mif_debug("hub active complete\n"); usb_change_modem_state(usb_ld, STATE_ONLINE); } else {
static int brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb = interface_to_usbdev(intf); struct brcmf_usbdev_info *devinfo; struct usb_interface_descriptor *desc; struct usb_endpoint_descriptor *endpoint; int ret = 0; u32 num_of_eps; u8 endpoint_num, ep; brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct); devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); if (devinfo == NULL) return -ENOMEM; devinfo->usbdev = usb; devinfo->dev = &usb->dev; /* Take an init lock, to protect for disconnect while still loading. * Necessary because of the asynchronous firmware load construction */ mutex_init(&devinfo->dev_init_lock); mutex_lock(&devinfo->dev_init_lock); usb_set_intfdata(intf, devinfo); /* Check that the device supports only one configuration */ if (usb->descriptor.bNumConfigurations != 1) { brcmf_err("Number of configurations: %d not supported\n", usb->descriptor.bNumConfigurations); ret = -ENODEV; goto fail; } if ((usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) && (usb->descriptor.bDeviceClass != USB_CLASS_MISC) && (usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS_CONTROLLER)) { brcmf_err("Device class: 0x%x not supported\n", usb->descriptor.bDeviceClass); ret = -ENODEV; goto fail; } desc = &intf->altsetting[0].desc; if ((desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || (desc->bInterfaceSubClass != 2) || (desc->bInterfaceProtocol != 0xff)) { brcmf_err("non WLAN interface %d: 0x%x:0x%x:0x%x\n", desc->bInterfaceNumber, desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol); ret = -ENODEV; goto fail; } num_of_eps = desc->bNumEndpoints; for (ep = 0; ep < num_of_eps; ep++) { endpoint = &intf->altsetting[0].endpoint[ep].desc; endpoint_num = usb_endpoint_num(endpoint); if (!usb_endpoint_xfer_bulk(endpoint)) continue; if (usb_endpoint_dir_in(endpoint)) { if (!devinfo->rx_pipe) devinfo->rx_pipe = usb_rcvbulkpipe(usb, endpoint_num); } else { if (!devinfo->tx_pipe) devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num); } } if (devinfo->rx_pipe == 0) { brcmf_err("No RX (in) Bulk EP found\n"); ret = -ENODEV; goto fail; } if (devinfo->tx_pipe == 0) { brcmf_err("No TX (out) Bulk EP found\n"); ret = -ENODEV; goto fail; } devinfo->ifnum = desc->bInterfaceNumber; if (usb->speed == USB_SPEED_SUPER) brcmf_dbg(USB, "Broadcom super speed USB WLAN interface detected\n"); else if (usb->speed == USB_SPEED_HIGH) brcmf_dbg(USB, "Broadcom high speed USB WLAN interface detected\n"); else brcmf_dbg(USB, "Broadcom full speed USB WLAN interface detected\n"); ret = brcmf_usb_probe_cb(devinfo); if (ret) goto fail; /* Success */ return 0; fail: mutex_unlock(&devinfo->dev_init_lock); kfree(devinfo); usb_set_intfdata(intf, NULL); return ret; }
int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting) { struct cdc_ncm_ctx *ctx; struct usb_driver *driver; u8 *buf; int len; int temp; u8 iface_no; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ctx->tx_timer.function = &cdc_ncm_tx_timer_cb; ctx->bh.data = (unsigned long)ctx; ctx->bh.func = cdc_ncm_txpath_bh; atomic_set(&ctx->stop, 0); spin_lock_init(&ctx->mtx); ctx->netdev = dev->net; /* store ctx pointer in device data field */ dev->data[0] = (unsigned long)ctx; /* get some pointers */ driver = driver_of(intf); buf = intf->cur_altsetting->extra; len = intf->cur_altsetting->extralen; ctx->udev = dev->udev; ctx->intf = intf; /* parse through descriptors associated with control interface */ while ((len > 0) && (buf[0] > 2) && (buf[0] <= len)) { if (buf[1] != USB_DT_CS_INTERFACE) goto advance; switch (buf[2]) { case USB_CDC_UNION_TYPE: if (buf[0] < sizeof(*(ctx->union_desc))) break; ctx->union_desc = (const struct usb_cdc_union_desc *)buf; ctx->control = usb_ifnum_to_if(dev->udev, ctx->union_desc->bMasterInterface0); ctx->data = usb_ifnum_to_if(dev->udev, ctx->union_desc->bSlaveInterface0); break; case USB_CDC_ETHERNET_TYPE: if (buf[0] < sizeof(*(ctx->ether_desc))) break; ctx->ether_desc = (const struct usb_cdc_ether_desc *)buf; dev->hard_mtu = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); if (dev->hard_mtu < CDC_NCM_MIN_DATAGRAM_SIZE) dev->hard_mtu = CDC_NCM_MIN_DATAGRAM_SIZE; else if (dev->hard_mtu > CDC_NCM_MAX_DATAGRAM_SIZE) dev->hard_mtu = CDC_NCM_MAX_DATAGRAM_SIZE; break; case USB_CDC_NCM_TYPE: if (buf[0] < sizeof(*(ctx->func_desc))) break; ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf; break; case USB_CDC_MBIM_TYPE: if (buf[0] < sizeof(*(ctx->mbim_desc))) break; ctx->mbim_desc = (const struct usb_cdc_mbim_desc *)buf; break; default: break; } advance: /* advance to next descriptor */ temp = buf[0]; buf += temp; len -= temp; } /* some buggy devices have an IAD but no CDC Union */ if (!ctx->union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) { ctx->control = intf; ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1); dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n"); } /* check if we got everything */ if ((ctx->control == NULL) || (ctx->data == NULL) || ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf)))) goto error; /* claim data interface, if different from control */ if (ctx->data != ctx->control) { temp = usb_driver_claim_interface(driver, ctx->data, dev); if (temp) goto error; } iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; /* Reset data interface. Some devices will not reset properly * unless they are configured first. Toggle the altsetting to * force a reset */ usb_set_interface(dev->udev, iface_no, data_altsetting); temp = usb_set_interface(dev->udev, iface_no, 0); if (temp) goto error2; /* initialize data interface */ if (cdc_ncm_setup(ctx)) goto error2; /* Some firmwares need a pause here or they will silently fail * to set up the interface properly. This value was decided * empirically on a Sierra Wireless MC7455 running 02.08.02.00 * firmware. */ usleep_range(10000, 20000); /* configure data interface */ temp = usb_set_interface(dev->udev, iface_no, data_altsetting); if (temp) goto error2; cdc_ncm_find_endpoints(ctx, ctx->data); cdc_ncm_find_endpoints(ctx, ctx->control); if ((ctx->in_ep == NULL) || (ctx->out_ep == NULL) || (ctx->status_ep == NULL)) goto error2; dev->net->ethtool_ops = &cdc_ncm_ethtool_ops; usb_set_intfdata(ctx->data, dev); usb_set_intfdata(ctx->control, dev); usb_set_intfdata(ctx->intf, dev); if (ctx->ether_desc) { temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress); if (temp) goto error2; dev_info(&dev->udev->dev, "MAC-Address: %pM\n", dev->net->dev_addr); } dev->in = usb_rcvbulkpipe(dev->udev, ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->out = usb_sndbulkpipe(dev->udev, ctx->out_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->status = ctx->status_ep; dev->rx_urb_size = ctx->rx_max; ctx->tx_speed = ctx->rx_speed = 0; return 0; error2: usb_set_intfdata(ctx->control, NULL); usb_set_intfdata(ctx->data, NULL); if (ctx->data != ctx->control) usb_driver_release_interface(driver, ctx->data); error: cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]); dev->data[0] = 0; dev_info(&dev->udev->dev, "bind() failure\n"); return -ENODEV; }
static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) { struct cmdbuf_t *tcb; unsigned long flags; int count; int status = -ENOENT; struct usb_cardstate *ucs = cs->hw.usb; do { if (!cb->len) { tcb = cb; spin_lock_irqsave(&cs->cmdlock, flags); cs->cmdbytes -= cs->curlen; gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", cs->curlen, cs->cmdbytes); cs->cmdbuf = cb = cb->next; if (cb) { cb->prev = NULL; cs->curlen = cb->len; } else { cs->lastcmdbuf = NULL; cs->curlen = 0; } spin_unlock_irqrestore(&cs->cmdlock, flags); if (tcb->wake_tasklet) tasklet_schedule(tcb->wake_tasklet); kfree(tcb); } if (cb) { count = min(cb->len, ucs->bulk_out_size); gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, usb_sndbulkpipe(ucs->udev, ucs->bulk_out_endpointAddr & 0x0f), cb->buf + cb->offset, count, gigaset_write_bulk_callback, cs); cb->offset += count; cb->len -= count; ucs->busy = 1; spin_lock_irqsave(&cs->lock, flags); status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV; spin_unlock_irqrestore(&cs->lock, flags); if (status) { ucs->busy = 0; dev_err(cs->dev, "could not submit urb (error %d)\n", -status); cb->len = 0; /* skip urb => remove cb+wakeup in next loop cycle */ } } } while (cb && status); /* next command on error */ return status; }
/* * Sends a barker buffer to the device * * This helper will allocate a kmalloced buffer and use it to transmit * (then free it). Reason for this is that other arches cannot use * stack/vmalloc/text areas for DMA transfers. * * Error recovery here is simpler: anything is considered a hard error * and will move the reset code to use a last-resort bus-based reset. */ static int __i2400mu_send_barker(struct i2400mu *i2400mu, const __le32 *barker, size_t barker_size, unsigned endpoint) { struct usb_endpoint_descriptor *epd = NULL; int pipe, actual_len, ret; struct device *dev = &i2400mu->usb_iface->dev; void *buffer; int do_autopm = 1; ret = usb_autopm_get_interface(i2400mu->usb_iface); if (ret < 0) { dev_err(dev, "RESET: can't get autopm: %d\n", ret); do_autopm = 0; } ret = -ENOMEM; buffer = kmalloc(barker_size, GFP_KERNEL); if (buffer == NULL) goto error_kzalloc; epd = usb_get_epd(i2400mu->usb_iface, endpoint); pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); memcpy(buffer, barker, barker_size); retry: ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size, &actual_len, 200); switch (ret) { case 0: if (actual_len != barker_size) { /* Too short? drop it */ dev_err(dev, "E: %s: short write (%d B vs %zu " "expected)\n", __func__, actual_len, barker_size); ret = -EIO; } break; case -EPIPE: /* * Stall -- maybe the device is choking with our * requests. Clear it and give it some time. If they * happen to often, it might be another symptom, so we * reset. * * No error handling for usb_clear_halt(0; if it * works, the retry works; if it fails, this switch * does the error handling for us. */ if (edc_inc(&i2400mu->urb_edc, 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { dev_err(dev, "E: %s: too many stalls in " "URB; resetting device\n", __func__); usb_queue_reset_device(i2400mu->usb_iface); /* fallthrough */ } else { usb_clear_halt(i2400mu->usb_dev, pipe); msleep(10); /* give the device some time */ goto retry; } case -EINVAL: /* while removing driver */ case -ENODEV: /* dev disconnect ... */ case -ENOENT: /* just ignore it */ case -ESHUTDOWN: /* and exit */ case -ECONNRESET: ret = -ESHUTDOWN; break; default: /* Some error? */ if (edc_inc(&i2400mu->urb_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { dev_err(dev, "E: %s: maximum errors in URB " "exceeded; resetting device\n", __func__); usb_queue_reset_device(i2400mu->usb_iface); } else { dev_warn(dev, "W: %s: cannot send URB: %d\n", __func__, ret); goto retry; } } kfree(buffer); error_kzalloc: if (do_autopm) usb_autopm_put_interface(i2400mu->usb_iface); return ret; }
static int btusb_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct btusb_data *data = hci_get_drvdata(hdev); struct usb_ctrlrequest *dr; struct urb *urb; unsigned int pipe; int err; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; dr = kmalloc(sizeof(*dr), GFP_ATOMIC); if (!dr) { usb_free_urb(urb); return -ENOMEM; } dr->bRequestType = data->cmdreq_type; dr->bRequest = 0; dr->wIndex = 0; dr->wValue = 0; dr->wLength = __cpu_to_le16(skb->len); pipe = usb_sndctrlpipe(data->udev, 0x00); usb_fill_control_urb(urb, data->udev, pipe, (void *) dr, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: if (!data->bulk_tx_ep) return -ENODEV; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) return -ENODEV; urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); if (!urb) return -ENOMEM; pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); usb_fill_int_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_isoc_tx_complete, skb, data->isoc_tx_ep->bInterval); urb->transfer_flags = URB_ISO_ASAP; __fill_isoc_descriptor(urb, skb->len, le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); hdev->stat.sco_tx++; goto skip_waking; default: return -EILSEQ; } err = inc_tx(data); if (err) { usb_anchor_urb(urb, &data->deferred); schedule_work(&data->waker); err = 0; goto done; } skip_waking: usb_anchor_urb(urb, &data->tx_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p submission failed (%d)", hdev->name, urb, -err); kfree(urb->setup_packet); usb_unanchor_urb(urb); } else { usb_mark_last_busy(data->udev); } done: usb_free_urb(urb); return err; }
/** * @brief This function downloads data/comand packet to device * * @param handle Pointer to moal_handle structure * @param pmbuf Pointer to mlan_buffer structure * @param ep Endpoint to send * * @return MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE */ mlan_status woal_write_data_async(moal_handle * handle, mlan_buffer * pmbuf, t_u8 ep) { struct usb_card_rec *cardp = handle->card; urb_context *context = NULL; t_u8 *data = (t_u8 *) (pmbuf->pbuf + pmbuf->data_offset); struct urb *tx_urb = NULL; mlan_status ret = MLAN_STATUS_SUCCESS; ENTER(); /* Check if device is removed */ if (handle->surprise_removed) { PRINTM(ERROR, "Device removed\n"); ret = MLAN_STATUS_FAILURE; goto tx_ret; } if ((ep == cardp->tx_data_ep) && (atomic_read(&cardp->tx_data_urb_pending) >= MVUSB_TX_HIGH_WMARK)) { ret = MLAN_STATUS_RESOURCE; goto tx_ret; } PRINTM(DATA, "woal_write_data_async: ep=%d\n", ep); if (ep == cardp->tx_cmd_ep) { context = &cardp->tx_cmd; } else { if (cardp->tx_data_ix >= MVUSB_TX_HIGH_WMARK) cardp->tx_data_ix = 0; context = &cardp->tx_data_list[cardp->tx_data_ix++]; } context->handle = handle; context->ep = ep; context->pmbuf = pmbuf; tx_urb = context->urb; /* * Use USB API usb_fill_bulk_urb() to set the * configuration information of the Tx bulk URB * and initialize the Tx callback */ usb_fill_bulk_urb(tx_urb, cardp->udev, usb_sndbulkpipe(cardp->udev, ep), data, pmbuf->data_len, woal_usb_tx_complete, (void *) context); tx_urb->transfer_flags |= URB_ZERO_PACKET; if (ep == cardp->tx_cmd_ep) atomic_inc(&cardp->tx_cmd_urb_pending); else atomic_inc(&cardp->tx_data_urb_pending); if ((ret = usb_submit_urb(tx_urb, GFP_ATOMIC))) { /* Submit URB failure */ PRINTM(ERROR, "Submit Tx data URB failed: %d\n", ret); if (ep == cardp->tx_cmd_ep) atomic_dec(&cardp->tx_cmd_urb_pending); else { atomic_dec(&cardp->tx_data_urb_pending); if (cardp->tx_data_ix) cardp->tx_data_ix--; else cardp->tx_data_ix = MVUSB_TX_HIGH_WMARK; } ret = MLAN_STATUS_FAILURE; } else { ret = MLAN_STATUS_SUCCESS; } tx_ret: if (!ret) ret = MLAN_STATUS_PENDING; LEAVE(); return ret; }