From e1f1481b8ffbb7cd84c18114560f43ed3a7affca Mon Sep 17 00:00:00 2001 From: Zhangwei6 Date: Thu, 17 Oct 2024 15:59:21 +0800 Subject: [PATCH] driver: virtio-camera accepts flag to output debug info Tracked-On: OAM-128423 Signed-off-by: Zhangwei6 --- drivers/media/platform/virtio/virtio-camera.c | 116 +++++++++++------- 1 file changed, 69 insertions(+), 47 deletions(-) diff --git a/drivers/media/platform/virtio/virtio-camera.c b/drivers/media/platform/virtio/virtio-camera.c index f3bc0f8a27f2..9becf7a6056b 100644 --- a/drivers/media/platform/virtio/virtio-camera.c +++ b/drivers/media/platform/virtio/virtio-camera.c @@ -24,6 +24,9 @@ #include #include "linux/virtio_shm.h" +/* Here borrow this bit to open debug log for virtio_camera */ +#define V4L2_DEV_VCAM_DEBUG 0x80 + #define VQ_NAME_LEN 24 /** * struct virtio_camera_ctrl_req - The internal data for one virtio-camera request and response @@ -80,7 +83,7 @@ struct virtio_camera_buffer { /** * struct virtual_camera - All internal data for one instance of virtual camera - * @vnode: video nodes + * @vnodes: video nodes * @nr_videos: number of videos; one virtual camera may contain multiple video streams * @v4l2_lock: ioctl serialization mutex * @v4l2_dev: top-level v4l2 device struct @@ -123,6 +126,11 @@ static inline struct virtio_camera_vq *vq_to_vcamvq(struct virtqueue *vq) return &vcam->vqs[vq->index]; } +static inline const char *get_vnode_name(struct virtio_camera_video *vnode) +{ + return video_device_node_name(&vnode->vdev); +} + static struct virtio_camera_ctrl_req * virtio_camera_create_req(unsigned int cmd) { @@ -146,6 +154,7 @@ static void virtio_camera_control_ack(struct virtqueue *vq) struct virtio_camera_vq *vcam_vq = vq_to_vcamvq(vq); struct virtio_camera_ctrl_req *req; struct vb2_v4l2_buffer *vbuf; + struct virtio_camera_video *vnode; unsigned int len; spin_lock_irq(&vcam_vq->lock); @@ -158,8 +167,11 @@ static void virtio_camera_control_ack(struct virtqueue *vq) vbuf->vb2_buf.timestamp = req->resp.u.buffer.timestamp; vbuf->planes[0].bytesused = req->resp.u.format.size.sizeimage; vb2_buffer_done(req->vb, VB2_BUF_STATE_DONE); - pr_debug("virtio-camera: mark the buffer done. UUID is %d, ptr is %pK\n", - req->resp.u.buffer.uuid[0] + req->resp.u.buffer.uuid[1], req->vb); + vnode = vb2_get_drv_priv(vbuf->vb2_buf.vb2_queue); + if(vnode->vdev.dev_debug & V4L2_DEV_VCAM_DEBUG) + pr_info("virtio-camera: %s mark the buffer done. index=%d, UUID is %d\n", + get_vnode_name(vnode), req->vb->index, + req->resp.u.buffer.uuid[0] + req->resp.u.buffer.uuid[1]); kfree(req); } @@ -192,7 +204,7 @@ static int vcam_vq_request(struct virtio_camera_video *vnode, spin_lock_irq(&vnode->ctr_vqx->lock); ret = virtqueue_add_sgs(vnode->ctr_vqx->vq, sgs, num_sgs - 1, 1, req, GFP_KERNEL); if (ret) { - pr_err("%s: fail to add req to vq, errno is %d\n", __func__, ret); + pr_err("%s: %s fail to add req to vq, errno is %d\n", __func__, get_vnode_name(vnode), ret); spin_unlock_irq(&vnode->ctr_vqx->lock); return ret; } @@ -238,13 +250,13 @@ int vcam_v4l2_fh_open(struct file *filp) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_FILE_OPEN); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init open-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init open, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) { - pr_err("virtio-camera: vnode%d file handler open failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s file handler open failed, err response.\n", get_vnode_name(vnode)); goto err_free; } @@ -268,13 +280,13 @@ int vcam_v4l2_fh_release(struct file *filp) vnode = video_drvdata(filp); vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_FILE_CLOSE); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init close-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init close, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) - pr_err("virtio-camera: vnode%d release file failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s release file failed, err response.\n", get_vnode_name(vnode)); kfree(vcam_req); return err; @@ -296,7 +308,7 @@ static int vcam_querycap(struct file *file, void *priv, strscpy(cap->bus_info, "platform:camera", sizeof(cap->bus_info)); strscpy(cap->driver, "virtio-camera", sizeof(cap->driver)); - snprintf(cap->card, sizeof(cap->card), "virtio-camera%u", vnode->idx); + snprintf(cap->card, sizeof(cap->card), "virtio-camera-node%u", vnode->idx); return 0; } @@ -308,15 +320,15 @@ static int vcam_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_ENUM_FORMAT); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init enum_fmt-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init enum_fmt, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } vcam_req->ctrl.header.index = f->index; err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); - if (err) { - pr_err("virtio-camera: vnode%d enum_fmt failed, err response.\n", vnode->idx); + if (err && f->index == 0) { + pr_err("virtio-camera: %s enum_fmt failed, err response.\n", get_vnode_name(vnode)); goto err_free; } @@ -337,7 +349,7 @@ static int vcam_enum_framesizes(struct file *file, void *fh, vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_ENUM_SIZE); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init enum_size-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init enum_size, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } @@ -345,8 +357,8 @@ static int vcam_enum_framesizes(struct file *file, void *fh, vcam_req->ctrl.u.format.pixelformat = fsize->pixel_format; err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); - if (err) { - pr_err("virtio-camera: vnode%d enum_size failed, err response.\n", vnode->idx); + if (err && fsize->index == 0) { + pr_err("virtio-camera: %s enum_size failed, err response.\n", get_vnode_name(vnode)); goto err_free; } @@ -369,7 +381,9 @@ static int vcam_enum_framesizes(struct file *file, void *fh, else fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; } - pr_debug("%s: fmt width is %d, height is %d\n", __func__, sz->width, sz->height); + if(vnode->vdev.dev_debug & V4L2_DEV_VCAM_DEBUG) + pr_info("%s: %s fmt width is %d, height is %d\n", __func__, + get_vnode_name(vnode), sz->width, sz->height); err_free: kfree(vcam_req); @@ -386,7 +400,7 @@ static int vcam_enum_frameintervals(struct file *file, void *fh, vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_ENUM_INTV); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init enum_interval-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init enum_interval, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } @@ -397,16 +411,17 @@ static int vcam_enum_frameintervals(struct file *file, void *fh, err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); sz = &vcam_req->resp.u.format.size; - if (err) { - pr_err("virtio-camera: vnode%d enum_interval failed, err response.\n", vnode->idx); + if (err && fintv->index ==0) { + pr_err("virtio-camera: %s enum_interval failed, err response.\n", get_vnode_name(vnode)); goto err_free; } fintv->type = V4L2_FRMIVAL_TYPE_DISCRETE; fintv->discrete.denominator = sz->fps; fintv->discrete.numerator = 1; - pr_debug("%s: idx is %d, denominator is %d, numerator is %d\n", __func__, - fintv->index, fintv->discrete.denominator, fintv->discrete.numerator); + if(vnode->vdev.dev_debug & V4L2_DEV_VCAM_DEBUG) + pr_info("%s: %s idx is %d, denominator is %d, numerator is %d\n", __func__, + get_vnode_name(vnode), fintv->index, fintv->discrete.denominator, fintv->discrete.numerator); err_free: kfree(vcam_req); @@ -421,13 +436,13 @@ static int vcam_g_fmt(struct file *file, void *fh, struct v4l2_format *f) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_GET_FORMAT); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init get_fmt-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init get_fmt, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) { - pr_err("virtio-camera: vnode%d get_fmt failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s get_fmt failed, err response.\n", get_vnode_name(vnode)); goto err_free; } @@ -459,13 +474,13 @@ static int vcam_s_fmt(struct file *file, void *fh, struct v4l2_format *f) int err; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - pr_err("virtio-camera: vnode%d only support video capture buffer.\n", vnode->idx); + pr_err("virtio-camera: %s only support video capture buffer.\n", get_vnode_name(vnode)); return -EINVAL; } vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_SET_FORMAT); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init set_fmt-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init set_fmt, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } @@ -476,7 +491,7 @@ static int vcam_s_fmt(struct file *file, void *fh, struct v4l2_format *f) err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) { - pr_err("virtio-camera: vnode%d set_fmt failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s set_fmt failed, err response.\n", get_vnode_name(vnode)); goto err_free; } @@ -507,7 +522,7 @@ static int vcam_try_fmt(struct file *file, void *fh, struct v4l2_format *f) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_TRY_FORMAT); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init try_fmt-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init try_fmt, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } @@ -518,7 +533,7 @@ static int vcam_try_fmt(struct file *file, void *fh, struct v4l2_format *f) err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) { - pr_err("virtio-camera: vnode%d try_fmt failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s try_fmt failed, err response.\n", get_vnode_name(vnode)); goto err_free; } @@ -609,8 +624,8 @@ vcam_queue_setup(struct vb2_queue *vq, if (*num_planes) { ret = sizes[0] < size ? -EINVAL : 0; if (ret != 0) - pr_err("virtio-camera: vnode%d fail to setup queue,\ - size[0]=%d is invalid.\n", vnode->idx, sizes[0]); + pr_err("virtio-camera: %s fail to setup queue,\ + size[0]=%d is invalid.\n", get_vnode_name(vnode), sizes[0]); return ret; } @@ -633,14 +648,14 @@ static int vcam_buf_init(struct vb2_buffer *vb) /* TODO */ if (WARN_ON(vb->num_planes != 1)) { - pr_err("virtio-camera: vnode%d fail to init buffer, only support 1 plane buffer.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init buffer, only support 1 plane buffer.\n", get_vnode_name(vnode)); return -EINVAL; } sgt = vb2_dma_sg_plane_desc(vb, 0); ents = kmalloc_array(sgt->nents, sizeof(*ents), GFP_KERNEL); if (!ents) { - pr_err("virtio-camera: vnode%d fail to init buffer, no mem", vnode->idx); + pr_err("virtio-camera: %s fail to init buffer, no mem", get_vnode_name(vnode)); return -ENOMEM; } @@ -660,7 +675,7 @@ static int vcam_buf_init(struct vb2_buffer *vb) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_CREATE_BUFFER); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init create_buffer-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init create_buffer, no mem.\n", get_vnode_name(vnode)); err = -ENOMEM; goto fail_alloc_req; } @@ -669,7 +684,7 @@ static int vcam_buf_init(struct vb2_buffer *vb) err = vcam_vq_request(vnode, vcam_req, ents, sgt->nents, false); if (err) { - pr_err("virtio-camera: vnode%d create_buffer failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s create_buffer failed, err response.\n", get_vnode_name(vnode)); goto err_free; } @@ -693,15 +708,15 @@ static void vcam_buf_cleanup(struct vb2_buffer *vb) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_DESTROY_BUFFER); if (unlikely(vcam_req == NULL)) { - pr_err("%s: Failed to clean vcam buffer\n", __func__); + pr_err("%s: %s Failed to clean vcam buffer\n", __func__, get_vnode_name(vnode)); return; } memcpy(vcam_req->ctrl.u.buffer.uuid, vbuf->uuid, sizeof(vbuf->uuid)); err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) { - pr_err("%s: Failed to deinit virtio-camera buffers, buffers may still be retained by backend\n", - __func__); + pr_err("%s: %s Failed to deinit virtio-camera buffers, buffers may still be retained by backend\n", + __func__, get_vnode_name(vnode)); } kfree(vcam_req); } @@ -724,7 +739,7 @@ static void vcam_buf_queue(struct vb2_buffer *vb) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_ENQUEUE_BUFFER); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init enqueue_buffer-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init enqueue_buffer, no mem.\n", get_vnode_name(vnode)); vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); return; } @@ -733,14 +748,15 @@ static void vcam_buf_queue(struct vb2_buffer *vb) vcam_req->vb = vb; err = vcam_vq_request(vnode, vcam_req, NULL, 0, true); if (err) { - pr_err("virtio-camera: vnode%d enqueue_buffer failed, err response, errno %d\n", vnode->idx, err); + pr_err("virtio-camera: %s enqueue_buffer failed, err response, errno %d\n", get_vnode_name(vnode), err); vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); goto err_free; } - pr_debug("%s: video%d queue a buffer, success. UUID is %d, ptr is %pK\n", - __func__, vnode->idx, vcam_req->resp.u.buffer.uuid[0] + vcam_req->resp.u.buffer.uuid[1], - vcam_req->vb); + if(vnode->vdev.dev_debug & V4L2_DEV_VCAM_DEBUG) + pr_info("virtio-camera: %s queue a buffer, success. index=%d, UUID is %d\n", + get_vnode_name(vnode), vb->index, + vcam_req->resp.u.buffer.uuid[0] + vcam_req->resp.u.buffer.uuid[1]); return; @@ -757,13 +773,13 @@ static int vcam_start_streaming(struct vb2_queue *q, unsigned int count) vnode->sequence = 0; vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_STREAM_ON); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init stream_on-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init stream_on, no mem.\n", get_vnode_name(vnode)); return -ENOMEM; } err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) - pr_err("virtio-camera: vnode%d stream_on failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s stream_on failed, err response.\n", get_vnode_name(vnode)); kfree(vcam_req); return err; @@ -777,14 +793,14 @@ static void vcam_stop_streaming(struct vb2_queue *q) vcam_req = virtio_camera_create_req(VIRTIO_CAMERA_CMD_STREAM_OFF); if (unlikely(vcam_req == NULL)) { - pr_err("virtio-camera: vnode%d fail to init stream_off-req, no mem.\n", vnode->idx); + pr_err("virtio-camera: %s fail to init stream_off, no mem.\n", get_vnode_name(vnode)); return; } /*TODO, mark all vcam buffers invalid when err occur*/ err = vcam_vq_request(vnode, vcam_req, NULL, 0, false); if (err) - pr_err("virtio-camera: vnode%d stream_off failed, err response.\n", vnode->idx); + pr_err("virtio-camera: %s stream_off failed, err response.\n", get_vnode_name(vnode)); vb2_wait_for_all_buffers(q); kfree(vcam_req); @@ -985,10 +1001,11 @@ static int virtio_camera_setup_vnode(struct virtio_device *vdev, virtio_camera_unregister_devs(vcam, i, j-1); return dev_err_probe(&vdev->dev, err, "failed to register video"); } + pr_info("virtio_camera registered video device %s\n", + get_vnode_name(vnode)); } } - pr_info("%s: success register video devices\n", __func__); return 0; } @@ -1007,6 +1024,11 @@ static int virtio_camera_probe(struct virtio_device *vdev) virtio_cread_bytes(vdev, 0, &vcam->config, sizeof(vcam->config)); + if (vcam->config.num_virtual_cameras == 0) { + pr_err("%s: get 0 cameras, invalid config.\n", __func__); + return -EINVAL; + } + if (vcam->config.num_virtual_cameras > ARRAY_SIZE(vcam->config.nr_per_virtual_camera)) { pr_err("%s: nr cameras too large %d", __func__, vcam->config.num_virtual_cameras); return -EINVAL;