From: jinhyung.jo Date: Tue, 7 Jul 2015 08:21:23 +0000 (+0900) Subject: maru-camera: Changed the method for passing the argument to/from device X-Git-Tag: submit/tizen/20160422.055611~1^2~39 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=42be8438d7f1fe7133b1a7f175b4e5cd5de86865;p=sdk%2Femulator%2Femulator-kernel.git maru-camera: Changed the method for passing the argument to/from device Without using the CPU I/O, directly using the device memory. Additionally Allowing the instance to 2. Modified the log format & contents. Change-Id: I919b3847e7e0fec02a873bed27bd064bae92a680 Signed-off-by: Jinhyung Jo --- diff --git a/drivers/maru/maru_camera.c b/drivers/maru/maru_camera.c index bd6f910fa4db..7323e40f93bb 100644 --- a/drivers/maru/maru_camera.c +++ b/drivers/maru/maru_camera.c @@ -5,6 +5,7 @@ * * Contact: * Jinhyung Jo + * Sangho Park * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,7 +20,7 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * Boston, MA 02110-1301, USA. * * Contributors: * - S-Core Co., Ltd @@ -56,28 +57,30 @@ static unsigned debug; +#define MARUCAM_MODULE_NAME "marucam" + #define marucam_err(fmt, arg...) \ - printk(KERN_ERR "[ERR]marucam[%s]: " fmt, __func__, ##arg) + printk(KERN_ERR "%s: error [%s:%d]: " fmt, MARUCAM_MODULE_NAME, \ + __func__, __LINE__, ##arg) #define marucam_warn(fmt, arg...) \ - printk(KERN_WARNING "[WARN]marucam[%s]: " fmt, __func__, ##arg) + printk(KERN_WARNING "%s: " fmt, MARUCAM_MODULE_NAME, ##arg) #define marucam_info(fmt, arg...) \ - printk(KERN_INFO "[INFO]marucam[%s]: " fmt, __func__, ##arg) + printk(KERN_INFO "%s: " fmt, MARUCAM_MODULE_NAME, ##arg) #define marucam_dbg(level, fmt, arg...) \ do { \ if (debug >= (level)) { \ - printk(KERN_DEBUG "[DBG]marucam[%s]: " fmt, \ - __func__, ##arg); \ + printk(KERN_DEBUG "%s: [%s:%d]: " fmt, \ + MARUCAM_MODULE_NAME, \ + __func__, __LINE__, ##arg); \ } \ } while (0) -#define MARUCAM_MODULE_NAME "marucam" - -#define MARUCAM_MAJOR_VERSION 0 -#define MARUCAM_MINOR_VERSION 25 -#define MARUCAM_RELEASE 1 +#define MARUCAM_MAJOR_VERSION 1 +#define MARUCAM_MINOR_VERSION 0 +#define MARUCAM_RELEASE 2 #define MARUCAM_VERSION \ KERNEL_VERSION(MARUCAM_MAJOR_VERSION, \ MARUCAM_MINOR_VERSION, MARUCAM_RELEASE) @@ -86,9 +89,6 @@ MODULE_DESCRIPTION("MARU Virtual Camera Driver"); MODULE_AUTHOR("Jinhyung Jo "); MODULE_LICENSE("GPL"); -#define DFL_WIDTH 640 -#define DFL_HEIGHT 480 - /* * Basic structures */ @@ -96,33 +96,31 @@ MODULE_LICENSE("GPL"); #define MARUCAM_OPEN 0x04 #define MARUCAM_CLOSE 0x08 #define MARUCAM_ISR 0x0C -#define MARUCAM_START_PREVIEW 0x10 -#define MARUCAM_STOP_PREVIEW 0x14 -#define MARUCAM_S_PARAM 0x18 -#define MARUCAM_G_PARAM 0x1C +#define MARUCAM_STREAMON 0x10 +#define MARUCAM_STREAMOFF 0x14 +#define MARUCAM_S_PARM 0x18 +#define MARUCAM_G_PARM 0x1C #define MARUCAM_ENUM_FMT 0x20 #define MARUCAM_TRY_FMT 0x24 #define MARUCAM_S_FMT 0x28 #define MARUCAM_G_FMT 0x2C -#define MARUCAM_QCTRL 0x30 +#define MARUCAM_QUERYCTRL 0x30 #define MARUCAM_S_CTRL 0x34 #define MARUCAM_G_CTRL 0x38 #define MARUCAM_ENUM_FSIZES 0x3C #define MARUCAM_ENUM_FINTV 0x40 -#define MARUCAM_S_DATA 0x44 -#define MARUCAM_G_DATA 0x48 -#define MARUCAM_DTC 0x50 -#define MARUCAM_REQFRAME 0x54 +#define MARUCAM_REQFRAME 0x44 +#define MARUCAM_EXIT 0x48 enum marucam_opstate { S_IDLE = 0, S_RUNNING = 1 }; - struct marucam_device { struct v4l2_device v4l2_dev; + unsigned char dev_index; spinlock_t slock; struct mutex mlock; enum marucam_opstate opstate; @@ -132,10 +130,10 @@ struct marucam_device { struct pci_dev *pdev; void __iomem *mmregs; - resource_size_t io_base; - resource_size_t io_size; + void __iomem *args; resource_size_t mem_base; resource_size_t mem_size; + resource_size_t iomem_size; enum v4l2_buf_type type; unsigned int width; @@ -149,7 +147,7 @@ struct marucam_device { /* * Use only one instance. */ -static struct marucam_device *marucam_instance; +static struct marucam_device *marucam_instance[2]; /* * The code below has been modified from 'videobuf_vmalloc.c'. @@ -160,7 +158,7 @@ static struct marucam_device *marucam_instance; #define MAGIC_CHECK(is, should) \ do { \ if (unlikely((is) != (should))) { \ - marucam_err("Invalid the magic number:" \ + marucam_err("invalid magic number:" \ " %x (expected %x)\n", is, should); \ BUG(); \ } \ @@ -190,18 +188,15 @@ static void videobuf_vm_close(struct vm_area_struct *vma) mutex_lock(&q->vb_lock); - if (q->streaming) { + if (q->streaming) videobuf_queue_cancel(q); - } for (i = 0; i < VIDEO_MAX_FRAME; i++) { - if (NULL == q->bufs[i]) { + if (NULL == q->bufs[i]) continue; - } - if (q->bufs[i]->map != map) { + if (q->bufs[i]->map != map) continue; - } mem = q->bufs[i]->priv; if (mem) { @@ -233,7 +228,7 @@ static struct videobuf_buffer *__videobuf_alloc_vb(size_t size) vb = kzalloc(size + sizeof(*mem), GFP_KERNEL); if (vb == NULL) { - marucam_err("Failed to allocate the video buffer\n"); + marucam_err("memory allocation failed for a video buffer\n"); return vb; } @@ -256,12 +251,12 @@ static int __videobuf_iolock(struct videobuf_queue *q, switch (vb->memory) { case V4L2_MEMORY_MMAP: if (!mem->mapped) { - marucam_err("The memory is not mmapped.\n"); + marucam_err("memory is not mapped\n"); return -EINVAL; } break; default: - marucam_err("Memory method currently unsupported.\n"); + marucam_err("V4L2_MEMORY_MMAP only supported\n"); return -EINVAL; } @@ -277,7 +272,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); if (NULL == map) { - marucam_err("Failed to allocate the video buffer map\n"); + marucam_err("memory allocation failed for a video buffer mapping\n"); return -ENOMEM; } @@ -299,7 +294,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, + vma->vm_pgoff) >> PAGE_SHIFT, pages, vma->vm_page_prot); if (retval < 0) { - marucam_err("Failed to remap the memory: %d\n", retval); + marucam_err("remap failed: %d\n", retval); mem->mapped = 0; mem = NULL; kfree(map); @@ -372,19 +367,19 @@ static void marucam_fillbuf(struct marucam_device *dev, uint32_t isr) spin_lock_irqsave(q1->irqlock, flags); if (dev->opstate != S_RUNNING) { - marucam_err("The device state is not S_RUNNING\n"); + marucam_err("state is not S_RUNNING\n"); spin_unlock_irqrestore(q1->irqlock, flags); return; } if (list_empty(&dev->active)) { - marucam_err("The active list is empty\n"); + marucam_err("active list is empty\n"); spin_unlock_irqrestore(q1->irqlock, flags); return; } buf = list_entry(dev->active.next, struct videobuf_buffer, queue); if (!waitqueue_active(&buf->done)) { - marucam_err("The list of wait queue is empty\n"); + marucam_err("wait queue list is empty\n"); spin_unlock_irqrestore(q1->irqlock, flags); return; } @@ -392,10 +387,10 @@ static void marucam_fillbuf(struct marucam_device *dev, uint32_t isr) list_del(&buf->queue); if (isr & 0x08) { - marucam_err("The device state is invalid\n"); + marucam_err("invalid state\n"); buf->state = 0xFF; /* invalid state */ } else { - marucam_dbg(2, "The video buffer is filled\n"); + marucam_dbg(2, "video buffer is filled\n"); buf->state = VIDEOBUF_DONE; } do_gettimeofday(&buf->ts); @@ -411,7 +406,7 @@ static irqreturn_t marucam_irq_handler(int irq, void *dev_id) isr = ioread32(dev->mmregs + MARUCAM_ISR); if (!isr) { - marucam_dbg(1, "This irq is not for this module\n"); + marucam_dbg(1, "mismatched irq\n"); return IRQ_NONE; } @@ -439,62 +434,61 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); return -EINVAL; } mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(f->index, dev->mmregs + MARUCAM_S_DATA); - + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)f, sizeof(struct v4l2_fmtdesc)); iowrite32(0, dev->mmregs + MARUCAM_ENUM_FMT); - ret = (int)ioread32(dev->mmregs + MARUCAM_ENUM_FMT); + ret = ioread32(dev->mmregs + MARUCAM_ENUM_FMT); if (ret) { + if (ret != EINVAL) { + marucam_err("enum_fmt failed: ret(%d), idx(%u)\n", + ret, f->index); + } mutex_unlock(&dev->mlock); return -ret; } - - f->index = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->flags = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA); - ioread32_rep(dev->mmregs + MARUCAM_G_DATA, f->description, 8); - + memcpy_fromio((void *)f, dev->args, sizeof(struct v4l2_fmtdesc)); mutex_unlock(&dev->mlock); + return 0; } static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; + struct v4l2_pix_format *pf = &f->fmt.pix; + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + return -EINVAL; + } mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)pf, sizeof(struct v4l2_format)); iowrite32(0, dev->mmregs + MARUCAM_G_FMT); - ret = (int)ioread32(dev->mmregs + MARUCAM_G_FMT); + ret = ioread32(dev->mmregs + MARUCAM_G_FMT); if (ret) { - marucam_err("Failed to get the format: %d\n", -ret); + marucam_err("g_fmt failed: ret(%d)\n", ret); mutex_unlock(&dev->mlock); return -ret; } + memcpy_fromio((void *)pf, dev->args, sizeof(struct v4l2_format)); - f->fmt.pix.width = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.height = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.field = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.bytesperline = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.sizeimage = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.colorspace = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.priv = ioread32(dev->mmregs + MARUCAM_G_DATA); - - dev->pixelformat = f->fmt.pix.pixelformat; - dev->width = f->fmt.pix.width; - dev->height = f->fmt.pix.height; - dev->vb_vidq.field = f->fmt.pix.field; + dev->pixelformat = pf->pixelformat; + dev->width = pf->width; + dev->height = pf->height; + dev->vb_vidq.field = pf->field; dev->type = f->type; mutex_unlock(&dev->mlock); @@ -504,33 +498,28 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; + struct v4l2_pix_format *pf = &f->fmt.pix; - mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(f->fmt.pix.width, dev->mmregs + MARUCAM_S_DATA); - iowrite32(f->fmt.pix.height, dev->mmregs + MARUCAM_S_DATA); - iowrite32(f->fmt.pix.pixelformat, dev->mmregs + MARUCAM_S_DATA); - iowrite32(f->fmt.pix.field, dev->mmregs + MARUCAM_S_DATA); + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + return -EINVAL; + } + mutex_lock(&dev->mlock); + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)pf, sizeof(struct v4l2_format)); iowrite32(0, dev->mmregs + MARUCAM_TRY_FMT); - ret = (int)ioread32(dev->mmregs + MARUCAM_TRY_FMT); + ret = ioread32(dev->mmregs + MARUCAM_TRY_FMT); if (ret) { - marucam_err("Failed to check the format: %d\n", -ret); + marucam_err("try_fmt failed: ret(%d), wxh(%ux%u), pf(0x%x)\n", + ret, pf->width, pf->height, + pf->pixelformat); mutex_unlock(&dev->mlock); return -ret; } - - f->fmt.pix.width = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.height = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.field = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.bytesperline = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.sizeimage = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.colorspace = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.priv = ioread32(dev->mmregs + MARUCAM_G_DATA); - + memcpy_fromio((void *)pf, dev->args, sizeof(struct v4l2_format)); mutex_unlock(&dev->mlock); return 0; } @@ -538,52 +527,49 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; struct videobuf_queue *q2 = &dev->vb_vidq; + struct v4l2_pix_format *pf = &f->fmt.pix; + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + return -EINVAL; + } mutex_lock(&dev->mlock); if (dev->opstate != S_IDLE) { - marucam_err("The device state is not S_IDLE\n"); + marucam_err("state is not S_IDLE\n"); mutex_unlock(&dev->mlock); return -EBUSY; } mutex_lock(&q2->vb_lock); if (videobuf_queue_is_busy(&dev->vb_vidq)) { - marucam_err("The videobuf queue is busy\n"); + marucam_err("videobuf queue is busy\n"); mutex_unlock(&q2->vb_lock); mutex_unlock(&dev->mlock); return -EBUSY; } mutex_unlock(&q2->vb_lock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(f->fmt.pix.width, dev->mmregs + MARUCAM_S_DATA); - iowrite32(f->fmt.pix.height, dev->mmregs + MARUCAM_S_DATA); - iowrite32(f->fmt.pix.pixelformat, dev->mmregs + MARUCAM_S_DATA); - iowrite32(f->fmt.pix.field, dev->mmregs + MARUCAM_S_DATA); + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)pf, sizeof(struct v4l2_format)); iowrite32(0, dev->mmregs + MARUCAM_S_FMT); - ret = (int)ioread32(dev->mmregs + MARUCAM_S_FMT); + ret = ioread32(dev->mmregs + MARUCAM_S_FMT); if (ret) { - marucam_err("Failed to set the format: %d\n", -ret); + marucam_err("s_fmt failed: ret(%d), wxh(%ux%u), pf(0x%x)\n", + ret, pf->width, pf->height, + pf->pixelformat); mutex_unlock(&dev->mlock); return -ret; } + memcpy_fromio((void *)pf, dev->args, sizeof(struct v4l2_format)); - f->fmt.pix.width = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.height = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.field = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.bytesperline = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.sizeimage = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.colorspace = ioread32(dev->mmregs + MARUCAM_G_DATA); - f->fmt.pix.priv = ioread32(dev->mmregs + MARUCAM_G_DATA); - - dev->pixelformat = f->fmt.pix.pixelformat; - dev->width = f->fmt.pix.width; - dev->height = f->fmt.pix.height; - dev->vb_vidq.field = f->fmt.pix.field; + dev->pixelformat = pf->pixelformat; + dev->width = pf->width; + dev->height = pf->height; + dev->vb_vidq.field = pf->field; dev->type = f->type; mutex_unlock(&dev->mlock); @@ -600,7 +586,9 @@ static int vidioc_reqbufs(struct file *file, void *priv, ret = videobuf_reqbufs(&dev->vb_vidq, p); if (ret) { - marucam_err("Failed to request the video buffers\n"); + marucam_err("%s failed: ret(%d), count(%u), type(%u), memory(%u)\n", + __func__, ret, p->count, + p->type, p->memory); } return ret; @@ -613,7 +601,9 @@ static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) ret = videobuf_querybuf(&dev->vb_vidq, p); if (ret) { - marucam_err("Failed to query the video buffer\n"); + marucam_err("%s failed: ret(%d), idx(%u), type(%u), memory(%u)\n", + __func__, ret, p->index, + p->type, p->memory); } return ret; @@ -626,7 +616,9 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) ret = videobuf_qbuf(&dev->vb_vidq, p); if (ret) { - marucam_err("Failed to queue the video buffer\n"); + marucam_err("%s failed: ret(%d), idx(%u), type(%u), memory(%u)\n", + __func__, ret, p->index, + p->type, p->memory); } return ret; @@ -639,7 +631,9 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) ret = videobuf_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK); if (ret) { - marucam_err("Failed to dequeue the video buffer\n"); + marucam_err("%s failed: ret(%d), idx(%u), type(%u), memory(%u)\n", + __func__, ret, p->index, + p->type, p->memory); } return ret; @@ -648,34 +642,38 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { int ret = 0; + unsigned int dev_ret; struct marucam_device *dev = priv; if (dev->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); return -EINVAL; } if (i != dev->type) { + marucam_err("mismatched buf type\n"); return -EINVAL; } mutex_lock(&dev->mlock); if (dev->opstate != S_IDLE) { - marucam_err("The device state is not S_IDLE\n"); + marucam_err("state is not S_IDLE\n"); mutex_unlock(&dev->mlock); return -EBUSY; } - iowrite32(1, dev->mmregs + MARUCAM_START_PREVIEW); - ret = (int)ioread32(dev->mmregs + MARUCAM_START_PREVIEW); - if (ret) { - marucam_err("Failed to start preview\n"); + memset_io(dev->args, 0x00, dev->iomem_size); + iowrite32(0, dev->mmregs + MARUCAM_STREAMON); + dev_ret = ioread32(dev->mmregs + MARUCAM_STREAMON); + if (dev_ret) { + marucam_err("stream_on failed: ret(%d)\n", dev_ret); mutex_unlock(&dev->mlock); - return -ret; + return -dev_ret; } INIT_LIST_HEAD(&dev->active); ret = videobuf_streamon(&dev->vb_vidq); if (ret) { - marucam_err("Failed to stream on the video buffer: %d\n", ret); + marucam_err("videobuf_streamon() failed: ret(%d)\n", ret); mutex_unlock(&dev->mlock); return ret; } @@ -688,12 +686,15 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { int ret = 0; + unsigned int dev_ret; struct marucam_device *dev = priv; if (dev->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); return -EINVAL; } if (i != dev->type) { + marucam_err("mismatched buf type\n"); return -EINVAL; } @@ -704,20 +705,19 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) return 0; } - iowrite32(1, dev->mmregs + MARUCAM_STOP_PREVIEW); - ret = (int)ioread32(dev->mmregs + MARUCAM_STOP_PREVIEW); - if (ret) { - marucam_err("Failed to stop preview\n"); + memset_io(dev->args, 0x00, dev->iomem_size); + iowrite32(0, dev->mmregs + MARUCAM_STREAMOFF); + dev_ret = ioread32(dev->mmregs + MARUCAM_STREAMOFF); + if (dev_ret) { + marucam_err("stream_off failed: ret(%d)\n", dev_ret); mutex_unlock(&dev->mlock); - return -ret; + return -dev_ret; } dev->opstate = S_IDLE; ret = videobuf_streamoff(&dev->vb_vidq); - if (ret) { - marucam_err("Failed to stream off the video buffer: %d\n", - ret); - } + if (ret) + marucam_err("videobuf_streamoff() failed: ret(%d)\n", ret); INIT_LIST_HEAD(&dev->active); mutex_unlock(&dev->mlock); @@ -732,9 +732,8 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i) static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp) { - if (inp->index != 0) { + if (inp->index != 0) return -EINVAL; - } inp->type = V4L2_INPUT_TYPE_CAMERA; sprintf(inp->name, "MARU Virtual Camera %u", inp->index); @@ -759,7 +758,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; mutex_lock(&dev->mlock); @@ -775,23 +774,19 @@ static int vidioc_queryctrl(struct file *file, void *priv, return -EINVAL; } - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(qc->id, dev->mmregs + MARUCAM_S_DATA); - - iowrite32(0, dev->mmregs + MARUCAM_QCTRL); - ret = (int)ioread32(dev->mmregs + MARUCAM_QCTRL); + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)qc, + sizeof(struct v4l2_queryctrl)); + iowrite32(0, dev->mmregs + MARUCAM_QUERYCTRL); + ret = ioread32(dev->mmregs + MARUCAM_QUERYCTRL); if (ret) { + marucam_err("query_ctrl failed: ret(%d), id(%u)\n", + ret, qc->id); mutex_unlock(&dev->mlock); return -ret; } - - qc->id = ioread32(dev->mmregs + MARUCAM_G_DATA); - qc->minimum = ioread32(dev->mmregs + MARUCAM_G_DATA); - qc->maximum = ioread32(dev->mmregs + MARUCAM_G_DATA); - qc->step = ioread32(dev->mmregs + MARUCAM_G_DATA); - qc->default_value = ioread32(dev->mmregs + MARUCAM_G_DATA); - qc->flags = ioread32(dev->mmregs + MARUCAM_G_DATA); - ioread32_rep(dev->mmregs + MARUCAM_G_DATA, qc->name, 8); + memcpy_fromio((void *)qc, dev->args, + sizeof(struct v4l2_queryctrl)); mutex_unlock(&dev->mlock); return 0; @@ -800,23 +795,23 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(ctrl->id, dev->mmregs + MARUCAM_S_DATA); - + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)ctrl, + sizeof(struct v4l2_control)); iowrite32(0, dev->mmregs + MARUCAM_G_CTRL); - ret = (int)ioread32(dev->mmregs + MARUCAM_G_CTRL); + ret = ioread32(dev->mmregs + MARUCAM_G_CTRL); if (ret) { - marucam_err("Failed to get the control value\n"); + marucam_err("g_ctrl failed: ret(%d), id(%u)\n", + ret, ctrl->id); mutex_unlock(&dev->mlock); return -ret; } - - ctrl->value = ioread32(dev->mmregs + MARUCAM_G_DATA); - + memcpy_fromio((void *)ctrl, dev->args, + sizeof(struct v4l2_control)); mutex_unlock(&dev->mlock); return 0; } @@ -824,22 +819,23 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(ctrl->id, dev->mmregs + MARUCAM_S_DATA); - iowrite32(ctrl->value, dev->mmregs + MARUCAM_S_DATA); - + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)ctrl, + sizeof(struct v4l2_control)); iowrite32(0, dev->mmregs + MARUCAM_S_CTRL); - ret = (int)ioread32(dev->mmregs + MARUCAM_S_CTRL); + ret = ioread32(dev->mmregs + MARUCAM_S_CTRL); if (ret) { - marucam_err("Failed to set the control value\n"); + marucam_err("s_ctrl failed: ret(%d), id(%u), val(%d)\n", + ret, ctrl->id, ctrl->value); mutex_unlock(&dev->mlock); return -ret; } - + memcpy_fromio((void *)ctrl, dev->args, + sizeof(struct v4l2_control)); mutex_unlock(&dev->mlock); return 0; } @@ -847,27 +843,28 @@ static int vidioc_s_ctrl(struct file *file, void *priv, static int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; struct v4l2_captureparm *cp = &parm->parm.capture; if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); return -EINVAL; } mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(cp->timeperframe.numerator, dev->mmregs + MARUCAM_S_DATA); - iowrite32(cp->timeperframe.denominator, dev->mmregs + MARUCAM_S_DATA); - - iowrite32(0, dev->mmregs + MARUCAM_S_PARAM); - ret = (int)ioread32(dev->mmregs + MARUCAM_S_PARAM); + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)cp, + sizeof(struct v4l2_captureparm)); + iowrite32(0, dev->mmregs + MARUCAM_S_PARM); + ret = ioread32(dev->mmregs + MARUCAM_S_PARM); if (ret) { - marucam_err("Failed to set the FPS\n"); + marucam_err("s_parm failed: ret(%d)\n", ret); mutex_unlock(&dev->mlock); return -ret; } - + memcpy_fromio((void *)cp, dev->args, + sizeof(struct v4l2_captureparm)); mutex_unlock(&dev->mlock); return 0; } @@ -875,28 +872,28 @@ static int vidioc_s_parm(struct file *file, void *priv, static int vidioc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; struct v4l2_captureparm *cp = &parm->parm.capture; if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); return -EINVAL; } mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(0, dev->mmregs + MARUCAM_G_PARAM); - ret = (int)ioread32(dev->mmregs + MARUCAM_G_PARAM); + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)cp, + sizeof(struct v4l2_captureparm)); + iowrite32(0, dev->mmregs + MARUCAM_G_PARM); + ret = ioread32(dev->mmregs + MARUCAM_G_PARM); if (ret) { - marucam_err("Failed to get the FPS\n"); + marucam_err("g_parm failed: ret(%d)\n", ret); mutex_unlock(&dev->mlock); return -ret; } - - cp->capability = ioread32(dev->mmregs + MARUCAM_G_DATA); - cp->timeperframe.numerator = ioread32(dev->mmregs + MARUCAM_G_DATA); - cp->timeperframe.denominator = ioread32(dev->mmregs + MARUCAM_G_DATA); - + memcpy_fromio((void *)cp, dev->args, + sizeof(struct v4l2_captureparm)); mutex_unlock(&dev->mlock); return 0; } @@ -904,25 +901,25 @@ static int vidioc_g_parm(struct file *file, void *priv, static int vidioc_enum_framesizes(struct file *file, void *priv, struct v4l2_frmsizeenum *fsize) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(fsize->index, dev->mmregs + MARUCAM_S_DATA); - iowrite32(fsize->pixel_format, dev->mmregs + MARUCAM_S_DATA); - + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)fsize, + sizeof(struct v4l2_frmsizeenum)); iowrite32(0, dev->mmregs + MARUCAM_ENUM_FSIZES); - ret = (int)ioread32(dev->mmregs + MARUCAM_ENUM_FSIZES); + ret = ioread32(dev->mmregs + MARUCAM_ENUM_FSIZES); if (ret) { + if (ret != EINVAL) { + marucam_err("enum_framesizes failed: %d, index(%u), pix(%u)\n", + ret, fsize->index, fsize->pixel_format); + } mutex_unlock(&dev->mlock); return -ret; } - - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = ioread32(dev->mmregs + MARUCAM_G_DATA); - fsize->discrete.height = ioread32(dev->mmregs + MARUCAM_G_DATA); - + memcpy_fromio((void *)fsize, dev->args, + sizeof(struct v4l2_frmsizeenum)); mutex_unlock(&dev->mlock); return 0; } @@ -930,27 +927,27 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, static int vidioc_enum_frameintervals(struct file *file, void *priv, struct v4l2_frmivalenum *fival) { - int ret; + unsigned int ret; struct marucam_device *dev = priv; mutex_lock(&dev->mlock); - iowrite32(0, dev->mmregs + MARUCAM_DTC); - iowrite32(fival->index, dev->mmregs + MARUCAM_S_DATA); - iowrite32(fival->pixel_format, dev->mmregs + MARUCAM_S_DATA); - iowrite32(fival->width, dev->mmregs + MARUCAM_S_DATA); - iowrite32(fival->height, dev->mmregs + MARUCAM_S_DATA); - + memset_io(dev->args, 0x00, dev->iomem_size); + memcpy_toio(dev->args, (const void *)fival, + sizeof(struct v4l2_frmivalenum)); iowrite32(0, dev->mmregs + MARUCAM_ENUM_FINTV); - ret = (int)ioread32(dev->mmregs + MARUCAM_ENUM_FINTV); + ret = ioread32(dev->mmregs + MARUCAM_ENUM_FINTV); if (ret) { + if (ret != EINVAL) { + marucam_err("%s failed: ret(%d), idx(%u), pf(%u), %ux%u\n", + __func__, ret, fival->index, + fival->pixel_format, fival->width, + fival->height); + } mutex_unlock(&dev->mlock); return -ret; } - - fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; - fival->discrete.numerator = ioread32(dev->mmregs + MARUCAM_G_DATA); - fival->discrete.denominator = ioread32(dev->mmregs + MARUCAM_G_DATA); - + memcpy_fromio((void *)fival, dev->args, + sizeof(struct v4l2_frmivalenum)); mutex_unlock(&dev->mlock); return 0; } @@ -966,11 +963,10 @@ static int buffer_setup(struct videobuf_queue *vq, *size = get_image_size(dev); - if (*count > 2) { + if (*count > 2) *count = 2; - } else if (*count == 0) { + else if (*count == 0) *count = 2; - } marucam_dbg(1, "count=%d, size=%d\n", *count, *size); @@ -989,14 +985,14 @@ static int buffer_prepare(struct videobuf_queue *vq, vb->size = get_image_size(dev); if (0 != vb->baddr && vb->bsize < vb->size) { - marucam_err("The video buffer size is invalid\n"); + marucam_err("invalid buffer size\n"); return -EINVAL; } if (vb->state == VIDEOBUF_NEEDS_INIT) { rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { - marucam_err("Failed to videobuf_iolock\n"); + marucam_err("videobuf_iolock() failed: ret(%d)\n", rc); vb->state = VIDEOBUF_NEEDS_INIT; return rc; } @@ -1042,27 +1038,28 @@ static struct videobuf_queue_ops marucam_video_qops = { static int marucam_open(struct file *file) { int ret; + unsigned int dev_ret; struct marucam_device *dev = video_drvdata(file); file->private_data = dev; mutex_lock(&dev->mlock); if (dev->in_use) { - marucam_err("The device has been already opened\n"); + marucam_err("already opened\n"); mutex_unlock(&dev->mlock); return -EBUSY; } dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - dev->pixelformat = V4L2_PIX_FMT_YUYV; - dev->width = DFL_WIDTH; - dev->height = DFL_HEIGHT; + dev->pixelformat = 0; + dev->width = 0; + dev->height = 0; ret = request_irq(dev->pdev->irq, marucam_irq_handler, IRQF_SHARED, MARUCAM_MODULE_NAME, dev); if (ret) { - marucam_err("Failed to request the irq: irq(#%d)\n", - dev->pdev->irq); + marucam_err("request_irq() failed: ret(%d), irq(#%d)\n", + ret, dev->pdev->irq); mutex_unlock(&dev->mlock); return ret; } @@ -1072,32 +1069,34 @@ static int marucam_open(struct file *file) V4L2_FIELD_NONE, sizeof(struct videobuf_buffer), dev, NULL); + memset_io(dev->args, 0x00, dev->iomem_size); iowrite32(0, dev->mmregs + MARUCAM_OPEN); - ret = (int)ioread32(dev->mmregs + MARUCAM_OPEN); - if (ret) { - marucam_err("Failed to open the device\n"); + dev_ret = ioread32(dev->mmregs + MARUCAM_OPEN); + if (dev_ret) { + marucam_err("device open failed: ret(%d)\n", dev_ret); free_irq(dev->pdev->irq, dev); mutex_unlock(&dev->mlock); - return -ret; + return -dev_ret; } dev->in_use = 1; mutex_unlock(&dev->mlock); return 0; + } static int marucam_close(struct file *file) { - int ret; + unsigned int ret; struct marucam_device *dev = file->private_data; mutex_lock(&dev->mlock); if (dev->opstate == S_RUNNING) { - marucam_err("The device has been terminated unexpectedly.\n"); - iowrite32(1, dev->mmregs + MARUCAM_STOP_PREVIEW); - ret = (int)ioread32(dev->mmregs + MARUCAM_STOP_PREVIEW); + marucam_err("unexpectedly terminated\n"); + iowrite32(0, dev->mmregs + MARUCAM_STREAMOFF); + ret = ioread32(dev->mmregs + MARUCAM_STREAMOFF); if (ret) { - marucam_err("Failed to stop the preview\n"); + marucam_err("stream_off failed: ret(%d)\n", ret); mutex_unlock(&dev->mlock); return -ret; } @@ -1111,10 +1110,11 @@ static int marucam_close(struct file *file) free_irq(dev->pdev->irq, dev); + memset_io(dev->args, 0x00, dev->iomem_size); iowrite32(0, dev->mmregs + MARUCAM_CLOSE); - ret = (int)ioread32(dev->mmregs + MARUCAM_CLOSE); + ret = ioread32(dev->mmregs + MARUCAM_CLOSE); if (ret) { - marucam_err("Failed to close the device\n"); + marucam_err("close failed: ret(%d)\n", ret); mutex_unlock(&dev->mlock); return -ret; } @@ -1132,9 +1132,8 @@ static unsigned int marucam_poll(struct file *file, struct videobuf_queue *q3 = &poll_dev->vb_vidq; struct videobuf_buffer *vbuf = NULL; - if (q3->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + if (q3->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return POLLERR; - } mutex_lock(&q3->vb_lock); if (q3->streaming) { @@ -1144,7 +1143,7 @@ static unsigned int marucam_poll(struct file *file, } } if (!vbuf) { - marucam_err("The video buffer list is empty\n"); + marucam_err("video buffer list is empty\n"); rval = POLLERR; } @@ -1226,7 +1225,7 @@ static struct video_device marucam_video_dev = { Initialization and module stuff ------------------------------------------------------------------*/ -DEFINE_PCI_DEVICE_TABLE(marucam_pci_id_tbl) = { +static const struct pci_device_id marucam_pci_id_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_TIZEN, PCI_DEVICE_ID_VIRTUAL_CAMERA) }, {} }; @@ -1240,184 +1239,177 @@ static int marucam_pci_initdev(struct pci_dev *pdev, debug = MARUCAM_DEBUG_LEVEL; - if (marucam_instance != NULL) { - marucam_err("Only one device allowed\n"); + if (!pci_resource_len(pdev, 0)) { + marucam_info("No available device\n"); + return -ENODEV; + } + + if (marucam_instance[0] && marucam_instance[1]) { + marucam_err("Two devices already exists\n"); return -EBUSY; } dev = kzalloc(sizeof(struct marucam_device), GFP_KERNEL); if (!dev) { - marucam_err("kzalloc() failed\n"); + marucam_err("Memory allocation failed for a marucam device\n"); return -ENOMEM; } - marucam_instance = dev; - ret_val = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); + ret_val = pci_enable_device(pdev); if (ret_val) { + marucam_err("pci_enable_device failed\n"); kfree(dev); - dev = NULL; - marucam_instance = NULL; return ret_val; } - INIT_LIST_HEAD(&dev->active); - spin_lock_init(&dev->slock); - mutex_init(&dev->mlock); - dev->opstate = S_IDLE; - - dev->pdev = pdev; + dev->mem_base = pci_resource_start(pdev, 0); + dev->mem_size = pci_resource_len(pdev, 0); - ret_val = -ENOMEM; - dev->vfd = video_device_alloc(); - if (!dev->vfd) { - marucam_err("video_device_alloc() failed!!\n"); - v4l2_device_unregister(&dev->v4l2_dev); + if (pci_request_region(pdev, 0, MARUCAM_MODULE_NAME)) { + marucam_err("request region failed for 0 bar\n"); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; - return ret_val; + return -EBUSY; } - memcpy(dev->vfd, &marucam_video_dev, sizeof(marucam_video_dev)); - - dev->vfd->dev_parent = &dev->pdev->dev; - dev->vfd->v4l2_dev = &dev->v4l2_dev; - - ret_val = pci_enable_device(dev->pdev); - if (ret_val) { - marucam_err("pci_enable_device failed!!\n"); - video_device_release(dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); + if (pci_request_region(pdev, 1, MARUCAM_MODULE_NAME)) { + marucam_err("request region failed for 1 bar\n"); + pci_release_region(pdev, 0); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; - return ret_val; + return -EBUSY; } - pci_set_master(dev->pdev); - - ret_val = -EIO; - dev->mem_base = pci_resource_start(dev->pdev, 0); - dev->mem_size = pci_resource_len(dev->pdev, 0); - if (!dev->mem_base) { - marucam_err("pci_resource_start failed!!\n"); - pci_disable_device(dev->pdev); - video_device_release(dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); + if (pci_request_region(pdev, 2, MARUCAM_MODULE_NAME)) { + marucam_err("request region failed for 2 bar\n"); + pci_release_region(pdev, 0); + pci_release_region(pdev, 1); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; - return ret_val; + return -EBUSY; } - if (!request_mem_region(dev->mem_base, dev->mem_size, - MARUCAM_MODULE_NAME)) { - marucam_err("request_mem_region(mem) failed!!\n"); - pci_disable_device(dev->pdev); - video_device_release(dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); + dev->args = pci_ioremap_bar(pdev, 1); + if (!dev->args) { + marucam_err("pci_ioremap_bar failed for 1 bar\n"); + pci_release_region(pdev, 0); + pci_release_region(pdev, 1); + pci_release_region(pdev, 2); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; - return ret_val; + return -EIO; } + dev->iomem_size = pci_resource_len(pdev, 1); - dev->io_base = pci_resource_start(dev->pdev, 1); - dev->io_size = pci_resource_len(dev->pdev, 1); - - if (!dev->io_base) { - marucam_err("pci_resource_start failed!!\n"); - release_mem_region(dev->mem_base, dev->mem_size); - pci_disable_device(dev->pdev); - video_device_release(dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); + dev->mmregs = pci_ioremap_bar(pdev, 2); + if (!dev->mmregs) { + marucam_err("pci_ioremap_bar failed for 2 bar\n"); + iounmap(dev->args); + pci_release_region(pdev, 0); + pci_release_region(pdev, 1); + pci_release_region(pdev, 2); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; - return ret_val; + return -EIO; } - if (!request_mem_region(dev->io_base, dev->io_size, - MARUCAM_MODULE_NAME)) { - marucam_err("request_mem_region(io) failed!!\n"); - release_mem_region(dev->mem_base, dev->mem_size); - pci_disable_device(dev->pdev); - video_device_release(dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); + dev->dev_index = ioread32(dev->mmregs + MARUCAM_INIT); + marucam_info("device index is %d", dev->dev_index); + pci_set_master(pdev); + pci_set_drvdata(pdev, dev); + + ret_val = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); + if (ret_val < 0) { + marucam_err("v4l2_device_register() failed: %d\n", ret_val); + iounmap(dev->args); + iounmap(dev->mmregs); + pci_release_region(pdev, 0); + pci_release_region(pdev, 1); + pci_release_region(pdev, 2); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; return ret_val; } - dev->mmregs = ioremap(dev->io_base, dev->io_size); - if (!dev->mmregs) { - marucam_err("ioremap failed!!\n"); - release_mem_region(dev->io_base, dev->io_size); - release_mem_region(dev->mem_base, dev->mem_size); - pci_disable_device(dev->pdev); - video_device_release(dev->vfd); + dev->vfd = video_device_alloc(); + if (dev->vfd == NULL) { v4l2_device_unregister(&dev->v4l2_dev); + iounmap(dev->args); + iounmap(dev->mmregs); + pci_release_region(pdev, 0); + pci_release_region(pdev, 1); + pci_release_region(pdev, 2); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; - return ret_val; + return -ENOMEM; } - ret_val = video_register_device(dev->vfd, VFL_TYPE_GRABBER, 0); + memcpy(dev->vfd, &marucam_video_dev, sizeof(marucam_video_dev)); + dev->vfd->dev_parent = &pdev->dev; + dev->vfd->v4l2_dev = &dev->v4l2_dev; + + ret_val = video_register_device(dev->vfd, + VFL_TYPE_GRABBER, + dev->dev_index); if (ret_val < 0) { - marucam_err("video_register_device failed!!\n"); - iounmap(dev->mmregs); - release_mem_region(dev->io_base, dev->io_size); - release_mem_region(dev->mem_base, dev->mem_size); - pci_disable_device(dev->pdev); + marucam_err("video_register_device() failed: %d\n", ret_val); video_device_release(dev->vfd); v4l2_device_unregister(&dev->v4l2_dev); + iounmap(dev->args); + iounmap(dev->mmregs); + pci_release_region(pdev, 0); + pci_release_region(pdev, 1); + pci_release_region(pdev, 2); + pci_disable_device(pdev); kfree(dev); - dev = NULL; - marucam_instance = NULL; return ret_val; } video_set_drvdata(dev->vfd, dev); - pci_set_drvdata(pdev, dev); + + INIT_LIST_HEAD(&dev->active); + spin_lock_init(&dev->slock); + mutex_init(&dev->mlock); + dev->opstate = S_IDLE; + dev->pdev = pdev; + snprintf(dev->vfd->name, sizeof(dev->vfd->name), "%s (%i)", marucam_video_dev.name, dev->vfd->num); - marucam_info("V4L2 device registerd as /dev/video%d\n", dev->vfd->num); + marucam_instance[dev->dev_index] = dev; + marucam_info("Maru Camera(%u.%u.%u) device is registerd as /dev/video%d\n", + (MARUCAM_VERSION >> 16) & 0xFF, + (MARUCAM_VERSION >> 8) & 0xFF, + MARUCAM_VERSION & 0xFF, + dev->vfd->num); return 0; } static void marucam_pci_removedev(struct pci_dev *pdev) { + unsigned char dev_index; struct marucam_device *dev = pci_get_drvdata(pdev); if (dev == NULL) { - marucam_warn("pci_remove on unknown pdev %p.\n", pdev); - return ; + marucam_warn("pci_remove on unknown pdev %p\n", pdev); + return; } + dev_index = dev->dev_index; video_unregister_device(dev->vfd); - - if (dev->mmregs) { - iounmap(dev->mmregs); - dev->mmregs = 0; - } - - if (dev->io_base) { - release_mem_region(dev->io_base, dev->io_size); - dev->io_base = 0; - } - if (dev->mem_base) { - release_mem_region(dev->mem_base, dev->mem_size); - dev->mem_base = 0; - } - pci_disable_device(dev->pdev); v4l2_device_unregister(&dev->v4l2_dev); + iounmap(dev->args); + iounmap(dev->mmregs); + pci_release_region(dev->pdev, 0); + pci_release_region(dev->pdev, 1); + pci_release_region(dev->pdev, 2); + pci_disable_device(dev->pdev); + + memset(dev, 0x00, sizeof(struct marucam_device)); kfree(dev); dev = NULL; - marucam_instance = NULL; + marucam_instance[dev_index] = NULL; } static struct pci_driver marucam_pci_driver = { @@ -1429,19 +1421,7 @@ static struct pci_driver marucam_pci_driver = { static int __init marucam_init(void) { - int retv = 0; - - retv = pci_register_driver(&marucam_pci_driver); - if (retv < 0) { - marucam_info("Error %d while loading marucam driver\n", retv); - return retv; - } - - marucam_info("MARU Camera Driver ver %u.%u.%u successfully loaded.\n", - (MARUCAM_VERSION >> 16) & 0xFF, (MARUCAM_VERSION >> 8) & 0xFF, - MARUCAM_VERSION & 0xFF); - - return retv; + return pci_register_driver(&marucam_pci_driver); } static void __exit marucam_exit(void)