Lines Matching +full:zero +full:- +full:initialised
1 // SPDX-License-Identifier: GPL-2.0
3 * U2F Zero LED and RNG driver
6 * Loosely based on drivers/hid/hid-led.c
23 #include "hid-ids.h"
44 .name = "U2F Zero",
53 /* We only use broadcast (CID-less) messages */
63 u8 data[HID_REPORT_SIZE - 7];
67 u8 data[HID_REPORT_SIZE - 5];
97 mutex_lock(&dev->lock); in u2fzero_send()
99 memcpy(dev->buf_out, req, sizeof(struct u2f_hid_report)); in u2fzero_send()
101 ret = hid_hw_output_report(dev->hdev, dev->buf_out, in u2fzero_send()
104 mutex_unlock(&dev->lock); in u2fzero_send()
109 return ret == sizeof(struct u2f_hid_msg) ? 0 : -EMSGSIZE; in u2fzero_send()
119 struct u2fzero_transfer_context *ctx = urb->context; in u2fzero_read_callback()
121 ctx->status = urb->status; in u2fzero_read_callback()
122 complete(&ctx->done); in u2fzero_read_callback()
130 struct hid_device *hdev = dev->hdev; in u2fzero_recv()
133 mutex_lock(&dev->lock); in u2fzero_recv()
135 memcpy(dev->buf_out, req, sizeof(struct u2f_hid_report)); in u2fzero_recv()
137 dev->urb->context = &ctx; in u2fzero_recv()
140 ret = usb_submit_urb(dev->urb, GFP_NOIO); in u2fzero_recv()
146 ret = hid_hw_output_report(dev->hdev, dev->buf_out, in u2fzero_recv()
157 usb_kill_urb(dev->urb); in u2fzero_recv()
160 ret = dev->urb->actual_length; in u2fzero_recv()
161 memcpy(resp, dev->buf_in, ret); in u2fzero_recv()
165 mutex_unlock(&dev->lock); in u2fzero_recv()
178 .cmd = hw_configs[dev->hw_revision].wink_cmd, in u2fzero_blink()
190 ldev->brightness = LED_OFF; in u2fzero_brightness_set()
206 .cmd = hw_configs[dev->hw_revision].rng_cmd, in u2fzero_rng_read()
218 if (!dev->present) { in u2fzero_rng_read()
219 hid_dbg(dev->hdev, "device not present"); in u2fzero_rng_read()
230 actual_length = min3((size_t)ret - min_length, in u2fzero_rng_read()
241 dev->led_name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, in u2fzero_init_led()
243 if (dev->led_name == NULL) in u2fzero_init_led()
244 return -ENOMEM; in u2fzero_init_led()
246 dev->ldev.name = dev->led_name; in u2fzero_init_led()
247 dev->ldev.max_brightness = LED_ON; in u2fzero_init_led()
248 dev->ldev.flags = LED_HW_PLUGGABLE; in u2fzero_init_led()
249 dev->ldev.brightness_set_blocking = u2fzero_brightness_set; in u2fzero_init_led()
251 return devm_led_classdev_register(&dev->hdev->dev, &dev->ldev); in u2fzero_init_led()
257 dev->rng_name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, in u2fzero_init_hwrng()
258 "%s-rng%u", DRIVER_SHORT, minor); in u2fzero_init_hwrng()
259 if (dev->rng_name == NULL) in u2fzero_init_hwrng()
260 return -ENOMEM; in u2fzero_init_hwrng()
262 dev->hwrng.name = dev->rng_name; in u2fzero_init_hwrng()
263 dev->hwrng.read = u2fzero_rng_read; in u2fzero_init_hwrng()
265 return devm_hwrng_register(&dev->hdev->dev, &dev->hwrng); in u2fzero_init_hwrng()
270 struct hid_device *hdev = dev->hdev; in u2fzero_fill_in_urb()
272 struct usbhid_device *usbhid = hdev->driver_data; in u2fzero_fill_in_urb()
276 if (dev->hdev->bus != BUS_USB) in u2fzero_fill_in_urb()
277 return -EINVAL; in u2fzero_fill_in_urb()
281 if (!usbhid->urbout || !usbhid->urbin) in u2fzero_fill_in_urb()
282 return -ENODEV; in u2fzero_fill_in_urb()
284 ep = usb_pipe_endpoint(udev, usbhid->urbin->pipe); in u2fzero_fill_in_urb()
286 return -ENODEV; in u2fzero_fill_in_urb()
288 dev->urb = usb_alloc_urb(0, GFP_KERNEL); in u2fzero_fill_in_urb()
289 if (!dev->urb) in u2fzero_fill_in_urb()
290 return -ENOMEM; in u2fzero_fill_in_urb()
292 pipe_in = (usbhid->urbin->pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); in u2fzero_fill_in_urb()
294 usb_fill_int_urb(dev->urb, in u2fzero_fill_in_urb()
297 dev->buf_in, in u2fzero_fill_in_urb()
301 ep->desc.bInterval); in u2fzero_fill_in_urb()
314 return -EINVAL; in u2fzero_probe()
316 dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); in u2fzero_probe()
318 return -ENOMEM; in u2fzero_probe()
320 dev->hw_revision = id->driver_data; in u2fzero_probe()
322 dev->buf_out = devm_kmalloc(&hdev->dev, in u2fzero_probe()
324 if (dev->buf_out == NULL) in u2fzero_probe()
325 return -ENOMEM; in u2fzero_probe()
327 dev->buf_in = devm_kmalloc(&hdev->dev, in u2fzero_probe()
329 if (dev->buf_in == NULL) in u2fzero_probe()
330 return -ENOMEM; in u2fzero_probe()
336 dev->hdev = hdev; in u2fzero_probe()
338 mutex_init(&dev->lock); in u2fzero_probe()
346 dev->present = true; in u2fzero_probe()
348 minor = ((struct hidraw *) hdev->hidraw)->minor; in u2fzero_probe()
356 hid_info(hdev, "%s LED initialised\n", hw_configs[dev->hw_revision].name); in u2fzero_probe()
364 hid_info(hdev, "%s RNG initialised\n", hw_configs[dev->hw_revision].name); in u2fzero_probe()
373 mutex_lock(&dev->lock); in u2fzero_remove()
374 dev->present = false; in u2fzero_remove()
375 mutex_unlock(&dev->lock); in u2fzero_remove()
378 usb_poison_urb(dev->urb); in u2fzero_remove()
379 usb_free_urb(dev->urb); in u2fzero_remove()
394 .name = "hid-" DRIVER_SHORT,
404 MODULE_DESCRIPTION("U2F Zero LED and RNG driver");