Lines Matching +full:open +full:- +full:circuit

1 // SPDX-License-Identifier: GPL-2.0
3 * chaoskey - driver for ChaosKey device from Altus Metrum.
6 * on a reverse-biased p-n junction in avalanche breakdown. More
31 dev_dbg(&(usb_if)->dev, format, ## arg)
34 dev_err(&(usb_if)->dev, format, ## arg)
73 /* Driver-local specific stuff */
79 int open; /* open count */ member
97 usb_dbg(dev->interface, "free"); in chaoskey_free()
98 usb_free_urb(dev->urb); in chaoskey_free()
99 kfree(dev->name); in chaoskey_free()
100 kfree(dev->buf); in chaoskey_free()
101 usb_put_intf(dev->interface); in chaoskey_free()
110 struct usb_host_interface *altsetting = interface->cur_altsetting; in chaoskey_probe()
114 int result = -ENOMEM; in chaoskey_probe()
118 usb_dbg(interface, "probe %s-%s", udev->product, udev->serial); in chaoskey_probe()
133 return -ENODEV; in chaoskey_probe()
149 dev->interface = usb_get_intf(interface); in chaoskey_probe()
151 dev->buf = kmalloc(size, GFP_KERNEL); in chaoskey_probe()
153 if (dev->buf == NULL) in chaoskey_probe()
156 dev->urb = usb_alloc_urb(0, GFP_KERNEL); in chaoskey_probe()
158 if (!dev->urb) in chaoskey_probe()
161 usb_fill_bulk_urb(dev->urb, in chaoskey_probe()
164 dev->buf, in chaoskey_probe()
173 if (udev->product && udev->serial) { in chaoskey_probe()
174 dev->name = kasprintf(GFP_KERNEL, "%s-%s", udev->product, in chaoskey_probe()
175 udev->serial); in chaoskey_probe()
176 if (dev->name == NULL) in chaoskey_probe()
180 dev->in_ep = in_ep; in chaoskey_probe()
182 if (le16_to_cpu(udev->descriptor.idVendor) != ALEA_VENDOR_ID) in chaoskey_probe()
183 dev->reads_started = true; in chaoskey_probe()
185 dev->size = size; in chaoskey_probe()
186 dev->present = true; in chaoskey_probe()
188 init_waitqueue_head(&dev->wait_q); in chaoskey_probe()
190 mutex_init(&dev->lock); in chaoskey_probe()
191 mutex_init(&dev->rng_lock); in chaoskey_probe()
201 dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name; in chaoskey_probe()
202 dev->hwrng.read = chaoskey_rng_read; in chaoskey_probe()
204 dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0); in chaoskey_probe()
205 if (!dev->hwrng_registered) in chaoskey_probe()
210 usb_dbg(interface, "chaoskey probe success, size %d", dev->size); in chaoskey_probe()
226 usb_dbg(interface, "disconnect failed - no dev"); in chaoskey_disconnect()
230 if (dev->hwrng_registered) in chaoskey_disconnect()
231 hwrng_unregister(&dev->hwrng); in chaoskey_disconnect()
236 mutex_lock(&dev->lock); in chaoskey_disconnect()
238 dev->present = false; in chaoskey_disconnect()
239 usb_poison_urb(dev->urb); in chaoskey_disconnect()
241 if (!dev->open) { in chaoskey_disconnect()
242 mutex_unlock(&dev->lock); in chaoskey_disconnect()
245 mutex_unlock(&dev->lock); in chaoskey_disconnect()
258 return -ENODEV; in chaoskey_open()
260 usb_dbg(interface, "open"); in chaoskey_open()
264 usb_dbg(interface, "open (dev)"); in chaoskey_open()
265 return -ENODEV; in chaoskey_open()
268 file->private_data = dev; in chaoskey_open()
269 mutex_lock(&dev->lock); in chaoskey_open()
270 ++dev->open; in chaoskey_open()
271 mutex_unlock(&dev->lock); in chaoskey_open()
273 usb_dbg(interface, "open success"); in chaoskey_open()
279 struct chaoskey *dev = file->private_data; in chaoskey_release()
283 return -ENODEV; in chaoskey_release()
285 interface = dev->interface; in chaoskey_release()
289 mutex_lock(&dev->lock); in chaoskey_release()
291 usb_dbg(interface, "open count at release is %d", dev->open); in chaoskey_release()
293 if (dev->open <= 0) { in chaoskey_release()
294 usb_dbg(interface, "invalid open count (%d)", dev->open); in chaoskey_release()
295 mutex_unlock(&dev->lock); in chaoskey_release()
296 return -ENODEV; in chaoskey_release()
299 --dev->open; in chaoskey_release()
301 if (!dev->present) { in chaoskey_release()
302 if (dev->open == 0) { in chaoskey_release()
303 mutex_unlock(&dev->lock); in chaoskey_release()
306 mutex_unlock(&dev->lock); in chaoskey_release()
308 mutex_unlock(&dev->lock); in chaoskey_release()
316 struct chaoskey *dev = urb->context; in chaos_read_callback()
317 int status = urb->status; in chaos_read_callback()
319 usb_dbg(dev->interface, "callback status (%d)", status); in chaos_read_callback()
322 dev->valid = urb->actual_length; in chaos_read_callback()
324 dev->valid = 0; in chaos_read_callback()
326 dev->used = 0; in chaos_read_callback()
331 dev->reading = false; in chaos_read_callback()
332 wake_up(&dev->wait_q); in chaos_read_callback()
335 /* Fill the buffer. Called with dev->lock held
343 usb_dbg(dev->interface, "fill"); in _chaoskey_fill()
347 if (dev->valid != dev->used) { in _chaoskey_fill()
348 usb_dbg(dev->interface, "not empty yet (valid %d used %d)", in _chaoskey_fill()
349 dev->valid, dev->used); in _chaoskey_fill()
354 if (!dev->present) { in _chaoskey_fill()
355 usb_dbg(dev->interface, "device not present"); in _chaoskey_fill()
356 return -ENODEV; in _chaoskey_fill()
360 result = usb_autopm_get_interface(dev->interface); in _chaoskey_fill()
362 usb_dbg(dev->interface, "wakeup failed (result %d)", result); in _chaoskey_fill()
366 dev->reading = true; in _chaoskey_fill()
367 result = usb_submit_urb(dev->urb, GFP_KERNEL); in _chaoskey_fill()
370 dev->reading = false; in _chaoskey_fill()
376 * though. Presumably the entropy-generating circuit needs in _chaoskey_fill()
379 started = dev->reads_started; in _chaoskey_fill()
380 dev->reads_started = true; in _chaoskey_fill()
382 dev->wait_q, in _chaoskey_fill()
383 !dev->reading, in _chaoskey_fill()
387 usb_kill_urb(dev->urb); in _chaoskey_fill()
392 result = -ETIMEDOUT; in _chaoskey_fill()
393 usb_kill_urb(dev->urb); in _chaoskey_fill()
395 result = dev->valid; in _chaoskey_fill()
399 usb_autopm_put_interface(dev->interface); in _chaoskey_fill()
401 usb_dbg(dev->interface, "read %d bytes", dev->valid); in _chaoskey_fill()
417 dev = file->private_data; in chaoskey_read()
419 if (dev == NULL || !dev->present) in chaoskey_read()
420 return -ENODEV; in chaoskey_read()
422 usb_dbg(dev->interface, "read %zu", count); in chaoskey_read()
429 result = mutex_lock_interruptible(&dev->rng_lock); in chaoskey_read()
432 mutex_unlock(&dev->rng_lock); in chaoskey_read()
434 result = mutex_lock_interruptible(&dev->lock); in chaoskey_read()
437 if (dev->valid == dev->used) { in chaoskey_read()
440 mutex_unlock(&dev->lock); in chaoskey_read()
445 this_time = dev->valid - dev->used; in chaoskey_read()
449 remain = copy_to_user(buffer, dev->buf + dev->used, this_time); in chaoskey_read()
451 result = -EFAULT; in chaoskey_read()
456 dev->used += this_time - remain; in chaoskey_read()
457 mutex_unlock(&dev->lock); in chaoskey_read()
461 count -= this_time; in chaoskey_read()
464 dev->used += this_time; in chaoskey_read()
465 mutex_unlock(&dev->lock); in chaoskey_read()
469 usb_dbg(dev->interface, "read %zu bytes", read_count); in chaoskey_read()
472 usb_dbg(dev->interface, "empty read, result %d", result); in chaoskey_read()
473 if (result == -ETIMEDOUT) in chaoskey_read()
474 result = -EAGAIN; in chaoskey_read()
484 usb_dbg(dev->interface, "rng_read max %zu wait %d", max, wait); in chaoskey_rng_read()
486 if (!dev->present) { in chaoskey_rng_read()
487 usb_dbg(dev->interface, "device not present"); in chaoskey_rng_read()
495 mutex_lock(&dev->rng_lock); in chaoskey_rng_read()
497 mutex_lock(&dev->lock); in chaoskey_rng_read()
499 mutex_unlock(&dev->rng_lock); in chaoskey_rng_read()
505 if (dev->valid == dev->used) in chaoskey_rng_read()
508 this_time = dev->valid - dev->used; in chaoskey_rng_read()
512 memcpy(data, dev->buf + dev->used, this_time); in chaoskey_rng_read()
514 dev->used += this_time; in chaoskey_rng_read()
516 mutex_unlock(&dev->lock); in chaoskey_rng_read()
518 usb_dbg(dev->interface, "rng_read this_time %d\n", this_time); in chaoskey_rng_read()
544 if (le16_to_cpu(udev->descriptor.idVendor) == ALEA_VENDOR_ID) in chaoskey_resume()
545 dev->reads_started = false; in chaoskey_resume()
558 .open = chaoskey_open,