em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream"); 
em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n"); 
static int em28xx_do_ioctl(struct inode *inode, struct file *filp,			   struct em28xx *dev, unsigned int cmd, void *arg,			   v4l2_kioctl driver_ioctl){	int ret;	switch (cmd) {		/* ---------- tv norms ---------- */	case VIDIOC_ENUMSTD:		{			struct v4l2_standard *e = arg;			unsigned int i;			i = e->index;			if (i >= TVNORMS)				return -EINVAL;			ret = v4l2_video_std_construct(e, tvnorms[e->index].id,						       tvnorms[e->index].name);			e->index = i;			if (ret < 0)				return ret;			return 0;		}	case VIDIOC_G_STD:		{			v4l2_std_id *id = arg;			*id = dev->tvnorm->id;			return 0;		}	case VIDIOC_S_STD:		{			v4l2_std_id *id = arg;			unsigned int i;			for (i = 0; i < TVNORMS; i++)				if (*id == tvnorms[i].id)					break;			if (i == TVNORMS)				for (i = 0; i < TVNORMS; i++)					if (*id & tvnorms[i].id)						break;			if (i == TVNORMS)				return -EINVAL;			down(&dev->lock);			dev->tvnorm = &tvnorms[i];			em28xx_set_norm(dev, dev->width, dev->height);/*		dev->width=norm_maxw(dev);		dev->height=norm_maxh(dev);		dev->frame_size=dev->width*dev->height*2;		dev->field_size=dev->frame_size>>1;		dev->bytesperline=dev->width*2;		dev->hscale=0;		dev->vscale=0;		em28xx_resolution_set(dev);*//*		em28xx_uninit_isoc(dev);		em28xx_set_alternate(dev);		em28xx_capture_start(dev, 1);		em28xx_resolution_set(dev);		em28xx_init_isoc(dev);*/			em28xx_i2c_call_clients(dev, DECODER_SET_NORM,						&tvnorms[i].mode);			em28xx_i2c_call_clients(dev, VIDIOC_S_STD,						&dev->tvnorm->id);			up(&dev->lock);			return 0;		}		/* ------ input switching ---------- */	case VIDIOC_ENUMINPUT:		{			struct v4l2_input *i = arg;			unsigned int n;			static const char *iname[] = {				[EM28XX_VMUX_COMPOSITE1] = "Composite1",				[EM28XX_VMUX_COMPOSITE2] = "Composite2",				[EM28XX_VMUX_COMPOSITE3] = "Composite3",				[EM28XX_VMUX_COMPOSITE4] = "Composite4",				[EM28XX_VMUX_SVIDEO] = "S-Video",				[EM28XX_VMUX_TELEVISION] = "Television",				[EM28XX_VMUX_CABLE] = "Cable TV",				[EM28XX_VMUX_DVB] = "DVB",				[EM28XX_VMUX_DEBUG] = "for debug only",			};			n = i->index;			if (n >= MAX_EM28XX_INPUT)				return -EINVAL;			if (0 == INPUT(n)->type)				return -EINVAL;			memset(i, 0, sizeof(*i));			i->index = n;			i->type = V4L2_INPUT_TYPE_CAMERA;			strcpy(i->name, iname[INPUT(n)->type]);			if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||			    (EM28XX_VMUX_CABLE == INPUT(n)->type))				i->type = V4L2_INPUT_TYPE_TUNER;			for (n = 0; n < ARRAY_SIZE(tvnorms); n++)				i->std |= tvnorms[n].id;			return 0;		}	case VIDIOC_G_INPUT:		{			int *i = arg;			*i = dev->ctl_input;			return 0;		}	case VIDIOC_S_INPUT:		{			int *index = arg;			if (*index >= MAX_EM28XX_INPUT)				return -EINVAL;			if (0 == INPUT(*index)->type)				return -EINVAL;			down(&dev->lock);			video_mux(dev, *index);			up(&dev->lock);			return 0;		}	case VIDIOC_G_AUDIO:		{			struct v4l2_audio *a = arg;			unsigned int index = a->index;			if (a->index > 1)				return -EINVAL;			memset(a, 0, sizeof(*a));			index = dev->ctl_ainput;			if (index == 0) {				strcpy(a->name, "Television");			} else {				strcpy(a->name, "Line In");			}			a->capability = V4L2_AUDCAP_STEREO;			a->index = index;			return 0;		}	case VIDIOC_S_AUDIO:		{			struct v4l2_audio *a = arg;			if (a->index != dev->ctl_ainput)				return -EINVAL;			return 0;		}		/* --- controls ---------------------------------------------- */	case VIDIOC_QUERYCTRL:		{			struct v4l2_queryctrl *qc = arg;			u8 i, n;			n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);			for (i = 0; i < n; i++)				if (qc->id && qc->id == em28xx_qctrl[i].id) {					memcpy(qc, &(em28xx_qctrl[i]),					       sizeof(*qc));					return 0;				}			return -EINVAL;		}	case VIDIOC_G_CTRL:		{			struct v4l2_control *ctrl = arg;			return em28xx_get_ctrl(dev, ctrl);		}	case VIDIOC_S_CTRL_OLD:	/* ??? */	case VIDIOC_S_CTRL:		{			struct v4l2_control *ctrl = arg;			u8 i, n;			n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);			for (i = 0; i < n; i++)				if (ctrl->id == em28xx_qctrl[i].id) {					if (ctrl->value <					    em28xx_qctrl[i].minimum					    || ctrl->value >					    em28xx_qctrl[i].maximum)						return -ERANGE;					return em28xx_set_ctrl(dev, ctrl);				}			return -EINVAL;		}		/* --- tuner ioctls ------------------------------------------ */	case VIDIOC_G_TUNER:		{			struct v4l2_tuner *t = arg;			int status = 0;			if (0 != t->index)				return -EINVAL;			memset(t, 0, sizeof(*t));			strcpy(t->name, "Tuner");			t->type = V4L2_TUNER_ANALOG_TV;			t->capability = V4L2_TUNER_CAP_NORM;			t->rangehigh = 0xffffffffUL;	/* FIXME: set correct range *//*		t->signal = 0xffff;*//*		em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/			/* No way to get signal strength? */			down(&dev->lock);			em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,						&status);			up(&dev->lock);			t->signal =			    (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;			em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x", t->signal,				 t->afc);			return 0;		}	case VIDIOC_S_TUNER:		{			struct v4l2_tuner *t = arg;			int status = 0;			if (0 != t->index)				return -EINVAL;			memset(t, 0, sizeof(*t));			strcpy(t->name, "Tuner");			t->type = V4L2_TUNER_ANALOG_TV;			t->capability = V4L2_TUNER_CAP_NORM;			t->rangehigh = 0xffffffffUL;	/* FIXME: set correct range *//*		t->signal = 0xffff; */			/* No way to get signal strength? */			down(&dev->lock);			em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,						&status);			up(&dev->lock);			t->signal =			    (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;			em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",				 t->signal, t->afc);			return 0;		}	case VIDIOC_G_FREQUENCY:		{			struct v4l2_frequency *f = arg;			memset(f, 0, sizeof(*f));			f->type = V4L2_TUNER_ANALOG_TV;			f->frequency = dev->ctl_freq;			return 0;		}	case VIDIOC_S_FREQUENCY:		{			struct v4l2_frequency *f = arg;			if (0 != f->tuner)				return -EINVAL;			if (V4L2_TUNER_ANALOG_TV != f->type)				return -EINVAL;			down(&dev->lock);			dev->ctl_freq = f->frequency;			em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);			up(&dev->lock);			return 0;		}	case VIDIOC_CROPCAP:		{			struct v4l2_cropcap *cc = arg;			if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)				return -EINVAL;			cc->bounds.left = 0;			cc->bounds.top = 0;			cc->bounds.width = dev->width;			cc->bounds.height = dev->height;			cc->defrect = cc->bounds;			cc->pixelaspect.numerator = 54;	/* 4:3 FIXME: remove magic numbers */			cc->pixelaspect.denominator = 59;			return 0;		}	case VIDIOC_STREAMON:		{			int *type = arg;			if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE			    || dev->io != IO_MMAP)				return -EINVAL;			if (list_empty(&dev->inqueue))				return -EINVAL;			dev->stream = STREAM_ON;	/* FIXME: Start video capture here? */			em28xx_videodbg("VIDIOC_STREAMON: starting stream");			return 0;		}	case VIDIOC_STREAMOFF:		{			int *type = arg;			int ret;			if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE			    || dev->io != IO_MMAP)				return -EINVAL;			if (dev->stream == STREAM_ON) {				em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream");				if ((ret = em28xx_stream_interrupt(dev)))					return ret;			}			em28xx_empty_framequeues(dev);			return 0;		}	default:		return v4l_compat_translate_ioctl(inode, filp, cmd, arg,						  driver_ioctl);	}	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/eac94356c8f9f7d3854ed0290a406b13bfe8df4c/em28xx-video.c/buggy/drivers/media/video/em28xx/em28xx-video.c