T_EpIn selectBestEpIn(WORD requestedSize) { UINT ep3_size = 0; UINT ep7_size = 0; T_EpIn bestEpIn; #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)) ep3_size = ((unicorn_usb_dev.usb_dev->epmaxpacketout[EP_OBC_ISO_IN]) / 2); //bytes to Words ep7_size = ((unicorn_usb_dev.usb_dev->epmaxpacketout[EP_OBC_INT_IN]) / 2); //bytes to Words #else ep3_size = ((usb_maxpacket(unicorn_usb_dev.usb_dev, usb_rcvisocpipe(unicorn_usb_dev.usb_dev, EP_OBC_ISO_IN),0)) / 2); //bytes to Words ep7_size = ((usb_maxpacket(unicorn_usb_dev.usb_dev, usb_rcvintpipe(unicorn_usb_dev.usb_dev, EP_OBC_INT_IN),0)) / 2); //bytes to Words #endif if(requestedSize <= 8) { bestEpIn = EP7; } else { bestEpIn = EP3; } return bestEpIn; }
/*-------------------------------------------------------------------*/ static int dabusb_alloc_buffers (pdabusb_t s) { int buffers = 0; pbuff_t b; unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE); int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe)); int packets = _ISOPIPESIZE / pipesize; int transfer_buffer_length = packets * pipesize; int i; dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d", pipesize, packets, transfer_buffer_length); while (buffers < (s->total_buffer_size << 10)) { b = (pbuff_t) kmalloc (sizeof (buff_t), GFP_KERNEL); if (!b) { err("kmalloc(sizeof(buff_t))==NULL"); goto err; } memset (b, 0, sizeof (buff_t)); b->s = s; b->purb = usb_alloc_urb(packets, GFP_KERNEL); if (!b->purb) { err("usb_alloc_urb == NULL"); kfree (b); goto err; } b->purb->transfer_buffer = kmalloc (transfer_buffer_length, GFP_KERNEL); if (!b->purb->transfer_buffer) { kfree (b->purb); kfree (b); err("kmalloc(%d)==NULL", transfer_buffer_length); goto err; } b->purb->transfer_buffer_length = transfer_buffer_length; b->purb->number_of_packets = packets; b->purb->complete = dabusb_iso_complete; b->purb->context = b; b->purb->dev = s->usbdev; b->purb->pipe = pipe; b->purb->transfer_flags = URB_ISO_ASAP; for (i = 0; i < packets; i++) { b->purb->iso_frame_desc[i].offset = i * pipesize; b->purb->iso_frame_desc[i].length = pipesize; } buffers += transfer_buffer_length; list_add_tail (&b->buff_list, &s->free_buff_list); } s->got_mem = buffers; return 0; err: dabusb_free_buffers (s); return -ENOMEM; }
int st5481_setup_in(struct st5481_in *in) { struct usb_device *dev = in->adapter->usb_dev; int retval; DBG(4, ""); in->rcvbuf = kmalloc(in->bufsize, GFP_KERNEL); retval = -ENOMEM; if (!in->rcvbuf) goto err; retval = st5481_setup_isocpipes(in->urb, dev, usb_rcvisocpipe(dev, in->ep), in->num_packets, in->packet_size, in->num_packets * in->packet_size, usb_in_complete, in); if (retval) goto err_free; return 0; err_free: kfree(in->rcvbuf); err: return retval; }
static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv) { struct urb *ip; int size = usbtv->iso_size; int i; ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL); if (ip == NULL) return NULL; ip->dev = usbtv->udev; ip->context = usbtv; ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP); ip->interval = 1; ip->transfer_flags = URB_ISO_ASAP; ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS, GFP_KERNEL); ip->complete = usbtv_iso_cb; ip->number_of_packets = USBTV_ISOC_PACKETS; ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS; for (i = 0; i < USBTV_ISOC_PACKETS; i++) { ip->iso_frame_desc[i].offset = size * i; ip->iso_frame_desc[i].length = size; } return ip; }
int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) { int i; /* create audio URBs and fill in constant values: */ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { struct urb *urb; /* URB for audio in: */ urb = line6pcm->urb_audio_in[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); if (urb == NULL) { dev_err(line6pcm->line6->ifcdev, "Out of memory\n"); return -ENOMEM; } urb->dev = line6pcm->line6->usbdev; urb->pipe = usb_rcvisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_read & USB_ENDPOINT_NUMBER_MASK); urb->transfer_flags = URB_ISO_ASAP; urb->start_frame = -1; urb->number_of_packets = LINE6_ISO_PACKETS; urb->interval = LINE6_ISO_INTERVAL; urb->error_count = 0; urb->complete = audio_in_callback; } return 0; }
unsigned int SysUsbIsocPipe(pUsb_device pUdev, unsigned char addr, unsigned char dir) { struct usb_device *udev = (struct usb_device *) pUdev; if( USB_DIR_IN==dir ) return usb_rcvisocpipe(udev, addr); return usb_sndisocpipe(udev, addr); }
static struct vsfsm_state_t *uvc_evt_handler_video(struct vsfsm_t *sm, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)sm->user_data; struct vsfusbh_t *usbh = hdata->usbh; struct vsfusbh_urb_t *vsfurb = &hdata->video_urb; switch (evt) { case VSFSM_EVT_INIT: break; case UAV_ISO_ENABLE: if (hdata->video_urb_buf == NULL) { vsfurb->vsfdev->epmaxpacketin[hdata->video_iso_ep] = hdata->video_iso_packet_len; hdata->video_urb_buf = vsf_bufmgr_malloc(hdata->video_iso_packet_len); if (hdata->video_urb_buf == NULL) return NULL; vsfurb->transfer_buffer = hdata->video_urb_buf; vsfurb->transfer_length = hdata->video_iso_packet_len; vsfurb->pipe = usb_rcvisocpipe(vsfurb->vsfdev, hdata->video_iso_ep); vsfurb->transfer_flags |= USB_ISO_ASAP; vsfurb->number_of_packets = 1; vsfurb->iso_frame_desc[0].offset = 0; vsfurb->iso_frame_desc[0].length = hdata->video_iso_packet_len; err = vsfusbh_submit_urb(usbh, vsfurb); if (err != VSFERR_NONE) goto error; } break; case UAV_ISO_DISABLE: // TODO break; case VSFSM_EVT_URB_COMPLETE: if (vsfurb->status == URB_OK) { hdata->video_payload.len = vsfurb->actual_length; vsfusbh_uvc_report(hdata, &hdata->cur_param, &hdata->video_payload); } else { goto error; } err = vsfusbh_relink_urb(usbh, vsfurb); if (err != VSFERR_NONE) goto error; break; default: break; } return NULL; error: vsf_bufmgr_free(hdata->video_urb_buf); hdata->video_urb_buf = NULL; return NULL; }
/****************************************************************************** * * submit_urbs * *****************************************************************************/ static int submit_urbs(struct camera_data *cam) { struct urb *urb; int fx, err, i; for(i=0; i<NUM_SBUF; ++i) { if (cam->sbuf[i].data) continue; cam->sbuf[i].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL); if (!cam->sbuf[i].data) { return -ENOMEM; } } /* We double buffer the Isoc lists, and also know the polling * interval is every frame (1 == (1 << (bInterval -1))). */ for(i=0; i<NUM_SBUF; ++i) { if(cam->sbuf[i].urb) { continue; } urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); if (!urb) { return -ENOMEM; } cam->sbuf[i].urb = urb; urb->dev = cam->dev; urb->context = cam; urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = cam->sbuf[i].data; urb->complete = cpia2_usb_complete; urb->number_of_packets = FRAMES_PER_DESC; urb->interval = 1; urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC; for (fx = 0; fx < FRAMES_PER_DESC; fx++) { urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx; urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC; } } /* Queue the ISO urbs, and resubmit in the completion handler */ for(i=0; i<NUM_SBUF; ++i) { err = usb_submit_urb(cam->sbuf[i].urb, GFP_KERNEL); if (err) { ERR("usb_submit_urb[%d]() = %d\n", i, err); return err; } } return 0; }
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 int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) { struct btusb_data *data = hdev->driver_data; struct urb *urb; unsigned char *buf; unsigned int pipe; int err, size; BT_DBG("%s", hdev->name); if (!data->isoc_rx_ep) return -ENODEV; urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags); if (!urb) return -ENOMEM; size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) * BTUSB_MAX_ISOC_FRAMES; buf = kmalloc(size, mem_flags); if (!buf) { usb_free_urb(urb); return -ENOMEM; } pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); urb->dev = data->udev; urb->pipe = pipe; urb->context = hdev; urb->complete = btusb_isoc_complete; urb->interval = data->isoc_rx_ep->bInterval; urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; urb->transfer_buffer = buf; urb->transfer_buffer_length = size; __fill_isoc_descriptor(urb, size, le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); usb_anchor_urb(urb, &data->isoc_anchor); err = usb_submit_urb(urb, mem_flags); if (err < 0) { BT_ERR("%s urb %p submission failed (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); } usb_free_urb(urb); return err; }
//A helper routine to assist error recoverying. static BOOL IsoClearError(__USB_ISO_DESCRIPTOR* pIsoDesc) { int pipe = 0; struct usb_device* pUsbDev = (struct usb_device*)pIsoDesc->pPhyDev->lpPrivateInfo; if (USB_TRANSFER_DIR_IN == pIsoDesc->direction) { pipe = usb_rcvisocpipe(pUsbDev, pIsoDesc->endpoint); } else { pipe = usb_sndisocpipe(pUsbDev, pIsoDesc->endpoint); } //Just reset the endpoint. return 0 == usb_clear_halt(pUsbDev, pipe) ? TRUE : FALSE; }
static int usb_isoc_urb_init(struct usb_data_stream *stream) { int i,j; if ((i = usb_allocate_stream_buffers(stream,stream->props.count, stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0) return i; /* allocate the URBs */ for (i = 0; i < stream->props.count; i++) { struct urb *urb; int frame_offset = 0; stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC); if (!stream->urb_list[i]) { deb_mem("not enough memory for urb_alloc_urb!\n"); for (j = 0; j < i; j++) usb_free_urb(stream->urb_list[i]); return -ENOMEM; } urb = stream->urb_list[i]; urb->dev = stream->udev; urb->context = stream; urb->complete = usb_urb_complete; urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = stream->props.u.isoc.interval; urb->number_of_packets = stream->props.u.isoc.framesperurb; urb->transfer_buffer_length = stream->buf_size; urb->transfer_buffer = stream->buf_list[i]; urb->transfer_dma = stream->dma_addr[i]; for (j = 0; j < stream->props.u.isoc.framesperurb; j++) { urb->iso_frame_desc[j].offset = frame_offset; urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize; frame_offset += stream->props.u.isoc.framesize; } stream->urbs_initialized++; } return 0; }
static int allocate_isoc_buffer(struct usb_somagic *somagic) { int buf_idx; int isoc_buf_size = 32 * 3072; // 32 = NUM_URB_FRAMES * 3072 = VIDEO_ISOC_PACKET_SIZE for (buf_idx = 0; buf_idx < SOMAGIC_NUM_ISOC_BUFFERS; buf_idx++) { int j,k; struct urb *urb; urb = usb_alloc_urb(32, GFP_KERNEL); // 32 = NUM_URB_FRAMES if (urb == NULL) { dev_err(&somagic->dev->dev, "%s: usb_alloc_urb() failed\n", __func__); return -ENOMEM; } somagic->isoc_buf[buf_idx].urb = urb; somagic->isoc_buf[buf_idx].data = usb_alloc_coherent(somagic->dev, isoc_buf_size, GFP_KERNEL, &urb->transfer_dma); urb->dev = somagic->dev; urb->context = somagic; urb->pipe = usb_rcvisocpipe(somagic->dev, 0x82); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = 1; urb->transfer_buffer = somagic->isoc_buf[buf_idx].data; urb->complete = isoc_complete; urb->number_of_packets = 32; // 32 = NUM_URB_FRAMES urb->transfer_buffer_length = isoc_buf_size; for (j = k = 0; j < 32; j++, k += 3072) { urb->iso_frame_desc[j].offset = k; urb->iso_frame_desc[j].length = 3072; } } printk(KERN_INFO "somagic::%s: Allocated ISOC urbs!\n", __func__); return 0; }
static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d) { int i,j; if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count, d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0) return i; /* allocate the URBs */ for (i = 0; i < d->props.urb.count; i++) { struct urb *urb; int frame_offset = 0; if ((d->urb_list[i] = usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL) return -ENOMEM; urb = d->urb_list[i]; urb->dev = d->udev; urb->context = d; urb->complete = dvb_usb_urb_complete; urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = d->props.urb.u.isoc.interval; urb->number_of_packets = d->props.urb.u.isoc.framesperurb; urb->transfer_buffer_length = d->buf_size; urb->transfer_buffer = d->buf_list[i]; urb->transfer_dma = d->dma_addr[i]; for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) { urb->iso_frame_desc[j].offset = frame_offset; urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize; frame_offset += d->props.urb.u.isoc.framesize; } d->urbs_initialized++; } return 0; }
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); } } }
/*-------------------------------------------------------------------*/ static void dabusb_iso_complete (struct urb *purb, struct pt_regs *regs) { pbuff_t b = purb->context; pdabusb_t s = b->s; int i; int len; int dst = 0; void *buf = purb->transfer_buffer; dbg("dabusb_iso_complete"); // process if URB was not killed if (purb->status != -ENOENT) { unsigned int pipe = usb_rcvisocpipe (purb->dev, _DABUSB_ISOPIPE); int pipesize = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe)); for (i = 0; i < purb->number_of_packets; i++) if (!purb->iso_frame_desc[i].status) { len = purb->iso_frame_desc[i].actual_length; if (len <= pipesize) { memcpy (buf + dst, buf + purb->iso_frame_desc[i].offset, len); dst += len; } else err("dabusb_iso_complete: invalid len %d", len); } else warn("dabusb_iso_complete: corrupted packet status: %d", purb->iso_frame_desc[i].status); if (dst != purb->actual_length) err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length); } if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) { s->overruns++; err("overrun (%d)", s->overruns); } wake_up (&s->wait); }
int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) { struct usb_line6 *line6 = line6pcm->line6; int i; line6pcm->in.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), GFP_KERNEL); if (line6pcm->in.urbs == NULL) return -ENOMEM; /* create audio URBs and fill in constant values: */ for (i = 0; i < line6->iso_buffers; ++i) { struct urb *urb; /* URB for audio in: */ urb = line6pcm->in.urbs[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); if (urb == NULL) return -ENOMEM; urb->dev = line6->usbdev; urb->pipe = usb_rcvisocpipe(line6->usbdev, line6->properties->ep_audio_r & USB_ENDPOINT_NUMBER_MASK); urb->transfer_flags = URB_ISO_ASAP; urb->start_frame = -1; urb->number_of_packets = LINE6_ISO_PACKETS; urb->interval = LINE6_ISO_INTERVAL; urb->error_count = 0; urb->complete = audio_in_callback; } return 0; }
/* Create and register the PCM device and mixer entries. Create URBs for playback and capture. */ int line6_init_pcm(struct usb_line6 *line6, struct line6_pcm_properties *properties) { int i, err; unsigned ep_read = line6->properties->ep_audio_r; unsigned ep_write = line6->properties->ep_audio_w; struct snd_pcm *pcm; struct snd_line6_pcm *line6pcm; if (!(line6->properties->capabilities & LINE6_CAP_PCM)) return 0; /* skip PCM initialization and report success */ err = snd_line6_new_pcm(line6, &pcm); if (err < 0) return err; line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL); if (!line6pcm) return -ENOMEM; mutex_init(&line6pcm->state_mutex); line6pcm->pcm = pcm; line6pcm->properties = properties; line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; line6pcm->volume_monitor = 255; line6pcm->line6 = line6; /* Read and write buffers are sized identically, so choose minimum */ line6pcm->max_packet_size = min( usb_maxpacket(line6->usbdev, usb_rcvisocpipe(line6->usbdev, ep_read), 0), usb_maxpacket(line6->usbdev, usb_sndisocpipe(line6->usbdev, ep_write), 1)); spin_lock_init(&line6pcm->out.lock); spin_lock_init(&line6pcm->in.lock); line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; line6->line6pcm = line6pcm; pcm->private_data = line6pcm; pcm->private_free = line6_cleanup_pcm; err = line6_create_audio_out_urbs(line6pcm); if (err < 0) return err; err = line6_create_audio_in_urbs(line6pcm); if (err < 0) return err; /* mixer: */ for (i = 0; i < ARRAY_SIZE(line6_controls); i++) { err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_controls[i], line6pcm)); if (err < 0) return err; } return 0; }
static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev) { struct usb_device *usb = comedi_to_usb_dev(dev); struct usbduxsigma_private *devpriv = dev->private; struct urb *urb; int i; devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL); devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL); devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL); devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(urb), GFP_KERNEL); devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(urb), GFP_KERNEL); if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf || !devpriv->ai_urbs || !devpriv->ao_urbs) return -ENOMEM; for (i = 0; i < devpriv->n_ai_urbs; i++) { /* one frame: 1ms */ urb = usb_alloc_urb(1, GFP_KERNEL); if (!urb) return -ENOMEM; devpriv->ai_urbs[i] = urb; urb->dev = usb; /* will be filled later with a pointer to the comedi-device */ /* and ONLY then the urb should be submitted */ urb->context = NULL; urb->pipe = usb_rcvisocpipe(usb, 6); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL); if (!urb->transfer_buffer) return -ENOMEM; urb->complete = usbduxsigma_ai_urb_complete; urb->number_of_packets = 1; urb->transfer_buffer_length = SIZEINBUF; urb->iso_frame_desc[0].offset = 0; urb->iso_frame_desc[0].length = SIZEINBUF; } for (i = 0; i < devpriv->n_ao_urbs; i++) { /* one frame: 1ms */ urb = usb_alloc_urb(1, GFP_KERNEL); if (!urb) return -ENOMEM; devpriv->ao_urbs[i] = urb; urb->dev = usb; /* will be filled later with a pointer to the comedi-device */ /* and ONLY then the urb should be submitted */ urb->context = NULL; urb->pipe = usb_sndisocpipe(usb, 2); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL); if (!urb->transfer_buffer) return -ENOMEM; urb->complete = usbduxsigma_ao_urb_complete; urb->number_of_packets = 1; urb->transfer_buffer_length = SIZEOUTBUF; urb->iso_frame_desc[0].offset = 0; urb->iso_frame_desc[0].length = SIZEOUTBUF; if (devpriv->high_speed) urb->interval = 8; /* uframes */ else urb->interval = 1; /* frames */ } if (devpriv->pwm_buf_sz) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; devpriv->pwm_urb = urb; urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz, GFP_KERNEL); if (!urb->transfer_buffer) return -ENOMEM; } return 0; }
static int detect_usb_format(struct ua101 *ua) { const struct uac_format_type_i_discrete_descriptor *fmt_capture; const struct uac_format_type_i_discrete_descriptor *fmt_playback; const struct usb_endpoint_descriptor *epd; unsigned int rate2; fmt_capture = find_format_descriptor(ua->intf[INTF_CAPTURE]); fmt_playback = find_format_descriptor(ua->intf[INTF_PLAYBACK]); if (!fmt_capture || !fmt_playback) return -ENXIO; switch (fmt_capture->bSubframeSize) { case 3: ua->format_bit = SNDRV_PCM_FMTBIT_S24_3LE; break; case 4: ua->format_bit = SNDRV_PCM_FMTBIT_S32_LE; break; default: dev_err(&ua->dev->dev, "sample width is not 24 or 32 bits\n"); return -ENXIO; } if (fmt_capture->bSubframeSize != fmt_playback->bSubframeSize) { dev_err(&ua->dev->dev, "playback/capture sample widths do not match\n"); return -ENXIO; } if (fmt_capture->bBitResolution != 24 || fmt_playback->bBitResolution != 24) { dev_err(&ua->dev->dev, "sample width is not 24 bits\n"); return -ENXIO; } ua->rate = combine_triple(fmt_capture->tSamFreq[0]); rate2 = combine_triple(fmt_playback->tSamFreq[0]); if (ua->rate != rate2) { dev_err(&ua->dev->dev, "playback/capture rates do not match: %u/%u\n", rate2, ua->rate); return -ENXIO; } switch (ua->dev->speed) { case USB_SPEED_FULL: ua->packets_per_second = 1000; break; case USB_SPEED_HIGH: ua->packets_per_second = 8000; break; default: dev_err(&ua->dev->dev, "unknown device speed\n"); return -ENXIO; } ua->capture.channels = fmt_capture->bNrChannels; ua->playback.channels = fmt_playback->bNrChannels; ua->capture.frame_bytes = fmt_capture->bSubframeSize * ua->capture.channels; ua->playback.frame_bytes = fmt_playback->bSubframeSize * ua->playback.channels; epd = &ua->intf[INTF_CAPTURE]->altsetting[1].endpoint[0].desc; if (!usb_endpoint_is_isoc_in(epd)) { dev_err(&ua->dev->dev, "invalid capture endpoint\n"); return -ENXIO; } ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, usb_endpoint_num(epd)); ua->capture.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize); epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc; if (!usb_endpoint_is_isoc_out(epd)) { dev_err(&ua->dev->dev, "invalid playback endpoint\n"); return -ENXIO; } ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd)); ua->playback.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize); return 0; }
static int tmsi_open(struct inode *inode, struct file *file) { struct tmsi_data* dev; struct usb_interface* interface; int i, subminor,pipe,retval = 0; subminor = iminor(inode); mutex_lock(&driver_lock); interface = usb_find_interface(&tmsi_driver, subminor); if (!interface) { pr_err("%s - error, can't find device for minor %d", __FUNCTION__, subminor); retval = -ENODEV; goto exit; } dev = usb_get_intfdata(interface); mutex_unlock(&driver_lock); if (!dev) { retval = -ENODEV; goto exit; } if (dev->device_open > 0) { retval=-1; goto exit; } else dev->device_open = 1; /* increment our usage count for the device */ kref_get(&dev->kref); /* save our object in the file's private structure */ file->private_data = dev; // Setup incoming databuffer #if LINUX_VERSION_CODE > KERNEL_VERSION(3,0,0) spin_lock_init(&dev->buffer_lock); #else dev->buffer_lock = SPIN_LOCK_UNLOCKED; #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32) dev->packet_buffer = &dev->inner_packet_buffer; kfifo_alloc(dev->packet_buffer, PACKET_BUFFER_SIZE, GFP_KERNEL); #else dev->packet_buffer = kfifo_alloc(PACKET_BUFFER_SIZE, GFP_KERNEL, &dev->buffer_lock); #endif // Setup initial bulk receive URB and submit pipe=usb_rcvbulkpipe(dev->udev, dev->bulk_recv_endpoint->bEndpointAddress); for (i = 0; i < BULK_RECV_URBS; ++i) { dev->bulk_recv_urb[i] = usb_alloc_urb(0, GFP_KERNEL); dev->bulk_recv_buffer[i] = kmalloc(dev->bulk_recv_endpoint->wMaxPacketSize, GFP_KERNEL); usb_fill_bulk_urb(dev->bulk_recv_urb[i], dev->udev, pipe, dev->bulk_recv_buffer[i], dev->bulk_recv_endpoint->wMaxPacketSize, (usb_complete_t) tmsi_read_bulk_callback, dev); retval = usb_submit_urb(dev->bulk_recv_urb[i], GFP_KERNEL); if (retval) pr_err("%s - failed submitting bulk read urb[%d], error %d", __FUNCTION__, i, retval); } // Setup initial isochronous receive URB's and submit pipe=usb_rcvisocpipe(dev->udev, dev->isoc_recv_endpoint->bEndpointAddress); for (i = 0; i < ISOC_RECV_URBS; ++i) { dev->isoc_recv_urb[i] = usb_alloc_urb(1, GFP_KERNEL); dev->isoc_recv_buffer[i] = kmalloc(dev->isoc_recv_endpoint->wMaxPacketSize, GFP_KERNEL); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) spin_lock_init(&dev->isoc_recv_urb[i]->lock); #endif dev->isoc_recv_urb[i]->dev = dev->udev; dev->isoc_recv_urb[i]->pipe = pipe; dev->isoc_recv_urb[i]->transfer_buffer = dev->isoc_recv_buffer[i]; dev->isoc_recv_urb[i]->transfer_buffer_length = dev->isoc_recv_endpoint->wMaxPacketSize; dev->isoc_recv_urb[i]->complete = (usb_complete_t) tmsi_read_isoc_callback; dev->isoc_recv_urb[i]->context = dev; dev->isoc_recv_urb[i]->interval = 1 << (dev->isoc_recv_endpoint->bInterval - 1); dev->isoc_recv_urb[i]->number_of_packets = 1; dev->isoc_recv_urb[i]->start_frame = -1; dev->isoc_recv_urb[i]->iso_frame_desc[0].offset = 0; dev->isoc_recv_urb[i]->iso_frame_desc[0].length = dev->isoc_recv_endpoint->wMaxPacketSize; dev->isoc_recv_urb[i]->transfer_flags = URB_ISO_ASAP; retval = usb_submit_urb(dev->isoc_recv_urb[i], GFP_KERNEL); if (retval) pr_err("%s - failed submitting isochronous read urb[%d], error %d", __FUNCTION__, i, retval); } dev->fifo_sem = kmalloc(sizeof (struct semaphore), GFP_KERNEL); sema_init(dev->fifo_sem, 0); dev->release_sem = kmalloc(sizeof (struct semaphore), GFP_KERNEL); sema_init(dev->release_sem, 0); info("Tmsi device open() success"); exit: return retval; }
int fnusb_start_iso(struct usb_linect *dev, fnusb_isoc_stream *strm, int ep, int xfers, int pkts, int len) { int ret, i, j; struct urb *urb; uint8_t *bufp; strm->dev = dev; strm->num_xfers = xfers; strm->pkts = pkts; strm->len = len; //strm->buffer = linect_rvmalloc(xfers * pkts * len); strm->buffer = kzalloc(xfers * pkts * len, GFP_KERNEL); strm->xfers = kzalloc(sizeof(struct urb*) * xfers, GFP_KERNEL); bufp = strm->buffer; for (i=0; i<xfers; i++) { LNT_DEBUG("Creating EP %02x transfer #%d\n", ep, i); strm->xfers[i] = usb_alloc_urb(pkts, GFP_KERNEL); urb = strm->xfers[i]; urb->interval = 1; urb->dev = dev->cam->udev; urb->pipe = usb_rcvisocpipe(dev->cam->udev, ep); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = bufp; urb->transfer_buffer_length = pkts*len; urb->complete = usb_linect_isoc_handler; urb->context = strm; urb->start_frame = 0; urb->number_of_packets = pkts; for (j=0; j<pkts; j++) { urb->iso_frame_desc[j].offset = j * len; urb->iso_frame_desc[j].length = len; } ret = usb_submit_urb(strm->xfers[i], GFP_KERNEL); if (ret) LNT_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); else LNT_DEBUG("URB 0x%p submitted.\n", strm->xfers[i]); switch (ret) { case -ENOMEM: LNT_ERROR("ENOMEM\n"); break; case -ENODEV: LNT_ERROR("ENODEV\n"); break; case -ENXIO: LNT_ERROR("ENXIO\n"); break; case -EINVAL: LNT_ERROR("EINVAL\n"); break; case -EAGAIN: LNT_ERROR("EAGAIN\n"); break; case -EFBIG: LNT_ERROR("EFBIG\n"); break; case -EPIPE: LNT_ERROR("EPIPE\n"); break; case -EMSGSIZE: LNT_ERROR("EMSGSIZE\n"); break; } bufp += pkts*len; } return 0; }
static int get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf) { int tmp; struct usb_host_interface *alt; struct usb_host_endpoint *in, *out; struct usb_host_endpoint *iso_in, *iso_out; struct usb_device *udev; for (tmp = 0; tmp < intf->num_altsetting; tmp++) { unsigned ep; in = out = NULL; iso_in = iso_out = NULL; alt = intf->altsetting + tmp; /* take the first altsetting with in-bulk + out-bulk; * ignore other endpoints and altsettings. */ for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { struct usb_host_endpoint *e; e = alt->endpoint + ep; switch (e->desc.bmAttributes) { case USB_ENDPOINT_XFER_BULK: break; case USB_ENDPOINT_XFER_ISOC: if (dev->info->iso) goto try_iso; /* FALLTHROUGH */ default: continue; } if (usb_endpoint_dir_in(&e->desc)) { if (!in) in = e; } else { if (!out) out = e; } continue; try_iso: if (usb_endpoint_dir_in(&e->desc)) { if (!iso_in) iso_in = e; } else { if (!iso_out) iso_out = e; } } if ((in && out) || iso_in || iso_out) goto found; } return -EINVAL; found: udev = testdev_to_usbdev(dev); if (alt->desc.bAlternateSetting != 0) { tmp = usb_set_interface(udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); if (tmp < 0) return tmp; } if (in) { dev->in_pipe = usb_rcvbulkpipe(udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->out_pipe = usb_sndbulkpipe(udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); } if (iso_in) { dev->iso_in = &iso_in->desc; dev->in_iso_pipe = usb_rcvisocpipe(udev, iso_in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); } if (iso_out) { dev->iso_out = &iso_out->desc; dev->out_iso_pipe = usb_sndisocpipe(udev, iso_out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); } return 0; }
/* Create and register the PCM device and mixer entries. Create URBs for playback and capture. */ int line6_init_pcm(struct usb_line6 *line6, struct line6_pcm_properties *properties) { static struct snd_device_ops pcm_ops = { .dev_free = snd_line6_pcm_free, }; int err; int ep_read = 0, ep_write = 0; struct snd_line6_pcm *line6pcm; if (!(line6->properties->capabilities & LINE6_BIT_PCM)) return 0; /* skip PCM initialization and report success */ /* initialize PCM subsystem based on product id: */ switch (line6->product) { case LINE6_DEVID_BASSPODXT: case LINE6_DEVID_BASSPODXTLIVE: case LINE6_DEVID_BASSPODXTPRO: case LINE6_DEVID_PODXT: case LINE6_DEVID_PODXTLIVE: case LINE6_DEVID_PODXTPRO: case LINE6_DEVID_PODHD300: ep_read = 0x82; ep_write = 0x01; break; case LINE6_DEVID_PODHD500: case LINE6_DEVID_PODX3: case LINE6_DEVID_PODX3LIVE: ep_read = 0x86; ep_write = 0x02; break; case LINE6_DEVID_POCKETPOD: ep_read = 0x82; ep_write = 0x02; break; case LINE6_DEVID_GUITARPORT: case LINE6_DEVID_PODSTUDIO_GX: case LINE6_DEVID_PODSTUDIO_UX1: case LINE6_DEVID_PODSTUDIO_UX2: case LINE6_DEVID_TONEPORT_GX: case LINE6_DEVID_TONEPORT_UX1: case LINE6_DEVID_TONEPORT_UX2: ep_read = 0x82; ep_write = 0x01; break; /* this is for interface_number == 1: case LINE6_DEVID_TONEPORT_UX2: case LINE6_DEVID_PODSTUDIO_UX2: ep_read = 0x87; ep_write = 0x00; break; */ default: MISSING_CASE; } line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL); if (line6pcm == NULL) return -ENOMEM; line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; line6pcm->volume_monitor = 255; line6pcm->line6 = line6; line6pcm->ep_audio_read = ep_read; line6pcm->ep_audio_write = ep_write; /* Read and write buffers are sized identically, so choose minimum */ line6pcm->max_packet_size = min( usb_maxpacket(line6->usbdev, usb_rcvisocpipe(line6->usbdev, ep_read), 0), usb_maxpacket(line6->usbdev, usb_sndisocpipe(line6->usbdev, ep_write), 1)); line6pcm->properties = properties; line6->line6pcm = line6pcm; /* PCM device: */ err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops); if (err < 0) return err; snd_card_set_dev(line6->card, line6->ifcdev); err = snd_line6_new_pcm(line6pcm); if (err < 0) return err; spin_lock_init(&line6pcm->lock_audio_out); spin_lock_init(&line6pcm->lock_audio_in); spin_lock_init(&line6pcm->lock_trigger); err = line6_create_audio_out_urbs(line6pcm); if (err < 0) return err; err = line6_create_audio_in_urbs(line6pcm); if (err < 0) return err; /* mixer: */ err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control_playback, line6pcm)); if (err < 0) return err; #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE /* impulse response test: */ err = device_create_file(line6->ifcdev, &dev_attr_impulse_volume); if (err < 0) return err; err = device_create_file(line6->ifcdev, &dev_attr_impulse_period); if (err < 0) return err; line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; #endif return 0; }
A_STATUS usb_hif_setup_pipe_resources(HIF_DEVICE_USB *device) { struct usb_interface *interface = device->interface; struct usb_host_interface *iface_desc = interface->cur_altsetting; struct usb_endpoint_descriptor *endpoint; int i; int urbcount; A_STATUS status = A_OK; HIF_USB_PIPE *pipe; A_UINT8 pipe_num; /* walk decriptors and setup pipes */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (IS_BULK_EP(endpoint->bmAttributes)) { AR_DEBUG_PRINTF(USB_HIF_DEBUG_ENUM, ( "%s Bulk Ep:0x%2.2X " "maxpktsz:%d\n", IS_DIR_IN(endpoint->bEndpointAddress) ? "RX" : "TX", endpoint->bEndpointAddress, le16_to_cpu (endpoint->wMaxPacketSize))); } else if (IS_INT_EP(endpoint->bmAttributes)) { AR_DEBUG_PRINTF(USB_HIF_DEBUG_ENUM, ( "%s Int Ep:0x%2.2X maxpktsz:%d interval:%d\n", IS_DIR_IN(endpoint->bEndpointAddress) ? "RX" : "TX", endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval)); } else if (IS_ISOC_EP(endpoint->bmAttributes)) { /* TODO for ISO */ AR_DEBUG_PRINTF(USB_HIF_DEBUG_ENUM, ( "%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d\n", IS_DIR_IN(endpoint->bEndpointAddress) ? "RX" : "TX", endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval)); } urbcount = 0; pipe_num = usb_hif_get_logical_pipe_num(device, endpoint-> bEndpointAddress, &urbcount); if (HIF_USB_PIPE_INVALID == pipe_num) continue; pipe = &device->pipes[pipe_num]; if (pipe->device != NULL) { /* hmmm..pipe was already setup */ continue; } pipe->device = device; pipe->logical_pipe_num = pipe_num; pipe->ep_address = endpoint->bEndpointAddress; pipe->max_packet_size = le16_to_cpu(endpoint->wMaxPacketSize); if (IS_BULK_EP(endpoint->bmAttributes)) { if (IS_DIR_IN(pipe->ep_address)) { pipe->usb_pipe_handle = usb_rcvbulkpipe(device->udev, pipe->ep_address); } else { pipe->usb_pipe_handle = usb_sndbulkpipe(device->udev, pipe->ep_address); } } else if (IS_INT_EP(endpoint->bmAttributes)) { if (IS_DIR_IN(pipe->ep_address)) { pipe->usb_pipe_handle = usb_rcvintpipe(device->udev, pipe->ep_address); } else { pipe->usb_pipe_handle = usb_sndintpipe(device->udev, pipe->ep_address); } } else if (IS_ISOC_EP(endpoint->bmAttributes)) { /* TODO for ISO */ if (IS_DIR_IN(pipe->ep_address)) { pipe->usb_pipe_handle = usb_rcvisocpipe(device->udev, pipe->ep_address); } else { pipe->usb_pipe_handle = usb_sndisocpipe(device->udev, pipe->ep_address); } } pipe->ep_desc = endpoint; if (!IS_DIR_IN(pipe->ep_address)) pipe->flags |= HIF_USB_PIPE_FLAG_TX; status = usb_hif_alloc_pipe_resources(pipe, urbcount); if (A_FAILED(status)) break; } return status; }
static int konicawc_start_data(struct uvd *uvd) { struct usb_device *dev = uvd->dev; int i, errFlag; struct konicawc *cam = (struct konicawc *)uvd->user_data; int pktsz; struct usb_interface *intf; struct usb_host_interface *interface = NULL; intf = usb_ifnum_to_if(dev, uvd->iface); if (intf) interface = usb_altnum_to_altsetting(intf, spd_to_iface[cam->speed]); if (!interface) return -ENXIO; pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize); DEBUG(1, "pktsz = %d", pktsz); if (!CAMERA_IS_OPERATIONAL(uvd)) { err("Camera is not operational"); return -EFAULT; } uvd->curframe = -1; konicawc_camera_on(uvd); /* Alternate interface 1 is is the biggest frame size */ i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); if (i < 0) { err("usb_set_interface error"); uvd->last_error = i; return -EBUSY; } /* We double buffer the Iso lists */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { int j, k; struct urb *urb = uvd->sbuf[i].urb; urb->dev = dev; urb->context = uvd; urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp); urb->interval = 1; urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = uvd->sbuf[i].data; urb->complete = konicawc_isoc_irq; urb->number_of_packets = FRAMES_PER_DESC; urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC; for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) { urb->iso_frame_desc[j].offset = k; urb->iso_frame_desc[j].length = pktsz; } urb = cam->sts_urb[i]; urb->dev = dev; urb->context = uvd; urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1); urb->interval = 1; urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = cam->sts_buf[i]; urb->complete = konicawc_isoc_irq; urb->number_of_packets = FRAMES_PER_DESC; urb->transfer_buffer_length = FRAMES_PER_DESC; for (j=0; j < FRAMES_PER_DESC; j++) { urb->iso_frame_desc[j].offset = j; urb->iso_frame_desc[j].length = 1; } } cam->last_data_urb = NULL; /* Submit all URBs */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL); if (errFlag) err("usb_submit_isoc(%d) ret %d", i, errFlag); errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); if (errFlag) err ("usb_submit_isoc(%d) ret %d", i, errFlag); } uvd->streaming = 1; DEBUG(1, "streaming=1 video_endp=$%02x", uvd->video_endp); return 0; }
/* Both v4l2_lock and vb_queue_lock should be locked when calling this */ static int pwc_isoc_init(struct pwc_device *pdev) { struct usb_device *udev; struct urb *urb; int i, j, ret; struct usb_interface *intf; struct usb_host_interface *idesc = NULL; int compression = 0; /* 0..3 = uncompressed..high */ pdev->vsync = 0; pdev->vlast_packet_size = 0; pdev->fill_buf = NULL; pdev->vframe_count = 0; pdev->visoc_errors = 0; udev = pdev->udev; retry: /* We first try with low compression and then retry with a higher compression setting if there is not enough bandwidth. */ ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt, pdev->vframes, &compression, 1); /* Get the current alternate interface, adjust packet size */ intf = usb_ifnum_to_if(udev, 0); if (intf) idesc = usb_altnum_to_altsetting(intf, pdev->valternate); if (!idesc) return -EIO; /* Search video endpoint */ pdev->vmax_packet_size = -1; for (i = 0; i < idesc->desc.bNumEndpoints; i++) { if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); break; } } if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n"); return -ENFILE; /* Odd error, that should be noticeable */ } /* Set alternate interface */ PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate); ret = usb_set_interface(pdev->udev, 0, pdev->valternate); if (ret == -ENOSPC && compression < 3) { compression++; goto retry; } if (ret < 0) return ret; /* Allocate and init Isochronuous urbs */ for (i = 0; i < MAX_ISO_BUFS; i++) { urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); if (urb == NULL) { PWC_ERROR("Failed to allocate urb %d\n", i); pwc_isoc_cleanup(pdev); return -ENOMEM; } pdev->urbs[i] = urb; PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb); urb->interval = 1; // devik urb->dev = udev; urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer = usb_alloc_coherent(udev, ISO_BUFFER_SIZE, GFP_KERNEL, &urb->transfer_dma); if (urb->transfer_buffer == NULL) { PWC_ERROR("Failed to allocate urb buffer %d\n", i); pwc_isoc_cleanup(pdev); return -ENOMEM; } urb->transfer_buffer_length = ISO_BUFFER_SIZE; urb->complete = pwc_isoc_handler; urb->context = pdev; urb->start_frame = 0; urb->number_of_packets = ISO_FRAMES_PER_DESC; for (j = 0; j < ISO_FRAMES_PER_DESC; j++) { urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE; urb->iso_frame_desc[j].length = pdev->vmax_packet_size; } } /* link */ for (i = 0; i < MAX_ISO_BUFS; i++) { ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL); if (ret == -ENOSPC && compression < 3) { compression++; pwc_isoc_cleanup(pdev); goto retry; } if (ret) { PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); pwc_isoc_cleanup(pdev); return ret; } PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->urbs[i]); } /* All is done... */ PWC_DEBUG_OPEN("<< pwc_isoc_init()\n"); return 0; }
static int cpia_usb_open(void *privdata) { struct usb_cpia *ucpia = (struct usb_cpia *) privdata; struct urb *urb; int ret, retval = 0, fx, err; if (!ucpia) return -EINVAL; ucpia->sbuf[0].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL); if (!ucpia->sbuf[0].data) return -EINVAL; ucpia->sbuf[1].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL); if (!ucpia->sbuf[1].data) { retval = -EINVAL; goto error_0; } ret = usb_set_interface(ucpia->dev, ucpia->iface, 3); if (ret < 0) { printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret); retval = -EBUSY; goto error_1; } ucpia->buffers[0]->status = FRAME_EMPTY; ucpia->buffers[0]->length = 0; ucpia->buffers[1]->status = FRAME_EMPTY; ucpia->buffers[1]->length = 0; ucpia->buffers[2]->status = FRAME_EMPTY; ucpia->buffers[2]->length = 0; ucpia->curbuff = ucpia->buffers[0]; ucpia->workbuff = ucpia->buffers[1]; /* We double buffer the Iso lists, and also know the polling * interval is every frame (1 == (1 << (bInterval -1))). */ urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); if (!urb) { printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n"); retval = -ENOMEM; goto error_1; } ucpia->sbuf[0].urb = urb; urb->dev = ucpia->dev; urb->context = ucpia; urb->pipe = usb_rcvisocpipe(ucpia->dev, 1); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ucpia->sbuf[0].data; urb->complete = cpia_usb_complete; urb->number_of_packets = FRAMES_PER_DESC; urb->interval = 1; urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC; for (fx = 0; fx < FRAMES_PER_DESC; fx++) { urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx; urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC; } urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); if (!urb) { printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 1\n"); retval = -ENOMEM; goto error_urb0; } ucpia->sbuf[1].urb = urb; urb->dev = ucpia->dev; urb->context = ucpia; urb->pipe = usb_rcvisocpipe(ucpia->dev, 1); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ucpia->sbuf[1].data; urb->complete = cpia_usb_complete; urb->number_of_packets = FRAMES_PER_DESC; urb->interval = 1; urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC; for (fx = 0; fx < FRAMES_PER_DESC; fx++) { urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx; urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC; } /* queue the ISO urbs, and resubmit in the completion handler */ err = usb_submit_urb(ucpia->sbuf[0].urb, GFP_KERNEL); if (err) { printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n", err); goto error_urb1; } err = usb_submit_urb(ucpia->sbuf[1].urb, GFP_KERNEL); if (err) { printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n", err); goto error_urb1; } ucpia->streaming = 1; ucpia->open = 1; return 0; error_urb1: /* free urb 1 */ usb_free_urb(ucpia->sbuf[1].urb); ucpia->sbuf[1].urb = NULL; error_urb0: /* free urb 0 */ usb_free_urb(ucpia->sbuf[0].urb); ucpia->sbuf[0].urb = NULL; error_1: kfree (ucpia->sbuf[1].data); ucpia->sbuf[1].data = NULL; error_0: kfree (ucpia->sbuf[0].data); ucpia->sbuf[0].data = NULL; return retval; }
/* * Called whenever the USB subsystem thinks we could be the right driver * to handle this device */ static int probe(struct usb_interface *intf, const struct usb_device_id *id) { int alt_set, endp; int found = 0; int i, j; int struct_size; struct usb_host_interface *host_interf; struct usb_interface_descriptor *interf_desc; struct usb_host_endpoint *host_endpoint; struct ttusbir_device *ttusbir; DPRINTK("Module ttusbir probe\n"); /* To reduce memory fragmentation we use only one allocation */ struct_size = sizeof(struct ttusbir_device) + (sizeof(struct urb *) * num_urbs) + (sizeof(char *) * num_urbs) + (num_urbs * 128); ttusbir = kzalloc(struct_size, GFP_KERNEL); if (!ttusbir) return -ENOMEM; ttusbir->urb = (struct urb **)((char *)ttusbir + sizeof(struct ttusbir_device)); ttusbir->buffer = (char **)((char *)ttusbir->urb + (sizeof(struct urb *) * num_urbs)); for (i = 0; i < num_urbs; i++) ttusbir->buffer[i] = (char *)ttusbir->buffer + (sizeof(char *)*num_urbs) + (i * 128); ttusbir->usb_driver = &usb_driver; ttusbir->alt_setting = -1; /* @TODO check if error can be returned */ ttusbir->udev = usb_get_dev(interface_to_usbdev(intf)); ttusbir->interf = intf; ttusbir->last_pulse = 0x00; ttusbir->last_num = 0; /* * Now look for interface setting we can handle * We are searching for the alt setting where end point * 0x82 has max packet size 16 */ for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) { host_interf = &intf->altsetting[alt_set]; interf_desc = &host_interf->desc; for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) { host_endpoint = &host_interf->endpoint[endp]; if ((host_endpoint->desc.bEndpointAddress == 0x82) && (host_endpoint->desc.wMaxPacketSize == 0x10)) { ttusbir->alt_setting = alt_set; ttusbir->endpoint = endp; found = 1; break; } } } if (ttusbir->alt_setting != -1) DPRINTK("alt setting: %d\n", ttusbir->alt_setting); else { err("Could not find alternate setting\n"); kfree(ttusbir); return -EINVAL; } /* OK lets setup this interface setting */ usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting); /* Store device info in interface structure */ usb_set_intfdata(intf, ttusbir); /* Register as a LIRC driver */ if (lirc_buffer_init(&ttusbir->rbuf, sizeof(lirc_t), 256) < 0) { err("Could not get memory for LIRC data buffer\n"); usb_set_intfdata(intf, NULL); kfree(ttusbir); return -ENOMEM; } strcpy(ttusbir->driver.name, "TTUSBIR"); ttusbir->driver.minor = -1; ttusbir->driver.code_length = 1; ttusbir->driver.sample_rate = 0; ttusbir->driver.data = ttusbir; ttusbir->driver.add_to_buf = NULL; ttusbir->driver.rbuf = &ttusbir->rbuf; ttusbir->driver.set_use_inc = set_use_inc; ttusbir->driver.set_use_dec = set_use_dec; ttusbir->driver.fops = NULL; ttusbir->driver.dev = &intf->dev; ttusbir->driver.owner = THIS_MODULE; ttusbir->driver.features = LIRC_CAN_REC_MODE2; ttusbir->minor = lirc_register_driver(&ttusbir->driver); if (ttusbir->minor < 0) { err("Error registering as LIRC driver\n"); usb_set_intfdata(intf, NULL); lirc_buffer_free(&ttusbir->rbuf); kfree(ttusbir); return -EIO; } /* Allocate and setup the URB that we will use to talk to the device */ for (i = 0; i < num_urbs; i++) { ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL); if (!ttusbir->urb[i]) { err("Could not allocate memory for the URB\n"); for (j = i - 1; j >= 0; j--) kfree(ttusbir->urb[j]); lirc_buffer_free(&ttusbir->rbuf); lirc_unregister_driver(ttusbir->minor); kfree(ttusbir); usb_set_intfdata(intf, NULL); return -ENOMEM; } ttusbir->urb[i]->dev = ttusbir->udev; ttusbir->urb[i]->context = ttusbir; ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev, ttusbir->endpoint); ttusbir->urb[i]->interval = 1; ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP; ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0]; ttusbir->urb[i]->complete = urb_complete; ttusbir->urb[i]->number_of_packets = 8; ttusbir->urb[i]->transfer_buffer_length = 128; for (j = 0; j < 8; j++) { ttusbir->urb[i]->iso_frame_desc[j].offset = j*16; ttusbir->urb[i]->iso_frame_desc[j].length = 16; } } return 0; }