| 1 |
|
| 2 | |
| 3 | * SSH request transport layer.
|
| 4 | *
|
| 5 | * Copyright (C) 2019-2022 Maximilian Luz <[email protected]>
|
| 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
|