Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 76401
b: refs/heads/master
c: a3a048c
h: refs/heads/master
i:
  76399: 216b6c4
v: v3
  • Loading branch information
Mauro Carvalho Chehab committed Jan 25, 2008
1 parent da5e4e3 commit 8e67b85
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 52 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2c94a674e059e89252d58da655efa4e798be4d48
refs/heads/master: a3a048cea301baba5d451991074a85dc20a8f228
124 changes: 73 additions & 51 deletions trunk/drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
int minor = iminor(inode);
int errCode = 0;
struct em28xx *h,*dev = NULL;
struct em28xx_fh *fh;

list_for_each_entry(h, &em28xx_devlist, devlist) {
if (h->vdev->minor == minor) {
Expand All @@ -251,19 +252,17 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
em28xx_videodbg("open minor=%d type=%s users=%d\n",
minor,v4l2_type_names[dev->type],dev->users);

mutex_lock(&dev->lock);
fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);

if (dev->users) {
em28xx_warn("this driver can be opened only once\n");
mutex_unlock(&dev->lock);
return -EBUSY;
if (!fh) {
em28xx_errdev("em28xx-video.c: Out of memory?!\n");
return -ENOMEM;
}
mutex_lock(&dev->lock);
fh->dev = dev;
filp->private_data = fh;

spin_lock_init(&dev->queue_lock);
init_waitqueue_head(&dev->wait_frame);
init_waitqueue_head(&dev->wait_stream);

if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
em28xx_set_alternate(dev);

dev->width = norm_maxw(dev);
Expand All @@ -277,26 +276,16 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
em28xx_capture_start(dev, 1);
em28xx_resolution_set(dev);

/* device needs to be initialized before isoc transfer */
video_mux(dev, 0);

/* start the transfer */
errCode = em28xx_init_isoc(dev);
if (errCode)
goto err;

em28xx_empty_framequeues(dev);
}

dev->users++;
filp->private_data = dev;
dev->io = IO_NONE;
dev->stream = STREAM_OFF;
dev->num_frames = 0;

/* prepare queues */
em28xx_empty_framequeues(dev);

dev->state |= DEV_INITIALIZED;

err:
mutex_unlock(&dev->lock);
Expand Down Expand Up @@ -333,34 +322,41 @@ static void em28xx_release_resources(struct em28xx *dev)
*/
static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
{
int errCode;
struct em28xx *dev=filp->private_data;
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;
int errCode;

em28xx_videodbg("users=%d\n", dev->users);

mutex_lock(&dev->lock);
if (fh->reader == 1)
fh->reader = 0;

em28xx_uninit_isoc(dev);
if (dev->users == 1) {
dev->reader = 0;

em28xx_release_buffers(dev);
em28xx_uninit_isoc(dev);
em28xx_release_buffers(dev);

/* the device is already disconnect, free the remaining resources */
if (dev->state & DEV_DISCONNECTED) {
em28xx_release_resources(dev);
mutex_unlock(&dev->lock);
kfree(dev);
return 0;
}
/* the device is already disconnect,
free the remaining resources */
if (dev->state & DEV_DISCONNECTED) {
em28xx_release_resources(dev);
mutex_unlock(&dev->lock);
kfree(dev);
return 0;
}

/* set alternate 0 */
dev->alt = 0;
em28xx_videodbg("setting alternate 0\n");
errCode = usb_set_interface(dev->udev, 0, 0);
if (errCode < 0) {
em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
errCode);
/* set alternate 0 */
dev->alt = 0;
em28xx_videodbg("setting alternate 0\n");
errCode = usb_set_interface(dev->udev, 0, 0);
if (errCode < 0) {
em28xx_errdev("cannot change alternate number to "
"0 (error=%i)\n", errCode);
}
}

kfree(fh);
dev->users--;
wake_up_interruptible_nr(&dev->open, 1);
mutex_unlock(&dev->lock);
Expand All @@ -378,13 +374,19 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
struct em28xx_frame_t *f, *i;
unsigned long lock_flags;
int ret = 0;
struct em28xx *dev = filp->private_data;
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;

mutex_lock(&dev->lock);

if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
em28xx_videodbg("V4l2_Buf_type_videocapture is set\n");

if (dev->reader > 0 && fh->reader == 0) {
mutex_unlock(&dev->lock);
return -EBUSY;
}

if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n");
em28xx_videodbg("not supported yet! ...\n");
Expand Down Expand Up @@ -423,6 +425,9 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
" the device again to choose the read method\n");
mutex_unlock(&dev->lock);
return -EINVAL;
} else {
dev->reader = 1;
fh->reader = 1;
}

if (dev->io == IO_NONE) {
Expand Down Expand Up @@ -491,7 +496,8 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
{
unsigned int mask = 0;
struct em28xx *dev = filp->private_data;
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;

mutex_lock(&dev->lock);

Expand Down Expand Up @@ -559,15 +565,23 @@ static struct vm_operations_struct em28xx_vm_ops = {
*/
static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long size = vma->vm_end - vma->vm_start,
start = vma->vm_start;
void *pos;
u32 i;

struct em28xx *dev = filp->private_data;
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;
unsigned long size = vma->vm_end - vma->vm_start;
unsigned long start = vma->vm_start;
void *pos;
u32 i;

mutex_lock(&dev->lock);

if (dev->reader > 0 && fh->reader == 0) {
mutex_unlock(&dev->lock);
return -EBUSY;
} else {
dev->reader = 1;
fh->reader = 1;
}

if (dev->state & DEV_DISCONNECTED) {
em28xx_videodbg("mmap: device not present\n");
mutex_unlock(&dev->lock);
Expand Down Expand Up @@ -918,6 +932,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
struct em28xx *dev, unsigned int cmd, void *arg,
v4l2_kioctl driver_ioctl)
{
struct em28xx_fh *fh = filp->private_data;
int ret;

switch (cmd) {
Expand Down Expand Up @@ -1227,6 +1242,8 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
return ret;
}
}

fh->reader = 0;
em28xx_empty_framequeues(dev);
mutex_unlock(&dev->lock);

Expand All @@ -1248,7 +1265,8 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, void *arg)
{
struct em28xx *dev = filp->private_data;
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;

if (!dev)
return -ENODEV;
Expand Down Expand Up @@ -1456,7 +1474,8 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
int ret = 0;
struct em28xx *dev = filp->private_data;
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;

if (dev->state & DEV_DISCONNECTED) {
em28xx_errdev("v4l2 ioctl: device not present\n");
Expand Down Expand Up @@ -1503,7 +1522,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,

dev->udev = udev;
mutex_init(&dev->lock);
spin_lock_init(&dev->queue_lock);
init_waitqueue_head(&dev->open);
init_waitqueue_head(&dev->wait_frame);
init_waitqueue_head(&dev->wait_stream);

dev->em28xx_write_regs = em28xx_write_regs;
dev->em28xx_read_reg = em28xx_read_reg;
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ struct em28xx {
int vscale; /* vertical scale factor (see datasheet) */
int interlaced; /* 1=interlace fileds, 0=just top fileds */
int type;
unsigned int reader:1;

unsigned long hash; /* eeprom hash - for boards with generic ID */
unsigned long i2c_hash; /* i2c devicelist hash - for boards with generic ID */
Expand Down Expand Up @@ -294,6 +295,11 @@ struct em28xx {
int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg);
};

struct em28xx_fh {
struct em28xx *dev;
unsigned int reader:1;
};

/* Provided by em28xx-i2c.c */

void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
Expand Down

0 comments on commit 8e67b85

Please sign in to comment.