1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * SSH request transport layer. 4 * 5 * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com> 6 */ 7 8 #ifndef _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H 9 #define _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H 10 11 #include <linux/atomic.h> 12 #include <linux/ktime.h> 13 #include <linux/list.h> 14 #include <linux/spinlock.h> 15 #include <linux/workqueue.h> 16 17 #include <linux/surface_aggregator/serial_hub.h> 18 #include <linux/surface_aggregator/controller.h> 19 20 #include "ssh_packet_layer.h" 21 22 /** 23 * enum ssh_rtl_state_flags - State-flags for &struct ssh_rtl. 24 * 25 * @SSH_RTL_SF_SHUTDOWN_BIT: 26 * Indicates that the request transport layer has been shut down or is 27 * being shut down and should not accept any new requests. 28 */ 29 enum ssh_rtl_state_flags { 30 SSH_RTL_SF_SHUTDOWN_BIT, 31 }; 32 33 /** 34 * struct ssh_rtl_ops - Callback operations for request transport layer. 35 * @handle_event: Function called when a SSH event has been received. The 36 * specified function takes the request layer, received command 37 * struct, and corresponding payload as arguments. If the event 38 * has no payload, the payload span is empty (not %NULL). 39 */ 40 struct ssh_rtl_ops { 41 void (*handle_event)(struct ssh_rtl *rtl, const struct ssh_command *cmd, 42 const struct ssam_span *data); 43 }; 44 45 /** 46 * struct ssh_rtl - SSH request transport layer. 47 * @ptl: Underlying packet transport layer. 48 * @state: State(-flags) of the transport layer. 49 * @queue: Request submission queue. 50 * @queue.lock: Lock for modifying the request submission queue. 51 * @queue.head: List-head of the request submission queue. 52 * @pending: Set/list of pending requests. 53 * @pending.lock: Lock for modifying the request set. 54 * @pending.head: List-head of the pending set/list. 55 * @pending.count: Number of currently pending requests. 56 * @tx: Transmitter subsystem. 57 * @tx.work: Transmitter work item. 58 * @rtx_timeout: Retransmission timeout subsystem. 59 * @rtx_timeout.lock: Lock for modifying the retransmission timeout reaper. 60 * @rtx_timeout.timeout: Timeout interval for retransmission. 61 * @rtx_timeout.expires: Time specifying when the reaper work is next scheduled. 62 * @rtx_timeout.reaper: Work performing timeout checks and subsequent actions. 63 * @ops: Request layer operations. 64 */ 65 struct ssh_rtl { 66 struct ssh_ptl ptl; 67 unsigned long state; 68 69 struct { 70 spinlock_t lock; 71 struct list_head head; 72 } queue; 73 74 struct { 75 spinlock_t lock; 76 struct list_head head; 77 atomic_t count; 78 } pending; 79 80 struct { 81 struct work_struct work; 82 } tx; 83 84 struct { 85 spinlock_t lock; 86 ktime_t timeout; 87 ktime_t expires; 88 struct delayed_work reaper; 89 } rtx_timeout; 90 91 struct ssh_rtl_ops ops; 92 }; 93 94 #define rtl_dbg(r, fmt, ...) ptl_dbg(&(r)->ptl, fmt, ##__VA_ARGS__) 95 #define rtl_info(p, fmt, ...) ptl_info(&(p)->ptl, fmt, ##__VA_ARGS__) 96 #define rtl_warn(r, fmt, ...) ptl_warn(&(r)->ptl, fmt, ##__VA_ARGS__) 97 #define rtl_err(r, fmt, ...) ptl_err(&(r)->ptl, fmt, ##__VA_ARGS__) 98 #define rtl_dbg_cond(r, fmt, ...) __ssam_prcond(rtl_dbg, r, fmt, ##__VA_ARGS__) 99 100 #define to_ssh_rtl(ptr, member) \ 101 container_of(ptr, struct ssh_rtl, member) 102 103 /** 104 * ssh_rtl_get_device() - Get device associated with request transport layer. 105 * @rtl: The request transport layer. 106 * 107 * Return: Returns the device on which the given request transport layer 108 * builds upon. 109 */ 110 static inline struct device *ssh_rtl_get_device(struct ssh_rtl *rtl) 111 { 112 return ssh_ptl_get_device(&rtl->ptl); 113 } 114 115 /** 116 * ssh_request_rtl() - Get request transport layer associated with request. 117 * @rqst: The request to get the request transport layer reference for. 118 * 119 * Return: Returns the &struct ssh_rtl associated with the given SSH request. 120 */ 121 static inline struct ssh_rtl *ssh_request_rtl(struct ssh_request *rqst) 122 { 123 struct ssh_ptl *ptl; 124 125 ptl = READ_ONCE(rqst->packet.ptl); 126 return likely(ptl) ? to_ssh_rtl(ptl, ptl) : NULL; 127 } 128 129 int ssh_rtl_submit(struct ssh_rtl *rtl, struct ssh_request *rqst); 130 bool ssh_rtl_cancel(struct ssh_request *rqst, bool pending); 131 132 int ssh_rtl_init(struct ssh_rtl *rtl, struct serdev_device *serdev, 133 const struct ssh_rtl_ops *ops); 134 135 int ssh_rtl_start(struct ssh_rtl *rtl); 136 int ssh_rtl_flush(struct ssh_rtl *rtl, unsigned long timeout); 137 void ssh_rtl_shutdown(struct ssh_rtl *rtl); 138 void ssh_rtl_destroy(struct ssh_rtl *rtl); 139 140 int ssh_request_init(struct ssh_request *rqst, enum ssam_request_flags flags, 141 const struct ssh_request_ops *ops); 142 143 #endif /* _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H */ 144