1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * SSH message parser. 4 * 5 * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> 6 */ 7 8 #ifndef _SURFACE_AGGREGATOR_SSH_PARSER_H 9 #define _SURFACE_AGGREGATOR_SSH_PARSER_H 10 11 #include <linux/device.h> 12 #include <linux/kfifo.h> 13 #include <linux/slab.h> 14 #include <linux/types.h> 15 16 #include <linux/surface_aggregator/serial_hub.h> 17 18 /** 19 * struct sshp_buf - Parser buffer for SSH messages. 20 * @ptr: Pointer to the beginning of the buffer. 21 * @len: Number of bytes used in the buffer. 22 * @cap: Maximum capacity of the buffer. 23 */ 24 struct sshp_buf { 25 u8 *ptr; 26 size_t len; 27 size_t cap; 28 }; 29 30 /** 31 * sshp_buf_init() - Initialize a SSH parser buffer. 32 * @buf: The buffer to initialize. 33 * @ptr: The memory backing the buffer. 34 * @cap: The length of the memory backing the buffer, i.e. its capacity. 35 * 36 * Initializes the buffer with the given memory as backing and set its used 37 * length to zero. 38 */ 39 static inline void sshp_buf_init(struct sshp_buf *buf, u8 *ptr, size_t cap) 40 { 41 buf->ptr = ptr; 42 buf->len = 0; 43 buf->cap = cap; 44 } 45 46 /** 47 * sshp_buf_alloc() - Allocate and initialize a SSH parser buffer. 48 * @buf: The buffer to initialize/allocate to. 49 * @cap: The desired capacity of the buffer. 50 * @flags: The flags used for allocating the memory. 51 * 52 * Allocates @cap bytes and initializes the provided buffer struct with the 53 * allocated memory. 54 * 55 * Return: Returns zero on success and %-ENOMEM if allocation failed. 56 */ 57 static inline int sshp_buf_alloc(struct sshp_buf *buf, size_t cap, gfp_t flags) 58 { 59 u8 *ptr; 60 61 ptr = kzalloc(cap, flags); 62 if (!ptr) 63 return -ENOMEM; 64 65 sshp_buf_init(buf, ptr, cap); 66 return 0; 67 } 68 69 /** 70 * sshp_buf_free() - Free a SSH parser buffer. 71 * @buf: The buffer to free. 72 * 73 * Frees a SSH parser buffer by freeing the memory backing it and then 74 * resetting its pointer to %NULL and length and capacity to zero. Intended to 75 * free a buffer previously allocated with sshp_buf_alloc(). 76 */ 77 static inline void sshp_buf_free(struct sshp_buf *buf) 78 { 79 kfree(buf->ptr); 80 buf->ptr = NULL; 81 buf->len = 0; 82 buf->cap = 0; 83 } 84 85 /** 86 * sshp_buf_drop() - Drop data from the beginning of the buffer. 87 * @buf: The buffer to drop data from. 88 * @n: The number of bytes to drop. 89 * 90 * Drops the first @n bytes from the buffer. Re-aligns any remaining data to 91 * the beginning of the buffer. 92 */ 93 static inline void sshp_buf_drop(struct sshp_buf *buf, size_t n) 94 { 95 memmove(buf->ptr, buf->ptr + n, buf->len - n); 96 buf->len -= n; 97 } 98 99 /** 100 * sshp_buf_read_from_fifo() - Transfer data from a fifo to the buffer. 101 * @buf: The buffer to write the data into. 102 * @fifo: The fifo to read the data from. 103 * 104 * Transfers the data contained in the fifo to the buffer, removing it from 105 * the fifo. This function will try to transfer as much data as possible, 106 * limited either by the remaining space in the buffer or by the number of 107 * bytes available in the fifo. 108 * 109 * Return: Returns the number of bytes transferred. 110 */ 111 static inline size_t sshp_buf_read_from_fifo(struct sshp_buf *buf, 112 struct kfifo *fifo) 113 { 114 size_t n; 115 116 n = kfifo_out(fifo, buf->ptr + buf->len, buf->cap - buf->len); 117 buf->len += n; 118 119 return n; 120 } 121 122 /** 123 * sshp_buf_span_from() - Initialize a span from the given buffer and offset. 124 * @buf: The buffer to create the span from. 125 * @offset: The offset in the buffer at which the span should start. 126 * @span: The span to initialize (output). 127 * 128 * Initializes the provided span to point to the memory at the given offset in 129 * the buffer, with the length of the span being capped by the number of bytes 130 * used in the buffer after the offset (i.e. bytes remaining after the 131 * offset). 132 * 133 * Warning: This function does not validate that @offset is less than or equal 134 * to the number of bytes used in the buffer or the buffer capacity. This must 135 * be guaranteed by the caller. 136 */ 137 static inline void sshp_buf_span_from(struct sshp_buf *buf, size_t offset, 138 struct ssam_span *span) 139 { 140 span->ptr = buf->ptr + offset; 141 span->len = buf->len - offset; 142 } 143 144 bool sshp_find_syn(const struct ssam_span *src, struct ssam_span *rem); 145 146 int sshp_parse_frame(const struct device *dev, const struct ssam_span *source, 147 struct ssh_frame **frame, struct ssam_span *payload, 148 size_t maxlen); 149 150 int sshp_parse_command(const struct device *dev, const struct ssam_span *source, 151 struct ssh_command **command, 152 struct ssam_span *command_data); 153 154 #endif /* _SURFACE_AGGREGATOR_SSH_PARSER_h */ 155