1// Copyright 2016 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "hid-fifo.h" 6 7#include <stdlib.h> 8#include <stdio.h> 9#include <string.h> 10 11#define min(a,b) ((a) < (b) ? (a) : (b)) 12 13zx_status_t zx_hid_fifo_create(zx_hid_fifo_t** fifo) { 14 *fifo = malloc(sizeof(zx_hid_fifo_t)); 15 if (*fifo == NULL) 16 return ZX_ERR_NO_MEMORY; 17 zx_hid_fifo_init(*fifo); 18 return ZX_OK; 19} 20 21void zx_hid_fifo_init(zx_hid_fifo_t* fifo) { 22 memset(fifo->buf, 0, HID_FIFO_SIZE); 23 fifo->head = fifo->tail = 0; 24 fifo->empty = true; 25 mtx_init(&fifo->lock, mtx_plain); 26} 27 28size_t zx_hid_fifo_size(zx_hid_fifo_t* fifo) { 29 if (fifo->empty) return 0; 30 if (fifo->head > fifo->tail) 31 return fifo->head - fifo->tail; 32 return HID_FIFO_SIZE - fifo->tail + fifo->head; 33} 34 35ssize_t zx_hid_fifo_peek(zx_hid_fifo_t* fifo, void* out) { 36 if (fifo->empty) 37 return 0; 38 *(uint8_t*)out = fifo->buf[fifo->tail]; 39 return 1; 40} 41 42ssize_t zx_hid_fifo_read(zx_hid_fifo_t* fifo, void* buf, size_t len) { 43 if (!buf) return ZX_ERR_INVALID_ARGS; 44 if (fifo->empty) return 0; 45 if (!len) return 0; 46 47 len = min(zx_hid_fifo_size(fifo), len); 48 for (size_t c = len; c > 0; c--, fifo->tail = (fifo->tail + 1) & HID_FIFO_MASK) { 49 *(uint8_t*)buf++ = fifo->buf[fifo->tail]; 50 } 51 if (fifo->tail == fifo->head) fifo->empty = true; 52 return len; 53} 54 55ssize_t zx_hid_fifo_write(zx_hid_fifo_t* fifo, const void* buf, size_t len) { 56 if (!fifo->empty && fifo->tail == fifo->head) return ZX_ERR_BUFFER_TOO_SMALL; 57 if (len > HID_FIFO_SIZE - zx_hid_fifo_size(fifo)) return ZX_ERR_BUFFER_TOO_SMALL; 58 59 for (size_t c = len; c > 0; c--, fifo->head = (fifo->head + 1) & HID_FIFO_MASK) { 60 fifo->buf[fifo->head] = *(uint8_t*)buf++; 61 } 62 fifo->empty = false; 63 return len; 64} 65 66void zx_hid_fifo_dump(zx_hid_fifo_t* fifo) { 67 printf("zx_hid_fifo_dump %p\n", fifo); 68 printf("head: %u tail: %u empty: %s\n", fifo->head, fifo->tail, fifo->empty ? "Y" : "N"); 69 if (fifo->empty) { 70 return; 71 } 72 uint32_t c = fifo->tail; 73 int i = 0; 74 do { 75 printf("%02x ", fifo->buf[c]); 76 if (i++ % 8 == 7) printf("\n"); 77 c = (c + 1) & HID_FIFO_MASK; 78 } while (c != fifo->head); 79 printf("\n"); 80} 81