All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab@infradead.org>
To: sensoray-dev <linux-dev@sensoray.com>
Cc: linux-media@vger.kernel.org, Douglas Landgraf <dougsland@gmail.com>
Subject: Re: [PATCH] s2255drv: cleanup of device structure
Date: Wed, 21 Apr 2010 01:30:17 -0300	[thread overview]
Message-ID: <20100421013017.2770faa8@pedra> (raw)
In-Reply-To: <tkrat.7c7e306760d428af@sensoray.com>

Hi Dean,

Em Mon, 12 Apr 2010 10:19:13 -0700 (PDT)
sensoray-dev <linux-dev@sensoray.com> escreveu:

> # HG changeset patch
> # User Dean Anderson <linux-dev@sensoray.com>
> # Date 1271092523 25200
> # Node ID 686a2330f4a6a4c79e299a17663f0f150031098e
> # Parent  f2f44853e2eb914d4fc6c7004631839b86fb6d0e
> s2255drv: cleanup of device structure
> 
> From: Dean Anderson <linux-dev@sensoray.com>
> 
> cleanup of device structure
> better organization of channels instead of multiple arrays in device
> simplifies open callback by removing search for channel index
> adding v4l2_device_disconnect
> 
> Priority: normal
> 
> Signed-off-by: Dean Anderson <linux-dev@sensoray.com>


Sorry, but the patch didn't apply:

patching file drivers/media/video/s2255drv.c
Hunk #1 succeeded at 190 (offset -1 lines).
Hunk #3 succeeded at 305 (offset -1 lines).
Hunk #5 succeeded at 577 (offset -1 lines).
Hunk #7 succeeded at 622 (offset -1 lines).
Hunk #9 succeeded at 661 (offset -1 lines).
Hunk #11 succeeded at 686 (offset -1 lines).
Hunk #13 succeeded at 754 (offset -1 lines).
Hunk #15 succeeded at 778 (offset -1 lines).
Hunk #17 succeeded at 893 (offset -1 lines).
Hunk #19 succeeded at 1013 (offset -1 lines).
Hunk #21 succeeded at 1243 (offset -1 lines).
Hunk #23 succeeded at 1307 (offset -1 lines).
Hunk #25 succeeded at 1353 (offset -1 lines).
Hunk #27 succeeded at 1414 (offset -1 lines).
Hunk #29 succeeded at 1435 (offset -1 lines).
Hunk #31 succeeded at 1477 (offset -1 lines).
Hunk #33 succeeded at 1531 (offset -1 lines).
Hunk #35 succeeded at 1584 (offset -1 lines).
Hunk #37 succeeded at 1632 (offset -1 lines).
Hunk #39 succeeded at 1711 (offset -1 lines).
Hunk #41 succeeded at 1843 (offset -1 lines).
Hunk #43 succeeded at 1925 (offset -1 lines).
Hunk #44 FAILED at 1947.
Hunk #45 succeeded at 2017 (offset 1 line).
Hunk #46 succeeded at 2044 (offset -1 lines).
Hunk #47 succeeded at 2065 (offset 1 line).
Hunk #48 succeeded at 2084 (offset -1 lines).
Hunk #49 succeeded at 2105 (offset 1 line).
Hunk #50 succeeded at 2132 (offset -1 lines).
Hunk #51 succeeded at 2228 (offset 1 line).
Hunk #52 succeeded at 2240 (offset -1 lines).
Hunk #53 succeeded at 2312 (offset 1 line).
Hunk #54 succeeded at 2337 (offset -1 lines).
Hunk #55 succeeded at 2437 (offset 1 line).
Hunk #56 succeeded at 2465 (offset -1 lines).
Hunk #57 succeeded at 2492 (offset 1 line).
Hunk #58 succeeded at 2548 (offset -1 lines).
Hunk #59 succeeded at 2587 (offset 1 line).
Hunk #60 succeeded at 2626 (offset -1 lines).
Hunk #61 succeeded at 2670 (offset 1 line).
1 out of 61 hunks FAILED -- saving rejects to file drivers/media/video/s2255drv.c.rej
>>> Patch patches/lmml_92061_s2255drv_cleanup_of_device_structure.patch doesn't apply

I might try to fix the failed hunk, but I prefer if you could double check what's going
wrong, since this is a long patch that are replacing some structs.

Please use my -git tree as the basis, since Douglas is currently in a training
and it may take some time until he could be able to sync the -hg tree.




> 
> diff -r f2f44853e2eb -r 686a2330f4a6 linux/drivers/media/video/s2255drv.c
> --- a/linux/drivers/media/video/s2255drv.c	Fri Apr 09 15:51:28 2010 -0700
> +++ b/linux/drivers/media/video/s2255drv.c	Mon Apr 12 10:15:23 2010 -0700
> @@ -191,7 +191,6 @@
>  struct s2255_dmaqueue {
>  	struct list_head	active;
>  	struct s2255_dev	*dev;
> -	int			channel;
>  };
>  
>  /* for firmware loading, fw_state */
> @@ -226,51 +225,60 @@
>  };
>  
>  struct s2255_fmt; /*forward declaration */
> +struct s2255_dev;
> +
> +struct s2255_channel {
> +	struct video_device	vdev;
> +	int			resources;
> +	struct s2255_dmaqueue	vidq;
> +	struct s2255_bufferi	buffer;
> +	struct s2255_mode	mode;
> +	/* jpeg compression */
> +	struct v4l2_jpegcompression jc;
> +	/* capture parameters (for high quality mode full size) */
> +	struct v4l2_captureparm cap_parm;
> +	int			cur_frame;
> +	int			last_frame;
> +
> +	int			b_acquire;
> +	/* allocated image size */
> +	unsigned long		req_image_size;
> +	/* received packet size */
> +	unsigned long		pkt_size;
> +	int			bad_payload;
> +	unsigned long		frame_count;
> +	/* if JPEG image */
> +	int                     jpg_size;
> +	/* if channel configured to default state */
> +	int                     configured;
> +	wait_queue_head_t       wait_setmode;
> +	int                     setmode_ready;
> +	/* video status items */
> +	int                     vidstatus;
> +	wait_queue_head_t       wait_vidstatus;
> +	int                     vidstatus_ready;
> +	unsigned int		width;
> +	unsigned int		height;
> +	const struct s2255_fmt	*fmt;
> +	int idx; /* channel number on device, 0-3 */
> +};
> +
>  
>  struct s2255_dev {
> -	struct video_device	vdev[MAX_CHANNELS];
> +	struct s2255_channel    channel[MAX_CHANNELS];
>  	struct v4l2_device 	v4l2_dev;
> -	atomic_t                channels; /* number of channels registered */
> +	atomic_t                num_channels;
>  	int			frames;
>  	struct mutex		lock;
>  	struct mutex		open_lock;
> -	int			resources[MAX_CHANNELS];
>  	struct usb_device	*udev;
>  	struct usb_interface	*interface;
>  	u8			read_endpoint;
> -
> -	struct s2255_dmaqueue	vidq[MAX_CHANNELS];
>  	struct timer_list	timer;
>  	struct s2255_fw	*fw_data;
>  	struct s2255_pipeinfo	pipe;
> -	struct s2255_bufferi	buffer[MAX_CHANNELS];
> -	struct s2255_mode	mode[MAX_CHANNELS];
> -	/* jpeg compression */
> -	struct v4l2_jpegcompression jc[MAX_CHANNELS];
> -	/* capture parameters (for high quality mode full size) */
> -	struct v4l2_captureparm cap_parm[MAX_CHANNELS];
> -	const struct s2255_fmt	*cur_fmt[MAX_CHANNELS];
> -	int			cur_frame[MAX_CHANNELS];
> -	int			last_frame[MAX_CHANNELS];
>  	u32			cc;	/* current channel */
> -	int			b_acquire[MAX_CHANNELS];
> -	/* allocated image size */
> -	unsigned long		req_image_size[MAX_CHANNELS];
> -	/* received packet size */
> -	unsigned long		pkt_size[MAX_CHANNELS];
> -	int			bad_payload[MAX_CHANNELS];
> -	unsigned long		frame_count[MAX_CHANNELS];
>  	int			frame_ready;
> -	/* if JPEG image */
> -	int                     jpg_size[MAX_CHANNELS];
> -	/* if channel configured to default state */
> -	int                     chn_configured[MAX_CHANNELS];
> -	wait_queue_head_t       wait_setmode[MAX_CHANNELS];
> -	int                     setmode_ready[MAX_CHANNELS];
> -	/* video status items */
> -	int                     vidstatus[MAX_CHANNELS];
> -	wait_queue_head_t       wait_vidstatus[MAX_CHANNELS];
> -	int                     vidstatus_ready[MAX_CHANNELS];
>  	int                     chn_ready;
>  	spinlock_t              slock;
>  	/* dsp firmware version (f2255usb.bin) */
> @@ -298,16 +306,10 @@
>  
>  struct s2255_fh {
>  	struct s2255_dev	*dev;
> -	const struct s2255_fmt	*fmt;
> -	unsigned int		width;
> -	unsigned int		height;
>  	struct videobuf_queue	vb_vidq;
>  	enum v4l2_buf_type	type;
> -	int			channel;
> -	/* mode below is the desired mode.
> -	   mode in s2255_dev is the current mode that was last set */
> -	struct s2255_mode	mode;
> -	int			resources[MAX_CHANNELS];
> +	struct s2255_channel	*channel;
> +	int			resources;
>  };
>  
>  /* current cypress EEPROM firmware version */
> @@ -360,12 +362,11 @@
>  
>  static int s2255_start_readpipe(struct s2255_dev *dev);
>  static void s2255_stop_readpipe(struct s2255_dev *dev);
> -static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn);
> -static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn);
> -static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
> -			   int chn, int jpgsize);
> -static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
> -			  struct s2255_mode *mode);
> +static int s2255_start_acquire(struct s2255_channel *channel);
> +static int s2255_stop_acquire(struct s2255_channel *channel);
> +static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
> +			   int jpgsize);
> +static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
>  static int s2255_board_shutdown(struct s2255_dev *dev);
>  static void s2255_fwload_start(struct s2255_dev *dev, int reset);
>  static void s2255_destroy(struct s2255_dev *dev);
> @@ -577,10 +578,11 @@
>  
>  }
>  
> -static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
> +static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
>  {
> -	struct s2255_dmaqueue *dma_q = &dev->vidq[chn];
> +	struct s2255_dmaqueue *dma_q = &channel->vidq;
>  	struct s2255_buffer *buf;
> +	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
>  	unsigned long flags = 0;
>  	int rc = 0;
>  	spin_lock_irqsave(&dev->slock, flags);
> @@ -593,7 +595,7 @@
>  			 struct s2255_buffer, vb.queue);
>  	list_del(&buf->vb.queue);
>  	do_gettimeofday(&buf->vb.ts);
> -	s2255_fillbuff(dev, buf, dma_q->channel, jpgsize);
> +	s2255_fillbuff(channel, buf, jpgsize);
>  	wake_up(&buf->vb.done);
>  	dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
>  unlock:
> @@ -621,8 +623,8 @@
>   *                  http://v4l.videotechnology.com/
>   *
>   */
> -static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
> -			   int chn, int jpgsize)
> +static void s2255_fillbuff(struct s2255_channel *channel,
> +			   struct s2255_buffer *buf, int jpgsize)
>  {
>  	int pos = 0;
>  	struct timeval ts;
> @@ -633,12 +635,11 @@
>  
>  	if (!vbuf)
>  		return;
> -
> -	last_frame = dev->last_frame[chn];
> +	last_frame = channel->last_frame;
>  	if (last_frame != -1) {
> -		frm = &dev->buffer[chn].frame[last_frame];
> +		frm = &channel->buffer.frame[last_frame];
>  		tmpbuf =
> -		    (const char *)dev->buffer[chn].frame[last_frame].lpvbits;
> +		    (const char *)channel->buffer.frame[last_frame].lpvbits;
>  		switch (buf->fmt->fourcc) {
>  		case V4L2_PIX_FMT_YUYV:
>  		case V4L2_PIX_FMT_UYVY:
> @@ -661,7 +662,7 @@
>  		default:
>  			printk(KERN_DEBUG "s2255: unknown format?\n");
>  		}
> -		dev->last_frame[chn] = -1;
> +		channel->last_frame = -1;
>  	} else {
>  		printk(KERN_ERR "s2255: =======no frame\n");
>  		return;
> @@ -671,7 +672,7 @@
>  		(unsigned long)vbuf, pos);
>  	/* tell v4l buffer was filled */
>  
> -	buf->vb.field_count = dev->frame_count[chn] * 2;
> +	buf->vb.field_count = channel->frame_count * 2;
>  	do_gettimeofday(&ts);
>  	buf->vb.ts = ts;
>  	buf->vb.state = VIDEOBUF_DONE;
> @@ -686,8 +687,8 @@
>  			unsigned int *size)
>  {
>  	struct s2255_fh *fh = vq->priv_data;
> -
> -	*size = fh->width * fh->height * (fh->fmt->depth >> 3);
> +	struct s2255_channel *channel = fh->channel;
> +	*size = channel->width * channel->height * (channel->fmt->depth >> 3);
>  
>  	if (0 == *count)
>  		*count = S2255_DEF_BUFS;
> @@ -710,30 +711,31 @@
>  			  enum v4l2_field field)
>  {
>  	struct s2255_fh *fh = vq->priv_data;
> +	struct s2255_channel *channel = fh->channel;
>  	struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
>  	int rc;
> +	int w = channel->width;
> +	int h = channel->height;
>  	dprintk(4, "%s, field=%d\n", __func__, field);
> -	if (fh->fmt == NULL)
> +	if (channel->fmt == NULL)
>  		return -EINVAL;
>  
> -	if ((fh->width < norm_minw(&fh->dev->vdev[fh->channel])) ||
> -	    (fh->width > norm_maxw(&fh->dev->vdev[fh->channel])) ||
> -	    (fh->height < norm_minh(&fh->dev->vdev[fh->channel])) ||
> -	    (fh->height > norm_maxh(&fh->dev->vdev[fh->channel]))) {
> +	if ((w < norm_minw(&channel->vdev)) ||
> +	    (w > norm_maxw(&channel->vdev)) ||
> +	    (h < norm_minh(&channel->vdev)) ||
> +	    (h > norm_maxh(&channel->vdev))) {
>  		dprintk(4, "invalid buffer prepare\n");
>  		return -EINVAL;
>  	}
> -
> -	buf->vb.size = fh->width * fh->height * (fh->fmt->depth >> 3);
> -
> +	buf->vb.size = w * h * (channel->fmt->depth >> 3);
>  	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
>  		dprintk(4, "invalid buffer prepare\n");
>  		return -EINVAL;
>  	}
>  
> -	buf->fmt = fh->fmt;
> -	buf->vb.width = fh->width;
> -	buf->vb.height = fh->height;
> +	buf->fmt = channel->fmt;
> +	buf->vb.width = w;
> +	buf->vb.height = h;
>  	buf->vb.field = field;
>  
>  	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
> @@ -753,8 +755,8 @@
>  {
>  	struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
>  	struct s2255_fh *fh = vq->priv_data;
> -	struct s2255_dev *dev = fh->dev;
> -	struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel];
> +	struct s2255_channel *channel = fh->channel;
> +	struct s2255_dmaqueue *vidq = &channel->vidq;
>  	dprintk(1, "%s\n", __func__);
>  	buf->vb.state = VIDEOBUF_QUEUED;
>  	list_add_tail(&buf->vb.queue, &vidq->active);
> @@ -765,7 +767,7 @@
>  {
>  	struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
>  	struct s2255_fh *fh = vq->priv_data;
> -	dprintk(4, "%s %d\n", __func__, fh->channel);
> +	dprintk(4, "%s %d\n", __func__, fh->channel->idx);
>  	free_buffer(vq, buf);
>  }
>  
> @@ -777,39 +779,44 @@
>  };
>  
>  
> -static int res_get(struct s2255_dev *dev, struct s2255_fh *fh)
> +static int res_get(struct s2255_fh *fh)
>  {
> +	struct s2255_dev *dev = fh->dev;
>  	/* is it free? */
> +	struct s2255_channel *channel = fh->channel;
>  	mutex_lock(&dev->lock);
> -	if (dev->resources[fh->channel]) {
> +	if (channel->resources) {
>  		/* no, someone else uses it */
>  		mutex_unlock(&dev->lock);
>  		return 0;
>  	}
>  	/* it's free, grab it */
> -	dev->resources[fh->channel] = 1;
> -	fh->resources[fh->channel] = 1;
> +	channel->resources = 1;
> +	fh->resources = 1;
>  	dprintk(1, "s2255: res: get\n");
>  	mutex_unlock(&dev->lock);
>  	return 1;
>  }
>  
> -static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh)
> +static int res_locked(struct s2255_fh *fh)
>  {
> -	return dev->resources[fh->channel];
> +	struct s2255_channel *channel = fh->channel;
> +	return channel->resources;
>  }
>  
>  static int res_check(struct s2255_fh *fh)
>  {
> -	return fh->resources[fh->channel];
> +	return fh->resources;
>  }
>  
>  
> -static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
> +static void res_free(struct s2255_fh *fh)
>  {
> +	struct s2255_channel *channel = fh->channel;
> +	struct s2255_dev *dev = fh->dev;
>  	mutex_lock(&dev->lock);
> -	dev->resources[fh->channel] = 0;
> -	fh->resources[fh->channel] = 0;
> +	channel->resources = 0;
> +	fh->resources = 0;
>  	mutex_unlock(&dev->lock);
>  	dprintk(1, "res: put\n");
>  }
> @@ -869,12 +876,13 @@
>  			    struct v4l2_format *f)
>  {
>  	struct s2255_fh *fh = priv;
> +	struct s2255_channel *channel = fh->channel;
>  
> -	f->fmt.pix.width = fh->width;
> -	f->fmt.pix.height = fh->height;
> +	f->fmt.pix.width = channel->width;
> +	f->fmt.pix.height = channel->height;
>  	f->fmt.pix.field = fh->vb_vidq.field;
> -	f->fmt.pix.pixelformat = fh->fmt->fourcc;
> -	f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3);
> +	f->fmt.pix.pixelformat = channel->fmt->fourcc;
> +	f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
>  	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
>  	return 0;
>  }
> @@ -886,11 +894,10 @@
>  	enum v4l2_field field;
>  	int  b_any_field = 0;
>  	struct s2255_fh *fh = priv;
> -	struct s2255_dev *dev = fh->dev;
> +	struct s2255_channel *channel = fh->channel;
>  	int is_ntsc;
> -
>  	is_ntsc =
> -	    (dev->vdev[fh->channel].current_norm & V4L2_STD_NTSC) ? 1 : 0;
> +		(channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
>  
>  	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
>  
> @@ -982,8 +989,10 @@
>  			    struct v4l2_format *f)
>  {
>  	struct s2255_fh *fh = priv;
> +	struct s2255_channel *channel = fh->channel;
>  	const struct s2255_fmt *fmt;
>  	struct videobuf_queue *q = &fh->vb_vidq;
> +	struct s2255_mode mode;
>  	int ret;
>  	int norm;
>  
> @@ -1005,54 +1014,61 @@
>  		goto out_s_fmt;
>  	}
>  
> -	if (res_locked(fh->dev, fh)) {
> +	if (res_locked(fh)) {
>  		dprintk(1, "%s: channel busy\n", __func__);
>  		ret = -EBUSY;
>  		goto out_s_fmt;
>  	}
> -
> -	fh->fmt = fmt;
> -	fh->width = f->fmt.pix.width;
> -	fh->height = f->fmt.pix.height;
> +	mode = channel->mode;
> +	channel->fmt = fmt;
> +	channel->width = f->fmt.pix.width;
> +	channel->height = f->fmt.pix.height;
>  	fh->vb_vidq.field = f->fmt.pix.field;
>  	fh->type = f->type;
> -	norm = norm_minw(&fh->dev->vdev[fh->channel]);
> -	if (fh->width > norm_minw(&fh->dev->vdev[fh->channel])) {
> -		if (fh->height > norm_minh(&fh->dev->vdev[fh->channel])) {
> -			if (fh->dev->cap_parm[fh->channel].capturemode &
> +	norm = norm_minw(&channel->vdev);
> +	if (channel->width > norm_minw(&channel->vdev)) {
> +		if (channel->height > norm_minh(&channel->vdev)) {
> +			if (channel->cap_parm.capturemode &
>  			    V4L2_MODE_HIGHQUALITY)
> -				fh->mode.scale = SCALE_4CIFSI;
> +				mode.scale = SCALE_4CIFSI;
>  			else
> -				fh->mode.scale = SCALE_4CIFS;
> +				mode.scale = SCALE_4CIFS;
>  		} else
> -			fh->mode.scale = SCALE_2CIFS;
> +			mode.scale = SCALE_2CIFS;
>  
>  	} else {
> -		fh->mode.scale = SCALE_1CIFS;
> +		mode.scale = SCALE_1CIFS;
>  	}
> -
>  	/* color mode */
> -	switch (fh->fmt->fourcc) {
> +	switch (channel->fmt->fourcc) {
>  	case V4L2_PIX_FMT_GREY:
> -		fh->mode.color &= ~MASK_COLOR;
> -		fh->mode.color |= COLOR_Y8;
> +		mode.color &= ~MASK_COLOR;
> +		mode.color |= COLOR_Y8;
>  		break;
>  	case V4L2_PIX_FMT_JPEG:
> -		fh->mode.color &= ~MASK_COLOR;
> -		fh->mode.color |= COLOR_JPG;
> -		fh->mode.color |= (fh->dev->jc[fh->channel].quality << 8);
> +		mode.color &= ~MASK_COLOR;
> +		mode.color |= COLOR_JPG;
> +		mode.color |= (channel->jc.quality << 8);
>  		break;
>  	case V4L2_PIX_FMT_YUV422P:
> -		fh->mode.color &= ~MASK_COLOR;
> -		fh->mode.color |= COLOR_YUVPL;
> +		mode.color &= ~MASK_COLOR;
> +		mode.color |= COLOR_YUVPL;
>  		break;
>  	case V4L2_PIX_FMT_YUYV:
>  	case V4L2_PIX_FMT_UYVY:
>  	default:
> -		fh->mode.color &= ~MASK_COLOR;
> -		fh->mode.color |= COLOR_YUVPK;
> +		mode.color &= ~MASK_COLOR;
> +		mode.color |= COLOR_YUVPK;
>  		break;
>  	}
> +	if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
> +		mode.restart = 1;
> +	else if (mode.scale != channel->mode.scale)
> +		mode.restart = 1;
> +	else if (mode.format != channel->mode.format)
> +		mode.restart = 1;
> +	channel->mode = mode;
> +	(void) s2255_set_mode(channel, &mode);
>  	ret = 0;
>  out_s_fmt:
>  	mutex_unlock(&q->vb_lock);
> @@ -1197,26 +1213,27 @@
>   * When the restart parameter is set, we sleep for ONE frame to allow the
>   * DSP time to get the new frame
>   */
> -static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
> +static int s2255_set_mode(struct s2255_channel *channel,
>  			  struct s2255_mode *mode)
>  {
>  	int res;
>  	__le32 *buffer;
>  	unsigned long chn_rev;
> +	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
>  	mutex_lock(&dev->lock);
> -	chn_rev = G_chnmap[chn];
> -	dprintk(3, "%s channel %lu\n", __func__, chn);
> +	chn_rev = G_chnmap[channel->idx];
> +	dprintk(3, "%s channel: %d\n", __func__, channel->idx);
>  	/* if JPEG, set the quality */
>  	if ((mode->color & MASK_COLOR) == COLOR_JPG) {
>  		mode->color &= ~MASK_COLOR;
>  		mode->color |= COLOR_JPG;
>  		mode->color &= ~MASK_JPG_QUALITY;
> -		mode->color |= (dev->jc[chn].quality << 8);
> +		mode->color |= (channel->jc.quality << 8);
>  	}
>  	/* save the mode */
> -	dev->mode[chn] = *mode;
> -	dev->req_image_size[chn] = get_transfer_size(mode);
> -	dprintk(1, "%s: reqsize %ld\n", __func__, dev->req_image_size[chn]);
> +	channel->mode = *mode;
> +	channel->req_image_size = get_transfer_size(mode);
> +	dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
>  	buffer = kzalloc(512, GFP_KERNEL);
>  	if (buffer == NULL) {
>  		dev_err(&dev->udev->dev, "out of mem\n");
> @@ -1227,38 +1244,38 @@
>  	buffer[0] = IN_DATA_TOKEN;
>  	buffer[1] = (__le32) cpu_to_le32(chn_rev);
>  	buffer[2] = CMD_SET_MODE;
> -	memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode));
> -	dev->setmode_ready[chn] = 0;
> +	memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
> +	channel->setmode_ready = 0;
>  	res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
>  	if (debug)
>  		s2255_print_cfg(dev, mode);
>  	kfree(buffer);
>  	/* wait at least 3 frames before continuing */
>  	if (mode->restart) {
> -		wait_event_timeout(dev->wait_setmode[chn],
> -				   (dev->setmode_ready[chn] != 0),
> +		wait_event_timeout(channel->wait_setmode,
> +				   (channel->setmode_ready != 0),
>  				   msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
> -		if (dev->setmode_ready[chn] != 1) {
> +		if (channel->setmode_ready != 1) {
>  			printk(KERN_DEBUG "s2255: no set mode response\n");
>  			res = -EFAULT;
>  		}
>  	}
>  	/* clear the restart flag */
> -	dev->mode[chn].restart = 0;
> +	channel->mode.restart = 0;
>  	mutex_unlock(&dev->lock);
> -	dprintk(1, "%s chn %lu, result: %d\n", __func__, chn, res);
> +	dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
>  	return res;
>  }
>  
> -static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn,
> -			    u32 *pstatus)
> +static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
>  {
>  	int res;
>  	__le32 *buffer;
>  	u32 chn_rev;
> +	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
>  	mutex_lock(&dev->lock);
> -	chn_rev = G_chnmap[chn];
> -	dprintk(4, "%s chan %lu\n", __func__, chn);
> +	chn_rev = G_chnmap[channel->idx];
> +	dprintk(4, "%s chan %d\n", __func__, channel->idx);
>  	buffer = kzalloc(512, GFP_KERNEL);
>  	if (buffer == NULL) {
>  		dev_err(&dev->udev->dev, "out of mem\n");
> @@ -1270,17 +1287,17 @@
>  	buffer[1] = (__le32) cpu_to_le32(chn_rev);
>  	buffer[2] = CMD_STATUS;
>  	*pstatus = 0;
> -	dev->vidstatus_ready[chn] = 0;
> +	channel->vidstatus_ready = 0;
>  	res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
>  	kfree(buffer);
> -	wait_event_timeout(dev->wait_vidstatus[chn],
> -			   (dev->vidstatus_ready[chn] != 0),
> +	wait_event_timeout(channel->wait_vidstatus,
> +			   (channel->vidstatus_ready != 0),
>  			   msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
> -	if (dev->vidstatus_ready[chn] != 1) {
> +	if (channel->vidstatus_ready != 1) {
>  		printk(KERN_DEBUG "s2255: no vidstatus response\n");
>  		res = -EFAULT;
>  	}
> -	*pstatus = dev->vidstatus[chn];
> +	*pstatus = channel->vidstatus;
>  	dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
>  	mutex_unlock(&dev->lock);
>  	return res;
> @@ -1291,9 +1308,7 @@
>  	int res;
>  	struct s2255_fh *fh = priv;
>  	struct s2255_dev *dev = fh->dev;
> -	struct s2255_mode *new_mode;
> -	struct s2255_mode *old_mode;
> -	int chn;
> +	struct s2255_channel *channel = fh->channel;
>  	int j;
>  	dprintk(4, "%s\n", __func__);
>  	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> @@ -1305,51 +1320,32 @@
>  		return -EINVAL;
>  	}
>  
> -	if (!res_get(dev, fh)) {
> +	if (!res_get(fh)) {
>  		s2255_dev_err(&dev->udev->dev, "stream busy\n");
>  		return -EBUSY;
>  	}
> -
> -	/* send a set mode command everytime with restart.
> -	   in case we switch resolutions or other parameters */
> -	chn = fh->channel;
> -	new_mode = &fh->mode;
> -	old_mode = &fh->dev->mode[chn];
> -
> -	if ((new_mode->color & MASK_COLOR) != (old_mode->color & MASK_COLOR))
> -		new_mode->restart = 1;
> -	else if (new_mode->scale != old_mode->scale)
> -		new_mode->restart = 1;
> -	else if (new_mode->format != old_mode->format)
> -		new_mode->restart = 1;
> -
> -	s2255_set_mode(dev, chn, new_mode);
> -	new_mode->restart = 0;
> -	*old_mode = *new_mode;
> -	dev->cur_fmt[chn] = fh->fmt;
> -	dev->last_frame[chn] = -1;
> -	dev->bad_payload[chn] = 0;
> -	dev->cur_frame[chn] = 0;
> -	dev->frame_count[chn] = 0;
> +	channel->last_frame = -1;
> +	channel->bad_payload = 0;
> +	channel->cur_frame = 0;
> +	channel->frame_count = 0;
>  	for (j = 0; j < SYS_FRAMES; j++) {
> -		dev->buffer[chn].frame[j].ulState = S2255_READ_IDLE;
> -		dev->buffer[chn].frame[j].cur_size = 0;
> +		channel->buffer.frame[j].ulState = S2255_READ_IDLE;
> +		channel->buffer.frame[j].cur_size = 0;
>  	}
>  	res = videobuf_streamon(&fh->vb_vidq);
>  	if (res == 0) {
> -		s2255_start_acquire(dev, chn);
> -		dev->b_acquire[chn] = 1;
> -	} else {
> -		res_free(dev, fh);
> -	}
> +		s2255_start_acquire(channel);
> +		channel->b_acquire = 1;
> +	} else
> +		res_free(fh);
> +
>  	return res;
>  }
>  
>  static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
>  {
>  	struct s2255_fh *fh = priv;
> -	struct s2255_dev *dev = fh->dev;
> -	dprintk(4, "%s\n, channel: %d", __func__, fh->channel);
> +	dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
>  	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
>  		printk(KERN_ERR "invalid fh type0\n");
>  		return -EINVAL;
> @@ -1358,16 +1354,16 @@
>  		printk(KERN_ERR "invalid type i\n");
>  		return -EINVAL;
>  	}
> -	s2255_stop_acquire(dev, fh->channel);
> +	s2255_stop_acquire(fh->channel);
>  	videobuf_streamoff(&fh->vb_vidq);
> -	res_free(dev, fh);
> +	res_free(fh);
>  	return 0;
>  }
>  
>  static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
>  {
>  	struct s2255_fh *fh = priv;
> -	struct s2255_mode *mode;
> +	struct s2255_mode mode;
>  	struct videobuf_queue *q = &fh->vb_vidq;
>  	int ret = 0;
>  	mutex_lock(&q->vb_lock);
> @@ -1376,29 +1372,32 @@
>  		ret = -EBUSY;
>  		goto out_s_std;
>  	}
> -	if (res_locked(fh->dev, fh)) {
> +	if (res_locked(fh)) {
>  		dprintk(1, "can't change standard after started\n");
>  		ret = -EBUSY;
>  		goto out_s_std;
>  	}
> -	mode = &fh->mode;
> +	mode = fh->channel->mode;
>  	if (*i & V4L2_STD_NTSC) {
>  		dprintk(4, "%s NTSC\n", __func__);
>  		/* if changing format, reset frame decimation/intervals */
> -		if (mode->format != FORMAT_NTSC) {
> -			mode->format = FORMAT_NTSC;
> -			mode->fdec = FDEC_1;
> +		if (mode.format != FORMAT_NTSC) {
> +			mode.restart = 1;
> +			mode.format = FORMAT_NTSC;
> +			mode.fdec = FDEC_1;
>  		}
>  	} else if (*i & V4L2_STD_PAL) {
>  		dprintk(4, "%s PAL\n", __func__);
> -		mode->format = FORMAT_PAL;
> -		if (mode->format != FORMAT_PAL) {
> -			mode->format = FORMAT_PAL;
> -			mode->fdec = FDEC_1;
> +		if (mode.format != FORMAT_PAL) {
> +			mode.restart = 1;
> +			mode.format = FORMAT_PAL;
> +			mode.fdec = FDEC_1;
>  		}
>  	} else {
>  		ret = -EINVAL;
>  	}
> +	if (mode.restart)
> +		s2255_set_mode(fh->channel, &mode);
>  out_s_std:
>  	mutex_unlock(&q->vb_lock);
>  	return ret;
> @@ -1416,6 +1415,7 @@
>  {
>  	struct s2255_fh *fh = priv;
>  	struct s2255_dev *dev = fh->dev;
> +	struct s2255_channel *channel = fh->channel;
>  	u32 status = 0;
>  	if (inp->index != 0)
>  		return -EINVAL;
> @@ -1424,7 +1424,7 @@
>  	inp->status = 0;
>  	if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
>  		int rc;
> -		rc = s2255_cmd_status(dev, fh->channel, &status);
> +		rc = s2255_cmd_status(fh->channel, &status);
>  		dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
>  		if (rc == 0)
>  			inp->status =  (status & 0x01) ? 0
> @@ -1436,7 +1436,7 @@
>  		strlcpy(inp->name, "Composite", sizeof(inp->name));
>  		break;
>  	case 0x2257:
> -		strlcpy(inp->name, (fh->channel < 2) ? "Composite" : "S-Video",
> +		strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
>  			sizeof(inp->name));
>  		break;
>  	}
> @@ -1460,6 +1460,7 @@
>  			    struct v4l2_queryctrl *qc)
>  {
>  	struct s2255_fh *fh = priv;
> +	struct s2255_channel *channel = fh->channel;
>  	struct s2255_dev *dev = fh->dev;
>  	switch (qc->id) {
>  	case V4L2_CID_BRIGHTNESS:
> @@ -1477,7 +1478,7 @@
>  	case V4L2_CID_PRIVATE_COLORFILTER:
>  		if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
>  			return -EINVAL;
> -		if ((dev->pid == 0x2257) && (fh->channel > 1))
> +		if ((dev->pid == 0x2257) && (channel->idx > 1))
>  			return -EINVAL;
>  		strlcpy(qc->name, "Color Filter", sizeof(qc->name));
>  		qc->type = V4L2_CTRL_TYPE_MENU;
> @@ -1499,25 +1500,26 @@
>  {
>  	struct s2255_fh *fh = priv;
>  	struct s2255_dev *dev = fh->dev;
> +	struct s2255_channel *channel = fh->channel;
>  	switch (ctrl->id) {
>  	case V4L2_CID_BRIGHTNESS:
> -		ctrl->value = fh->mode.bright;
> +		ctrl->value = channel->mode.bright;
>  		break;
>  	case V4L2_CID_CONTRAST:
> -		ctrl->value = fh->mode.contrast;
> +		ctrl->value = channel->mode.contrast;
>  		break;
>  	case V4L2_CID_SATURATION:
> -		ctrl->value = fh->mode.saturation;
> +		ctrl->value = channel->mode.saturation;
>  		break;
>  	case V4L2_CID_HUE:
> -		ctrl->value = fh->mode.hue;
> +		ctrl->value = channel->mode.hue;
>  		break;
>  	case V4L2_CID_PRIVATE_COLORFILTER:
>  		if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
>  			return -EINVAL;
> -		if ((dev->pid == 0x2257) && (fh->channel > 1))
> +		if ((dev->pid == 0x2257) && (channel->idx > 1))
>  			return -EINVAL;
> -		ctrl->value = !((fh->mode.color & MASK_INPUT_TYPE) >> 16);
> +		ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
>  		break;
>  	default:
>  		return -EINVAL;
> @@ -1530,41 +1532,42 @@
>  			 struct v4l2_control *ctrl)
>  {
>  	struct s2255_fh *fh = priv;
> -	struct s2255_dev *dev = fh->dev;
> -	struct s2255_mode *mode;
> -	mode = &fh->mode;
> +	struct s2255_channel *channel = fh->channel;
> +	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
> +	struct s2255_mode mode;
> +	mode = channel->mode;
>  	dprintk(4, "%s\n", __func__);
>  	/* update the mode to the corresponding value */
>  	switch (ctrl->id) {
>  	case V4L2_CID_BRIGHTNESS:
> -		mode->bright = ctrl->value;
> +		mode.bright = ctrl->value;
>  		break;
>  	case V4L2_CID_CONTRAST:
> -		mode->contrast = ctrl->value;
> +		mode.contrast = ctrl->value;
>  		break;
>  	case V4L2_CID_HUE:
> -		mode->hue = ctrl->value;
> +		mode.hue = ctrl->value;
>  		break;
>  	case V4L2_CID_SATURATION:
> -		mode->saturation = ctrl->value;
> +		mode.saturation = ctrl->value;
>  		break;
>  	case V4L2_CID_PRIVATE_COLORFILTER:
>  		if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
>  			return -EINVAL;
> -		if ((dev->pid == 0x2257) && (fh->channel > 1))
> +		if ((dev->pid == 0x2257) && (channel->idx > 1))
>  			return -EINVAL;
> -		mode->color &= ~MASK_INPUT_TYPE;
> -		mode->color |= ((ctrl->value ? 0 : 1) << 16);
> +		mode.color &= ~MASK_INPUT_TYPE;
> +		mode.color |= ((ctrl->value ? 0 : 1) << 16);
>  		break;
>  	default:
>  		return -EINVAL;
>  	}
> -	mode->restart = 0;
> +	mode.restart = 0;
>  	/* set mode here.  Note: stream does not need restarted.
>  	   some V4L programs restart stream unnecessarily
>  	   after a s_crtl.
>  	*/
> -	s2255_set_mode(dev, fh->channel, mode);
> +	s2255_set_mode(fh->channel, &mode);
>  	return 0;
>  }
>  
> @@ -1572,8 +1575,8 @@
>  			 struct v4l2_jpegcompression *jc)
>  {
>  	struct s2255_fh *fh = priv;
> -	struct s2255_dev *dev = fh->dev;
> -	*jc = dev->jc[fh->channel];
> +	struct s2255_channel *channel = fh->channel;
> +	*jc = channel->jc;
>  	dprintk(2, "%s: quality %d\n", __func__, jc->quality);
>  	return 0;
>  }
> @@ -1582,10 +1585,10 @@
>  			 struct v4l2_jpegcompression *jc)
>  {
>  	struct s2255_fh *fh = priv;
> -	struct s2255_dev *dev = fh->dev;
> +	struct s2255_channel *channel = fh->channel;
>  	if (jc->quality < 0 || jc->quality > 100)
>  		return -EINVAL;
> -	dev->jc[fh->channel].quality = jc->quality;
> +	channel->jc.quality = jc->quality;
>  	dprintk(2, "%s: quality %d\n", __func__, jc->quality);
>  	return 0;
>  }
> @@ -1594,17 +1597,17 @@
>  			 struct v4l2_streamparm *sp)
>  {
>  	struct s2255_fh *fh = priv;
> -	struct s2255_dev *dev = fh->dev;
>  	__u32 def_num, def_dem;
> +	struct s2255_channel *channel = fh->channel;
>  	if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>  		return -EINVAL;
>  	memset(sp, 0, sizeof(struct v4l2_streamparm));
>  	sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
> -	sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
> -	def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
> -	def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
> +	sp->parm.capture.capturemode = channel->cap_parm.capturemode;
> +	def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
> +	def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
>  	sp->parm.capture.timeperframe.denominator = def_dem;
> -	switch (fh->mode.fdec) {
> +	switch (channel->mode.fdec) {
>  	default:
>  	case FDEC_1:
>  		sp->parm.capture.timeperframe.numerator = def_num;
> @@ -1630,17 +1633,19 @@
>  			 struct v4l2_streamparm *sp)
>  {
>  	struct s2255_fh *fh = priv;
> -	struct s2255_dev *dev = fh->dev;
> +	struct s2255_channel *channel = fh->channel;
> +	struct s2255_mode mode;
>  	int fdec = FDEC_1;
>  	__u32 def_num, def_dem;
>  	if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>  		return -EINVAL;
> +	mode = channel->mode;
>  	/* high quality capture mode requires a stream restart */
> -	if (dev->cap_parm[fh->channel].capturemode
> -	    != sp->parm.capture.capturemode && res_locked(fh->dev, fh))
> +	if (channel->cap_parm.capturemode
> +	    != sp->parm.capture.capturemode && res_locked(fh))
>  		return -EBUSY;
> -	def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
> -	def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
> +	def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
> +	def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
>  	if (def_dem != sp->parm.capture.timeperframe.denominator)
>  		sp->parm.capture.timeperframe.numerator = def_num;
>  	else if (sp->parm.capture.timeperframe.numerator <= def_num)
> @@ -1655,9 +1660,9 @@
>  		sp->parm.capture.timeperframe.numerator = def_num * 5;
>  		fdec = FDEC_5;
>  	}
> -	fh->mode.fdec = fdec;
> +	mode.fdec = fdec;
>  	sp->parm.capture.timeperframe.denominator = def_dem;
> -	s2255_set_mode(dev, fh->channel, &fh->mode);
> +	s2255_set_mode(channel, &mode);
>  	dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
>  		__func__,
>  		sp->parm.capture.capturemode,
> @@ -1707,20 +1712,13 @@
>  static int s2255_open(struct file *file)
>  {
>  	struct video_device *vdev = video_devdata(file);
> -	struct s2255_dev *dev = video_drvdata(file);
> +	struct s2255_channel *channel = video_drvdata(file);
> +	struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
>  	struct s2255_fh *fh;
>  	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> -	int i = 0;
> -	int cur_channel = -1;
>  	int state;
>  	dprintk(1, "s2255: open called (dev=%s)\n",
>  		video_device_node_name(vdev));
> -
> -	for (i = 0; i < MAX_CHANNELS; i++)
> -		if (&dev->vdev[i] == vdev) {
> -			cur_channel = i;
> -			break;
> -		}
>  	/*
>  	 * open lock necessary to prevent multiple instances
>  	 * of v4l-conf (or other programs) from simultaneously
> @@ -1791,24 +1789,20 @@
>  	file->private_data = fh;
>  	fh->dev = dev;
>  	fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> -	fh->mode = dev->mode[cur_channel];
> -	fh->fmt = dev->cur_fmt[cur_channel];
> -	/* default 4CIF NTSC */
> -	fh->width = LINE_SZ_4CIFS_NTSC;
> -	fh->height = NUM_LINES_4CIFS_NTSC * 2;
> -	fh->channel = cur_channel;
> -	/* configure channel to default state */
> -	if (!dev->chn_configured[cur_channel]) {
> -		s2255_set_mode(dev, cur_channel, &fh->mode);
> -		dev->chn_configured[cur_channel] = 1;
> +	fh->channel = channel;
> +	if (!channel->configured) {
> +		/* configure channel to default state */
> +		channel->fmt = &formats[0];
> +		s2255_set_mode(channel, &channel->mode);
> +		channel->configured = 1;
>  	}
>  	dprintk(1, "%s: dev=%s type=%s\n", __func__,
>  		video_device_node_name(vdev), v4l2_type_names[type]);
>  	dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
>  		(unsigned long)fh, (unsigned long)dev,
> -		(unsigned long)&dev->vidq[cur_channel]);
> +		(unsigned long)&channel->vidq);
>  	dprintk(4, "%s: list_empty active=%d\n", __func__,
> -		list_empty(&dev->vidq[cur_channel].active));
> +		list_empty(&channel->vidq.active));
>  	videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
>  				    NULL, &dev->slock,
>  				    fh->type,
> @@ -1850,6 +1844,7 @@
>  	mutex_destroy(&dev->open_lock);
>  	mutex_destroy(&dev->lock);
>  	usb_put_dev(dev->udev);
> +	v4l2_device_unregister(&dev->v4l2_dev);
>  	dprintk(1, "%s", __func__);
>  	kfree(dev);
>  }
> @@ -1859,14 +1854,15 @@
>  	struct s2255_fh *fh = file->private_data;
>  	struct s2255_dev *dev = fh->dev;
>  	struct video_device *vdev = video_devdata(file);
> +	struct s2255_channel *channel = fh->channel;
>  	if (!dev)
>  		return -ENODEV;
>  	/* turn off stream */
>  	if (res_check(fh)) {
> -		if (dev->b_acquire[fh->channel])
> -			s2255_stop_acquire(dev, fh->channel);
> +		if (channel->b_acquire)
> +			s2255_stop_acquire(fh->channel);
>  		videobuf_streamoff(&fh->vb_vidq);
> -		res_free(dev, fh);
> +		res_free(fh);
>  	}
>  	videobuf_mmap_free(&fh->vb_vidq);
>  	dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
> @@ -1930,9 +1926,10 @@
>  
>  static void s2255_video_device_release(struct video_device *vdev)
>  {
> -	struct s2255_dev *dev = video_get_drvdata(vdev);
> -	dprintk(4, "%s, chnls: %d \n", __func__, atomic_read(&dev->channels));
> -	if (atomic_dec_and_test(&dev->channels))
> +	struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
> +	dprintk(4, "%s, chnls: %d \n", __func__,
> +		atomic_read(&dev->num_channels));
> +	if (atomic_dec_and_test(&dev->num_channels))
>  		s2255_destroy(dev);
>  	return;
>  }
> @@ -1951,46 +1948,48 @@
>  	int ret;
>  	int i;
>  	int cur_nr = video_nr;
> +	struct s2255_channel *channel;
>  	ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
>  	if (ret)
>  		return ret;
>  	/* initialize all video 4 linux */
>  	/* register 4 video devices */
>  	for (i = 0; i < MAX_CHANNELS; i++) {
> -		INIT_LIST_HEAD(&dev->vidq[i].active);
> -		dev->vidq[i].dev = dev;
> -		dev->vidq[i].channel = i;
> +		channel = &dev->channel[i];
> +		INIT_LIST_HEAD(&channel->vidq.active);
> +		channel->vidq.dev = dev;
>  		/* register 4 video devices */
> -		memcpy(&dev->vdev[i], &template, sizeof(struct video_device));
> -		dev->vdev[i].v4l2_dev = &dev->v4l2_dev;
> -		video_set_drvdata(&dev->vdev[i], dev);
> +		channel->vdev = template;
> +		channel->vdev.v4l2_dev = &dev->v4l2_dev;
> +		video_set_drvdata(&channel->vdev, channel);
>  		if (video_nr == -1)
> -			ret = video_register_device(&dev->vdev[i],
> +			ret = video_register_device(&channel->vdev,
>  						    VFL_TYPE_GRABBER,
>  						    video_nr);
>  		else
> -			ret = video_register_device(&dev->vdev[i],
> +			ret = video_register_device(&channel->vdev,
>  						    VFL_TYPE_GRABBER,
>  						    cur_nr + i);
> +
>  		if (ret) {
>  			dev_err(&dev->udev->dev,
>  				"failed to register video device!\n");
>  			break;
>  		}
> -		atomic_inc(&dev->channels);
> +		atomic_inc(&dev->num_channels);
>  		v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
> -			  video_device_node_name(&dev->vdev[i]));
> +			  video_device_node_name(&channel->vdev));
>  
>  	}
>  	printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
>  	       S2255_MAJOR_VERSION,
>  	       S2255_MINOR_VERSION);
>  	/* if no channels registered, return error and probe will fail*/
> -	if (atomic_read(&dev->channels) == 0) {
> +	if (atomic_read(&dev->num_channels) == 0) {
>  		v4l2_device_unregister(&dev->v4l2_dev);
>  		return ret;
>  	}
> -	if (atomic_read(&dev->channels) != MAX_CHANNELS)
> +	if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
>  		printk(KERN_WARNING "s2255: Not all channels available.\n");
>  	return 0;
>  }
> @@ -2017,12 +2016,11 @@
>  	s32 idx = -1;
>  	struct s2255_framei *frm;
>  	unsigned char *pdata;
> -
> +	struct s2255_channel *channel;
>  	dprintk(100, "buffer to user\n");
> -
> -	idx = dev->cur_frame[dev->cc];
> -	frm = &dev->buffer[dev->cc].frame[idx];
> -
> +	channel = &dev->channel[dev->cc];
> +	idx = channel->cur_frame;
> +	frm = &channel->buffer.frame[idx];
>  	if (frm->ulState == S2255_READ_IDLE) {
>  		int jj;
>  		unsigned int cc;
> @@ -2047,16 +2045,18 @@
>  				}
>  				/* reverse it */
>  				dev->cc = G_chnmap[cc];
> +				channel = &dev->channel[dev->cc];
>  				payload =  pdword[3];
> -				if (payload > dev->req_image_size[dev->cc]) {
> -					dev->bad_payload[dev->cc]++;
> +				if (payload > channel->req_image_size) {
> +					channel->bad_payload++;
>  					/* discard the bad frame */
>  					return -EINVAL;
>  				}
> -				dev->pkt_size[dev->cc] = payload;
> -				dev->jpg_size[dev->cc] = pdword[4];
> +				channel->pkt_size = payload;
> +				channel->jpg_size = pdword[4];
>  				break;
>  			case S2255_MARKER_RESPONSE:
> +
>  				pdata += DEF_USB_BLOCK;
>  				jj += DEF_USB_BLOCK;
>  				if (pdword[1] >= MAX_CHANNELS)
> @@ -2064,12 +2064,13 @@
>  				cc = G_chnmap[pdword[1]];
>  				if (cc >= MAX_CHANNELS)
>  					break;
> +				channel = &dev->channel[cc];
>  				switch (pdword[2]) {
>  				case S2255_RESPONSE_SETMODE:
>  					/* check if channel valid */
>  					/* set mode ready */
> -					dev->setmode_ready[cc] = 1;
> -					wake_up(&dev->wait_setmode[cc]);
> +					channel->setmode_ready = 1;
> +					wake_up(&channel->wait_setmode);
>  					dprintk(5, "setmode ready %d\n", cc);
>  					break;
>  				case S2255_RESPONSE_FW:
> @@ -2084,9 +2085,9 @@
>  					wake_up(&dev->fw_data->wait_fw);
>  					break;
>  				case S2255_RESPONSE_STATUS:
> -					dev->vidstatus[cc] = pdword[3];
> -					dev->vidstatus_ready[cc] = 1;
> -					wake_up(&dev->wait_vidstatus[cc]);
> +					channel->vidstatus = pdword[3];
> +					channel->vidstatus_ready = 1;
> +					wake_up(&channel->wait_vidstatus);
>  					dprintk(5, "got vidstatus %x chan %d\n",
>  						pdword[3], cc);
>  					break;
> @@ -2103,13 +2104,11 @@
>  		if (!bframe)
>  			return -EINVAL;
>  	}
> -
> -
> -	idx = dev->cur_frame[dev->cc];
> -	frm = &dev->buffer[dev->cc].frame[idx];
> -
> +	channel = &dev->channel[dev->cc];
> +	idx = channel->cur_frame;
> +	frm = &channel->buffer.frame[idx];
>  	/* search done.  now find out if should be acquiring on this channel */
> -	if (!dev->b_acquire[dev->cc]) {
> +	if (!channel->b_acquire) {
>  		/* we found a frame, but this channel is turned off */
>  		frm->ulState = S2255_READ_IDLE;
>  		return -EINVAL;
> @@ -2134,30 +2133,28 @@
>  
>  	copy_size = (pipe_info->cur_transfer_size - offset);
>  
> -	size = dev->pkt_size[dev->cc] - PREFIX_SIZE;
> +	size = channel->pkt_size - PREFIX_SIZE;
>  
>  	/* sanity check on pdest */
> -	if ((copy_size + frm->cur_size) < dev->req_image_size[dev->cc])
> +	if ((copy_size + frm->cur_size) < channel->req_image_size)
>  		memcpy(pdest, psrc, copy_size);
>  
>  	frm->cur_size += copy_size;
>  	dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
>  
>  	if (frm->cur_size >= size) {
> -
> -		u32 cc = dev->cc;
>  		dprintk(2, "****************[%d]Buffer[%d]full*************\n",
> -			cc, idx);
> -		dev->last_frame[cc] = dev->cur_frame[cc];
> -		dev->cur_frame[cc]++;
> +			dev->cc, idx);
> +		channel->last_frame = channel->cur_frame;
> +		channel->cur_frame++;
>  		/* end of system frame ring buffer, start at zero */
> -		if ((dev->cur_frame[cc] == SYS_FRAMES) ||
> -		    (dev->cur_frame[cc] == dev->buffer[cc].dwFrames))
> -			dev->cur_frame[cc] = 0;
> +		if ((channel->cur_frame == SYS_FRAMES) ||
> +		    (channel->cur_frame == channel->buffer.dwFrames))
> +			channel->cur_frame = 0;
>  		/* frame ready */
> -		if (dev->b_acquire[cc])
> -			s2255_got_frame(dev, cc, dev->jpg_size[cc]);
> -		dev->frame_count[cc]++;
> +		if (channel->b_acquire)
> +			s2255_got_frame(channel, channel->jpg_size);
> +		channel->frame_count++;
>  		frm->ulState = S2255_READ_IDLE;
>  		frm->cur_size = 0;
>  
> @@ -2230,16 +2227,12 @@
>   * Create the system ring buffer to copy frames into from the
>   * usb read pipe.
>   */
> -static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn)
> +static int s2255_create_sys_buffers(struct s2255_channel *channel)
>  {
>  	unsigned long i;
>  	unsigned long reqsize;
>  	dprintk(1, "create sys buffers\n");
> -	if (chn >= MAX_CHANNELS)
> -		return -1;
> -
> -	dev->buffer[chn].dwFrames = SYS_FRAMES;
> -
> +	channel->buffer.dwFrames = SYS_FRAMES;
>  	/* always allocate maximum size(PAL) for system buffers */
>  	reqsize = SYS_FRAMES_MAXSIZE;
>  
> @@ -2248,42 +2241,40 @@
>  
>  	for (i = 0; i < SYS_FRAMES; i++) {
>  		/* allocate the frames */
> -		dev->buffer[chn].frame[i].lpvbits = vmalloc(reqsize);
> -
> -		dprintk(1, "valloc %p chan %lu, idx %lu, pdata %p\n",
> -			&dev->buffer[chn].frame[i], chn, i,
> -			dev->buffer[chn].frame[i].lpvbits);
> -		dev->buffer[chn].frame[i].size = reqsize;
> -		if (dev->buffer[chn].frame[i].lpvbits == NULL) {
> +		channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
> +		dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
> +			&channel->buffer.frame[i], channel->idx, i,
> +			channel->buffer.frame[i].lpvbits);
> +		channel->buffer.frame[i].size = reqsize;
> +		if (channel->buffer.frame[i].lpvbits == NULL) {
>  			printk(KERN_INFO "out of memory.  using less frames\n");
> -			dev->buffer[chn].dwFrames = i;
> +			channel->buffer.dwFrames = i;
>  			break;
>  		}
>  	}
>  
>  	/* make sure internal states are set */
>  	for (i = 0; i < SYS_FRAMES; i++) {
> -		dev->buffer[chn].frame[i].ulState = 0;
> -		dev->buffer[chn].frame[i].cur_size = 0;
> +		channel->buffer.frame[i].ulState = 0;
> +		channel->buffer.frame[i].cur_size = 0;
>  	}
>  
> -	dev->cur_frame[chn] = 0;
> -	dev->last_frame[chn] = -1;
> +	channel->cur_frame = 0;
> +	channel->last_frame = -1;
>  	return 0;
>  }
>  
> -static int s2255_release_sys_buffers(struct s2255_dev *dev,
> -				     unsigned long channel)
> +static int s2255_release_sys_buffers(struct s2255_channel *channel)
>  {
>  	unsigned long i;
>  	dprintk(1, "release sys buffers\n");
>  	for (i = 0; i < SYS_FRAMES; i++) {
> -		if (dev->buffer[channel].frame[i].lpvbits) {
> +		if (channel->buffer.frame[i].lpvbits) {
>  			dprintk(1, "vfree %p\n",
> -				dev->buffer[channel].frame[i].lpvbits);
> -			vfree(dev->buffer[channel].frame[i].lpvbits);
> +				channel->buffer.frame[i].lpvbits);
> +			vfree(channel->buffer.frame[i].lpvbits);
>  		}
> -		dev->buffer[channel].frame[i].lpvbits = NULL;
> +		channel->buffer.frame[i].lpvbits = NULL;
>  	}
>  	return 0;
>  }
> @@ -2320,17 +2311,20 @@
>  			fw_ver & 0xff);
>  
>  	for (j = 0; j < MAX_CHANNELS; j++) {
> -		dev->b_acquire[j] = 0;
> -		dev->mode[j] = mode_def;
> +		struct s2255_channel *channel = &dev->channel[j];
> +		channel->b_acquire = 0;
> +		channel->mode = mode_def;
>  		if (dev->pid == 0x2257 && j > 1)
> -			dev->mode[j].color |= (1 << 16);
> -		dev->jc[j].quality = S2255_DEF_JPEG_QUAL;
> -		dev->cur_fmt[j] = &formats[0];
> -		dev->mode[j].restart = 1;
> -		dev->req_image_size[j] = get_transfer_size(&mode_def);
> -		dev->frame_count[j] = 0;
> +			channel->mode.color |= (1 << 16);
> +		channel->jc.quality = S2255_DEF_JPEG_QUAL;
> +		channel->width = LINE_SZ_4CIFS_NTSC;
> +		channel->height = NUM_LINES_4CIFS_NTSC * 2;
> +		channel->fmt = &formats[0];
> +		channel->mode.restart = 1;
> +		channel->req_image_size = get_transfer_size(&mode_def);
> +		channel->frame_count = 0;
>  		/* create the system buffers */
> -		s2255_create_sys_buffers(dev, j);
> +		s2255_create_sys_buffers(channel);
>  	}
>  	/* start read pipe */
>  	s2255_start_readpipe(dev);
> @@ -2344,14 +2338,12 @@
>  	dprintk(1, "%s: dev: %p", __func__,  dev);
>  
>  	for (i = 0; i < MAX_CHANNELS; i++) {
> -		if (dev->b_acquire[i])
> -			s2255_stop_acquire(dev, i);
> +		if (dev->channel[i].b_acquire)
> +			s2255_stop_acquire(&dev->channel[i]);
>  	}
> -
>  	s2255_stop_readpipe(dev);
> -
>  	for (i = 0; i < MAX_CHANNELS; i++)
> -		s2255_release_sys_buffers(dev, i);
> +		s2255_release_sys_buffers(&dev->channel[i]);
>  	/* release transfer buffer */
>  	kfree(dev->pipe.transfer_buffer);
>  	return 0;
> @@ -2444,29 +2436,26 @@
>  }
>  
>  /* starts acquisition process */
> -static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
> +static int s2255_start_acquire(struct s2255_channel *channel)
>  {
>  	unsigned char *buffer;
>  	int res;
>  	unsigned long chn_rev;
>  	int j;
> -	if (chn >= MAX_CHANNELS) {
> -		dprintk(2, "start acquire failed, bad channel %lu\n", chn);
> -		return -1;
> -	}
> -	chn_rev = G_chnmap[chn];
> +	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
> +	chn_rev = G_chnmap[channel->idx];
>  	buffer = kzalloc(512, GFP_KERNEL);
>  	if (buffer == NULL) {
>  		dev_err(&dev->udev->dev, "out of mem\n");
>  		return -ENOMEM;
>  	}
>  
> -	dev->last_frame[chn] = -1;
> -	dev->bad_payload[chn] = 0;
> -	dev->cur_frame[chn] = 0;
> +	channel->last_frame = -1;
> +	channel->bad_payload = 0;
> +	channel->cur_frame = 0;
>  	for (j = 0; j < SYS_FRAMES; j++) {
> -		dev->buffer[chn].frame[j].ulState = 0;
> -		dev->buffer[chn].frame[j].cur_size = 0;
> +		channel->buffer.frame[j].ulState = 0;
> +		channel->buffer.frame[j].cur_size = 0;
>  	}
>  
>  	/* send the start command */
> @@ -2477,21 +2466,18 @@
>  	if (res != 0)
>  		dev_err(&dev->udev->dev, "CMD_START error\n");
>  
> -	dprintk(2, "start acquire exit[%lu] %d \n", chn, res);
> +	dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
>  	kfree(buffer);
>  	return 0;
>  }
>  
> -static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)
> +static int s2255_stop_acquire(struct s2255_channel *channel)
>  {
>  	unsigned char *buffer;
>  	int res;
>  	unsigned long chn_rev;
> -	if (chn >= MAX_CHANNELS) {
> -		dprintk(2, "stop acquire failed, bad channel %lu\n", chn);
> -		return -1;
> -	}
> -	chn_rev = G_chnmap[chn];
> +	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
> +	chn_rev = G_chnmap[channel->idx];
>  	buffer = kzalloc(512, GFP_KERNEL);
>  	if (buffer == NULL) {
>  		dev_err(&dev->udev->dev, "out of mem\n");
> @@ -2505,8 +2491,8 @@
>  	if (res != 0)
>  		dev_err(&dev->udev->dev, "CMD_STOP error\n");
>  	kfree(buffer);
> -	dev->b_acquire[chn] = 0;
> -	dprintk(4, "%s: chn %lu, res %d\n", __func__, chn, res);
> +	channel->b_acquire = 0;
> +	dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
>  	return res;
>  }
>  
> @@ -2563,7 +2549,7 @@
>  		s2255_dev_err(&interface->dev, "out of memory\n");
>  		return -ENOMEM;
>  	}
> -	atomic_set(&dev->channels, 0);
> +	atomic_set(&dev->num_channels, 0);
>  	dev->pid = id->idProduct;
>  	dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
>  	if (!dev->fw_data)
> @@ -2600,8 +2586,10 @@
>  	dev->timer.data = (unsigned long)dev->fw_data;
>  	init_waitqueue_head(&dev->fw_data->wait_fw);
>  	for (i = 0; i < MAX_CHANNELS; i++) {
> -		init_waitqueue_head(&dev->wait_setmode[i]);
> -		init_waitqueue_head(&dev->wait_vidstatus[i]);
> +		struct s2255_channel *channel = &dev->channel[i];
> +		dev->channel[i].idx = i;
> +		init_waitqueue_head(&channel->wait_setmode);
> +		init_waitqueue_head(&channel->wait_vidstatus);
>  	}
>  
>  	dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
> @@ -2639,7 +2627,7 @@
>  			printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
>  		if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
>  			printk(KERN_WARNING "s2255: 2257 requires firmware %d"
> -			       "or above.\n", S2255_MIN_DSP_COLORFILTER);
> +			       " or above.\n", S2255_MIN_DSP_COLORFILTER);
>  	}
>  	usb_reset_device(dev->udev);
>  	/* load 2255 board specific */
> @@ -2681,25 +2669,23 @@
>  {
>  	struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
>  	int i;
> -	int channels = atomic_read(&dev->channels);
> -	v4l2_device_unregister(&dev->v4l2_dev);
> +	int channels = atomic_read(&dev->num_channels);
> +	v4l2_device_disconnect(&dev->v4l2_dev);
>  	/*see comments in the uvc_driver.c usb disconnect function */
> -	atomic_inc(&dev->channels);
> +	atomic_inc(&dev->num_channels);
>  	/* unregister each video device. */
> -	for (i = 0; i < channels; i++) {
> -		if (video_is_registered(&dev->vdev[i]))
> -			video_unregister_device(&dev->vdev[i]);
> -	}
> +	for (i = 0; i < channels; i++)
> +		video_unregister_device(&dev->channel[i].vdev);
>  	/* wake up any of our timers */
>  	atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
>  	wake_up(&dev->fw_data->wait_fw);
>  	for (i = 0; i < MAX_CHANNELS; i++) {
> -		dev->setmode_ready[i] = 1;
> -		wake_up(&dev->wait_setmode[i]);
> -		dev->vidstatus_ready[i] = 1;
> -		wake_up(&dev->wait_vidstatus[i]);
> +		dev->channel[i].setmode_ready = 1;
> +		wake_up(&dev->channel[i].wait_setmode);
> +		dev->channel[i].vidstatus_ready = 1;
> +		wake_up(&dev->channel[i].wait_vidstatus);
>  	}
> -	if (atomic_dec_and_test(&dev->channels))
> +	if (atomic_dec_and_test(&dev->num_channels))
>  		s2255_destroy(dev);
>  	dev_info(&interface->dev, "%s\n", __func__);
>  }
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html




Cheers,
Mauro

  reply	other threads:[~2010-04-21  4:30 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-12 17:19 [PATCH] s2255drv: cleanup of device structure sensoray-dev
2010-04-21  4:30 ` Mauro Carvalho Chehab [this message]
  -- strict thread matches above, loose matches on Subject: below --
2010-06-01 22:12 sensoray-dev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100421013017.2770faa8@pedra \
    --to=mchehab@infradead.org \
    --cc=dougsland@gmail.com \
    --cc=linux-dev@sensoray.com \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.