--- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -503,6 +503,10 @@ unsigned int max_req_size, req_size, header_size; unsigned int nreq; + pr_info_once("uvc: Video prep enter: video=%p ep=%p max_req=%u max_payload=%u imagesize=%u interval=%u\n", + video, video->ep, video->max_req_size, video->max_payload_size, + video->imagesize, video->interval); + max_req_size = video->max_req_size; if (!usb_endpoint_xfer_isoc(video->ep->desc)) { @@ -534,6 +538,16 @@ } video->req_size = req_size; + if (!req_size || !video->max_payload_size || !video->imagesize || !nreq) { + uvcg_info(&uvc->func, + "Video prep requests: imagesize=%u interval=%u interval_dur=%u nreq=%u header=%u req_size=%u max_req=%u max_payload=%u ep_maxpacket=%u maxburst=%u mult=%u bInterval=%u speed=%u\n", + video->imagesize, video->interval, interval_duration, nreq, + header_size, req_size, max_req_size, + video->max_payload_size, video->ep->maxpacket, + video->ep->maxburst, video->ep->mult, + video->ep->desc->bInterval, cdev->gadget->speed); + } + /* We need to compensate the amount of requests to be * allocated with the maximum amount of zero length requests. * Since it is possible that hw_submit will initially @@ -764,20 +778,70 @@ { int ret; + if (!video) { + pr_err("uvcg_video_enable: missing video\n"); + return -EINVAL; + } + + if (!video->uvc || !video->uvc->func.config || + !video->uvc->func.config->cdev) { + pr_err("uvcg_video_enable: missing uvc/func/config video=%p uvc=%p\n", + video, video->uvc); + return -ENODEV; + } + if (video->ep == NULL) { uvcg_info(&video->uvc->func, "Video enable failed, device is uninitialized.\n"); return -ENODEV; } + if (!video->kworker || !video->async_wq) { + uvcg_err(&video->uvc->func, + "Video enable failed, missing worker(s) kworker=%p async_wq=%p\n", + video->kworker, video->async_wq); + return -EINVAL; + } + + if (!video->queue.queue.dev) { + uvcg_err(&video->uvc->func, + "Video enable failed, missing queue device\n"); + return -EINVAL; + } + /* * Safe to access request related fields without req_lock because * this is the only thread currently active, and no other * request handling thread will become active until this function * returns. */ + uvcg_info(&video->uvc->func, + "Video enable start: video=%p ep=%p kworker=%p async_wq=%p req_size=%u max_payload=%u requests=%u reqs_per_frame=%u use_sg=%u flags=0x%x\n", + video, video->ep, video->kworker, video->async_wq, + video->req_size, video->max_payload_size, + video->uvc_num_requests, video->reqs_per_frame, + video->queue.use_sg, video->queue.flags); + video->is_enabled = true; + if (!video->queue.queue.lock || !video->queue.queue.ops || + !video->queue.queue.mem_ops) { + uvcg_err(&video->uvc->func, + "Video queue not ready: dev=%p lock=%p ops=%p mem_ops=%p buf_ops=%p drv_priv=%p type=%u io_modes=0x%x\n", + video->queue.queue.dev, video->queue.queue.lock, + video->queue.queue.ops, video->queue.queue.mem_ops, + video->queue.queue.buf_ops, video->queue.queue.drv_priv, + video->queue.queue.type, video->queue.queue.io_modes); + return -EINVAL; + } + + uvcg_info(&video->uvc->func, + "Video queue enable: dev=%p lock=%p ops=%p mem_ops=%p buf_ops=%p drv_priv=%p type=%u io_modes=0x%x\n", + video->queue.queue.dev, video->queue.queue.lock, + video->queue.queue.ops, video->queue.queue.mem_ops, + video->queue.queue.buf_ops, video->queue.queue.drv_priv, + video->queue.queue.type, video->queue.queue.io_modes); + if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0) return ret;