--- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -503,9 +503,22 @@ 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; + uvcg_info(&uvc->func, + "Video prep ep: ep=%p desc=%p maxpacket=%u maxburst=%u mult=%u\n", + video->ep, video->ep->desc, video->ep->maxpacket, + video->ep->maxburst, video->ep->mult); + if (!usb_endpoint_xfer_isoc(video->ep->desc)) { + uvcg_info(&uvc->func, + "Video prep non-isoc: attrs=0x%x max_req=%u imagesize=%u interval=%u\n", + video->ep->desc->bmAttributes, max_req_size, + video->imagesize, video->interval); video->req_size = max_req_size; video->reqs_per_frame = video->uvc_num_requests = DIV_ROUND_UP(video->imagesize, max_req_size); @@ -534,6 +547,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 @@ -558,6 +581,11 @@ */ uvc_video_prep_requests(video); + uvcg_info(&video->uvc->func, + "Video alloc: req_size=%u max_req=%u max_payload=%u uvc_num_requests=%u reqs_per_frame=%u\n", + video->req_size, video->max_req_size, video->max_payload_size, + video->uvc_num_requests, video->reqs_per_frame); + for (i = 0; i < video->uvc_num_requests; i++) { ureq = kzalloc(sizeof(struct uvc_request), GFP_KERNEL); if (ureq == NULL) @@ -764,20 +792,78 @@ { 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->ep->desc) { + uvcg_err(&video->uvc->func, + "Video enable failed, missing ep desc ep=%p maxpacket=%u maxburst=%u mult=%u\n", + video->ep, video->ep->maxpacket, + video->ep->maxburst, video->ep->mult); + return -EINVAL; + } + + 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; --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -298,6 +298,14 @@ int ret; uvcg_info(f, "%s(%u, %u)\n", __func__, interface, alt); + uvcg_info(f, + "UVC set_alt: intf=%u alt=%u state=%u speed=%u ep=%p desc=%p maxpacket=%u maxburst=%u mult=%u\n", + interface, alt, uvc->state, cdev->gadget->speed, + uvc->video.ep, + uvc->video.ep ? uvc->video.ep->desc : NULL, + uvc->video.ep ? uvc->video.ep->maxpacket : 0, + uvc->video.ep ? uvc->video.ep->maxburst : 0, + uvc->video.ep ? uvc->video.ep->mult : 0); if (interface == uvc->control_intf) { if (alt) @@ -362,10 +370,34 @@ return ret; usb_ep_enable(uvc->video.ep); + if (uvc->video.ep->desc) + uvcg_info(f, + "UVC ep config: speed=%u addr=0x%02x attrs=0x%02x maxpacket=%u maxburst=%u mult=%u wMaxPacket=0x%04x interval=%u\n", + f->config->cdev->gadget->speed, + uvc->video.ep->address, + uvc->video.ep->desc->bmAttributes, + uvc->video.ep->maxpacket, uvc->video.ep->maxburst, + uvc->video.ep->mult, + le16_to_cpu(uvc->video.ep->desc->wMaxPacketSize), + uvc->video.ep->desc->bInterval); + else + uvcg_err(f, + "UVC ep config: missing desc speed=%u maxpacket=%u maxburst=%u mult=%u\n", + f->config->cdev->gadget->speed, + uvc->video.ep->maxpacket, uvc->video.ep->maxburst, + uvc->video.ep->mult); + uvc->video.max_req_size = uvc->video.ep->maxpacket * max_t(unsigned int, uvc->video.ep->maxburst, 1) * (uvc->video.ep->mult); + uvcg_info(f, + "UVC max_req_size=%u (maxpacket=%u maxburst=%u mult=%u)\n", + uvc->video.max_req_size, + uvc->video.ep->maxpacket, + uvc->video.ep->maxburst, + uvc->video.ep->mult); + memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMON; v4l2_event_queue(&uvc->vdev, &v4l2_event);