Path: blob/master/drivers/media/video/gspca/gspca.c
17621 views
/*1* Main USB camera driver2*3* Copyright (C) 2008-2011 Jean-François Moine <http://moinejf.free.fr>4*5* Camera button input handling by Márton Németh6* Copyright (C) 2009-2010 Márton Németh <[email protected]>7*8* This program is free software; you can redistribute it and/or modify it9* under the terms of the GNU General Public License as published by the10* Free Software Foundation; either version 2 of the License, or (at your11* option) any later version.12*13* This program is distributed in the hope that it will be useful, but14* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY15* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License16* for more details.17*18* You should have received a copy of the GNU General Public License19* along with this program; if not, write to the Free Software Foundation,20* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.21*/2223#define MODULE_NAME "gspca"2425#include <linux/init.h>26#include <linux/version.h>27#include <linux/fs.h>28#include <linux/vmalloc.h>29#include <linux/sched.h>30#include <linux/slab.h>31#include <linux/mm.h>32#include <linux/string.h>33#include <linux/pagemap.h>34#include <linux/io.h>35#include <asm/page.h>36#include <linux/uaccess.h>37#include <linux/ktime.h>38#include <media/v4l2-ioctl.h>3940#include "gspca.h"4142#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)43#include <linux/input.h>44#include <linux/usb/input.h>45#endif4647/* global values */48#define DEF_NURBS 3 /* default number of URBs */49#if DEF_NURBS > MAX_NURBS50#error "DEF_NURBS too big"51#endif5253MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");54MODULE_DESCRIPTION("GSPCA USB Camera Driver");55MODULE_LICENSE("GPL");5657#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 13, 0)5859#ifdef GSPCA_DEBUG60int gspca_debug = D_ERR | D_PROBE;61EXPORT_SYMBOL(gspca_debug);6263static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h)64{65if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') {66PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d",67txt,68pixfmt & 0xff,69(pixfmt >> 8) & 0xff,70(pixfmt >> 16) & 0xff,71pixfmt >> 24,72w, h);73} else {74PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d",75txt,76pixfmt,77w, h);78}79}80#else81#define PDEBUG_MODE(txt, pixfmt, w, h)82#endif8384/* specific memory types - !! should be different from V4L2_MEMORY_xxx */85#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */86#define GSPCA_MEMORY_READ 78788#define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)8990/*91* VMA operations.92*/93static void gspca_vm_open(struct vm_area_struct *vma)94{95struct gspca_frame *frame = vma->vm_private_data;9697frame->vma_use_count++;98frame->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED;99}100101static void gspca_vm_close(struct vm_area_struct *vma)102{103struct gspca_frame *frame = vma->vm_private_data;104105if (--frame->vma_use_count <= 0)106frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED;107}108109static const struct vm_operations_struct gspca_vm_ops = {110.open = gspca_vm_open,111.close = gspca_vm_close,112};113114/*115* Input and interrupt endpoint handling functions116*/117#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)118static void int_irq(struct urb *urb)119{120struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;121int ret;122123ret = urb->status;124switch (ret) {125case 0:126if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev,127urb->transfer_buffer, urb->actual_length) < 0) {128PDEBUG(D_ERR, "Unknown packet received");129}130break;131132case -ENOENT:133case -ECONNRESET:134case -ENODEV:135case -ESHUTDOWN:136/* Stop is requested either by software or hardware is gone,137* keep the ret value non-zero and don't resubmit later.138*/139break;140141default:142PDEBUG(D_ERR, "URB error %i, resubmitting", urb->status);143urb->status = 0;144ret = 0;145}146147if (ret == 0) {148ret = usb_submit_urb(urb, GFP_ATOMIC);149if (ret < 0)150err("Resubmit URB failed with error %i", ret);151}152}153154static int gspca_input_connect(struct gspca_dev *dev)155{156struct input_dev *input_dev;157int err = 0;158159dev->input_dev = NULL;160if (dev->sd_desc->int_pkt_scan || dev->sd_desc->other_input) {161input_dev = input_allocate_device();162if (!input_dev)163return -ENOMEM;164165usb_make_path(dev->dev, dev->phys, sizeof(dev->phys));166strlcat(dev->phys, "/input0", sizeof(dev->phys));167168input_dev->name = dev->sd_desc->name;169input_dev->phys = dev->phys;170171usb_to_input_id(dev->dev, &input_dev->id);172173input_dev->evbit[0] = BIT_MASK(EV_KEY);174input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);175input_dev->dev.parent = &dev->dev->dev;176177err = input_register_device(input_dev);178if (err) {179err("Input device registration failed with error %i",180err);181input_dev->dev.parent = NULL;182input_free_device(input_dev);183} else {184dev->input_dev = input_dev;185}186}187188return err;189}190191static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,192struct usb_endpoint_descriptor *ep)193{194unsigned int buffer_len;195int interval;196struct urb *urb;197struct usb_device *dev;198void *buffer = NULL;199int ret = -EINVAL;200201buffer_len = le16_to_cpu(ep->wMaxPacketSize);202interval = ep->bInterval;203PDEBUG(D_CONF, "found int in endpoint: 0x%x, "204"buffer_len=%u, interval=%u",205ep->bEndpointAddress, buffer_len, interval);206207dev = gspca_dev->dev;208209urb = usb_alloc_urb(0, GFP_KERNEL);210if (!urb) {211ret = -ENOMEM;212goto error;213}214215buffer = usb_alloc_coherent(dev, buffer_len,216GFP_KERNEL, &urb->transfer_dma);217if (!buffer) {218ret = -ENOMEM;219goto error_buffer;220}221usb_fill_int_urb(urb, dev,222usb_rcvintpipe(dev, ep->bEndpointAddress),223buffer, buffer_len,224int_irq, (void *)gspca_dev, interval);225urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;226ret = usb_submit_urb(urb, GFP_KERNEL);227if (ret < 0) {228PDEBUG(D_ERR, "submit int URB failed with error %i", ret);229goto error_submit;230}231gspca_dev->int_urb = urb;232return ret;233234error_submit:235usb_free_coherent(dev,236urb->transfer_buffer_length,237urb->transfer_buffer,238urb->transfer_dma);239error_buffer:240usb_free_urb(urb);241error:242return ret;243}244245static void gspca_input_create_urb(struct gspca_dev *gspca_dev)246{247struct usb_interface *intf;248struct usb_host_interface *intf_desc;249struct usb_endpoint_descriptor *ep;250int i;251252if (gspca_dev->sd_desc->int_pkt_scan) {253intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);254intf_desc = intf->cur_altsetting;255for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {256ep = &intf_desc->endpoint[i].desc;257if (usb_endpoint_dir_in(ep) &&258usb_endpoint_xfer_int(ep)) {259260alloc_and_submit_int_urb(gspca_dev, ep);261break;262}263}264}265}266267static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)268{269struct urb *urb;270271urb = gspca_dev->int_urb;272if (urb) {273gspca_dev->int_urb = NULL;274usb_kill_urb(urb);275usb_free_coherent(gspca_dev->dev,276urb->transfer_buffer_length,277urb->transfer_buffer,278urb->transfer_dma);279usb_free_urb(urb);280}281}282#else283static inline void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)284{285}286287static inline void gspca_input_create_urb(struct gspca_dev *gspca_dev)288{289}290291static inline int gspca_input_connect(struct gspca_dev *dev)292{293return 0;294}295#endif296297/*298* fill a video frame from an URB and resubmit299*/300static void fill_frame(struct gspca_dev *gspca_dev,301struct urb *urb)302{303u8 *data; /* address of data in the iso message */304int i, len, st;305cam_pkt_op pkt_scan;306307if (urb->status != 0) {308if (urb->status == -ESHUTDOWN)309return; /* disconnection */310#ifdef CONFIG_PM311if (gspca_dev->frozen)312return;313#endif314PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);315urb->status = 0;316goto resubmit;317}318pkt_scan = gspca_dev->sd_desc->pkt_scan;319for (i = 0; i < urb->number_of_packets; i++) {320len = urb->iso_frame_desc[i].actual_length;321322/* check the packet status and length */323st = urb->iso_frame_desc[i].status;324if (st) {325err("ISOC data error: [%d] len=%d, status=%d",326i, len, st);327gspca_dev->last_packet_type = DISCARD_PACKET;328continue;329}330if (len == 0) {331if (gspca_dev->empty_packet == 0)332gspca_dev->empty_packet = 1;333continue;334}335336/* let the packet be analyzed by the subdriver */337PDEBUG(D_PACK, "packet [%d] o:%d l:%d",338i, urb->iso_frame_desc[i].offset, len);339data = (u8 *) urb->transfer_buffer340+ urb->iso_frame_desc[i].offset;341pkt_scan(gspca_dev, data, len);342}343344resubmit:345/* resubmit the URB */346st = usb_submit_urb(urb, GFP_ATOMIC);347if (st < 0)348err("usb_submit_urb() ret %d", st);349}350351/*352* ISOC message interrupt from the USB device353*354* Analyse each packet and call the subdriver for copy to the frame buffer.355*/356static void isoc_irq(struct urb *urb)357{358struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;359360PDEBUG(D_PACK, "isoc irq");361if (!gspca_dev->streaming)362return;363fill_frame(gspca_dev, urb);364}365366/*367* bulk message interrupt from the USB device368*/369static void bulk_irq(struct urb *urb)370{371struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;372int st;373374PDEBUG(D_PACK, "bulk irq");375if (!gspca_dev->streaming)376return;377switch (urb->status) {378case 0:379break;380case -ESHUTDOWN:381return; /* disconnection */382default:383#ifdef CONFIG_PM384if (gspca_dev->frozen)385return;386#endif387PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);388urb->status = 0;389goto resubmit;390}391392PDEBUG(D_PACK, "packet l:%d", urb->actual_length);393gspca_dev->sd_desc->pkt_scan(gspca_dev,394urb->transfer_buffer,395urb->actual_length);396397resubmit:398/* resubmit the URB */399if (gspca_dev->cam.bulk_nurbs != 0) {400st = usb_submit_urb(urb, GFP_ATOMIC);401if (st < 0)402err("usb_submit_urb() ret %d", st);403}404}405406/*407* add data to the current frame408*409* This function is called by the subdrivers at interrupt level.410*411* To build a frame, these ones must add412* - one FIRST_PACKET413* - 0 or many INTER_PACKETs414* - one LAST_PACKET415* DISCARD_PACKET invalidates the whole frame.416*/417void gspca_frame_add(struct gspca_dev *gspca_dev,418enum gspca_packet_type packet_type,419const u8 *data,420int len)421{422struct gspca_frame *frame;423int i, j;424425PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);426427if (packet_type == FIRST_PACKET) {428i = atomic_read(&gspca_dev->fr_i);429430/* if there are no queued buffer, discard the whole frame */431if (i == atomic_read(&gspca_dev->fr_q)) {432gspca_dev->last_packet_type = DISCARD_PACKET;433gspca_dev->sequence++;434return;435}436j = gspca_dev->fr_queue[i];437frame = &gspca_dev->frame[j];438frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());439frame->v4l2_buf.sequence = gspca_dev->sequence++;440gspca_dev->image = frame->data;441gspca_dev->image_len = 0;442} else {443switch (gspca_dev->last_packet_type) {444case DISCARD_PACKET:445if (packet_type == LAST_PACKET)446gspca_dev->last_packet_type = packet_type;447return;448case LAST_PACKET:449return;450}451}452453/* append the packet to the frame buffer */454if (len > 0) {455if (gspca_dev->image_len + len > gspca_dev->frsz) {456PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d",457gspca_dev->image_len + len,458gspca_dev->frsz);459packet_type = DISCARD_PACKET;460} else {461/* !! image is NULL only when last pkt is LAST or DISCARD462if (gspca_dev->image == NULL) {463err("gspca_frame_add() image == NULL");464return;465}466*/467memcpy(gspca_dev->image + gspca_dev->image_len,468data, len);469gspca_dev->image_len += len;470}471}472gspca_dev->last_packet_type = packet_type;473474/* if last packet, invalidate packet concatenation until475* next first packet, wake up the application and advance476* in the queue */477if (packet_type == LAST_PACKET) {478i = atomic_read(&gspca_dev->fr_i);479j = gspca_dev->fr_queue[i];480frame = &gspca_dev->frame[j];481frame->v4l2_buf.bytesused = gspca_dev->image_len;482frame->v4l2_buf.flags = (frame->v4l2_buf.flags483| V4L2_BUF_FLAG_DONE)484& ~V4L2_BUF_FLAG_QUEUED;485i = (i + 1) % GSPCA_MAX_FRAMES;486atomic_set(&gspca_dev->fr_i, i);487wake_up_interruptible(&gspca_dev->wq); /* event = new frame */488PDEBUG(D_FRAM, "frame complete len:%d",489frame->v4l2_buf.bytesused);490gspca_dev->image = NULL;491gspca_dev->image_len = 0;492}493}494EXPORT_SYMBOL(gspca_frame_add);495496static int gspca_is_compressed(__u32 format)497{498switch (format) {499case V4L2_PIX_FMT_MJPEG:500case V4L2_PIX_FMT_JPEG:501case V4L2_PIX_FMT_SPCA561:502case V4L2_PIX_FMT_PAC207:503case V4L2_PIX_FMT_MR97310A:504return 1;505}506return 0;507}508509static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,510enum v4l2_memory memory, unsigned int count)511{512struct gspca_frame *frame;513unsigned int frsz;514int i;515516i = gspca_dev->curr_mode;517frsz = gspca_dev->cam.cam_mode[i].sizeimage;518PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);519frsz = PAGE_ALIGN(frsz);520if (count >= GSPCA_MAX_FRAMES)521count = GSPCA_MAX_FRAMES - 1;522gspca_dev->frbuf = vmalloc_32(frsz * count);523if (!gspca_dev->frbuf) {524err("frame alloc failed");525return -ENOMEM;526}527gspca_dev->capt_file = file;528gspca_dev->memory = memory;529gspca_dev->frsz = frsz;530gspca_dev->nframes = count;531for (i = 0; i < count; i++) {532frame = &gspca_dev->frame[i];533frame->v4l2_buf.index = i;534frame->v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;535frame->v4l2_buf.flags = 0;536frame->v4l2_buf.field = V4L2_FIELD_NONE;537frame->v4l2_buf.length = frsz;538frame->v4l2_buf.memory = memory;539frame->v4l2_buf.sequence = 0;540frame->data = gspca_dev->frbuf + i * frsz;541frame->v4l2_buf.m.offset = i * frsz;542}543atomic_set(&gspca_dev->fr_q, 0);544atomic_set(&gspca_dev->fr_i, 0);545gspca_dev->fr_o = 0;546return 0;547}548549static void frame_free(struct gspca_dev *gspca_dev)550{551int i;552553PDEBUG(D_STREAM, "frame free");554if (gspca_dev->frbuf != NULL) {555vfree(gspca_dev->frbuf);556gspca_dev->frbuf = NULL;557for (i = 0; i < gspca_dev->nframes; i++)558gspca_dev->frame[i].data = NULL;559}560gspca_dev->nframes = 0;561gspca_dev->frsz = 0;562gspca_dev->capt_file = NULL;563gspca_dev->memory = GSPCA_MEMORY_NO;564}565566static void destroy_urbs(struct gspca_dev *gspca_dev)567{568struct urb *urb;569unsigned int i;570571PDEBUG(D_STREAM, "kill transfer");572for (i = 0; i < MAX_NURBS; i++) {573urb = gspca_dev->urb[i];574if (urb == NULL)575break;576577gspca_dev->urb[i] = NULL;578usb_kill_urb(urb);579if (urb->transfer_buffer != NULL)580usb_free_coherent(gspca_dev->dev,581urb->transfer_buffer_length,582urb->transfer_buffer,583urb->transfer_dma);584usb_free_urb(urb);585}586}587588static int gspca_set_alt0(struct gspca_dev *gspca_dev)589{590int ret;591592if (gspca_dev->alt == 0)593return 0;594ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);595if (ret < 0)596err("set alt 0 err %d", ret);597return ret;598}599600/* Note: both the queue and the usb locks should be held when calling this */601static void gspca_stream_off(struct gspca_dev *gspca_dev)602{603gspca_dev->streaming = 0;604if (gspca_dev->present) {605if (gspca_dev->sd_desc->stopN)606gspca_dev->sd_desc->stopN(gspca_dev);607destroy_urbs(gspca_dev);608gspca_input_destroy_urb(gspca_dev);609gspca_set_alt0(gspca_dev);610gspca_input_create_urb(gspca_dev);611}612613/* always call stop0 to free the subdriver's resources */614if (gspca_dev->sd_desc->stop0)615gspca_dev->sd_desc->stop0(gspca_dev);616PDEBUG(D_STREAM, "stream off OK");617}618619/*620* look for an input transfer endpoint in an alternate setting621*/622static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,623int xfer)624{625struct usb_host_endpoint *ep;626int i, attr;627628for (i = 0; i < alt->desc.bNumEndpoints; i++) {629ep = &alt->endpoint[i];630attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;631if (attr == xfer632&& ep->desc.wMaxPacketSize != 0633&& usb_endpoint_dir_in(&ep->desc))634return ep;635}636return NULL;637}638639/*640* look for an input (isoc or bulk) endpoint641*642* The endpoint is defined by the subdriver.643* Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep).644* This routine may be called many times when the bandwidth is too small645* (the bandwidth is checked on urb submit).646*/647static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)648{649struct usb_interface *intf;650struct usb_host_endpoint *ep;651int xfer, i, ret;652653intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);654ep = NULL;655xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK656: USB_ENDPOINT_XFER_ISOC;657i = gspca_dev->alt; /* previous alt setting */658if (gspca_dev->cam.reverse_alts) {659while (++i < gspca_dev->nbalt) {660ep = alt_xfer(&intf->altsetting[i], xfer);661if (ep)662break;663}664} else {665while (--i >= 0) {666ep = alt_xfer(&intf->altsetting[i], xfer);667if (ep)668break;669}670}671if (ep == NULL) {672err("no transfer endpoint found");673return NULL;674}675PDEBUG(D_STREAM, "use alt %d ep 0x%02x",676i, ep->desc.bEndpointAddress);677gspca_dev->alt = i; /* memorize the current alt setting */678if (gspca_dev->nbalt > 1) {679ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);680if (ret < 0) {681err("set alt %d err %d", i, ret);682ep = NULL;683}684}685return ep;686}687688/*689* create the URBs for image transfer690*/691static int create_urbs(struct gspca_dev *gspca_dev,692struct usb_host_endpoint *ep)693{694struct urb *urb;695int n, nurbs, i, psize, npkt, bsize;696697/* calculate the packet size and the number of packets */698psize = le16_to_cpu(ep->desc.wMaxPacketSize);699700if (!gspca_dev->cam.bulk) { /* isoc */701702/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */703if (gspca_dev->pkt_size == 0)704psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));705else706psize = gspca_dev->pkt_size;707npkt = gspca_dev->cam.npkt;708if (npkt == 0)709npkt = 32; /* default value */710bsize = psize * npkt;711PDEBUG(D_STREAM,712"isoc %d pkts size %d = bsize:%d",713npkt, psize, bsize);714nurbs = DEF_NURBS;715} else { /* bulk */716npkt = 0;717bsize = gspca_dev->cam.bulk_size;718if (bsize == 0)719bsize = psize;720PDEBUG(D_STREAM, "bulk bsize:%d", bsize);721if (gspca_dev->cam.bulk_nurbs != 0)722nurbs = gspca_dev->cam.bulk_nurbs;723else724nurbs = 1;725}726727for (n = 0; n < nurbs; n++) {728urb = usb_alloc_urb(npkt, GFP_KERNEL);729if (!urb) {730err("usb_alloc_urb failed");731return -ENOMEM;732}733gspca_dev->urb[n] = urb;734urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,735bsize,736GFP_KERNEL,737&urb->transfer_dma);738739if (urb->transfer_buffer == NULL) {740err("usb_alloc_coherent failed");741return -ENOMEM;742}743urb->dev = gspca_dev->dev;744urb->context = gspca_dev;745urb->transfer_buffer_length = bsize;746if (npkt != 0) { /* ISOC */747urb->pipe = usb_rcvisocpipe(gspca_dev->dev,748ep->desc.bEndpointAddress);749urb->transfer_flags = URB_ISO_ASAP750| URB_NO_TRANSFER_DMA_MAP;751urb->interval = ep->desc.bInterval;752urb->complete = isoc_irq;753urb->number_of_packets = npkt;754for (i = 0; i < npkt; i++) {755urb->iso_frame_desc[i].length = psize;756urb->iso_frame_desc[i].offset = psize * i;757}758} else { /* bulk */759urb->pipe = usb_rcvbulkpipe(gspca_dev->dev,760ep->desc.bEndpointAddress);761urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;762urb->complete = bulk_irq;763}764}765return 0;766}767768/*769* start the USB transfer770*/771static int gspca_init_transfer(struct gspca_dev *gspca_dev)772{773struct usb_host_endpoint *ep;774struct urb *urb;775int n, ret;776777if (mutex_lock_interruptible(&gspca_dev->usb_lock))778return -ERESTARTSYS;779780if (!gspca_dev->present) {781ret = -ENODEV;782goto unlock;783}784785/* reset the streaming variables */786gspca_dev->image = NULL;787gspca_dev->image_len = 0;788gspca_dev->last_packet_type = DISCARD_PACKET;789gspca_dev->sequence = 0;790791gspca_dev->usb_err = 0;792793/* set the higher alternate setting and794* loop until urb submit succeeds */795if (gspca_dev->cam.reverse_alts)796gspca_dev->alt = 0;797else798gspca_dev->alt = gspca_dev->nbalt;799800if (gspca_dev->sd_desc->isoc_init) {801ret = gspca_dev->sd_desc->isoc_init(gspca_dev);802if (ret < 0)803goto unlock;804}805806gspca_input_destroy_urb(gspca_dev);807ep = get_ep(gspca_dev);808if (ep == NULL) {809ret = -EIO;810goto out;811}812for (;;) {813if (!gspca_dev->cam.no_urb_create) {814PDEBUG(D_STREAM, "init transfer alt %d",815gspca_dev->alt);816ret = create_urbs(gspca_dev, ep);817if (ret < 0) {818destroy_urbs(gspca_dev);819goto out;820}821}822823/* clear the bulk endpoint */824if (gspca_dev->cam.bulk)825usb_clear_halt(gspca_dev->dev,826gspca_dev->urb[0]->pipe);827828/* start the cam */829ret = gspca_dev->sd_desc->start(gspca_dev);830if (ret < 0) {831destroy_urbs(gspca_dev);832goto out;833}834gspca_dev->streaming = 1;835836/* some bulk transfers are started by the subdriver */837if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)838break;839840/* submit the URBs */841for (n = 0; n < MAX_NURBS; n++) {842urb = gspca_dev->urb[n];843if (urb == NULL)844break;845ret = usb_submit_urb(urb, GFP_KERNEL);846if (ret < 0)847break;848}849if (ret >= 0)850break;851gspca_stream_off(gspca_dev);852if (ret != -ENOSPC) {853err("usb_submit_urb alt %d err %d",854gspca_dev->alt, ret);855goto out;856}857858/* the bandwidth is not wide enough859* negotiate or try a lower alternate setting */860PDEBUG(D_ERR|D_STREAM,861"bandwidth not wide enough - trying again");862msleep(20); /* wait for kill complete */863if (gspca_dev->sd_desc->isoc_nego) {864ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);865if (ret < 0)866goto out;867} else {868ep = get_ep(gspca_dev);869if (ep == NULL) {870ret = -EIO;871goto out;872}873}874}875out:876gspca_input_create_urb(gspca_dev);877unlock:878mutex_unlock(&gspca_dev->usb_lock);879return ret;880}881882static void gspca_set_default_mode(struct gspca_dev *gspca_dev)883{884struct gspca_ctrl *ctrl;885int i;886887i = gspca_dev->cam.nmodes - 1; /* take the highest mode */888gspca_dev->curr_mode = i;889gspca_dev->width = gspca_dev->cam.cam_mode[i].width;890gspca_dev->height = gspca_dev->cam.cam_mode[i].height;891gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat;892893/* set the current control values to their default values894* which may have changed in sd_init() */895ctrl = gspca_dev->cam.ctrls;896if (ctrl != NULL) {897for (i = 0;898i < gspca_dev->sd_desc->nctrls;899i++, ctrl++)900ctrl->val = ctrl->def;901}902}903904static int wxh_to_mode(struct gspca_dev *gspca_dev,905int width, int height)906{907int i;908909for (i = gspca_dev->cam.nmodes; --i > 0; ) {910if (width >= gspca_dev->cam.cam_mode[i].width911&& height >= gspca_dev->cam.cam_mode[i].height)912break;913}914return i;915}916917/*918* search a mode with the right pixel format919*/920static int gspca_get_mode(struct gspca_dev *gspca_dev,921int mode,922int pixfmt)923{924int modeU, modeD;925926modeU = modeD = mode;927while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) {928if (--modeD >= 0) {929if (gspca_dev->cam.cam_mode[modeD].pixelformat930== pixfmt)931return modeD;932}933if (++modeU < gspca_dev->cam.nmodes) {934if (gspca_dev->cam.cam_mode[modeU].pixelformat935== pixfmt)936return modeU;937}938}939return -EINVAL;940}941942#ifdef CONFIG_VIDEO_ADV_DEBUG943static int vidioc_g_register(struct file *file, void *priv,944struct v4l2_dbg_register *reg)945{946int ret;947struct gspca_dev *gspca_dev = priv;948949if (!gspca_dev->sd_desc->get_chip_ident)950return -EINVAL;951952if (!gspca_dev->sd_desc->get_register)953return -EINVAL;954955if (mutex_lock_interruptible(&gspca_dev->usb_lock))956return -ERESTARTSYS;957gspca_dev->usb_err = 0;958if (gspca_dev->present)959ret = gspca_dev->sd_desc->get_register(gspca_dev, reg);960else961ret = -ENODEV;962mutex_unlock(&gspca_dev->usb_lock);963964return ret;965}966967static int vidioc_s_register(struct file *file, void *priv,968struct v4l2_dbg_register *reg)969{970int ret;971struct gspca_dev *gspca_dev = priv;972973if (!gspca_dev->sd_desc->get_chip_ident)974return -EINVAL;975976if (!gspca_dev->sd_desc->set_register)977return -EINVAL;978979if (mutex_lock_interruptible(&gspca_dev->usb_lock))980return -ERESTARTSYS;981gspca_dev->usb_err = 0;982if (gspca_dev->present)983ret = gspca_dev->sd_desc->set_register(gspca_dev, reg);984else985ret = -ENODEV;986mutex_unlock(&gspca_dev->usb_lock);987988return ret;989}990#endif991992static int vidioc_g_chip_ident(struct file *file, void *priv,993struct v4l2_dbg_chip_ident *chip)994{995int ret;996struct gspca_dev *gspca_dev = priv;997998if (!gspca_dev->sd_desc->get_chip_ident)999return -EINVAL;10001001if (mutex_lock_interruptible(&gspca_dev->usb_lock))1002return -ERESTARTSYS;1003gspca_dev->usb_err = 0;1004if (gspca_dev->present)1005ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);1006else1007ret = -ENODEV;1008mutex_unlock(&gspca_dev->usb_lock);10091010return ret;1011}10121013static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,1014struct v4l2_fmtdesc *fmtdesc)1015{1016struct gspca_dev *gspca_dev = priv;1017int i, j, index;1018__u32 fmt_tb[8];10191020/* give an index to each format */1021index = 0;1022j = 0;1023for (i = gspca_dev->cam.nmodes; --i >= 0; ) {1024fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat;1025j = 0;1026for (;;) {1027if (fmt_tb[j] == fmt_tb[index])1028break;1029j++;1030}1031if (j == index) {1032if (fmtdesc->index == index)1033break; /* new format */1034index++;1035if (index >= ARRAY_SIZE(fmt_tb))1036return -EINVAL;1037}1038}1039if (i < 0)1040return -EINVAL; /* no more format */10411042fmtdesc->pixelformat = fmt_tb[index];1043if (gspca_is_compressed(fmt_tb[index]))1044fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;1045fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;1046fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;1047fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;1048fmtdesc->description[3] = fmtdesc->pixelformat >> 24;1049fmtdesc->description[4] = '\0';1050return 0;1051}10521053static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,1054struct v4l2_format *fmt)1055{1056struct gspca_dev *gspca_dev = priv;1057int mode;10581059mode = gspca_dev->curr_mode;1060memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode],1061sizeof fmt->fmt.pix);1062return 0;1063}10641065static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,1066struct v4l2_format *fmt)1067{1068int w, h, mode, mode2;10691070w = fmt->fmt.pix.width;1071h = fmt->fmt.pix.height;10721073#ifdef GSPCA_DEBUG1074if (gspca_debug & D_CONF)1075PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h);1076#endif1077/* search the closest mode for width and height */1078mode = wxh_to_mode(gspca_dev, w, h);10791080/* OK if right palette */1081if (gspca_dev->cam.cam_mode[mode].pixelformat1082!= fmt->fmt.pix.pixelformat) {10831084/* else, search the closest mode with the same pixel format */1085mode2 = gspca_get_mode(gspca_dev, mode,1086fmt->fmt.pix.pixelformat);1087if (mode2 >= 0)1088mode = mode2;1089/* else1090; * no chance, return this mode */1091}1092memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode],1093sizeof fmt->fmt.pix);1094return mode; /* used when s_fmt */1095}10961097static int vidioc_try_fmt_vid_cap(struct file *file,1098void *priv,1099struct v4l2_format *fmt)1100{1101struct gspca_dev *gspca_dev = priv;1102int ret;11031104ret = try_fmt_vid_cap(gspca_dev, fmt);1105if (ret < 0)1106return ret;1107return 0;1108}11091110static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,1111struct v4l2_format *fmt)1112{1113struct gspca_dev *gspca_dev = priv;1114int ret;11151116if (mutex_lock_interruptible(&gspca_dev->queue_lock))1117return -ERESTARTSYS;11181119ret = try_fmt_vid_cap(gspca_dev, fmt);1120if (ret < 0)1121goto out;11221123if (gspca_dev->nframes != 01124&& fmt->fmt.pix.sizeimage > gspca_dev->frsz) {1125ret = -EINVAL;1126goto out;1127}11281129if (ret == gspca_dev->curr_mode) {1130ret = 0;1131goto out; /* same mode */1132}11331134if (gspca_dev->streaming) {1135ret = -EBUSY;1136goto out;1137}1138gspca_dev->width = fmt->fmt.pix.width;1139gspca_dev->height = fmt->fmt.pix.height;1140gspca_dev->pixfmt = fmt->fmt.pix.pixelformat;1141gspca_dev->curr_mode = ret;11421143ret = 0;1144out:1145mutex_unlock(&gspca_dev->queue_lock);1146return ret;1147}11481149static int vidioc_enum_framesizes(struct file *file, void *priv,1150struct v4l2_frmsizeenum *fsize)1151{1152struct gspca_dev *gspca_dev = priv;1153int i;1154__u32 index = 0;11551156for (i = 0; i < gspca_dev->cam.nmodes; i++) {1157if (fsize->pixel_format !=1158gspca_dev->cam.cam_mode[i].pixelformat)1159continue;11601161if (fsize->index == index) {1162fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;1163fsize->discrete.width =1164gspca_dev->cam.cam_mode[i].width;1165fsize->discrete.height =1166gspca_dev->cam.cam_mode[i].height;1167return 0;1168}1169index++;1170}11711172return -EINVAL;1173}11741175static int vidioc_enum_frameintervals(struct file *filp, void *priv,1176struct v4l2_frmivalenum *fival)1177{1178struct gspca_dev *gspca_dev = priv;1179int mode = wxh_to_mode(gspca_dev, fival->width, fival->height);1180__u32 i;11811182if (gspca_dev->cam.mode_framerates == NULL ||1183gspca_dev->cam.mode_framerates[mode].nrates == 0)1184return -EINVAL;11851186if (fival->pixel_format !=1187gspca_dev->cam.cam_mode[mode].pixelformat)1188return -EINVAL;11891190for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) {1191if (fival->index == i) {1192fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;1193fival->discrete.numerator = 1;1194fival->discrete.denominator =1195gspca_dev->cam.mode_framerates[mode].rates[i];1196return 0;1197}1198}11991200return -EINVAL;1201}12021203static void gspca_release(struct video_device *vfd)1204{1205struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);12061207PDEBUG(D_PROBE, "%s released",1208video_device_node_name(&gspca_dev->vdev));12091210kfree(gspca_dev->usb_buf);1211kfree(gspca_dev);1212}12131214static int dev_open(struct file *file)1215{1216struct gspca_dev *gspca_dev;12171218PDEBUG(D_STREAM, "[%s] open", current->comm);1219gspca_dev = (struct gspca_dev *) video_devdata(file);1220if (!gspca_dev->present)1221return -ENODEV;12221223/* protect the subdriver against rmmod */1224if (!try_module_get(gspca_dev->module))1225return -ENODEV;12261227file->private_data = gspca_dev;1228#ifdef GSPCA_DEBUG1229/* activate the v4l2 debug */1230if (gspca_debug & D_V4L2)1231gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL1232| V4L2_DEBUG_IOCTL_ARG;1233else1234gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL1235| V4L2_DEBUG_IOCTL_ARG);1236#endif1237return 0;1238}12391240static int dev_close(struct file *file)1241{1242struct gspca_dev *gspca_dev = file->private_data;12431244PDEBUG(D_STREAM, "[%s] close", current->comm);1245if (mutex_lock_interruptible(&gspca_dev->queue_lock))1246return -ERESTARTSYS;12471248/* if the file did the capture, free the streaming resources */1249if (gspca_dev->capt_file == file) {1250if (gspca_dev->streaming) {1251mutex_lock(&gspca_dev->usb_lock);1252gspca_dev->usb_err = 0;1253gspca_stream_off(gspca_dev);1254mutex_unlock(&gspca_dev->usb_lock);1255}1256frame_free(gspca_dev);1257}1258file->private_data = NULL;1259module_put(gspca_dev->module);1260mutex_unlock(&gspca_dev->queue_lock);12611262PDEBUG(D_STREAM, "close done");12631264return 0;1265}12661267static int vidioc_querycap(struct file *file, void *priv,1268struct v4l2_capability *cap)1269{1270struct gspca_dev *gspca_dev = priv;1271int ret;12721273/* protect the access to the usb device */1274if (mutex_lock_interruptible(&gspca_dev->usb_lock))1275return -ERESTARTSYS;1276if (!gspca_dev->present) {1277ret = -ENODEV;1278goto out;1279}1280strncpy((char *) cap->driver, gspca_dev->sd_desc->name,1281sizeof cap->driver);1282if (gspca_dev->dev->product != NULL) {1283strncpy((char *) cap->card, gspca_dev->dev->product,1284sizeof cap->card);1285} else {1286snprintf((char *) cap->card, sizeof cap->card,1287"USB Camera (%04x:%04x)",1288le16_to_cpu(gspca_dev->dev->descriptor.idVendor),1289le16_to_cpu(gspca_dev->dev->descriptor.idProduct));1290}1291usb_make_path(gspca_dev->dev, (char *) cap->bus_info,1292sizeof(cap->bus_info));1293cap->version = DRIVER_VERSION_NUMBER;1294cap->capabilities = V4L2_CAP_VIDEO_CAPTURE1295| V4L2_CAP_STREAMING1296| V4L2_CAP_READWRITE;1297ret = 0;1298out:1299mutex_unlock(&gspca_dev->usb_lock);1300return ret;1301}13021303static int get_ctrl(struct gspca_dev *gspca_dev,1304int id)1305{1306const struct ctrl *ctrls;1307int i;13081309for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;1310i < gspca_dev->sd_desc->nctrls;1311i++, ctrls++) {1312if (gspca_dev->ctrl_dis & (1 << i))1313continue;1314if (id == ctrls->qctrl.id)1315return i;1316}1317return -1;1318}13191320static int vidioc_queryctrl(struct file *file, void *priv,1321struct v4l2_queryctrl *q_ctrl)1322{1323struct gspca_dev *gspca_dev = priv;1324const struct ctrl *ctrls;1325struct gspca_ctrl *gspca_ctrl;1326int i, idx;1327u32 id;13281329id = q_ctrl->id;1330if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {1331id &= V4L2_CTRL_ID_MASK;1332id++;1333idx = -1;1334for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {1335if (gspca_dev->ctrl_dis & (1 << i))1336continue;1337if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)1338continue;1339if (idx >= 01340&& gspca_dev->sd_desc->ctrls[i].qctrl.id1341> gspca_dev->sd_desc->ctrls[idx].qctrl.id)1342continue;1343idx = i;1344}1345} else {1346idx = get_ctrl(gspca_dev, id);1347}1348if (idx < 0)1349return -EINVAL;1350ctrls = &gspca_dev->sd_desc->ctrls[idx];1351memcpy(q_ctrl, &ctrls->qctrl, sizeof *q_ctrl);1352if (gspca_dev->cam.ctrls != NULL) {1353gspca_ctrl = &gspca_dev->cam.ctrls[idx];1354q_ctrl->default_value = gspca_ctrl->def;1355q_ctrl->minimum = gspca_ctrl->min;1356q_ctrl->maximum = gspca_ctrl->max;1357}1358if (gspca_dev->ctrl_inac & (1 << idx))1359q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;1360return 0;1361}13621363static int vidioc_s_ctrl(struct file *file, void *priv,1364struct v4l2_control *ctrl)1365{1366struct gspca_dev *gspca_dev = priv;1367const struct ctrl *ctrls;1368struct gspca_ctrl *gspca_ctrl;1369int idx, ret;13701371idx = get_ctrl(gspca_dev, ctrl->id);1372if (idx < 0)1373return -EINVAL;1374if (gspca_dev->ctrl_inac & (1 << idx))1375return -EINVAL;1376ctrls = &gspca_dev->sd_desc->ctrls[idx];1377if (gspca_dev->cam.ctrls != NULL) {1378gspca_ctrl = &gspca_dev->cam.ctrls[idx];1379if (ctrl->value < gspca_ctrl->min1380|| ctrl->value > gspca_ctrl->max)1381return -ERANGE;1382} else {1383gspca_ctrl = NULL;1384if (ctrl->value < ctrls->qctrl.minimum1385|| ctrl->value > ctrls->qctrl.maximum)1386return -ERANGE;1387}1388PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);1389if (mutex_lock_interruptible(&gspca_dev->usb_lock))1390return -ERESTARTSYS;1391if (!gspca_dev->present) {1392ret = -ENODEV;1393goto out;1394}1395gspca_dev->usb_err = 0;1396if (ctrls->set != NULL) {1397ret = ctrls->set(gspca_dev, ctrl->value);1398goto out;1399}1400if (gspca_ctrl != NULL) {1401gspca_ctrl->val = ctrl->value;1402if (ctrls->set_control != NULL1403&& gspca_dev->streaming)1404ctrls->set_control(gspca_dev);1405}1406ret = gspca_dev->usb_err;1407out:1408mutex_unlock(&gspca_dev->usb_lock);1409return ret;1410}14111412static int vidioc_g_ctrl(struct file *file, void *priv,1413struct v4l2_control *ctrl)1414{1415struct gspca_dev *gspca_dev = priv;1416const struct ctrl *ctrls;1417int idx, ret;14181419idx = get_ctrl(gspca_dev, ctrl->id);1420if (idx < 0)1421return -EINVAL;1422ctrls = &gspca_dev->sd_desc->ctrls[idx];14231424if (mutex_lock_interruptible(&gspca_dev->usb_lock))1425return -ERESTARTSYS;1426if (!gspca_dev->present) {1427ret = -ENODEV;1428goto out;1429}1430gspca_dev->usb_err = 0;1431if (ctrls->get != NULL) {1432ret = ctrls->get(gspca_dev, &ctrl->value);1433goto out;1434}1435if (gspca_dev->cam.ctrls != NULL)1436ctrl->value = gspca_dev->cam.ctrls[idx].val;1437ret = 0;1438out:1439mutex_unlock(&gspca_dev->usb_lock);1440return ret;1441}14421443static int vidioc_querymenu(struct file *file, void *priv,1444struct v4l2_querymenu *qmenu)1445{1446struct gspca_dev *gspca_dev = priv;14471448if (!gspca_dev->sd_desc->querymenu)1449return -EINVAL;1450return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu);1451}14521453static int vidioc_enum_input(struct file *file, void *priv,1454struct v4l2_input *input)1455{1456struct gspca_dev *gspca_dev = priv;14571458if (input->index != 0)1459return -EINVAL;1460input->type = V4L2_INPUT_TYPE_CAMERA;1461input->status = gspca_dev->cam.input_flags;1462strncpy(input->name, gspca_dev->sd_desc->name,1463sizeof input->name);1464return 0;1465}14661467static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)1468{1469*i = 0;1470return 0;1471}14721473static int vidioc_s_input(struct file *file, void *priv, unsigned int i)1474{1475if (i > 0)1476return -EINVAL;1477return (0);1478}14791480static int vidioc_reqbufs(struct file *file, void *priv,1481struct v4l2_requestbuffers *rb)1482{1483struct gspca_dev *gspca_dev = priv;1484int i, ret = 0, streaming;14851486i = rb->memory; /* (avoid compilation warning) */1487switch (i) {1488case GSPCA_MEMORY_READ: /* (internal call) */1489case V4L2_MEMORY_MMAP:1490case V4L2_MEMORY_USERPTR:1491break;1492default:1493return -EINVAL;1494}1495if (mutex_lock_interruptible(&gspca_dev->queue_lock))1496return -ERESTARTSYS;14971498if (gspca_dev->memory != GSPCA_MEMORY_NO1499&& gspca_dev->memory != GSPCA_MEMORY_READ1500&& gspca_dev->memory != rb->memory) {1501ret = -EBUSY;1502goto out;1503}15041505/* only one file may do the capture */1506if (gspca_dev->capt_file != NULL1507&& gspca_dev->capt_file != file) {1508ret = -EBUSY;1509goto out;1510}15111512/* if allocated, the buffers must not be mapped */1513for (i = 0; i < gspca_dev->nframes; i++) {1514if (gspca_dev->frame[i].vma_use_count) {1515ret = -EBUSY;1516goto out;1517}1518}15191520/* stop streaming */1521streaming = gspca_dev->streaming;1522if (streaming) {1523mutex_lock(&gspca_dev->usb_lock);1524gspca_dev->usb_err = 0;1525gspca_stream_off(gspca_dev);1526mutex_unlock(&gspca_dev->usb_lock);15271528/* Don't restart the stream when switching from read1529* to mmap mode */1530if (gspca_dev->memory == GSPCA_MEMORY_READ)1531streaming = 0;1532}15331534/* free the previous allocated buffers, if any */1535if (gspca_dev->nframes != 0)1536frame_free(gspca_dev);1537if (rb->count == 0) /* unrequest */1538goto out;1539ret = frame_alloc(gspca_dev, file, rb->memory, rb->count);1540if (ret == 0) {1541rb->count = gspca_dev->nframes;1542if (streaming)1543ret = gspca_init_transfer(gspca_dev);1544}1545out:1546mutex_unlock(&gspca_dev->queue_lock);1547PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count);1548return ret;1549}15501551static int vidioc_querybuf(struct file *file, void *priv,1552struct v4l2_buffer *v4l2_buf)1553{1554struct gspca_dev *gspca_dev = priv;1555struct gspca_frame *frame;15561557if (v4l2_buf->index < 01558|| v4l2_buf->index >= gspca_dev->nframes)1559return -EINVAL;15601561frame = &gspca_dev->frame[v4l2_buf->index];1562memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);1563return 0;1564}15651566static int vidioc_streamon(struct file *file, void *priv,1567enum v4l2_buf_type buf_type)1568{1569struct gspca_dev *gspca_dev = priv;1570int ret;15711572if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)1573return -EINVAL;1574if (mutex_lock_interruptible(&gspca_dev->queue_lock))1575return -ERESTARTSYS;15761577/* check the capture file */1578if (gspca_dev->capt_file != file) {1579ret = -EBUSY;1580goto out;1581}15821583if (gspca_dev->nframes == 01584|| !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {1585ret = -EINVAL;1586goto out;1587}1588if (!gspca_dev->streaming) {1589ret = gspca_init_transfer(gspca_dev);1590if (ret < 0)1591goto out;1592}1593#ifdef GSPCA_DEBUG1594if (gspca_debug & D_STREAM) {1595PDEBUG_MODE("stream on OK",1596gspca_dev->pixfmt,1597gspca_dev->width,1598gspca_dev->height);1599}1600#endif1601ret = 0;1602out:1603mutex_unlock(&gspca_dev->queue_lock);1604return ret;1605}16061607static int vidioc_streamoff(struct file *file, void *priv,1608enum v4l2_buf_type buf_type)1609{1610struct gspca_dev *gspca_dev = priv;1611int ret;16121613if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)1614return -EINVAL;16151616if (mutex_lock_interruptible(&gspca_dev->queue_lock))1617return -ERESTARTSYS;16181619if (!gspca_dev->streaming) {1620ret = 0;1621goto out;1622}16231624/* check the capture file */1625if (gspca_dev->capt_file != file) {1626ret = -EBUSY;1627goto out;1628}16291630/* stop streaming */1631if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {1632ret = -ERESTARTSYS;1633goto out;1634}1635gspca_dev->usb_err = 0;1636gspca_stream_off(gspca_dev);1637mutex_unlock(&gspca_dev->usb_lock);1638/* In case another thread is waiting in dqbuf */1639wake_up_interruptible(&gspca_dev->wq);16401641/* empty the transfer queues */1642atomic_set(&gspca_dev->fr_q, 0);1643atomic_set(&gspca_dev->fr_i, 0);1644gspca_dev->fr_o = 0;1645ret = 0;1646out:1647mutex_unlock(&gspca_dev->queue_lock);1648return ret;1649}16501651static int vidioc_g_jpegcomp(struct file *file, void *priv,1652struct v4l2_jpegcompression *jpegcomp)1653{1654struct gspca_dev *gspca_dev = priv;1655int ret;16561657if (!gspca_dev->sd_desc->get_jcomp)1658return -EINVAL;1659if (mutex_lock_interruptible(&gspca_dev->usb_lock))1660return -ERESTARTSYS;1661gspca_dev->usb_err = 0;1662if (gspca_dev->present)1663ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);1664else1665ret = -ENODEV;1666mutex_unlock(&gspca_dev->usb_lock);1667return ret;1668}16691670static int vidioc_s_jpegcomp(struct file *file, void *priv,1671struct v4l2_jpegcompression *jpegcomp)1672{1673struct gspca_dev *gspca_dev = priv;1674int ret;16751676if (!gspca_dev->sd_desc->set_jcomp)1677return -EINVAL;1678if (mutex_lock_interruptible(&gspca_dev->usb_lock))1679return -ERESTARTSYS;1680gspca_dev->usb_err = 0;1681if (gspca_dev->present)1682ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);1683else1684ret = -ENODEV;1685mutex_unlock(&gspca_dev->usb_lock);1686return ret;1687}16881689static int vidioc_g_parm(struct file *filp, void *priv,1690struct v4l2_streamparm *parm)1691{1692struct gspca_dev *gspca_dev = priv;16931694parm->parm.capture.readbuffers = gspca_dev->nbufread;16951696if (gspca_dev->sd_desc->get_streamparm) {1697int ret;16981699if (mutex_lock_interruptible(&gspca_dev->usb_lock))1700return -ERESTARTSYS;1701if (gspca_dev->present) {1702gspca_dev->usb_err = 0;1703gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);1704ret = gspca_dev->usb_err;1705} else {1706ret = -ENODEV;1707}1708mutex_unlock(&gspca_dev->usb_lock);1709return ret;1710}17111712return 0;1713}17141715static int vidioc_s_parm(struct file *filp, void *priv,1716struct v4l2_streamparm *parm)1717{1718struct gspca_dev *gspca_dev = priv;1719int n;17201721n = parm->parm.capture.readbuffers;1722if (n == 0 || n >= GSPCA_MAX_FRAMES)1723parm->parm.capture.readbuffers = gspca_dev->nbufread;1724else1725gspca_dev->nbufread = n;17261727if (gspca_dev->sd_desc->set_streamparm) {1728int ret;17291730if (mutex_lock_interruptible(&gspca_dev->usb_lock))1731return -ERESTARTSYS;1732if (gspca_dev->present) {1733gspca_dev->usb_err = 0;1734gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);1735ret = gspca_dev->usb_err;1736} else {1737ret = -ENODEV;1738}1739mutex_unlock(&gspca_dev->usb_lock);1740return ret;1741}17421743return 0;1744}17451746static int dev_mmap(struct file *file, struct vm_area_struct *vma)1747{1748struct gspca_dev *gspca_dev = file->private_data;1749struct gspca_frame *frame;1750struct page *page;1751unsigned long addr, start, size;1752int i, ret;17531754start = vma->vm_start;1755size = vma->vm_end - vma->vm_start;1756PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size);17571758if (mutex_lock_interruptible(&gspca_dev->queue_lock))1759return -ERESTARTSYS;1760if (!gspca_dev->present) {1761ret = -ENODEV;1762goto out;1763}1764if (gspca_dev->capt_file != file) {1765ret = -EINVAL;1766goto out;1767}17681769frame = NULL;1770for (i = 0; i < gspca_dev->nframes; ++i) {1771if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) {1772PDEBUG(D_STREAM, "mmap bad memory type");1773break;1774}1775if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT)1776== vma->vm_pgoff) {1777frame = &gspca_dev->frame[i];1778break;1779}1780}1781if (frame == NULL) {1782PDEBUG(D_STREAM, "mmap no frame buffer found");1783ret = -EINVAL;1784goto out;1785}1786if (size != frame->v4l2_buf.length) {1787PDEBUG(D_STREAM, "mmap bad size");1788ret = -EINVAL;1789goto out;1790}17911792/*1793* - VM_IO marks the area as being a mmaped region for I/O to a1794* device. It also prevents the region from being core dumped.1795*/1796vma->vm_flags |= VM_IO;17971798addr = (unsigned long) frame->data;1799while (size > 0) {1800page = vmalloc_to_page((void *) addr);1801ret = vm_insert_page(vma, start, page);1802if (ret < 0)1803goto out;1804start += PAGE_SIZE;1805addr += PAGE_SIZE;1806size -= PAGE_SIZE;1807}18081809vma->vm_ops = &gspca_vm_ops;1810vma->vm_private_data = frame;1811gspca_vm_open(vma);1812ret = 0;1813out:1814mutex_unlock(&gspca_dev->queue_lock);1815return ret;1816}18171818static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file,1819enum v4l2_memory memory)1820{1821if (!gspca_dev->present)1822return -ENODEV;1823if (gspca_dev->capt_file != file || gspca_dev->memory != memory ||1824!gspca_dev->streaming)1825return -EINVAL;18261827/* check if a frame is ready */1828return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i);1829}18301831static int frame_ready(struct gspca_dev *gspca_dev, struct file *file,1832enum v4l2_memory memory)1833{1834int ret;18351836if (mutex_lock_interruptible(&gspca_dev->queue_lock))1837return -ERESTARTSYS;1838ret = frame_ready_nolock(gspca_dev, file, memory);1839mutex_unlock(&gspca_dev->queue_lock);1840return ret;1841}18421843/*1844* dequeue a video buffer1845*1846* If nonblock_ing is false, block until a buffer is available.1847*/1848static int vidioc_dqbuf(struct file *file, void *priv,1849struct v4l2_buffer *v4l2_buf)1850{1851struct gspca_dev *gspca_dev = priv;1852struct gspca_frame *frame;1853int i, j, ret;18541855PDEBUG(D_FRAM, "dqbuf");18561857if (mutex_lock_interruptible(&gspca_dev->queue_lock))1858return -ERESTARTSYS;18591860for (;;) {1861ret = frame_ready_nolock(gspca_dev, file, v4l2_buf->memory);1862if (ret < 0)1863goto out;1864if (ret > 0)1865break;18661867mutex_unlock(&gspca_dev->queue_lock);18681869if (file->f_flags & O_NONBLOCK)1870return -EAGAIN;18711872/* wait till a frame is ready */1873ret = wait_event_interruptible_timeout(gspca_dev->wq,1874frame_ready(gspca_dev, file, v4l2_buf->memory),1875msecs_to_jiffies(3000));1876if (ret < 0)1877return ret;1878if (ret == 0)1879return -EIO;18801881if (mutex_lock_interruptible(&gspca_dev->queue_lock))1882return -ERESTARTSYS;1883}18841885i = gspca_dev->fr_o;1886j = gspca_dev->fr_queue[i];1887frame = &gspca_dev->frame[j];18881889gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;18901891if (gspca_dev->sd_desc->dq_callback) {1892mutex_lock(&gspca_dev->usb_lock);1893gspca_dev->usb_err = 0;1894if (gspca_dev->present)1895gspca_dev->sd_desc->dq_callback(gspca_dev);1896mutex_unlock(&gspca_dev->usb_lock);1897}18981899frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;1900memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);1901PDEBUG(D_FRAM, "dqbuf %d", j);1902ret = 0;19031904if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {1905if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,1906frame->data,1907frame->v4l2_buf.bytesused)) {1908PDEBUG(D_ERR|D_STREAM,1909"dqbuf cp to user failed");1910ret = -EFAULT;1911}1912}1913out:1914mutex_unlock(&gspca_dev->queue_lock);1915return ret;1916}19171918/*1919* queue a video buffer1920*1921* Attempting to queue a buffer that has already been1922* queued will return -EINVAL.1923*/1924static int vidioc_qbuf(struct file *file, void *priv,1925struct v4l2_buffer *v4l2_buf)1926{1927struct gspca_dev *gspca_dev = priv;1928struct gspca_frame *frame;1929int i, index, ret;19301931PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);19321933if (mutex_lock_interruptible(&gspca_dev->queue_lock))1934return -ERESTARTSYS;19351936index = v4l2_buf->index;1937if ((unsigned) index >= gspca_dev->nframes) {1938PDEBUG(D_FRAM,1939"qbuf idx %d >= %d", index, gspca_dev->nframes);1940ret = -EINVAL;1941goto out;1942}1943if (v4l2_buf->memory != gspca_dev->memory) {1944PDEBUG(D_FRAM, "qbuf bad memory type");1945ret = -EINVAL;1946goto out;1947}19481949frame = &gspca_dev->frame[index];1950if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) {1951PDEBUG(D_FRAM, "qbuf bad state");1952ret = -EINVAL;1953goto out;1954}19551956frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;19571958if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) {1959frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;1960frame->v4l2_buf.length = v4l2_buf->length;1961}19621963/* put the buffer in the 'queued' queue */1964i = atomic_read(&gspca_dev->fr_q);1965gspca_dev->fr_queue[i] = index;1966atomic_set(&gspca_dev->fr_q, (i + 1) % GSPCA_MAX_FRAMES);19671968v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;1969v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE;1970ret = 0;1971out:1972mutex_unlock(&gspca_dev->queue_lock);1973return ret;1974}19751976/*1977* allocate the resources for read()1978*/1979static int read_alloc(struct gspca_dev *gspca_dev,1980struct file *file)1981{1982struct v4l2_buffer v4l2_buf;1983int i, ret;19841985PDEBUG(D_STREAM, "read alloc");1986if (gspca_dev->nframes == 0) {1987struct v4l2_requestbuffers rb;19881989memset(&rb, 0, sizeof rb);1990rb.count = gspca_dev->nbufread;1991rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;1992rb.memory = GSPCA_MEMORY_READ;1993ret = vidioc_reqbufs(file, gspca_dev, &rb);1994if (ret != 0) {1995PDEBUG(D_STREAM, "read reqbuf err %d", ret);1996return ret;1997}1998memset(&v4l2_buf, 0, sizeof v4l2_buf);1999v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;2000v4l2_buf.memory = GSPCA_MEMORY_READ;2001for (i = 0; i < gspca_dev->nbufread; i++) {2002v4l2_buf.index = i;2003ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);2004if (ret != 0) {2005PDEBUG(D_STREAM, "read qbuf err: %d", ret);2006return ret;2007}2008}2009gspca_dev->memory = GSPCA_MEMORY_READ;2010}20112012/* start streaming */2013ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);2014if (ret != 0)2015PDEBUG(D_STREAM, "read streamon err %d", ret);2016return ret;2017}20182019static unsigned int dev_poll(struct file *file, poll_table *wait)2020{2021struct gspca_dev *gspca_dev = file->private_data;2022int ret;20232024PDEBUG(D_FRAM, "poll");20252026poll_wait(file, &gspca_dev->wq, wait);20272028/* if reqbufs is not done, the user would use read() */2029if (gspca_dev->memory == GSPCA_MEMORY_NO) {2030ret = read_alloc(gspca_dev, file);2031if (ret != 0)2032return POLLERR;2033}20342035if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)2036return POLLERR;20372038/* check if an image has been received */2039if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i))2040ret = POLLIN | POLLRDNORM; /* yes */2041else2042ret = 0;2043mutex_unlock(&gspca_dev->queue_lock);2044if (!gspca_dev->present)2045return POLLHUP;2046return ret;2047}20482049static ssize_t dev_read(struct file *file, char __user *data,2050size_t count, loff_t *ppos)2051{2052struct gspca_dev *gspca_dev = file->private_data;2053struct gspca_frame *frame;2054struct v4l2_buffer v4l2_buf;2055struct timeval timestamp;2056int n, ret, ret2;20572058PDEBUG(D_FRAM, "read (%zd)", count);2059if (!gspca_dev->present)2060return -ENODEV;2061if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */2062ret = read_alloc(gspca_dev, file);2063if (ret != 0)2064return ret;2065}20662067/* get a frame */2068timestamp = ktime_to_timeval(ktime_get());2069timestamp.tv_sec--;2070n = 2;2071for (;;) {2072memset(&v4l2_buf, 0, sizeof v4l2_buf);2073v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;2074v4l2_buf.memory = GSPCA_MEMORY_READ;2075ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);2076if (ret != 0) {2077PDEBUG(D_STREAM, "read dqbuf err %d", ret);2078return ret;2079}20802081/* if the process slept for more than 1 second,2082* get a newer frame */2083frame = &gspca_dev->frame[v4l2_buf.index];2084if (--n < 0)2085break; /* avoid infinite loop */2086if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec)2087break;2088ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);2089if (ret != 0) {2090PDEBUG(D_STREAM, "read qbuf err %d", ret);2091return ret;2092}2093}20942095/* copy the frame */2096if (count > frame->v4l2_buf.bytesused)2097count = frame->v4l2_buf.bytesused;2098ret = copy_to_user(data, frame->data, count);2099if (ret != 0) {2100PDEBUG(D_ERR|D_STREAM,2101"read cp to user lack %d / %zd", ret, count);2102ret = -EFAULT;2103goto out;2104}2105ret = count;2106out:2107/* in each case, requeue the buffer */2108ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf);2109if (ret2 != 0)2110return ret2;2111return ret;2112}21132114static struct v4l2_file_operations dev_fops = {2115.owner = THIS_MODULE,2116.open = dev_open,2117.release = dev_close,2118.read = dev_read,2119.mmap = dev_mmap,2120.unlocked_ioctl = video_ioctl2,2121.poll = dev_poll,2122};21232124static const struct v4l2_ioctl_ops dev_ioctl_ops = {2125.vidioc_querycap = vidioc_querycap,2126.vidioc_dqbuf = vidioc_dqbuf,2127.vidioc_qbuf = vidioc_qbuf,2128.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,2129.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,2130.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,2131.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,2132.vidioc_streamon = vidioc_streamon,2133.vidioc_queryctrl = vidioc_queryctrl,2134.vidioc_g_ctrl = vidioc_g_ctrl,2135.vidioc_s_ctrl = vidioc_s_ctrl,2136.vidioc_querymenu = vidioc_querymenu,2137.vidioc_enum_input = vidioc_enum_input,2138.vidioc_g_input = vidioc_g_input,2139.vidioc_s_input = vidioc_s_input,2140.vidioc_reqbufs = vidioc_reqbufs,2141.vidioc_querybuf = vidioc_querybuf,2142.vidioc_streamoff = vidioc_streamoff,2143.vidioc_g_jpegcomp = vidioc_g_jpegcomp,2144.vidioc_s_jpegcomp = vidioc_s_jpegcomp,2145.vidioc_g_parm = vidioc_g_parm,2146.vidioc_s_parm = vidioc_s_parm,2147.vidioc_enum_framesizes = vidioc_enum_framesizes,2148.vidioc_enum_frameintervals = vidioc_enum_frameintervals,2149#ifdef CONFIG_VIDEO_ADV_DEBUG2150.vidioc_g_register = vidioc_g_register,2151.vidioc_s_register = vidioc_s_register,2152#endif2153.vidioc_g_chip_ident = vidioc_g_chip_ident,2154};21552156static const struct video_device gspca_template = {2157.name = "gspca main driver",2158.fops = &dev_fops,2159.ioctl_ops = &dev_ioctl_ops,2160.release = gspca_release,2161};21622163/* initialize the controls */2164static void ctrls_init(struct gspca_dev *gspca_dev)2165{2166struct gspca_ctrl *ctrl;2167int i;21682169for (i = 0, ctrl = gspca_dev->cam.ctrls;2170i < gspca_dev->sd_desc->nctrls;2171i++, ctrl++) {2172ctrl->def = gspca_dev->sd_desc->ctrls[i].qctrl.default_value;2173ctrl->val = ctrl->def;2174ctrl->min = gspca_dev->sd_desc->ctrls[i].qctrl.minimum;2175ctrl->max = gspca_dev->sd_desc->ctrls[i].qctrl.maximum;2176}2177}21782179/*2180* probe and create a new gspca device2181*2182* This function must be called by the sub-driver when it is2183* called for probing a new device.2184*/2185int gspca_dev_probe2(struct usb_interface *intf,2186const struct usb_device_id *id,2187const struct sd_desc *sd_desc,2188int dev_size,2189struct module *module)2190{2191struct gspca_dev *gspca_dev;2192struct usb_device *dev = interface_to_usbdev(intf);2193int ret;21942195PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct);21962197/* create the device */2198if (dev_size < sizeof *gspca_dev)2199dev_size = sizeof *gspca_dev;2200gspca_dev = kzalloc(dev_size, GFP_KERNEL);2201if (!gspca_dev) {2202err("couldn't kzalloc gspca struct");2203return -ENOMEM;2204}2205gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);2206if (!gspca_dev->usb_buf) {2207err("out of memory");2208ret = -ENOMEM;2209goto out;2210}2211gspca_dev->dev = dev;2212gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber;2213gspca_dev->nbalt = intf->num_altsetting;22142215/* check if any audio device */2216if (dev->config->desc.bNumInterfaces != 1) {2217int i;2218struct usb_interface *intf2;22192220for (i = 0; i < dev->config->desc.bNumInterfaces; i++) {2221intf2 = dev->config->interface[i];2222if (intf2 != NULL2223&& intf2->altsetting != NULL2224&& intf2->altsetting->desc.bInterfaceClass ==2225USB_CLASS_AUDIO) {2226gspca_dev->audio = 1;2227break;2228}2229}2230}22312232gspca_dev->sd_desc = sd_desc;2233gspca_dev->nbufread = 2;2234gspca_dev->empty_packet = -1; /* don't check the empty packets */22352236/* configure the subdriver and initialize the USB device */2237ret = sd_desc->config(gspca_dev, id);2238if (ret < 0)2239goto out;2240if (gspca_dev->cam.ctrls != NULL)2241ctrls_init(gspca_dev);2242ret = sd_desc->init(gspca_dev);2243if (ret < 0)2244goto out;2245gspca_set_default_mode(gspca_dev);22462247ret = gspca_input_connect(gspca_dev);2248if (ret)2249goto out;22502251mutex_init(&gspca_dev->usb_lock);2252mutex_init(&gspca_dev->queue_lock);2253init_waitqueue_head(&gspca_dev->wq);22542255/* init video stuff */2256memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);2257gspca_dev->vdev.parent = &intf->dev;2258gspca_dev->module = module;2259gspca_dev->present = 1;2260ret = video_register_device(&gspca_dev->vdev,2261VFL_TYPE_GRABBER,2262-1);2263if (ret < 0) {2264err("video_register_device err %d", ret);2265goto out;2266}22672268usb_set_intfdata(intf, gspca_dev);2269PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));22702271gspca_input_create_urb(gspca_dev);22722273return 0;2274out:2275#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)2276if (gspca_dev->input_dev)2277input_unregister_device(gspca_dev->input_dev);2278#endif2279kfree(gspca_dev->usb_buf);2280kfree(gspca_dev);2281return ret;2282}2283EXPORT_SYMBOL(gspca_dev_probe2);22842285/* same function as the previous one, but check the interface */2286int gspca_dev_probe(struct usb_interface *intf,2287const struct usb_device_id *id,2288const struct sd_desc *sd_desc,2289int dev_size,2290struct module *module)2291{2292struct usb_device *dev = interface_to_usbdev(intf);22932294/* we don't handle multi-config cameras */2295if (dev->descriptor.bNumConfigurations != 1) {2296err("%04x:%04x too many config",2297id->idVendor, id->idProduct);2298return -ENODEV;2299}23002301/* the USB video interface must be the first one */2302if (dev->config->desc.bNumInterfaces != 12303&& intf->cur_altsetting->desc.bInterfaceNumber != 0)2304return -ENODEV;23052306return gspca_dev_probe2(intf, id, sd_desc, dev_size, module);2307}2308EXPORT_SYMBOL(gspca_dev_probe);23092310/*2311* USB disconnection2312*2313* This function must be called by the sub-driver2314* when the device disconnects, after the specific resources are freed.2315*/2316void gspca_disconnect(struct usb_interface *intf)2317{2318struct gspca_dev *gspca_dev = usb_get_intfdata(intf);2319#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)2320struct input_dev *input_dev;2321#endif23222323PDEBUG(D_PROBE, "%s disconnect",2324video_device_node_name(&gspca_dev->vdev));2325mutex_lock(&gspca_dev->usb_lock);23262327gspca_dev->present = 0;2328wake_up_interruptible(&gspca_dev->wq);23292330destroy_urbs(gspca_dev);23312332#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)2333gspca_input_destroy_urb(gspca_dev);2334input_dev = gspca_dev->input_dev;2335if (input_dev) {2336gspca_dev->input_dev = NULL;2337input_unregister_device(input_dev);2338}2339#endif23402341/* the device is freed at exit of this function */2342gspca_dev->dev = NULL;2343mutex_unlock(&gspca_dev->usb_lock);23442345usb_set_intfdata(intf, NULL);23462347/* release the device */2348/* (this will call gspca_release() immediately or on last close) */2349video_unregister_device(&gspca_dev->vdev);23502351/* PDEBUG(D_PROBE, "disconnect complete"); */2352}2353EXPORT_SYMBOL(gspca_disconnect);23542355#ifdef CONFIG_PM2356int gspca_suspend(struct usb_interface *intf, pm_message_t message)2357{2358struct gspca_dev *gspca_dev = usb_get_intfdata(intf);23592360if (!gspca_dev->streaming)2361return 0;2362gspca_dev->frozen = 1; /* avoid urb error messages */2363if (gspca_dev->sd_desc->stopN)2364gspca_dev->sd_desc->stopN(gspca_dev);2365destroy_urbs(gspca_dev);2366gspca_input_destroy_urb(gspca_dev);2367gspca_set_alt0(gspca_dev);2368if (gspca_dev->sd_desc->stop0)2369gspca_dev->sd_desc->stop0(gspca_dev);2370return 0;2371}2372EXPORT_SYMBOL(gspca_suspend);23732374int gspca_resume(struct usb_interface *intf)2375{2376struct gspca_dev *gspca_dev = usb_get_intfdata(intf);23772378gspca_dev->frozen = 0;2379gspca_dev->sd_desc->init(gspca_dev);2380gspca_input_create_urb(gspca_dev);2381if (gspca_dev->streaming)2382return gspca_init_transfer(gspca_dev);2383return 0;2384}2385EXPORT_SYMBOL(gspca_resume);2386#endif2387/* -- cam driver utility functions -- */23882389/* auto gain and exposure algorithm based on the knee algorithm described here:2390http://ytse.tricolour.net/docs/LowLightOptimization.html23912392Returns 0 if no changes were made, 1 if the gain and or exposure settings2393where changed. */2394int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,2395int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee)2396{2397int i, steps, gain, orig_gain, exposure, orig_exposure, autogain;2398const struct ctrl *gain_ctrl = NULL;2399const struct ctrl *exposure_ctrl = NULL;2400const struct ctrl *autogain_ctrl = NULL;2401int retval = 0;24022403for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {2404if (gspca_dev->ctrl_dis & (1 << i))2405continue;2406if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)2407gain_ctrl = &gspca_dev->sd_desc->ctrls[i];2408if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)2409exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];2410if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_AUTOGAIN)2411autogain_ctrl = &gspca_dev->sd_desc->ctrls[i];2412}2413if (!gain_ctrl || !exposure_ctrl || !autogain_ctrl) {2414PDEBUG(D_ERR, "Error: gspca_auto_gain_n_exposure called "2415"on cam without (auto)gain/exposure");2416return 0;2417}24182419if (gain_ctrl->get(gspca_dev, &gain) ||2420exposure_ctrl->get(gspca_dev, &exposure) ||2421autogain_ctrl->get(gspca_dev, &autogain) || !autogain)2422return 0;24232424orig_gain = gain;2425orig_exposure = exposure;24262427/* If we are of a multiple of deadzone, do multiple steps to reach the2428desired lumination fast (with the risc of a slight overshoot) */2429steps = abs(desired_avg_lum - avg_lum) / deadzone;24302431PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",2432avg_lum, desired_avg_lum, steps);24332434for (i = 0; i < steps; i++) {2435if (avg_lum > desired_avg_lum) {2436if (gain > gain_knee)2437gain--;2438else if (exposure > exposure_knee)2439exposure--;2440else if (gain > gain_ctrl->qctrl.default_value)2441gain--;2442else if (exposure > exposure_ctrl->qctrl.minimum)2443exposure--;2444else if (gain > gain_ctrl->qctrl.minimum)2445gain--;2446else2447break;2448} else {2449if (gain < gain_ctrl->qctrl.default_value)2450gain++;2451else if (exposure < exposure_knee)2452exposure++;2453else if (gain < gain_knee)2454gain++;2455else if (exposure < exposure_ctrl->qctrl.maximum)2456exposure++;2457else if (gain < gain_ctrl->qctrl.maximum)2458gain++;2459else2460break;2461}2462}24632464if (gain != orig_gain) {2465gain_ctrl->set(gspca_dev, gain);2466retval = 1;2467}2468if (exposure != orig_exposure) {2469exposure_ctrl->set(gspca_dev, exposure);2470retval = 1;2471}24722473return retval;2474}2475EXPORT_SYMBOL(gspca_auto_gain_n_exposure);24762477/* -- module insert / remove -- */2478static int __init gspca_init(void)2479{2480info("v%d.%d.%d registered",2481(DRIVER_VERSION_NUMBER >> 16) & 0xff,2482(DRIVER_VERSION_NUMBER >> 8) & 0xff,2483DRIVER_VERSION_NUMBER & 0xff);2484return 0;2485}2486static void __exit gspca_exit(void)2487{2488}24892490module_init(gspca_init);2491module_exit(gspca_exit);24922493#ifdef GSPCA_DEBUG2494module_param_named(debug, gspca_debug, int, 0644);2495MODULE_PARM_DESC(debug,2496"Debug (bit) 0x01:error 0x02:probe 0x04:config"2497" 0x08:stream 0x10:frame 0x20:packet"2498" 0x0100: v4l2");2499#endif250025012502