Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0+ */
0002 /*
0003  * SSH request transport layer.
0004  *
0005  * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com>
0006  */
0007 
0008 #ifndef _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
0009 #define _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
0010 
0011 #include <linux/atomic.h>
0012 #include <linux/ktime.h>
0013 #include <linux/list.h>
0014 #include <linux/spinlock.h>
0015 #include <linux/workqueue.h>
0016 
0017 #include <linux/surface_aggregator/serial_hub.h>
0018 #include <linux/surface_aggregator/controller.h>
0019 
0020 #include "ssh_packet_layer.h"
0021 
0022 /**
0023  * enum ssh_rtl_state_flags - State-flags for &struct ssh_rtl.
0024  *
0025  * @SSH_RTL_SF_SHUTDOWN_BIT:
0026  *  Indicates that the request transport layer has been shut down or is
0027  *  being shut down and should not accept any new requests.
0028  */
0029 enum ssh_rtl_state_flags {
0030     SSH_RTL_SF_SHUTDOWN_BIT,
0031 };
0032 
0033 /**
0034  * struct ssh_rtl_ops - Callback operations for request transport layer.
0035  * @handle_event: Function called when a SSH event has been received. The
0036  *                specified function takes the request layer, received command
0037  *                struct, and corresponding payload as arguments. If the event
0038  *                has no payload, the payload span is empty (not %NULL).
0039  */
0040 struct ssh_rtl_ops {
0041     void (*handle_event)(struct ssh_rtl *rtl, const struct ssh_command *cmd,
0042                  const struct ssam_span *data);
0043 };
0044 
0045 /**
0046  * struct ssh_rtl - SSH request transport layer.
0047  * @ptl:           Underlying packet transport layer.
0048  * @state:         State(-flags) of the transport layer.
0049  * @queue:         Request submission queue.
0050  * @queue.lock:    Lock for modifying the request submission queue.
0051  * @queue.head:    List-head of the request submission queue.
0052  * @pending:       Set/list of pending requests.
0053  * @pending.lock:  Lock for modifying the request set.
0054  * @pending.head:  List-head of the pending set/list.
0055  * @pending.count: Number of currently pending requests.
0056  * @tx:            Transmitter subsystem.
0057  * @tx.work:       Transmitter work item.
0058  * @rtx_timeout:   Retransmission timeout subsystem.
0059  * @rtx_timeout.lock:    Lock for modifying the retransmission timeout reaper.
0060  * @rtx_timeout.timeout: Timeout interval for retransmission.
0061  * @rtx_timeout.expires: Time specifying when the reaper work is next scheduled.
0062  * @rtx_timeout.reaper:  Work performing timeout checks and subsequent actions.
0063  * @ops:           Request layer operations.
0064  */
0065 struct ssh_rtl {
0066     struct ssh_ptl ptl;
0067     unsigned long state;
0068 
0069     struct {
0070         spinlock_t lock;
0071         struct list_head head;
0072     } queue;
0073 
0074     struct {
0075         spinlock_t lock;
0076         struct list_head head;
0077         atomic_t count;
0078     } pending;
0079 
0080     struct {
0081         struct work_struct work;
0082     } tx;
0083 
0084     struct {
0085         spinlock_t lock;
0086         ktime_t timeout;
0087         ktime_t expires;
0088         struct delayed_work reaper;
0089     } rtx_timeout;
0090 
0091     struct ssh_rtl_ops ops;
0092 };
0093 
0094 #define rtl_dbg(r, fmt, ...)  ptl_dbg(&(r)->ptl, fmt, ##__VA_ARGS__)
0095 #define rtl_info(p, fmt, ...) ptl_info(&(p)->ptl, fmt, ##__VA_ARGS__)
0096 #define rtl_warn(r, fmt, ...) ptl_warn(&(r)->ptl, fmt, ##__VA_ARGS__)
0097 #define rtl_err(r, fmt, ...)  ptl_err(&(r)->ptl, fmt, ##__VA_ARGS__)
0098 #define rtl_dbg_cond(r, fmt, ...) __ssam_prcond(rtl_dbg, r, fmt, ##__VA_ARGS__)
0099 
0100 #define to_ssh_rtl(ptr, member) \
0101     container_of(ptr, struct ssh_rtl, member)
0102 
0103 /**
0104  * ssh_rtl_get_device() - Get device associated with request transport layer.
0105  * @rtl: The request transport layer.
0106  *
0107  * Return: Returns the device on which the given request transport layer
0108  * builds upon.
0109  */
0110 static inline struct device *ssh_rtl_get_device(struct ssh_rtl *rtl)
0111 {
0112     return ssh_ptl_get_device(&rtl->ptl);
0113 }
0114 
0115 /**
0116  * ssh_request_rtl() - Get request transport layer associated with request.
0117  * @rqst: The request to get the request transport layer reference for.
0118  *
0119  * Return: Returns the &struct ssh_rtl associated with the given SSH request.
0120  */
0121 static inline struct ssh_rtl *ssh_request_rtl(struct ssh_request *rqst)
0122 {
0123     struct ssh_ptl *ptl;
0124 
0125     ptl = READ_ONCE(rqst->packet.ptl);
0126     return likely(ptl) ? to_ssh_rtl(ptl, ptl) : NULL;
0127 }
0128 
0129 int ssh_rtl_submit(struct ssh_rtl *rtl, struct ssh_request *rqst);
0130 bool ssh_rtl_cancel(struct ssh_request *rqst, bool pending);
0131 
0132 int ssh_rtl_init(struct ssh_rtl *rtl, struct serdev_device *serdev,
0133          const struct ssh_rtl_ops *ops);
0134 
0135 int ssh_rtl_start(struct ssh_rtl *rtl);
0136 int ssh_rtl_flush(struct ssh_rtl *rtl, unsigned long timeout);
0137 void ssh_rtl_shutdown(struct ssh_rtl *rtl);
0138 void ssh_rtl_destroy(struct ssh_rtl *rtl);
0139 
0140 int ssh_request_init(struct ssh_request *rqst, enum ssam_request_flags flags,
0141              const struct ssh_request_ops *ops);
0142 
0143 #endif /* _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H */