/* * ultracam_veio() * * History: * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged. */ static int ultracam_veio( struct uvd *uvd, unsigned char req, unsigned short value, unsigned short index, int is_out) { static const char proc[] = "ultracam_veio"; unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */; int i; if (!CAMERA_IS_OPERATIONAL(uvd)) return 0; if (!is_out) { i = usb_control_msg( uvd->dev, usb_rcvctrlpipe(uvd->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, cp, sizeof(cp), 1000); #if 1 dev_info(&uvd->dev->dev, "USB => %02x%02x%02x%02x%02x%02x%02x%02x " "(req=$%02x val=$%04x ind=$%04x)\n", cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], req, value, index); #endif } else { i = usb_control_msg( uvd->dev, usb_sndctrlpipe(uvd->dev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 1000); } if (i < 0) { err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.", proc, i); uvd->last_error = i; } return i; }
static void konicawc_isoc_irq(struct urb *urb) #endif { struct uvd *uvd = urb->context; struct konicawc *cam = (struct konicawc *)uvd->user_data; /* We don't want to do anything if we are about to be removed! */ if (!CAMERA_IS_OPERATIONAL(uvd)) return; if (!uvd->streaming) { DEBUG(1, "Not streaming, but interrupt!"); return; } DEBUG(3, "got frame %d len = %d buflen =%d", urb->start_frame, urb->actual_length, urb->transfer_buffer_length); uvd->stats.urb_count++; if (urb->transfer_buffer_length > 32) { cam->last_data_urb = urb; return; } /* Copy the data received into ring queue */ if(cam->last_data_urb) { int len = 0; if(urb->start_frame != cam->last_data_urb->start_frame) err("Lost sync on frames"); else if (!urb->status && !cam->last_data_urb->status) len = konicawc_compress_iso(uvd, cam->last_data_urb, urb); resubmit_urb(uvd, cam->last_data_urb); resubmit_urb(uvd, urb); cam->last_data_urb = NULL; uvd->stats.urb_length = len; uvd->stats.data_count += len; if(len) RingQueue_WakeUpInterruptible(&uvd->dp); return; } return; }
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; }