/* Send raw message in pieces of wMaxPacketSize bytes. */ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, int size) { int i, done = 0; #if DO_DUMP_URB_SEND line6_write_hexdump(line6, 'S', buffer, size); #endif for (i = 0; i < size; i += line6->max_packet_size) { int partial; const char *frag_buf = buffer + i; int frag_size = min(line6->max_packet_size, size - i); int retval; retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, line6->ep_control_write), (char *)frag_buf, frag_size, &partial, LINE6_TIMEOUT * HZ); if (retval) { dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval); break; } done += frag_size; } return done; }
/* Transmit Line6 control parameter. */ int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value) { int retval; unsigned char *buffer; int partial; buffer = kmalloc(3, GFP_KERNEL); if (!buffer) { dev_err(line6->ifcdev, "out of memory\n"); return -ENOMEM; } buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST; buffer[1] = param; buffer[2] = value; retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, line6->ep_control_write), buffer, 3, &partial, LINE6_TIMEOUT * HZ); if (retval) dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval); kfree(buffer); return retval; }
/* Asynchronously send part of a raw message. */ static int line6_send_raw_message_async_part(struct message *msg, struct urb *urb) { int retval; struct usb_line6 *line6 = msg->line6; int done = msg->done; int bytes = min(msg->size - done, line6->max_packet_size); usb_fill_int_urb(urb, line6->usbdev, usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w), (char *)msg->buffer + done, bytes, line6_async_request_sent, msg, line6->interval); msg->done += bytes; retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval < 0) { dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n", __func__, retval); usb_free_urb(urb); kfree(msg); return retval; } return 0; }
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { struct usb_endpoint_descriptor *ep_irq_out; int error = -ENOMEM; if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) return 0; xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->odata_dma); if (!xpad->odata) goto fail1; mutex_init(&xpad->odata_mutex); xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_out) goto fail2; ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; usb_fill_int_urb(xpad->irq_out, xpad->udev, usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), xpad->odata, XPAD_PKT_LEN, xpad_irq_out, xpad, ep_irq_out->bInterval); xpad->irq_out->transfer_dma = xpad->odata_dma; xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; return 0; fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); fail1: return error; }
static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port) { int ret; int actual_len; u8 *buffer_cmd = NULL; if (!metrousb_is_unidirectional_mode(port)) return 0; buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL); if (!buffer_cmd) return -ENOMEM; *buffer_cmd = cmd; ret = usb_interrupt_msg(port->serial->dev, usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress), buffer_cmd, sizeof(cmd), &actual_len, USB_CTRL_SET_TIMEOUT); kfree(buffer_cmd); if (ret < 0) return ret; else if (actual_len != sizeof(cmd)) return -EIO; return 0; }
static int ksdazzle_submit_tx_fragment(struct ksdazzle_cb *kingsun) { unsigned int wraplen; int ret; /* We can send at most 7 bytes of payload at a time */ wraplen = 7; if (wraplen > kingsun->tx_buf_clear_used) wraplen = kingsun->tx_buf_clear_used; /* Prepare payload prefix with used length */ memset(kingsun->tx_payload, 0, 8); kingsun->tx_payload[0] = (unsigned char)0xf8 + wraplen; memcpy(kingsun->tx_payload + 1, kingsun->tx_buf_clear, wraplen); usb_fill_int_urb(kingsun->tx_urb, kingsun->usbdev, usb_sndintpipe(kingsun->usbdev, kingsun->ep_out), kingsun->tx_payload, 8, ksdazzle_send_irq, kingsun, 1); kingsun->tx_urb->status = 0; ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC); /* Remember how much data was sent, in order to update at callback */ kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0; return ret; }
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { struct usb_endpoint_descriptor *ep_irq_out; int ep_irq_out_idx; if (xpad->xtype == XTYPE_UNKNOWN) return 0; xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->odata_dma); if (!xpad->odata) { return -ENOMEM; } mutex_init(&xpad->odata_mutex); xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_out) { usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); return -ENOMEM; } /* Xbox One controller has in/out endpoints swapped. */ ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1; ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc; usb_fill_int_urb(xpad->irq_out, xpad->udev, usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), xpad->odata, XPAD_PKT_LEN, xpad_irq_out, xpad, ep_irq_out->bInterval); xpad->irq_out->transfer_dma = xpad->odata_dma; xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; return 0; }
/* Send channel number (i.e., switch to a different sound). */ int line6_send_program(struct usb_line6 *line6, u8 value) { int retval; unsigned char *buffer; int partial; buffer = kmalloc(2, GFP_KERNEL); if (!buffer) return -ENOMEM; buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST; buffer[1] = value; retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, line6->ep_control_write), buffer, 2, &partial, LINE6_TIMEOUT * HZ); if (retval) dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval); kfree(buffer); return retval; }
/* Send raw message in pieces of wMaxPacketSize bytes. */ static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, int size) { int i, done = 0; for (i = 0; i < size; i += line6->max_packet_size) { int partial; const char *frag_buf = buffer + i; int frag_size = min(line6->max_packet_size, size - i); int retval; retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w), (char *)frag_buf, frag_size, &partial, LINE6_TIMEOUT * HZ); if (retval) { dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval); break; } done += frag_size; } return done; }
static int mwifiex_usb_construct_send_urb(struct mwifiex_adapter *adapter, struct usb_tx_data_port *port, u8 ep, struct urb_context *context, struct sk_buff *skb_send) { struct usb_card_rec *card = adapter->card; int ret = -EINPROGRESS; struct urb *tx_urb; context->adapter = adapter; context->ep = ep; context->skb = skb_send; tx_urb = context->urb; if (ep == card->tx_cmd_ep && card->tx_cmd_ep_type == USB_ENDPOINT_XFER_INT) usb_fill_int_urb(tx_urb, card->udev, usb_sndintpipe(card->udev, ep), skb_send->data, skb_send->len, mwifiex_usb_tx_complete, (void *)context, card->tx_cmd_interval); else usb_fill_bulk_urb(tx_urb, card->udev, usb_sndbulkpipe(card->udev, ep), skb_send->data, skb_send->len, mwifiex_usb_tx_complete, (void *)context); tx_urb->transfer_flags |= URB_ZERO_PACKET; if (ep == card->tx_cmd_ep) atomic_inc(&card->tx_cmd_urb_pending); else atomic_inc(&port->tx_data_urb_pending); if (ep != card->tx_cmd_ep && atomic_read(&port->tx_data_urb_pending) == MWIFIEX_TX_DATA_URB) { port->block_status = true; adapter->data_sent = mwifiex_usb_data_sent(adapter); ret = -ENOSR; } if (usb_submit_urb(tx_urb, GFP_ATOMIC)) { mwifiex_dbg(adapter, ERROR, "%s: usb_submit_urb failed\n", __func__); if (ep == card->tx_cmd_ep) { atomic_dec(&card->tx_cmd_urb_pending); } else { atomic_dec(&port->tx_data_urb_pending); port->block_status = false; adapter->data_sent = false; if (port->tx_data_ix) port->tx_data_ix--; else port->tx_data_ix = MWIFIEX_TX_DATA_URB; } ret = -1; } return ret; }
/* Send channel number (i.e., switch to a different sound). */ int line6_send_program(struct usb_line6 *line6, int value) { int retval; unsigned char *buffer; unsigned int partial; buffer = kmalloc(2, GFP_KERNEL); if (!buffer) { dev_err(line6->ifcdev, "out of memory\n"); return -ENOMEM; } buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST; buffer[1] = value; #if DO_DUMP_URB_SEND line6_write_hexdump(line6, 'S', buffer, 2); #endif retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, line6->ep_control_write), buffer, 2, &partial, LINE6_TIMEOUT * HZ); if (retval) dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval); kfree(buffer); return retval; }
/* Asynchronously send part of a raw message. */ static int line6_send_raw_message_async_part(struct message *msg, struct urb *urb) { int retval; struct usb_line6 *line6 = msg->line6; int done = msg->done; int bytes = min(msg->size - done, line6->max_packet_size); usb_fill_int_urb(urb, line6->usbdev, usb_sndintpipe(line6->usbdev, line6->ep_control_write), (char *)msg->buffer + done, bytes, line6_async_request_sent, msg, line6->interval); #if DO_DUMP_URB_SEND line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes); #endif msg->done += bytes; retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval < 0) { dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n", __func__, retval); usb_free_urb(urb); kfree(msg); return -EINVAL; } return 0; }
T_EpOut selectBestEpOut(WORD *epOutSize, WORD requestedSize) { UINT ep2_size = 0; UINT ep6_size = 0; T_EpOut bestEpOut; #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)) ep2_size = ((unicorn_usb_dev.usb_dev->epmaxpacketout[EP_OBC_ISO_OUT]) / 2); //bytes to Words ep6_size = ((unicorn_usb_dev.usb_dev->epmaxpacketout[EP_OBC_INT_OUT]) / 2); //bytes to Words #else ep2_size = ((usb_maxpacket(unicorn_usb_dev.usb_dev,usb_sndisocpipe(unicorn_usb_dev.usb_dev, EP_OBC_ISO_OUT),1)) / 2); //bytes to Words ep6_size = ((usb_maxpacket(unicorn_usb_dev.usb_dev,usb_sndintpipe(unicorn_usb_dev.usb_dev,EP_OBC_INT_OUT),1)) / 2); //bytes to Words #endif if(requestedSize <= ep6_size) { *epOutSize = ep6_size; bestEpOut = EP6; } else { *epOutSize = ep2_size; bestEpOut = EP2; } return bestEpOut; }
int InterruptOut(PMINI_ADAPTER Adapter, PUCHAR pData) { int status = STATUS_SUCCESS; int lenwritten = 0; PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter; if( FALSE == Adapter->bShutStatus && FALSE == Adapter->IdleMode && FALSE == Adapter->bPreparingForLowPowerMode && FALSE == Adapter->device_removed) { status = usb_interrupt_msg (psInterfaceAdapter->udev, usb_sndintpipe(psInterfaceAdapter->udev, psInterfaceAdapter->sIntrOut.int_out_endpointAddr), pData, 8, &lenwritten, 5000); } if(status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending clear pattern down fails with status:%d..\n",status); return status; } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten); return STATUS_SUCCESS; } } /* InterruptOut() */
static int iforce_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface; struct usb_endpoint_descriptor *epirq, *epout; struct iforce *iforce; int err = -ENOMEM; interface = intf->cur_altsetting; epirq = &interface->endpoint[0].desc; epout = &interface->endpoint[1].desc; if (!(iforce = kzalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) goto fail; if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL))) goto fail; if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL))) goto fail; if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL))) goto fail; iforce->bus = IFORCE_USB; iforce->usbdev = dev; iforce->cr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE; iforce->cr.wIndex = 0; iforce->cr.wLength = cpu_to_le16(16); usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress), iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval); usb_fill_int_urb(iforce->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress), iforce + 1, 32, iforce_usb_out, iforce, epout->bInterval); usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0), (void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce); err = iforce_init_device(iforce); if (err) goto fail; usb_set_intfdata(intf, iforce); return 0; fail: if (iforce) { usb_free_urb(iforce->irq); usb_free_urb(iforce->out); usb_free_urb(iforce->ctrl); kfree(iforce); } return err; }
unsigned int SysUsbIntPipe(pUsb_device pUdev, unsigned char addr, unsigned char dir) { struct usb_device *udev = (struct usb_device *) pUdev; if( USB_DIR_IN==dir ) return usb_rcvintpipe(udev, addr); return usb_sndintpipe(udev, addr); }
static int get_pipe(struct stub_device *sdev, int epnum, int dir) { struct usb_device *udev = interface_to_usbdev(sdev->interface); struct usb_host_endpoint *ep; struct usb_endpoint_descriptor *epd = NULL; ep = get_ep_from_epnum(udev, epnum); if (!ep) { uerr("no such endpoint?, %d", epnum); BUG(); } epd = &ep->desc; #if 0 /* epnum 0 is always control */ if (epnum == 0) { if (dir == USBIP_DIR_OUT) return usb_sndctrlpipe(udev, 0); else return usb_rcvctrlpipe(udev, 0); } #endif if (usb_endpoint_xfer_control(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndctrlpipe(udev, epnum); else return usb_rcvctrlpipe(udev, epnum); } if (usb_endpoint_xfer_bulk(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndbulkpipe(udev, epnum); else return usb_rcvbulkpipe(udev, epnum); } if (usb_endpoint_xfer_int(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndintpipe(udev, epnum); else return usb_rcvintpipe(udev, epnum); } if (usb_endpoint_xfer_isoc(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndisocpipe(udev, epnum); else return usb_rcvisocpipe(udev, epnum); } /* NOT REACHED */ uerr("get pipe, epnum %d\n", epnum); return 0; }
static ssize_t exemple_write (struct file * file, const char __user * data, size_t length, loff_t * offset) { int o0, o1, o2, o3, o4, o5, o6, o7; char * buffer; int err; buffer = kmalloc(length, GFP_KERNEL); if (buffer == NULL) { return -ENOMEM; } if (copy_from_user(buffer, data, length)) { kfree(buffer); return -EINVAL; } err = (sscanf(buffer, "%d %d %d %d %d %d %d %d", &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7) != 8); kfree(buffer); if (err) return -EINVAL; if (mutex_lock_interruptible(& exemple_mtx)) return -ERESTARTSYS; while(exemple_out_busy) if (wait_event_interruptible_timeout(exemple_out_wq, ! exemple_out_busy, HZ) <= 0) { mutex_unlock(& exemple_mtx); return -ERESTARTSYS; } exemple_out_busy = 1; exemple_out_buffer[0] = o0 & 0xFF; exemple_out_buffer[1] = o1 & 0xFF; exemple_out_buffer[2] = o2 & 0xFF; exemple_out_buffer[3] = o3 & 0xFF; exemple_out_buffer[4] = o4 & 0xFF; exemple_out_buffer[5] = o5 & 0xFF; exemple_out_buffer[6] = o6 & 0xFF; exemple_out_buffer[7] = o7 & 0xFF; usb_fill_int_urb(exemple_out_urb, exemple_usb_device, usb_sndintpipe(exemple_usb_device, exemple_out_endpoint->bEndpointAddress), exemple_out_buffer, EXEMPLE_OUT_BUFFER_SIZE, exemple_write_callback, NULL, exemple_out_endpoint->bInterval); err = usb_submit_urb(exemple_out_urb, GFP_KERNEL); mutex_unlock(& exemple_mtx); if (err == 0) return length; return err; }
/* Don't start the URB */ static void auerisdn_bintbo_setup(struct auerisdn *ip, unsigned int len) { ip->intbo_state = INTBOS_IDLE; FILL_INT_URB(ip->intbo_urbp, ip->usbdev, usb_sndintpipe(ip->usbdev, ip->intbo_endp), ip->intbo_bufp, len, auerisdn_bintbo_complete, ip, ip->outInterval); ip->intbo_urbp->transfer_flags |= USB_ASYNC_UNLINK; ip->intbo_urbp->status = 0; }
static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb, u8 *buffer, void *context, void(*handler)(struct urb *urb)) { usb_init_urb(urb); urb->transfer_buffer = buffer; urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP); urb->complete = handler; urb->context = context; urb->interval = 1; urb->dev = rt->chip->dev; }
static ssize_t write_exemple (struct file * file, const char __user * data, size_t length, loff_t * offset) { int o0, o1, o2, o3, o4, o5, o6, o7; char * buffer; int err; buffer = kmalloc(length, GFP_KERNEL); if (buffer == NULL) { return -ENOMEM; } if (copy_from_user(buffer, data, length)) { kfree(buffer); return -EINVAL; } err = (sscanf(buffer, "%d %d %d %d %d %d %d %d", &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7) != 8); kfree(buffer); if (err) return -EINVAL; /* * Attendre que la requete precedente soit terminee. */ while(intr_out_busy_exemple) if (wait_event_interruptible(intr_out_queue_exemple, ! intr_out_busy_exemple)) return -ERESTARTSYS; intr_out_busy_exemple = 1; intr_out_buf_exemple[0] = o0 & 0xFF; intr_out_buf_exemple[1] = o1 & 0xFF; intr_out_buf_exemple[2] = o2 & 0xFF; intr_out_buf_exemple[3] = o3 & 0xFF; intr_out_buf_exemple[4] = o4 & 0xFF; intr_out_buf_exemple[5] = o5 & 0xFF; intr_out_buf_exemple[6] = o6 & 0xFF; intr_out_buf_exemple[7] = o7 & 0xFF; usb_fill_int_urb(intr_out_urb_exemple, usb_device_exemple, usb_sndintpipe(usb_device_exemple, intr_out_end_exemple->bEndpointAddress), intr_out_buf_exemple, INTERRUPT_OUT_SIZE_EXEMPLE, write_callback_exemple, NULL, intr_out_end_exemple->bInterval); err = usb_submit_urb(intr_out_urb_exemple, GFP_KERNEL); if (err == 0) return length; return err; }
static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev) { int ret; int actual_len; ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP), buffer, buffer[1] + 2, &actual_len, HZ); if (ret < 0) return ret; else if (actual_len != buffer[1] + 2) return -EIO; return 0; }
static int bcd2000_init_midi(struct bcd2000 *bcd2k) { int ret; struct snd_rawmidi *rmidi; ret = snd_rawmidi_new(bcd2k->card, bcd2k->card->shortname, 0, 1, /* output */ 1, /* input */ &rmidi); if (ret < 0) return ret; strlcpy(rmidi->name, bcd2k->card->shortname, sizeof(rmidi->name)); rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; rmidi->private_data = bcd2k; rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &bcd2000_midi_output); rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &bcd2000_midi_input); bcd2k->rmidi = rmidi; bcd2k->midi_in_urb = usb_alloc_urb(0, GFP_KERNEL); bcd2k->midi_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!bcd2k->midi_in_urb || !bcd2k->midi_out_urb) { dev_err(&bcd2k->dev->dev, PREFIX "usb_alloc_urb failed\n"); return -ENOMEM; } usb_fill_int_urb(bcd2k->midi_in_urb, bcd2k->dev, usb_rcvintpipe(bcd2k->dev, 0x81), bcd2k->midi_in_buf, BUFSIZE, bcd2000_input_complete, bcd2k, 1); usb_fill_int_urb(bcd2k->midi_out_urb, bcd2k->dev, usb_sndintpipe(bcd2k->dev, 0x1), bcd2k->midi_out_buf, BUFSIZE, bcd2000_output_complete, bcd2k, 1); bcd2000_init_device(bcd2k); return 0; }
/* * Called from net/core when new frame is available. */ static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev) { struct kingsun_cb *kingsun; int wraplen; int ret = 0; if (skb == NULL || netdev == NULL) return -EINVAL; netif_stop_queue(netdev); /* the IRDA wrapping routines don't deal with non linear skb */ SKB_LINEAR_ASSERT(skb); kingsun = netdev_priv(netdev); spin_lock(&kingsun->lock); /* Append data to the end of whatever data remains to be transmitted */ wraplen = async_wrap_skb(skb, kingsun->out_buf, KINGSUN_FIFO_SIZE); /* Calculate how much data can be transmitted in this urb */ usb_fill_int_urb(kingsun->tx_urb, kingsun->usbdev, usb_sndintpipe(kingsun->usbdev, kingsun->ep_out), kingsun->out_buf, wraplen, kingsun_send_irq, kingsun, 1); if ((ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC))) { err("kingsun_hard_xmit: failed tx_urb submit: %d", ret); switch (ret) { case -ENODEV: case -EPIPE: break; default: kingsun->stats.tx_errors++; netif_start_queue(netdev); } } else { kingsun->stats.tx_packets++; kingsun->stats.tx_bytes += skb->len; } dev_kfree_skb(skb); spin_unlock(&kingsun->lock); return ret; }
int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, const bool free_buf) { struct urb *urb; int err = 0; if (!IS_INITIALIZED(ar)) { err = -EPERM; goto err_free; } if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) { err = -EINVAL; goto err_free; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { err = -ENOMEM; goto err_free; } if (ar->usb_ep_cmd_is_bulk) usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev, AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, carl9170_usb_cmd_complete, ar); else usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, carl9170_usb_cmd_complete, ar, 1); if (free_buf) urb->transfer_flags |= URB_FREE_BUFFER; usb_anchor_urb(urb, &ar->tx_cmd); usb_free_urb(urb); return carl9170_usb_submit_cmd_urb(ar); err_free: if (free_buf) kfree(cmd); return err; }
static netdev_tx_t kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev) { struct kingsun_cb *kingsun; int wraplen; int ret = 0; netif_stop_queue(netdev); SKB_LINEAR_ASSERT(skb); kingsun = netdev_priv(netdev); spin_lock(&kingsun->lock); wraplen = async_wrap_skb(skb, kingsun->out_buf, KINGSUN_FIFO_SIZE); usb_fill_int_urb(kingsun->tx_urb, kingsun->usbdev, usb_sndintpipe(kingsun->usbdev, kingsun->ep_out), kingsun->out_buf, wraplen, kingsun_send_irq, kingsun, 1); if ((ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC))) { err("kingsun_hard_xmit: failed tx_urb submit: %d", ret); switch (ret) { case -ENODEV: case -EPIPE: break; default: netdev->stats.tx_errors++; netif_start_queue(netdev); } } else { netdev->stats.tx_packets++; netdev->stats.tx_bytes += skb->len; } dev_kfree_skb(skb); spin_unlock(&kingsun->lock); return NETDEV_TX_OK; }
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) //初始化设备输出 { struct usb_endpoint_descriptor *ep_irq_out; int ep_irq_out_idx; int error; xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->odata_dma); //输出类型的 DMA接口 数据 和 地址 if (!xpad->odata) { error = -ENOMEM; goto fail1; } //初始化互斥锁 用于同步 mutex_init(&xpad->odata_mutex); xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); //初始化 out型 urb if (!xpad->irq_out) { error = -ENOMEM; goto fail2; } /* Xbox One controller has in/out endpoints swapped. */ ep_irq_out_idx = 1; ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc; //函数结构 usb_fill_int_urb(struct urb* urb,struct usb_device * dev,unsigned int pipe,void * transfer_buffer,int buffer_length,usb_complete_t complete,void * context,int interval) //根据 usb设备,usb管道,输出缓冲区的首地址,缓冲区长度,out 型 urb入口函数,手柄设备数据信息,out endpoint口的轮换间隔信息 得到 输出型的urb usb_fill_int_urb(xpad->irq_out, xpad->udev, usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), xpad->odata, XPAD_PKT_LEN, xpad_irq_out, xpad, ep_irq_out->bInterval); xpad->irq_out->transfer_dma = xpad->odata_dma; //分配DMA接口地址 xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; //允许 输出型urb 进行DMA传输 return 0; fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); fail1: return error; }
static void find_usb_pipe(struct baseband_usb *usb) { struct usb_device *usbdev = usb->usb.device; struct usb_interface *intf = usb->usb.interface; unsigned char numendpoint = intf->cur_altsetting->desc.bNumEndpoints; struct usb_host_endpoint *endpoint = intf->cur_altsetting->endpoint; unsigned char n; for (n = 0; n < numendpoint; n++) { if (usb_endpoint_is_isoc_in(&endpoint[n].desc)) { pr_debug("endpoint[%d] isochronous in\n", n); usb->usb.pipe.isoch.in = usb_rcvisocpipe(usbdev, endpoint[n].desc.bEndpointAddress); } else if (usb_endpoint_is_isoc_out(&endpoint[n].desc)) { pr_debug("endpoint[%d] isochronous out\n", n); usb->usb.pipe.isoch.out = usb_sndisocpipe(usbdev, endpoint[n].desc.bEndpointAddress); } else if (usb_endpoint_is_bulk_in(&endpoint[n].desc)) { pr_debug("endpoint[%d] bulk in\n", n); usb->usb.pipe.bulk.in = usb_rcvbulkpipe(usbdev, endpoint[n].desc.bEndpointAddress); } else if (usb_endpoint_is_bulk_out(&endpoint[n].desc)) { pr_debug("endpoint[%d] bulk out\n", n); usb->usb.pipe.bulk.out = usb_sndbulkpipe(usbdev, endpoint[n].desc.bEndpointAddress); } else if (usb_endpoint_is_int_in(&endpoint[n].desc)) { pr_debug("endpoint[%d] interrupt in\n", n); usb->usb.pipe.interrupt.in = usb_rcvintpipe(usbdev, endpoint[n].desc.bEndpointAddress); } else if (usb_endpoint_is_int_out(&endpoint[n].desc)) { pr_debug("endpoint[%d] interrupt out\n", n); usb->usb.pipe.interrupt.out = usb_sndintpipe(usbdev, endpoint[n].desc.bEndpointAddress); } else { pr_debug("endpoint[%d] skipped\n", n); } } }
/* * Send a command to the firmware. */ int otus_send_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd) { if (cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4) { return (EINVAL); } /* * Commands are sent on the CMD endpoint. */ usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, carl9170_usb_cmd_complete, ar, 1); if (free_buf) urb->transfer_flags |= URB_FREE_BUFFER; usb_anchor_urb(urb, &ar->tx_cmd); usb_free_urb(urb); return carl9170_usb_submit_cmd_urb(ar); }
/** * usb_tranzport_write */ static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct usb_tranzport *dev; size_t bytes_to_write; int retval = 0; dev = file->private_data; /* verify that we actually have some data to write */ if (count == 0) goto exit; /* lock this object */ if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } /* wait until previous transfer is finished */ if (dev->interrupt_out_busy) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy); if (retval < 0) { goto unlock_exit; } } /* write the data into interrupt_out_buffer from userspace */ bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); if (bytes_to_write < count) dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write); dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { retval = -EFAULT; goto unlock_exit; } if (dev->interrupt_out_endpoint == NULL) { err("Endpoint should not be be null! \n"); goto unlock_exit; } /* send off the urb */ usb_fill_int_urb(dev->interrupt_out_urb, interface_to_usbdev(dev->intf), usb_sndintpipe(interface_to_usbdev(dev->intf), dev->interrupt_out_endpoint->bEndpointAddress), dev->interrupt_out_buffer, bytes_to_write, usb_tranzport_interrupt_out_callback, dev, dev->interrupt_out_interval); dev->interrupt_out_busy = 1; wmb(); retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval) { dev->interrupt_out_busy = 0; err("Couldn't submit interrupt_out_urb %d\n", retval); goto unlock_exit; } retval = bytes_to_write; unlock_exit: /* unlock the device */ up(&dev->sem); exit: return retval; }