static ssize_t ikalcd_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { struct usb_ikalcd *dev; int retval = 0; struct urb *urb = NULL; char *buf = NULL; struct usb_ctrlrequest *cr; size_t writesize = min(count, (size_t)LCD_COMMAND_SIZE); int i; dev = 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 (!(file->f_flags & O_NONBLOCK)) { if (down_interruptible(&dev->limit_sem)) { retval = -ERESTARTSYS; goto exit; } } else { if (down_trylock(&dev->limit_sem)) { retval = -EAGAIN; goto exit; } } spin_lock_irq(&dev->err_lock); retval = dev->errors; if (retval < 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_alloc_coherent(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); */ buf = kmalloc(LCD_COMMAND_SIZE, GFP_KERNEL); if (!buf) { retval = -ENOMEM; goto error; } cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!cr) { retval = -ENOMEM; goto error; } for (i=0; i<LCD_COMMAND_SIZE; i++) buf[i] = 0x11; 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; } cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE; cr->bRequest = 0x09; cr->wValue = cpu_to_le16(0x300); cr->wIndex = cpu_to_le16(dev->interface->cur_altsetting->desc.bInterfaceNumber); cr->wLength = cpu_to_le16(LCD_COMMAND_SIZE); /* initialize the urb properly */ /* usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, writesize, ikalcd_write_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; */ usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (unsigned char*)cr, (void*)buf, LCD_COMMAND_SIZE, ikalcd_write_control_callback, dev); 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) { dev_err(&dev->interface->dev, "%s - failed submitting write urb, error %d\n", __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_free_coherent(dev->udev, writesize, buf, urb->transfer_dma); usb_free_urb(urb); } up(&dev->limit_sem); exit: return retval; }
int __devinit st5481_setup_usb(struct st5481_adapter *adapter) { struct usb_device *dev = adapter->usb_dev; struct st5481_ctrl *ctrl = &adapter->ctrl; struct st5481_intr *intr = &adapter->intr; struct usb_host_interface *altsetting; struct usb_host_endpoint *endpoint; int status; struct urb *urb; u8 *buf; DBG(1,""); if ((status = usb_reset_configuration (dev)) < 0) { WARN("reset_configuration failed,status=%d",status); return status; } altsetting = &(dev->config->interface[0]->altsetting[3]); // Check if the config is sane if ( altsetting->desc.bNumEndpoints != 7 ) { WARN("expecting 7 got %d endpoints!", altsetting->desc.bNumEndpoints); return -EINVAL; } // The descriptor is wrong for some early samples of the ST5481 chip altsetting->endpoint[3].desc.wMaxPacketSize = 32; altsetting->endpoint[4].desc.wMaxPacketSize = 32; // Use alternative setting 3 on interface 0 to have 2B+D if ((status = usb_set_interface (dev, 0, 3)) < 0) { WARN("usb_set_interface failed,status=%d",status); return status; } // Allocate URB for control endpoint urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { return -ENOMEM; } ctrl->urb = urb; // Fill the control URB usb_fill_control_urb (urb, dev, usb_sndctrlpipe(dev, 0), NULL, NULL, 0, usb_ctrl_complete, adapter); fifo_init(&ctrl->msg_fifo.f, ARRAY_SIZE(ctrl->msg_fifo.data)); // Allocate URBs and buffers for interrupt endpoint urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { return -ENOMEM; } intr->urb = urb; buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL); if (!buf) { return -ENOMEM; } endpoint = &altsetting->endpoint[EP_INT-1]; // Fill the interrupt URB usb_fill_int_urb(urb, dev, usb_rcvintpipe(dev, endpoint->desc.bEndpointAddress), buf, INT_PKT_SIZE, usb_int_complete, adapter, endpoint->desc.bInterval); return 0; }
static int redrat3_dev_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct device *dev = &intf->dev; struct usb_host_interface *uhi; struct redrat3_dev *rr3; struct usb_endpoint_descriptor *ep; struct usb_endpoint_descriptor *ep_narrow = NULL; struct usb_endpoint_descriptor *ep_wide = NULL; struct usb_endpoint_descriptor *ep_out = NULL; u8 addr, attrs; int pipe, i; int retval = -ENOMEM; uhi = intf->cur_altsetting; /* find our bulk-in and bulk-out endpoints */ for (i = 0; i < uhi->desc.bNumEndpoints; ++i) { ep = &uhi->endpoint[i].desc; addr = ep->bEndpointAddress; attrs = ep->bmAttributes; if (((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && ((attrs & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { dev_dbg(dev, "found bulk-in endpoint at 0x%02x\n", ep->bEndpointAddress); /* data comes in on 0x82, 0x81 is for learning */ if (ep->bEndpointAddress == RR3_NARROW_IN_EP_ADDR) ep_narrow = ep; if (ep->bEndpointAddress == RR3_WIDE_IN_EP_ADDR) ep_wide = ep; } if ((ep_out == NULL) && ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) && ((attrs & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { dev_dbg(dev, "found bulk-out endpoint at 0x%02x\n", ep->bEndpointAddress); ep_out = ep; } } if (!ep_narrow || !ep_out || !ep_wide) { dev_err(dev, "Couldn't find all endpoints\n"); retval = -ENODEV; goto no_endpoints; } /* allocate memory for our device state and initialize it */ rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL); if (!rr3) goto no_endpoints; rr3->dev = &intf->dev; rr3->ep_narrow = ep_narrow; rr3->ep_out = ep_out; rr3->udev = udev; /* set up bulk-in endpoint */ rr3->narrow_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rr3->narrow_urb) goto redrat_free; rr3->wide_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rr3->wide_urb) goto redrat_free; rr3->bulk_in_buf = usb_alloc_coherent(udev, le16_to_cpu(ep_narrow->wMaxPacketSize), GFP_KERNEL, &rr3->dma_in); if (!rr3->bulk_in_buf) goto redrat_free; pipe = usb_rcvbulkpipe(udev, ep_narrow->bEndpointAddress); usb_fill_bulk_urb(rr3->narrow_urb, udev, pipe, rr3->bulk_in_buf, le16_to_cpu(ep_narrow->wMaxPacketSize), redrat3_handle_async, rr3); rr3->narrow_urb->transfer_dma = rr3->dma_in; rr3->narrow_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; pipe = usb_rcvbulkpipe(udev, ep_wide->bEndpointAddress); usb_fill_bulk_urb(rr3->wide_urb, udev, pipe, rr3->bulk_in_buf, le16_to_cpu(ep_narrow->wMaxPacketSize), redrat3_handle_async, rr3); rr3->wide_urb->transfer_dma = rr3->dma_in; rr3->wide_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; redrat3_reset(rr3); redrat3_get_firmware_rev(rr3); /* default.. will get overridden by any sends with a freq defined */ rr3->carrier = 38000; atomic_set(&rr3->flash, 0); rr3->flash_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rr3->flash_urb) goto redrat_free; /* learn urb */ rr3->learn_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rr3->learn_urb) goto redrat_free; /* setup packet is 'c0 b2 0000 0000 0001' */ rr3->learn_control.bRequestType = 0xc0; rr3->learn_control.bRequest = RR3_MODSIG_CAPTURE; rr3->learn_control.wLength = cpu_to_le16(1); usb_fill_control_urb(rr3->learn_urb, udev, usb_rcvctrlpipe(udev, 0), (unsigned char *)&rr3->learn_control, &rr3->learn_buf, sizeof(rr3->learn_buf), redrat3_learn_complete, rr3); /* setup packet is 'c0 b9 0000 0000 0001' */ rr3->flash_control.bRequestType = 0xc0; rr3->flash_control.bRequest = RR3_BLINK_LED; rr3->flash_control.wLength = cpu_to_le16(1); usb_fill_control_urb(rr3->flash_urb, udev, usb_rcvctrlpipe(udev, 0), (unsigned char *)&rr3->flash_control, &rr3->flash_in_buf, sizeof(rr3->flash_in_buf), redrat3_led_complete, rr3); /* led control */ rr3->led.name = "redrat3:red:feedback"; rr3->led.default_trigger = "rc-feedback"; rr3->led.brightness_set = redrat3_brightness_set; retval = led_classdev_register(&intf->dev, &rr3->led); if (retval) goto redrat_free; rr3->rc = redrat3_init_rc_dev(rr3); if (!rr3->rc) { retval = -ENOMEM; goto led_free; } /* might be all we need to do? */ retval = redrat3_enable_detector(rr3); if (retval < 0) goto led_free; /* we can register the device now, as it is ready */ usb_set_intfdata(intf, rr3); return 0; led_free: led_classdev_unregister(&rr3->led); redrat_free: redrat3_delete(rr3, rr3->udev); no_endpoints: return retval; }
static void notification_available_cb(struct urb *urb) { int status; struct usb_cdc_notification *ctrl; struct ctrl_bridge *dev = urb->context; struct bridge *brdg = dev->brdg; unsigned int ctrl_bits; unsigned char *data; switch (urb->status) { case 0: break; case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: case -EPROTO: return; case -EPIPE: dev_err(&dev->intf->dev, "%s: stall on int endpoint\n", __func__); case -EOVERFLOW: default: pr_debug_ratelimited("%s: non zero urb status = %d\n", __func__, urb->status); goto resubmit_int_urb; } ctrl = (struct usb_cdc_notification *)urb->transfer_buffer; data = (unsigned char *)(ctrl + 1); switch (ctrl->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: dev->resp_avail++; usb_fill_control_urb(dev->readurb, dev->udev, usb_rcvctrlpipe(dev->udev, 0), (unsigned char *)dev->in_ctlreq, dev->readbuf, DEFAULT_READ_URB_LENGTH, resp_avail_cb, dev); usb_anchor_urb(dev->readurb, &dev->tx_submitted); status = usb_submit_urb(dev->readurb, GFP_ATOMIC); if (status) { dev_err(&dev->intf->dev, "%s: Error submitting Read URB %d\n", __func__, status); usb_unanchor_urb(dev->readurb); goto resubmit_int_urb; } return; case USB_CDC_NOTIFY_NETWORK_CONNECTION: dev_dbg(&dev->intf->dev, "%s network\n", ctrl->wValue ? "connected to" : "disconnected from"); break; case USB_CDC_NOTIFY_SERIAL_STATE: dev->notify_ser_state++; ctrl_bits = get_unaligned_le16(data); dev_dbg(&dev->intf->dev, "serial state: %d\n", ctrl_bits); dev->cbits_tohost = ctrl_bits; if (brdg && brdg->ops.send_cbits) brdg->ops.send_cbits(brdg->ctx, ctrl_bits); break; default: dev_err(&dev->intf->dev, "%s: unknown notification %d received:" "index %d len %d data0 %d data1 %d", __func__, ctrl->bNotificationType, ctrl->wIndex, ctrl->wLength, data[0], data[1]); } resubmit_int_urb: usb_anchor_urb(urb, &dev->tx_submitted); status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&dev->intf->dev, "%s: Error re-submitting Int URB %d\n", __func__, status); usb_unanchor_urb(urb); } }
static int rmnet_usb_ctrl_write(struct rmnet_ctrl_dev *dev, char *buf, size_t size) { int result; struct urb *sndurb; struct usb_ctrlrequest *out_ctlreq; struct usb_device *udev; #ifdef HTC_DEBUG_QMI_STUCK struct ctrl_write_context *context; #endif if (!is_dev_connected(dev)) return -ENETRESET; udev = interface_to_usbdev(dev->intf); sndurb = usb_alloc_urb(0, GFP_KERNEL); if (!sndurb) { dev_err(dev->devicep, "Error allocating read urb\n"); return -ENOMEM; } out_ctlreq = kmalloc(sizeof(*out_ctlreq), GFP_KERNEL); if (!out_ctlreq) { usb_free_urb(sndurb); dev_err(dev->devicep, "Error allocating setup packet buffer\n"); return -ENOMEM; } #ifdef HTC_DEBUG_QMI_STUCK context = kmalloc(sizeof(struct ctrl_write_context), GFP_KERNEL); if (!context) { kfree(out_ctlreq); usb_free_urb(sndurb); dev_err(dev->devicep, "Error allocating private data\n"); return -ENOMEM; } context->dev = dev; #endif out_ctlreq->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; out_ctlreq->wValue = 0; out_ctlreq->wIndex = dev->intf->cur_altsetting->desc.bInterfaceNumber; out_ctlreq->wLength = cpu_to_le16(size); usb_fill_control_urb(sndurb, udev, usb_sndctrlpipe(udev, 0), (unsigned char *)out_ctlreq, (void *)buf, size, #ifdef HTC_DEBUG_QMI_STUCK ctrl_write_callback, context); #else ctrl_write_callback, dev); #endif result = usb_autopm_get_interface(dev->intf); if (result < 0) { dev_err(dev->devicep, "%s: Unable to resume interface: %d\n", __func__, result); usb_free_urb(sndurb); kfree(out_ctlreq); #ifdef HTC_DEBUG_QMI_STUCK kfree(context); #endif return result; } #ifdef HTC_LOG_RMNET_USB_CTRL log_rmnet_usb_ctrl_event(dev->intf, "Tx", size); #endif #ifdef HTC_DEBUG_QMI_STUCK init_timer(&context->timer); context->timer.function = rmnet_usb_ctrl_write_timer_expire; context->timer.data = (unsigned long)sndurb; context->start_jiffies = jiffies; mod_timer(&context->timer, jiffies + msecs_to_jiffies(QMI_TX_NO_CB_TIMEOUT)); #endif usb_anchor_urb(sndurb, &dev->tx_submitted); dev->snd_encap_cmd_cnt++; result = usb_submit_urb(sndurb, GFP_KERNEL); if (result < 0) { dev_err(dev->devicep, "%s: Submit URB error %d\n", __func__, result); dev->snd_encap_cmd_cnt--; usb_autopm_put_interface(dev->intf); usb_unanchor_urb(sndurb); usb_free_urb(sndurb); kfree(out_ctlreq); #ifdef HTC_DEBUG_QMI_STUCK del_timer(&context->timer); kfree(context); #endif return result; } return size; }
static int btusb_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct btusb_data *data = hdev->driver_data; 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) { BT_ERR("%s urb %p submission failed", hdev->name, urb); kfree(urb->setup_packet); usb_unanchor_urb(urb); } else { usb_mark_last_busy(data->udev); } done: usb_free_urb(urb); return err; }
int PIPEnsControlIn( PSDevice pDevice, BYTE byRequest, WORD wValue, WORD wIndex, WORD wLength, PBYTE pbyBuffer ) { int ntStatus = 0; int ii; if (pDevice->Flags & fMP_DISCONNECTED) return STATUS_FAILURE; if (pDevice->Flags & fMP_CONTROL_READS) return STATUS_FAILURE; if (pDevice->Flags & fMP_CONTROL_WRITES) return STATUS_FAILURE; MP_SET_FLAG(pDevice, fMP_CONTROL_READS); pDevice->sUsbCtlRequest.bRequestType = 0xC0; pDevice->sUsbCtlRequest.bRequest = byRequest; pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue); pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex); pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength); pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK; pDevice->pControlURB->actual_length = 0; usb_fill_control_urb(pDevice->pControlURB, pDevice->usb, usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest, pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice); ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "control request submission failed: %d\n", ntStatus); MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); return STATUS_FAILURE; } spin_unlock_irq(&pDevice->lock); for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { if (pDevice->Flags & fMP_CONTROL_READS) mdelay(1); else break; if (ii >= USB_CTL_WAIT) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "control rcv request submission timeout\n"); spin_lock_irq(&pDevice->lock); MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); return STATUS_FAILURE; } } spin_lock_irq(&pDevice->lock); return ntStatus; }
static void wdm_int_callback(struct urb *urb) { int rv = 0; int status = urb->status; struct wdm_device *desc; struct usb_ctrlrequest *req; struct usb_cdc_notification *dr; desc = urb->context; req = desc->irq; dr = (struct usb_cdc_notification *)desc->sbuf; if (status) { switch (status) { case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: return; /* unplug */ case -EPIPE: set_bit(WDM_INT_STALL, &desc->flags); dev_err(&desc->intf->dev, "Stall on int endpoint\n"); goto sw; /* halt is cleared in work */ default: dev_err(&desc->intf->dev, "nonzero urb status received: %d\n", status); break; } } if (urb->actual_length < sizeof(struct usb_cdc_notification)) { dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n", urb->actual_length); goto exit; } switch (dr->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: dev_dbg(&desc->intf->dev, "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d", dr->wIndex, dr->wLength); break; case USB_CDC_NOTIFY_NETWORK_CONNECTION: dev_dbg(&desc->intf->dev, "NOTIFY_NETWORK_CONNECTION %s network", dr->wValue ? "connected to" : "disconnected from"); goto exit; default: clear_bit(WDM_POLL_RUNNING, &desc->flags); dev_err(&desc->intf->dev, "unknown notification %d received: index %d len %d\n", dr->bNotificationType, dr->wIndex, dr->wLength); goto exit; } req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; req->wValue = 0; req->wIndex = desc->inum; req->wLength = cpu_to_le16(desc->wMaxCommand); usb_fill_control_urb( desc->response, interface_to_usbdev(desc->intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)req, desc->inbuf, desc->wMaxCommand, wdm_in_callback, desc ); desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { rv = usb_submit_urb(desc->response, GFP_ATOMIC); dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", __func__, rv); } spin_unlock(&desc->iuspin); if (rv < 0) { if (rv == -EPERM) return; if (rv == -ENOMEM) { sw: rv = schedule_work(&desc->rxwork); if (rv) dev_err(&desc->intf->dev, "Cannot schedule work\n"); } } exit: rv = usb_submit_urb(urb, GFP_ATOMIC); if (rv) dev_err(&desc->intf->dev, "%s - usb_submit_urb failed with result %d\n", __func__, rv); }
static int bpa10x_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct bpa10x_data *data = hdev->driver_data; 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; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; *skb_push(skb, 1) = bt_cb(skb)->pkt_type; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: dr = kmalloc(sizeof(*dr), GFP_ATOMIC); if (!dr) { usb_free_urb(urb); return -ENOMEM; } dr->bRequestType = USB_TYPE_VENDOR; 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, bpa10x_tx_complete, skb); hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: pipe = usb_sndbulkpipe(data->udev, 0x02); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, bpa10x_tx_complete, skb); hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: pipe = usb_sndbulkpipe(data->udev, 0x02); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, bpa10x_tx_complete, skb); hdev->stat.sco_tx++; break; default: usb_free_urb(urb); return -EILSEQ; } usb_anchor_urb(urb, &data->tx_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { BT_ERR("%s urb %p submission failed", hdev->name, urb); kfree(urb->setup_packet); usb_unanchor_urb(urb); } usb_free_urb(urb); return 0; }
int usb_control_msg(struct usb_device *dev, u32 pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size, int *actual_length, int timeout) { int rc; u64 tout; struct urb u; struct vmm_completion uc; struct usb_ctrlrequest __cacheline_aligned setup; /* Initialize setup packet */ setup.bRequestType = requesttype; setup.bRequest = request; setup.wValue = vmm_cpu_to_le16(value); setup.wIndex = vmm_cpu_to_le16(index); setup.wLength = vmm_cpu_to_le16(size); DPRINTF("%s: request: 0x%X, requesttype: 0x%X, " \ "value 0x%X index 0x%X length 0x%X\n", __func__, request, requesttype, value, index, size); /* Initialize URB */ usb_init_urb(&u); /* Initialize URB completion */ INIT_COMPLETION(&uc); /* Fill URB */ usb_fill_control_urb(&u, dev, pipe, (u8 *)&setup, data, size, urb_request_complete, &uc); /* Submit URB */ rc = usb_hcd_submit_urb(&u); if (rc) { return rc; } /* Wait for completion */ if (timeout < 1) { vmm_completion_wait(&uc); rc = VMM_OK; } else { tout = timeout * 1000000ULL; rc = vmm_completion_wait_timeout(&uc, &tout); } if (rc) { return rc; } /* If URB failed then return status */ if (u.status < 0) { return u.status; } /* Return actual transfer length */ if (actual_length) { *actual_length = u.actual_length; } return VMM_OK; }
static int yurex_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_yurex *dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int retval = -ENOMEM; int i; DEFINE_WAIT(wait); /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { err("Out of memory"); goto error; } kref_init(&dev->kref); mutex_init(&dev->io_mutex); spin_lock_init(&dev->lock); init_waitqueue_head(&dev->waitq); dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; /* set up the endpoint information */ iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) { dev->int_in_endpointAddr = endpoint->bEndpointAddress; break; } } if (!dev->int_in_endpointAddr) { retval = -ENODEV; err("Could not find endpoints"); goto error; } /* allocate control URB */ dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->cntl_urb) { err("Could not allocate control URB"); goto error; } /* allocate buffer for control req */ dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, GFP_KERNEL, &dev->cntl_urb->setup_dma); if (!dev->cntl_req) { err("Could not allocate cntl_req"); goto error; } /* allocate buffer for control msg */ dev->cntl_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, GFP_KERNEL, &dev->cntl_urb->transfer_dma); if (!dev->cntl_buffer) { err("Could not allocate cntl_buffer"); goto error; } /* configure control URB */ dev->cntl_req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; dev->cntl_req->bRequest = HID_REQ_SET_REPORT; dev->cntl_req->wValue = cpu_to_le16((HID_OUTPUT_REPORT + 1) << 8); dev->cntl_req->wIndex = cpu_to_le16(iface_desc->desc.bInterfaceNumber); dev->cntl_req->wLength = cpu_to_le16(YUREX_BUF_SIZE); usb_fill_control_urb(dev->cntl_urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (void *)dev->cntl_req, dev->cntl_buffer, YUREX_BUF_SIZE, yurex_control_callback, dev); dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* allocate interrupt URB */ dev->urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->urb) { err("Could not allocate URB"); goto error; } /* allocate buffer for interrupt in */ dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, GFP_KERNEL, &dev->urb->transfer_dma); if (!dev->int_buffer) { err("Could not allocate int_buffer"); goto error; } /* configure interrupt URB */ usb_fill_int_urb(dev->urb, dev->udev, usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr), dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; err("Could not submitting URB"); goto error; } /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); /* we can register the device now, as it is ready */ retval = usb_register_dev(interface, &yurex_class); if (retval) { err("Not able to get a minor for this device."); usb_set_intfdata(interface, NULL); goto error; } dev->bbu = -1; dev_info(&interface->dev, "USB YUREX device now attached to Yurex #%d\n", interface->minor); return 0; error: if (dev) /* this frees allocated memory */ kref_put(&dev->kref, yurex_delete); return retval; }
static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { struct usb_ctrlrequest *req; int status; struct urb *urb; void *buf = NULL; u16 buf_le; if (2 == size) { buf_le = *((u16 *)data); cpu_to_le16s(&buf_le); } urb = usb_alloc_urb(0, GFP_ATOMIC); if (urb == NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) netdev_err(dev->net, "Error allocating URB in write_cmd_async!"); #else deverr(dev, "Error allocating URB in write_cmd_async!"); #endif return; } if (data) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) if (2 == size) buf = kmemdup(&buf_le, size, GFP_ATOMIC); else buf = kmemdup(data, size, GFP_ATOMIC); #else buf = kmalloc(size, GFP_ATOMIC); #endif if (!buf) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) netdev_err(dev->net, "Error allocating buffer in %s!\n", __func__); #else deverr(dev, "Error allocating buffer in %s!\n", __func__); #endif return; } else { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) if (2 == size) memcpy(buf, &buf_le, size); else memcpy(buf, data, size); #endif } } req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); if (req == NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) netdev_err(dev->net, "Failed to allocate memory for control request"); #else deverr(dev, "Failed to allocate memory for control request"); #endif usb_free_urb(urb); return; } req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; req->bRequest = cmd; req->wValue = cpu_to_le16(value); req->wIndex = cpu_to_le16(index); req->wLength = cpu_to_le16(size); usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (void *)req, buf, size, ax88179_async_cmd_callback, req); status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) netdev_err(dev->net, "Error submitting the control message: status=%d", status); #else deverr(dev, "Error submitting the control message: status=%d", status); #endif kfree(req); usb_free_urb(urb); } }
static void ipc_bridge_int_cb(struct urb *urb) { struct ipc_bridge *dev = urb->context; struct usb_cdc_notification *ctl; int status; unsigned long flags; if (urb->dev->state == USB_STATE_NOTATTACHED) return; spin_lock_irqsave(&dev->lock, flags); dev->rx_state = RX_IDLE; spin_unlock_irqrestore(&dev->lock, flags); switch (urb->status) { case 0: case -ENOENT: break; case -ESHUTDOWN: case -ECONNRESET: case -EPROTO: case -EPIPE: return; case -EOVERFLOW: default: ipc_bridge_submit_inturb(dev, GFP_ATOMIC); return; } if (!urb->actual_length) return; ctl = urb->transfer_buffer; switch (ctl->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: spin_lock_irqsave(&dev->lock, flags); dev->rx_state = RX_BUSY; spin_unlock_irqrestore(&dev->lock, flags); usb_fill_control_urb(dev->readurb, dev->udev, usb_rcvctrlpipe(dev->udev, 0), (unsigned char *)dev->in_ctlreq, dev->readbuf, IPC_BRIDGE_MAX_READ_SZ, ipc_bridge_read_cb, dev); status = usb_submit_urb(dev->readurb, GFP_ATOMIC); if (status) { dev_err(&dev->intf->dev, "read urb submit err %d\n", status); goto resubmit_int_urb; } dev->get_encap_resp++; /* Tell runtime pm core that we are busy */ usb_autopm_get_interface_no_resume(dev->intf); return; default: dev_err(&dev->intf->dev, "unknown data on int ep\n"); } resubmit_int_urb: ipc_bridge_submit_inturb(dev, GFP_ATOMIC); }
static ssize_t wdm_write (struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { u8 *buf; int rv = -EMSGSIZE, r, we; struct wdm_device *desc = file->private_data; struct usb_ctrlrequest *req; if (count > desc->wMaxCommand) count = desc->wMaxCommand; spin_lock_irq(&desc->iuspin); we = desc->werr; desc->werr = 0; spin_unlock_irq(&desc->iuspin); if (we < 0) return -EIO; r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ rv = -ERESTARTSYS; if (r) goto outnl; r = usb_autopm_get_interface(desc->intf); if (r < 0) goto outnp; if (!(file->f_flags & O_NONBLOCK)) r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); else if (test_bit(WDM_IN_USE, &desc->flags)) r = -EAGAIN; if (r < 0) goto out; if (test_bit(WDM_DISCONNECTING, &desc->flags)) { rv = -ENODEV; goto out; } desc->outbuf = buf = kmalloc(count, GFP_KERNEL); if (!buf) { rv = -ENOMEM; goto out; } r = copy_from_user(buf, buffer, count); if (r > 0) { kfree(buf); rv = -EFAULT; goto out; } req = desc->orq; usb_fill_control_urb( desc->command, interface_to_usbdev(desc->intf), /* using common endpoint 0 */ usb_sndctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)req, buf, count, wdm_out_callback, desc ); req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; req->wValue = 0; req->wIndex = desc->inum; req->wLength = cpu_to_le16(count); set_bit(WDM_IN_USE, &desc->flags); rv = usb_submit_urb(desc->command, GFP_KERNEL); if (rv < 0) { kfree(buf); clear_bit(WDM_IN_USE, &desc->flags); dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); } else { dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", req->wIndex); } out: usb_autopm_put_interface(desc->intf); outnp: mutex_unlock(&desc->wlock); outnl: return rv < 0 ? rv : count; }
static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { struct opticon_private *priv = usb_get_serial_data(port->serial); struct usb_serial *serial = port->serial; struct urb *urb; unsigned char *buffer; unsigned long flags; int status; struct usb_ctrlrequest *dr; dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); if (priv->outstanding_urbs > URB_UPPER_LIMIT) { spin_unlock_irqrestore(&priv->lock, flags); dbg("%s - write limit hit", __func__); return 0; } priv->outstanding_urbs++; spin_unlock_irqrestore(&priv->lock, flags); buffer = kmalloc(count, GFP_ATOMIC); if (!buffer) { dev_err(&port->dev, "out of memory\n"); count = -ENOMEM; goto error_no_buffer; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { dev_err(&port->dev, "no more free urbs\n"); count = -ENOMEM; goto error_no_urb; } memcpy(buffer, buf, count); usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); /* The conncected devices do not have a bulk write endpoint, * to transmit data to de barcode device the control endpoint is used */ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); if (!dr) { dev_err(&port->dev, "out of memory\n"); count = -ENOMEM; goto error_no_dr; } dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; dr->bRequest = 0x01; dr->wValue = 0; dr->wIndex = 0; dr->wLength = cpu_to_le16(count); usb_fill_control_urb(urb, serial->dev, usb_sndctrlpipe(serial->dev, 0), (unsigned char *)dr, buffer, count, opticon_write_control_callback, priv); /* send it down the pipe */ status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - usb_submit_urb(write endpoint) failed status = %d\n", __func__, status); count = status; goto error; } /* we are done with this urb, so let the host driver * really free it when it is finished with it */ usb_free_urb(urb); return count; error: kfree(dr); error_no_dr: usb_free_urb(urb); error_no_urb: kfree(buffer); error_no_buffer: spin_lock_irqsave(&priv->lock, flags); --priv->outstanding_urbs; spin_unlock_irqrestore(&priv->lock, flags); return count; }
/* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */ static void powermate_sync_state(struct powermate_device *pm) { if (pm->requires_update == 0) return; /* no updates are required */ if (pm->config->status == -EINPROGRESS) return; /* an update is already in progress; it'll issue this update when it completes */ if (pm->requires_update & UPDATE_PULSE_ASLEEP){ pm->configcr->wValue = cpu_to_le16( SET_PULSE_ASLEEP ); pm->configcr->wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 ); pm->requires_update &= ~UPDATE_PULSE_ASLEEP; }else if (pm->requires_update & UPDATE_PULSE_AWAKE){ pm->configcr->wValue = cpu_to_le16( SET_PULSE_AWAKE ); pm->configcr->wIndex = cpu_to_le16( pm->pulse_awake ? 1 : 0 ); pm->requires_update &= ~UPDATE_PULSE_AWAKE; }else if (pm->requires_update & UPDATE_PULSE_MODE){ int op, arg; /* the powermate takes an operation and an argument for its pulse algorithm. the operation can be: 0: divide the speed 1: pulse at normal speed 2: multiply the speed the argument only has an effect for operations 0 and 2, and ranges between 1 (least effect) to 255 (maximum effect). thus, several states are equivalent and are coalesced into one state. we map this onto a range from 0 to 510, with: 0 -- 254 -- use divide (0 = slowest) 255 -- use normal speed 256 -- 510 -- use multiple (510 = fastest). Only values of 'arg' quite close to 255 are particularly useful/spectacular. */ if (pm->pulse_speed < 255) { op = 0; // divide arg = 255 - pm->pulse_speed; } else if (pm->pulse_speed > 255) { op = 2; // multiply arg = pm->pulse_speed - 255; } else { op = 1; // normal speed arg = 0; // can be any value } pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE ); pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op ); pm->requires_update &= ~UPDATE_PULSE_MODE; } else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) { pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS ); pm->configcr->wIndex = cpu_to_le16( pm->static_brightness ); pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS; } else { printk(KERN_ERR "powermate: unknown update required"); pm->requires_update = 0; /* fudge the bug */ return; } /* printk("powermate: %04x %04x\n", pm->configcr->wValue, pm->configcr->wIndex); */ pm->configcr->bRequestType = 0x41; /* vendor request */ pm->configcr->bRequest = 0x01; pm->configcr->wLength = 0; usb_fill_control_urb(pm->config, pm->udev, usb_sndctrlpipe(pm->udev, 0), (void *) pm->configcr, NULL, 0, powermate_config_complete, pm); pm->config->setup_dma = pm->configcr_dma; pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP; if (usb_submit_urb(pm->config, GFP_ATOMIC)) printk(KERN_ERR "powermate: usb_submit_urb(config) failed"); }
int ctrl_bridge_write(unsigned int id, char *data, size_t size) { int result; struct urb *writeurb; struct usb_ctrlrequest *out_ctlreq; struct usb_device *udev; struct ctrl_bridge *dev; if (id >= MAX_BRIDGE_DEVICES) { result = -EINVAL; goto free_data; } dev = __dev[id]; if (!dev) { result = -ENODEV; goto free_data; } /* wait till, LPA wake complete */ if (pm_dev_wait_lpa_wake() < 0) return -EAGAIN; udev = interface_to_usbdev(dev->intf); dev_dbg(&udev->dev, "%s:[id]:%u: write (%d bytes)\n", __func__, id, size); writeurb = usb_alloc_urb(0, GFP_ATOMIC); if (!writeurb) { dev_err(&udev->dev, "%s: error allocating read urb\n", __func__); result = -ENOMEM; goto free_data; } out_ctlreq = kmalloc(sizeof(*out_ctlreq), GFP_ATOMIC); if (!out_ctlreq) { dev_err(&udev->dev, "%s: error allocating setup packet buffer\n", __func__); result = -ENOMEM; goto free_urb; } /* CDC Send Encapsulated Request packet */ out_ctlreq->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); if (!data && !size) { out_ctlreq->bRequest = USB_CDC_REQ_SET_CONTROL_LINE_STATE; out_ctlreq->wValue = dev->cbits_tomdm; dev->set_ctrl_line_sts++; } else { out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; out_ctlreq->wValue = 0; dev->snd_encap_cmd++; } out_ctlreq->wIndex = dev->intf->cur_altsetting->desc.bInterfaceNumber; out_ctlreq->wLength = cpu_to_le16(size); usb_fill_control_urb(writeurb, udev, usb_sndctrlpipe(udev, 0), (unsigned char *)out_ctlreq, (void *)data, size, ctrl_write_callback, dev); result = usb_autopm_get_interface_async(dev->intf); if (result < 0) { dev_err(&udev->dev, "%s: unable to resume interface: %d\n", __func__, result); /* * Revisit: if (result == -EPERM) * bridge_suspend(dev->intf, PMSG_SUSPEND); */ goto free_ctrlreq; } if (test_bit(SUSPENDED, &dev->flags)) { usb_anchor_urb(writeurb, &dev->tx_deferred); goto deferred; } usb_anchor_urb(writeurb, &dev->tx_submitted); result = usb_submit_urb(writeurb, GFP_ATOMIC); if (result < 0) { dev_err(&udev->dev, "%s: submit URB error %d\n", __func__, result); usb_autopm_put_interface_async(dev->intf); goto unanchor_urb; } deferred: return size; unanchor_urb: usb_unanchor_urb(writeurb); free_ctrlreq: kfree(out_ctlreq); free_urb: usb_free_urb(writeurb); free_data: kfree(data); return result; }
static void notification_available_cb(struct urb *urb) { int status; struct usb_cdc_notification *ctrl; struct usb_device *udev; struct ctrl_bridge *dev = urb->context; struct bridge *brdg = dev->brdg; unsigned int ctrl_bits; unsigned char *data; unsigned int iface_num; /* if this intf is already disconnected, this urb free-ed before * calling from qh_completions. just return and do nothing */ if (!dev->intf) return; udev = interface_to_usbdev(dev->intf); iface_num = dev->intf->cur_altsetting->desc.bInterfaceNumber; switch (urb->status) { case 0: pr_info("[NACB:%d]<\n", iface_num); /*success*/ break; case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: case -EPROTO: /* unplug */ return; case -EPIPE: dev_err(&udev->dev, "%s: stall on int endpoint\n", __func__); /* TBD : halt to be cleared in work */ case -EOVERFLOW: default: pr_debug_ratelimited("%s: non zero urb status = %d\n", __func__, urb->status); goto resubmit_int_urb; } ctrl = (struct usb_cdc_notification *)urb->transfer_buffer; data = (unsigned char *)(ctrl + 1); switch (ctrl->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: dev->resp_avail++; usb_fill_control_urb(dev->readurb, udev, usb_rcvctrlpipe(udev, 0), (unsigned char *)dev->in_ctlreq, dev->readbuf, DEFAULT_READ_URB_LENGTH, resp_avail_cb, dev); status = usb_submit_urb(dev->readurb, GFP_ATOMIC); if (status) { dev_err(&udev->dev, "%s: Error submitting Read URB %d\n", __func__, status); goto resubmit_int_urb; } else pr_info("[NRA:%d]>\n", iface_num); return; case USB_CDC_NOTIFY_NETWORK_CONNECTION: dev_dbg(&udev->dev, "%s network\n", ctrl->wValue ? "connected to" : "disconnected from"); break; case USB_CDC_NOTIFY_SERIAL_STATE: dev->notify_ser_state++; ctrl_bits = get_unaligned_le16(data); dev_dbg(&udev->dev, "serial state: %d\n", ctrl_bits); dev->cbits_tohost = ctrl_bits; if (brdg && brdg->ops.send_cbits) brdg->ops.send_cbits(brdg->ctx, ctrl_bits); #ifdef CONFIG_MDM_HSIC_PM pr_info("%s: set lpa handling to false\n", __func__); lpa_handling = false; #endif break; default: dev_err(&udev->dev, "%s: unknown notification %d received:" "index %d len %d data0 %d data1 %d", __func__, ctrl->bNotificationType, ctrl->wIndex, ctrl->wLength, data[0], data[1]); } resubmit_int_urb: status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&udev->dev, "%s: Error re-submitting Int URB %d\n", __func__, status); } else pr_info("[CHKRA:%d]>\n", iface_num); }
static int igorplugusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev; struct usb_host_interface *idesc; struct usb_endpoint_descriptor *ep; struct igorplugusb *ir; struct rc_dev *rc; int ret = -ENOMEM; udev = interface_to_usbdev(intf); idesc = intf->cur_altsetting; if (idesc->desc.bNumEndpoints != 1) { dev_err(&intf->dev, "incorrect number of endpoints"); return -ENODEV; } ep = &idesc->endpoint[0].desc; if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_control(ep)) { dev_err(&intf->dev, "endpoint incorrect"); return -ENODEV; } ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL); if (!ir) return -ENOMEM; ir->dev = &intf->dev; setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir); ir->request.bRequest = GET_INFRACODE; ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN; ir->request.wLength = cpu_to_le16(sizeof(ir->buf_in)); ir->urb = usb_alloc_urb(0, GFP_KERNEL); if (!ir->urb) goto fail; usb_fill_control_urb(ir->urb, udev, usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request, ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir); usb_make_path(udev, ir->phys, sizeof(ir->phys)); rc = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rc) goto fail; rc->device_name = DRIVER_DESC; rc->input_phys = ir->phys; usb_to_input_id(udev, &rc->input_id); rc->dev.parent = &intf->dev; /* * This device can only store 36 pulses + spaces, which is not enough * for the NEC protocol and many others. */ rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER & ~(RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC6_6A_20 | RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_SANYO); rc->priv = ir; rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_HAUPPAUGE; rc->timeout = MS_TO_NS(100); rc->rx_resolution = 85333; ir->rc = rc; ret = rc_register_device(rc); if (ret) { dev_err(&intf->dev, "failed to register rc device: %d", ret); goto fail; } usb_set_intfdata(intf, ir); igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY); return 0; fail: rc_free_device(ir->rc); usb_free_urb(ir->urb); del_timer(&ir->timer); return ret; }
static int rmnet_usb_ctrl_write(struct rmnet_ctrl_dev *dev, char *buf, size_t size) { int result; struct urb *sndurb; struct usb_ctrlrequest *out_ctlreq; struct usb_device *udev; if (!is_dev_connected(dev)) return -ENETRESET; udev = interface_to_usbdev(dev->intf); usb_mark_last_busy(udev); sndurb = usb_alloc_urb(0, GFP_KERNEL); if (!sndurb) { dev_err(dev->devicep, "Error allocating read urb\n"); return -ENOMEM; } out_ctlreq = kmalloc(sizeof(*out_ctlreq), GFP_KERNEL); if (!out_ctlreq) { kfree(buf); usb_free_urb(sndurb); dev_err(dev->devicep, "Error allocating setup packet buffer\n"); return -ENOMEM; } /* CDC Send Encapsulated Request packet */ out_ctlreq->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; out_ctlreq->wValue = 0; out_ctlreq->wIndex = dev->intf->cur_altsetting->desc.bInterfaceNumber; out_ctlreq->wLength = cpu_to_le16(size); usb_fill_control_urb(sndurb, udev, usb_sndctrlpipe(udev, 0), (unsigned char *)out_ctlreq, (void *)buf, size, ctrl_write_callback, dev); result = usb_autopm_get_interface(dev->intf); if (result < 0) { dev_err(dev->devicep, "%s: Unable to resume interface: %d\n", __func__, result); /* * Revisit: if (result == -EPERM) * rmnet_usb_suspend(dev->intf, PMSG_SUSPEND); */ kfree(buf); usb_free_urb(sndurb); kfree(out_ctlreq); return result; } usb_anchor_urb(sndurb, &dev->tx_submitted); dev->snd_encap_cmd_cnt++; usb_mark_last_busy(udev); result = usb_submit_urb(sndurb, GFP_KERNEL); if (result < 0) { dev_err(dev->devicep, "%s: Submit URB error %d\n", __func__, result); dev->snd_encap_cmd_cnt--; usb_autopm_put_interface(dev->intf); usb_unanchor_urb(sndurb); kfree(buf); usb_free_urb(sndurb); kfree(out_ctlreq); return result; } return size; }
static void notification_available_cb(struct urb *urb) { int status; struct usb_cdc_notification *ctrl; struct usb_device *udev; struct rmnet_ctrl_dev *dev = urb->context; unsigned int iface_num; if (!dev->intf) return; udev = interface_to_usbdev(dev->intf); iface_num = dev->intf->cur_altsetting->desc.bInterfaceNumber; switch (urb->status) { case 0: pr_info("[NACB:%d]<\n", iface_num); /*success*/ break; /*do not resubmit*/ case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: case -EPROTO: return; case -EPIPE: pr_err_ratelimited("%s: Stall on int endpoint\n", __func__); /* TBD : halt to be cleared in work */ return; /*resubmit*/ case -EOVERFLOW: pr_err_ratelimited("%s: Babble error happened\n", __func__); default: pr_debug_ratelimited("%s: Non zero urb status = %d\n", __func__, urb->status); goto resubmit_int_urb; } ctrl = urb->transfer_buffer; switch (ctrl->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: dev->resp_avail_cnt++; usb_fill_control_urb(dev->rcvurb, udev, usb_rcvctrlpipe(udev, 0), (unsigned char *)dev->in_ctlreq, dev->rcvbuf, DEFAULT_READ_URB_LENGTH, resp_avail_cb, dev); usb_mark_last_busy(udev); status = usb_submit_urb(dev->rcvurb, GFP_ATOMIC); if (status) { dev_err(dev->devicep, "%s: Error submitting Read URB %d\n", __func__, status); goto resubmit_int_urb; } else pr_info("[NRA:%d]>\n", iface_num); if (!dev->resp_available) { dev->resp_available = true; wake_up(&dev->open_wait_queue); } return; default: dev_err(dev->devicep, "%s:Command not implemented\n", __func__); } resubmit_int_urb: usb_mark_last_busy(udev); status = usb_submit_urb(urb, GFP_ATOMIC); if (status) dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n", __func__, status); return; }
static void notification_available_cb(struct urb *urb) { int status; struct usb_cdc_notification *ctrl; struct ctrl_bridge *dev = urb->context; struct bridge *brdg = dev->brdg; unsigned int ctrl_bits; unsigned char *data; unsigned long flags; /*usb device disconnect*/ if (urb->dev->state == USB_STATE_NOTATTACHED) return; spin_lock_irqsave(&dev->lock, flags); dev->rx_state = RX_IDLE; spin_unlock_irqrestore(&dev->lock, flags); switch (urb->status) { case 0: /*success*/ break; case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: case -EPROTO: /* unplug */ return; case -EPIPE: dev_err(&dev->intf->dev, "%s: stall on int endpoint\n", __func__); /* TBD : halt to be cleared in work */ case -EOVERFLOW: default: pr_debug_ratelimited("%s: non zero urb status = %d\n", __func__, urb->status); goto resubmit_int_urb; } ctrl = (struct usb_cdc_notification *)urb->transfer_buffer; data = (unsigned char *)(ctrl + 1); switch (ctrl->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: spin_lock_irqsave(&dev->lock, flags); dev->rx_state = RX_BUSY; spin_unlock_irqrestore(&dev->lock, flags); dev->resp_avail++; usb_autopm_get_interface_no_resume(dev->intf); usb_fill_control_urb(dev->readurb, dev->udev, usb_rcvctrlpipe(dev->udev, 0), (unsigned char *)dev->in_ctlreq, dev->readbuf, DEFAULT_READ_URB_LENGTH, resp_avail_cb, dev); status = usb_submit_urb(dev->readurb, GFP_ATOMIC); if (status) { dev_err(&dev->intf->dev, "%s: Error submitting Read URB %d\n", __func__, status); usb_autopm_put_interface_async(dev->intf); goto resubmit_int_urb; } return; case USB_CDC_NOTIFY_NETWORK_CONNECTION: dev_dbg(&dev->intf->dev, "%s network\n", ctrl->wValue ? "connected to" : "disconnected from"); break; case USB_CDC_NOTIFY_SERIAL_STATE: dev->notify_ser_state++; ctrl_bits = get_unaligned_le16(data); dev_dbg(&dev->intf->dev, "serial state: %d\n", ctrl_bits); dev->cbits_tohost = ctrl_bits; if (brdg && brdg->ops.send_cbits) brdg->ops.send_cbits(brdg->ctx, ctrl_bits); break; default: dev_err(&dev->intf->dev, "%s: unknown notification %d received:" "index %d len %d data0 %d data1 %d", __func__, ctrl->bNotificationType, ctrl->wIndex, ctrl->wLength, data[0], data[1]); } resubmit_int_urb: ctrl_bridge_start_read(dev, GFP_ATOMIC); }