1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * uvc_status.c -- USB Video Class driver - Status endpoint 4 * 5 * Copyright (C) 2005-2009 6 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 7 */ 8 9#include <asm/barrier.h> 10#include <linux/kernel.h> 11#include <linux/input.h> 12#include <linux/slab.h> 13#include <linux/usb.h> 14#include <linux/usb/input.h> 15 16#include "uvcvideo.h" 17 18/* -------------------------------------------------------------------------- 19 * Input device 20 */ 21#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV 22static int uvc_input_init(struct uvc_device *dev) 23{ 24 struct input_dev *input; 25 int ret; 26 27 input = input_allocate_device(); 28 if (input == NULL) 29 return -ENOMEM; 30 31 usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys)); 32 strlcat(dev->input_phys, "/button", sizeof(dev->input_phys)); 33 34 input->name = dev->name; 35 input->phys = dev->input_phys; 36 usb_to_input_id(dev->udev, &input->id); 37 input->dev.parent = &dev->intf->dev; 38 39 __set_bit(EV_KEY, input->evbit); 40 __set_bit(KEY_CAMERA, input->keybit); 41 42 if ((ret = input_register_device(input)) < 0) 43 goto error; 44 45 dev->input = input; 46 return 0; 47 48error: 49 input_free_device(input); 50 return ret; 51} 52 53static void uvc_input_unregister(struct uvc_device *dev) 54{ 55 if (dev->input) 56 input_unregister_device(dev->input); 57} 58 59static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, 60 int value) 61{ 62 if (dev->input) { 63 input_report_key(dev->input, code, value); 64 input_sync(dev->input); 65 } 66} 67 68#else 69#define uvc_input_init(dev) 70#define uvc_input_unregister(dev) 71#define uvc_input_report_key(dev, code, value) 72#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ 73 74/* -------------------------------------------------------------------------- 75 * Status interrupt endpoint 76 */ 77struct uvc_streaming_status { 78 u8 bStatusType; 79 u8 bOriginator; 80 u8 bEvent; 81 u8 bValue[]; 82} __packed; 83 84struct uvc_control_status { 85 u8 bStatusType; 86 u8 bOriginator; 87 u8 bEvent; 88 u8 bSelector; 89 u8 bAttribute; 90 u8 bValue[]; 91} __packed; 92 93static void uvc_event_streaming(struct uvc_device *dev, 94 struct uvc_streaming_status *status, int len) 95{ 96 if (len < 3) { 97 uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " 98 "received.\n"); 99 return; 100 } 101 102 if (status->bEvent == 0) { 103 if (len < 4) 104 return; 105 uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", 106 status->bOriginator, 107 status->bValue[0] ? "pressed" : "released", len); 108 uvc_input_report_key(dev, KEY_CAMERA, status->bValue[0]); 109 } else { 110 uvc_trace(UVC_TRACE_STATUS, 111 "Stream %u error event %02x len %d.\n", 112 status->bOriginator, status->bEvent, len); 113 } 114} 115 116#define UVC_CTRL_VALUE_CHANGE 0 117#define UVC_CTRL_INFO_CHANGE 1 118#define UVC_CTRL_FAILURE_CHANGE 2 119#define UVC_CTRL_MIN_CHANGE 3 120#define UVC_CTRL_MAX_CHANGE 4 121 122static struct uvc_control *uvc_event_entity_find_ctrl(struct uvc_entity *entity, 123 u8 selector) 124{ 125 struct uvc_control *ctrl; 126 unsigned int i; 127 128 for (i = 0, ctrl = entity->controls; i < entity->ncontrols; i++, ctrl++) 129 if (ctrl->info.selector == selector) 130 return ctrl; 131 132 return NULL; 133} 134 135static struct uvc_control *uvc_event_find_ctrl(struct uvc_device *dev, 136 const struct uvc_control_status *status, 137 struct uvc_video_chain **chain) 138{ 139 list_for_each_entry((*chain), &dev->chains, list) { 140 struct uvc_entity *entity; 141 struct uvc_control *ctrl; 142 143 list_for_each_entry(entity, &(*chain)->entities, chain) { 144 if (entity->id != status->bOriginator) 145 continue; 146 147 ctrl = uvc_event_entity_find_ctrl(entity, 148 status->bSelector); 149 if (ctrl) 150 return ctrl; 151 } 152 } 153 154 return NULL; 155} 156 157static bool uvc_event_control(struct urb *urb, 158 const struct uvc_control_status *status, int len) 159{ 160 static const char *attrs[] = { "value", "info", "failure", "min", "max" }; 161 struct uvc_device *dev = urb->context; 162 struct uvc_video_chain *chain; 163 struct uvc_control *ctrl; 164 165 if (len < 6 || status->bEvent != 0 || 166 status->bAttribute >= ARRAY_SIZE(attrs)) { 167 uvc_trace(UVC_TRACE_STATUS, "Invalid control status event " 168 "received.\n"); 169 return false; 170 } 171 172 uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n", 173 status->bOriginator, status->bSelector, 174 attrs[status->bAttribute], len); 175 176 /* Find the control. */ 177 ctrl = uvc_event_find_ctrl(dev, status, &chain); 178 if (!ctrl) 179 return false; 180 181 switch (status->bAttribute) { 182 case UVC_CTRL_VALUE_CHANGE: 183 return uvc_ctrl_status_event_async(urb, chain, ctrl, 184 status->bValue); 185 186 case UVC_CTRL_INFO_CHANGE: 187 case UVC_CTRL_FAILURE_CHANGE: 188 case UVC_CTRL_MIN_CHANGE: 189 case UVC_CTRL_MAX_CHANGE: 190 break; 191 } 192 193 return false; 194} 195 196static void uvc_status_complete(struct urb *urb) 197{ 198 struct uvc_device *dev = urb->context; 199 int len, ret; 200 201 switch (urb->status) { 202 case 0: 203 break; 204 205 case -ENOENT: /* usb_kill_urb() called. */ 206 case -ECONNRESET: /* usb_unlink_urb() called. */ 207 case -ESHUTDOWN: /* The endpoint is being disabled. */ 208 case -EPROTO: /* Device is disconnected (reported by some 209 * host controller). */ 210 return; 211 212 default: 213 uvc_printk(KERN_WARNING, "Non-zero status (%d) in status " 214 "completion handler.\n", urb->status); 215 return; 216 } 217 218 len = urb->actual_length; 219 if (len > 0) { 220 switch (dev->status[0] & 0x0f) { 221 case UVC_STATUS_TYPE_CONTROL: { 222 struct uvc_control_status *status = 223 (struct uvc_control_status *)dev->status; 224 225 if (uvc_event_control(urb, status, len)) 226 /* The URB will be resubmitted in work context. */ 227 return; 228 break; 229 } 230 231 case UVC_STATUS_TYPE_STREAMING: { 232 struct uvc_streaming_status *status = 233 (struct uvc_streaming_status *)dev->status; 234 235 uvc_event_streaming(dev, status, len); 236 break; 237 } 238 239 default: 240 uvc_trace(UVC_TRACE_STATUS, "Unknown status event " 241 "type %u.\n", dev->status[0]); 242 break; 243 } 244 } 245 246 /* Resubmit the URB. */ 247 urb->interval = dev->int_ep->desc.bInterval; 248 if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 249 uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n", 250 ret); 251 } 252} 253 254int uvc_status_init(struct uvc_device *dev) 255{ 256 struct usb_host_endpoint *ep = dev->int_ep; 257 unsigned int pipe; 258 int interval; 259 260 if (ep == NULL) 261 return 0; 262 263 uvc_input_init(dev); 264 265 dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL); 266 if (dev->status == NULL) 267 return -ENOMEM; 268 269 dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); 270 if (dev->int_urb == NULL) { 271 kfree(dev->status); 272 return -ENOMEM; 273 } 274 275 pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); 276 277 /* For high-speed interrupt endpoints, the bInterval value is used as 278 * an exponent of two. Some developers forgot about it. 279 */ 280 interval = ep->desc.bInterval; 281 if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH && 282 (dev->quirks & UVC_QUIRK_STATUS_INTERVAL)) 283 interval = fls(interval) - 1; 284 285 usb_fill_int_urb(dev->int_urb, dev->udev, pipe, 286 dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, 287 dev, interval); 288 289 return 0; 290} 291 292void uvc_status_unregister(struct uvc_device *dev) 293{ 294 usb_kill_urb(dev->int_urb); 295 uvc_input_unregister(dev); 296} 297 298void uvc_status_cleanup(struct uvc_device *dev) 299{ 300 usb_free_urb(dev->int_urb); 301 kfree(dev->status); 302} 303 304int uvc_status_start(struct uvc_device *dev, gfp_t flags) 305{ 306 if (dev->int_urb == NULL) 307 return 0; 308 309 return usb_submit_urb(dev->int_urb, flags); 310} 311 312void uvc_status_stop(struct uvc_device *dev) 313{ 314 struct uvc_ctrl_work *w = &dev->async_ctrl; 315 316 /* 317 * Prevent the asynchronous control handler from requeing the URB. The 318 * barrier is needed so the flush_status change is visible to other 319 * CPUs running the asynchronous handler before usb_kill_urb() is 320 * called below. 321 */ 322 smp_store_release(&dev->flush_status, true); 323 324 /* 325 * Cancel any pending asynchronous work. If any status event was queued, 326 * process it synchronously. 327 */ 328 if (cancel_work_sync(&w->work)) 329 uvc_ctrl_status_event(w->chain, w->ctrl, w->data); 330 331 /* Kill the urb. */ 332 usb_kill_urb(dev->int_urb); 333 334 /* 335 * The URB completion handler may have queued asynchronous work. This 336 * won't resubmit the URB as flush_status is set, but it needs to be 337 * cancelled before returning or it could then race with a future 338 * uvc_status_start() call. 339 */ 340 if (cancel_work_sync(&w->work)) 341 uvc_ctrl_status_event(w->chain, w->ctrl, w->data); 342 343 /* 344 * From this point, there are no events on the queue and the status URB 345 * is dead. No events will be queued until uvc_status_start() is called. 346 * The barrier is needed to make sure that flush_status is visible to 347 * uvc_ctrl_status_event_work() when uvc_status_start() will be called 348 * again. 349 */ 350 smp_store_release(&dev->flush_status, false); 351} 352