⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpia.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
*f++ = LIMIT(b + y1); *f++ = LIMIT(g + y1); *f++ = LIMIT(r + y1);copylen += 6;				}			}			/* Skip the last byte */			data++;			if (++frame->curline >= frame->hdrheight)				goto nextframe;			break;		} /* end case STATE_LINES */		} /* end switch (scanstate) */	} /* end while (1) */nextframe:	if (debug >= 1)		printk(KERN_DEBUG "cpia: marking as success\n");	if (scratch_left(data) >= 4 && *((__u32 *)data) == 0xFFFFFFFF)		data += 4;	frame->grabstate = FRAME_DONE;	goto wakeup;error:	if (debug >= 1)		printk(KERN_DEBUG "cpia: marking as error\n");	frame->grabstate = FRAME_ERROR;	/* Get a fresh frame since this frame may have been important */	cpia->compress = 0;	copylen = 0;wakeup:	cpia->curframe = -1;	/* This will cause the process to request another frame. */	if (waitqueue_active(&frame->wq))		wake_up_interruptible(&frame->wq);out:	/* Grab the remaining */	left = scratch_left(data);	memmove(cpia->scratch, data, left);	cpia->scratchlen = left;	/* Update the frame's uncompressed length. */	frame->scanlength += copylen;}/* * Make all of the blocks of data contiguous */static int cpia_compress_isochronous(struct usb_cpia *cpia, urb_t *urb){	unsigned char *cdata, *data;	int i, totlen = 0;	data = cpia->scratch + cpia->scratchlen;	for (i = 0; i < urb->number_of_packets; i++) {		int n = urb->iso_frame_desc[i].actual_length;		int st = urb->iso_frame_desc[i].status;				cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;		if (st && debug >= 1)			printk(KERN_DEBUG "cpia data error: [%d] len=%d, status=%X\n",				i, n, st);		if ((cpia->scratchlen + n) > SCRATCH_BUF_SIZE) {			printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n",cpia->scratchlen, n );			return totlen;		}		if (n) {			memmove(data, cdata, n);			data += n;			totlen += n;			cpia->scratchlen += n;		}	}	return totlen;}static void cpia_isoc_irq(struct urb *urb){	int len;	struct usb_cpia *cpia = urb->context;	struct cpia_sbuf *sbuf;	int i;#if 0printk("cpia_isoc_irq: %p status %d, errcount = %d, length = %d\n", urb, urb->status, urb->error_count, urb->actual_length);#endif	if (!cpia->streaming) {		if (debug >= 1)			printk(KERN_DEBUG "cpia: oops, not streaming, but interrupt\n");		return;	}		sbuf = &cpia->sbuf[cpia->cursbuf];	// usb_kill_isoc(sbuf->isodesc);	/* Copy the data received into our scratch buffer */	len = cpia_compress_isochronous(cpia, urb);	/* If we don't have a frame we're current working on, complain */	if (cpia->scratchlen) {		if (cpia->curframe < 0) {			if (debug >= 1)				printk(KERN_DEBUG "cpia: received data, but no frame available\n");		} else			cpia_parse_data(cpia);	}	for (i = 0; i < FRAMES_PER_DESC; i++) {		sbuf->urb->iso_frame_desc[i].status = 0;		sbuf->urb->iso_frame_desc[i].actual_length = 0;	}	/* Move to the next sbuf */	cpia->cursbuf = (cpia->cursbuf + 1) % CPIA_NUMSBUF;	/* Reschedule this block of Isochronous desc */	// usb_run_isoc(sbuf->isodesc, cpia->sbuf[cpia->cursbuf].isodesc);	return;}static int cpia_init_isoc(struct usb_cpia *cpia){	struct usb_device *dev = cpia->dev;	urb_t *urb;	int fx, err;	cpia->compress = 0;	cpia->curframe = -1;	cpia->cursbuf = 0;	cpia->scratchlen = 0;	/* Alternate interface 3 is is the biggest frame size */	if (usb_set_interface(cpia->dev, cpia->iface, 3) < 0) {		printk(KERN_ERR "usb_set_interface error\n");		return -EBUSY;	}	/* We double buffer the Iso lists *///	err = usb_init_isoc(dev, usb_rcvisocpipe(dev, 1), FRAMES_PER_DESC, cpia, &cpia->sbuf[0].isodesc);	urb = usb_alloc_urb(FRAMES_PER_DESC);		if (!urb) {		printk(KERN_ERR "cpia_init_isoc: usb_init_isoc ret %d\n",			0);		return -ENOMEM;	}	cpia->sbuf[0].urb = urb;	urb->dev = dev;	urb->context = cpia;	urb->pipe = usb_rcvisocpipe(dev, 1);	urb->transfer_flags = USB_ISO_ASAP;	urb->transfer_buffer = cpia->sbuf[0].data; 	urb->complete = cpia_isoc_irq; 	urb->number_of_packets = FRAMES_PER_DESC; 	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);	if (!urb) {		printk(KERN_ERR "cpia_init_isoc: usb_init_isoc ret %d\n",			0);		return -ENOMEM;	}	cpia->sbuf[1].urb = urb;	urb->dev = dev;	urb->context = cpia;	urb->pipe = usb_rcvisocpipe(dev, 1);	urb->transfer_flags = USB_ISO_ASAP;	urb->transfer_buffer = cpia->sbuf[1].data; 	urb->complete = cpia_isoc_irq; 	urb->number_of_packets = FRAMES_PER_DESC; 	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;	}	cpia->sbuf[1].urb->next = cpia->sbuf[0].urb;	cpia->sbuf[0].urb->next = cpia->sbuf[1].urb;		err = usb_submit_urb(cpia->sbuf[0].urb);	if (err)		printk(KERN_ERR "cpia_init_isoc: usb_run_isoc(0) ret %d\n",			err);	err = usb_submit_urb(cpia->sbuf[1].urb);	if (err)		printk(KERN_ERR "cpia_init_isoc: usb_run_isoc(1) ret %d\n",			err);	cpia->streaming = 1;	return 0;}static void cpia_stop_isoc(struct usb_cpia *cpia){	if (!cpia->streaming)		return;	/* Turn off continuous grab */	if (usb_cpia_set_grab_mode(cpia->dev, 0) < 0) {		printk(KERN_ERR "cpia_set_grab_mode error\n");		return /* -EBUSY */;	}	/* Set packet size to 0 */	if (usb_set_interface(cpia->dev, cpia->iface, 0) < 0) {		printk(KERN_ERR "usb_set_interface error\n");		return /* -EINVAL */;	}	/* Unschedule all of the iso td's */	usb_unlink_urb(cpia->sbuf[1].urb);	usb_unlink_urb(cpia->sbuf[0].urb);	cpia->streaming = 0;	/* Delete them all */	usb_free_urb(cpia->sbuf[1].urb);	usb_free_urb(cpia->sbuf[0].urb);}static int cpia_new_frame(struct usb_cpia *cpia, int framenum){	struct cpia_frame *frame;	int width, height;	/* If we're not grabbing a frame right now and the other frame is */	/*  ready to be grabbed into, then use it instead */	if (cpia->curframe == -1) {		if (cpia->frame[(framenum - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES].grabstate == FRAME_READY)			framenum = (framenum - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES;	} else		return 0;	frame = &cpia->frame[framenum];	width = frame->width;	height = frame->height;	frame->grabstate = FRAME_GRABBING;	frame->scanstate = STATE_SCANNING;	frame->scanlength = 0;		/* accumulated in cpia_parse_data() */	cpia->curframe = framenum;	/* Make sure it's not too big */	if (width > 352)		width = 352;	width = (width / 8) * 8;	/* Multiple of 8 */	if (height > 288)		height = 288;	height = (height / 4) * 4;	/* Multiple of 4 */	/* Set the ROI they want */	if (usb_cpia_set_roi(cpia->dev, 0, width / 8, 0, height / 4) < 0)		return -EBUSY;	if (usb_cpia_set_compression(cpia->dev, cpia->compress ?			COMP_AUTO : COMP_DISABLED, DONT_DECIMATE) < 0) {		printk(KERN_ERR "cpia_set_compression error\n");		return -EBUSY;	}	/* We want a fresh frame every 30 we get */	cpia->compress = (cpia->compress + 1) % 30;	/* Grab the frame */	if (usb_cpia_upload_frame(cpia->dev, WAIT_FOR_NEXT_FRAME) < 0) {		printk(KERN_ERR "cpia_upload_frame error\n");		return -EBUSY;	}	return 0;}/* Video 4 Linux API */static int cpia_open(struct video_device *dev, int flags){	int err = -EBUSY;	struct usb_cpia *cpia = (struct usb_cpia *)dev;	down(&cpia->lock);	if (cpia->user)		goto out_unlock;	cpia->frame[0].grabstate = FRAME_UNUSED;	cpia->frame[1].grabstate = FRAME_UNUSED;	err = -ENOMEM;	/* Allocate memory for the frame buffers */	cpia->fbuf = rvmalloc(2 * MAX_FRAME_SIZE);	if (!cpia->fbuf)		goto open_err_ret;	cpia->frame[0].data = cpia->fbuf;	cpia->frame[1].data = cpia->fbuf + MAX_FRAME_SIZE;	cpia->sbuf[0].data = kmalloc (FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);	if (!cpia->sbuf[0].data)		goto open_err_on0;	cpia->sbuf[1].data = kmalloc (FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);	if (!cpia->sbuf[1].data)		goto open_err_on1;	/* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used	 * (using read() instead). */	cpia->frame[0].width = 352;	cpia->frame[0].height = 288;	cpia->frame[0].bytes_read = 0;	cpia->frame[1].width = 352;	cpia->frame[1].height = 288;	cpia->frame[1].bytes_read = 0;	err = cpia_init_isoc(cpia);	if (err)		goto open_err_on2;	cpia->user++;	up(&cpia->lock);	MOD_INC_USE_COUNT;	return 0;open_err_on2:	kfree (cpia->sbuf[1].data);open_err_on1:	kfree (cpia->sbuf[0].data);open_err_on0:	rvfree(cpia->fbuf, 2 * MAX_FRAME_SIZE);open_err_ret:	return err;out_unlock:	up(&cpia->lock);	return err;}static void cpia_close(struct video_device *dev){	struct usb_cpia *cpia = (struct usb_cpia *)dev;	down(&cpia->lock);		cpia->user--;	MOD_DEC_USE_COUNT;	cpia_stop_isoc(cpia);	rvfree(cpia->fbuf, 2 * MAX_FRAME_SIZE);	kfree(cpia->sbuf[1].data);	kfree(cpia->sbuf[0].data);	up(&cpia->lock);}static int cpia_init_done(struct video_device *dev){	return 0;}static long cpia_write(struct video_device *dev, const char *buf, unsigned long count, int noblock){	return -EINVAL;}static int cpia_ioctl(struct video_device *dev, unsigned int cmd, void *arg){	struct usb_cpia *cpia = (struct usb_cpia *)dev;	switch (cmd) {		case VIDIOCGCAP:		{			struct video_capability b;			strcpy(b.name, "CPiA USB Camera");			b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;			b.channels = 1;			b.audios = 0;			b.maxwidth = 352;	/* CIF */			b.maxheight = 288;	/*  "  */			b.minwidth = 8;			b.minheight = 4;			if (copy_to_user(arg, &b, sizeof(b)))				return -EFAULT;			return 0;		}		case VIDIOCGCHAN:		{			struct video_channel v;			if (copy_from_user(&v, arg, sizeof(v)))				return -EFAULT;			if (v.channel != 0)				return -EINVAL;			v.flags = 0;			v.tuners = 0;			v.type = VIDEO_TYPE_CAMERA;			strcpy(v.name, "Camera");			if (copy_to_user(arg, &v, sizeof(v)))				return -EFAULT;			return 0;		}		case VIDIOCSCHAN:		{			int v;			if (copy_from_user(&v, arg, sizeof(v)))				return -EFAULT;			if (v != 0)				return -EINVAL;			return 0;		}		case VIDIOCGPICT:		{			struct video_picture p;			p.colour = 0x8000;	/* Damn British people :) */			p.hue = 0x8000;			p.brightness = 180 << 8;	/* XXX */			p.contrast = 192 << 8;		/* XXX */			p.whiteness = 105 << 8;		/* XXX */			p.depth = 24;			p.palette = VIDEO_PALETTE_RGB24;			if (copy_to_user(arg, &p, sizeof(p)))				return -EFAULT;			return 0;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -