内部 API 文档¶
数据包传输层¶
-
struct sshp_buf¶
用于 SSH 消息的解析器缓冲区。
定义:
struct sshp_buf {
u8 *ptr;
size_t len;
size_t cap;
};
成员
ptr
指向缓冲区开头的指针。
len
缓冲区中使用的字节数。
cap
缓冲区的最大容量。
参数
struct sshp_buf *buf
要初始化的缓冲区。
u8 *ptr
支持缓冲区的内存。
size_t cap
支持缓冲区的内存长度,即其容量。
描述
使用给定的内存作为后备初始化缓冲区,并将其已用长度设置为零。
参数
struct sshp_buf *buf
要初始化/分配的缓冲区。
size_t cap
缓冲区的期望容量。
gfp_t flags
用于分配内存的标志。
描述
分配 cap 字节,并使用分配的内存初始化提供的缓冲区结构。
返回
成功返回零,如果分配失败,则返回 -ENOMEM
。
参数
struct sshp_buf *buf
要释放的缓冲区。
描述
通过释放支持它的内存,然后将其指针重置为 NULL
,长度和容量重置为零,来释放 SSH 解析器缓冲区。旨在释放之前使用 sshp_buf_alloc()
分配的缓冲区。
参数
struct sshp_buf *buf
要从中删除数据的缓冲区。
size_t n
要删除的字节数。
描述
从缓冲区中删除前 n 个字节。将任何剩余数据重新对齐到缓冲区的开头。
参数
struct sshp_buf *buf
要将数据写入的缓冲区。
struct kfifo *fifo
要从中读取数据的 fifo。
描述
将 fifo 中包含的数据传输到缓冲区,并从 fifo 中删除它。此函数将尝试传输尽可能多的数据,受限于缓冲区中的剩余空间或 fifo 中可用的字节数。
返回
返回传输的字节数。
-
void sshp_buf_span_from(struct sshp_buf *buf, size_t offset, struct ssam_span *span)¶
从给定的缓冲区和偏移量初始化 span。
参数
struct sshp_buf *buf
从中创建 span 的缓冲区。
size_t offset
span 应开始的缓冲区中的偏移量。
struct ssam_span *span
要初始化的 span (输出)。
描述
初始化提供的 span 以指向缓冲区中给定偏移量处的内存,span 的长度受限于偏移量之后缓冲区中使用的字节数(即偏移量之后剩余的字节数)。
警告:此函数不验证 offset 是否小于或等于缓冲区中使用的字节数或缓冲区容量。这必须由调用者保证。
参数
const struct ssam_span *src
应计算 CRC 的数据范围。
const u8 *crc
指向期望的 u16 CRC 值的指针。
描述
计算提供的数据范围 (src) 的 CRC,将其与给定地址 (crc) 处存储的 CRC 进行比较,并返回此比较的结果,即如果相等则返回 true
。此函数旨在对原始输入/消息数据运行。
返回
如果计算的 CRC 与存储的 CRC 匹配,则返回 true
,否则返回 false
。
参数
const struct ssam_span *src
要检查开头的数据范围。
参数
const struct ssam_span *src
要搜索的数据范围。
struct ssam_span *rem
如果找到,则指示剩余数据的范围(输出),从 SSH SYN 字节开始。
描述
在给定的源范围中搜索 SSH SYN 字节。如果找到,则将 **rem** 范围设置为剩余数据,从第一个 SYN 字节开始,并以源范围长度为上限,并返回 true
。此函数不复制任何数据,而只是设置指向相应起始地址和长度值的指针。
如果找不到 SSH SYN 字节,则将 **rem** 范围设置为源范围末尾的零长度范围,并返回 false
。
如果在源范围末尾找到部分 SSH SYN 字节,则将 **rem** 范围设置为覆盖这些部分 SYN 字节,并以源范围末尾为上限,并返回 false
。然后,一旦有更多数据可用,应再次运行此函数。
返回
如果找到完整的 SSH SYN 序列,则返回 true
,否则返回 false
。
-
int sshp_parse_frame(const struct device *dev, const struct ssam_span *source, struct ssh_frame **frame, struct ssam_span *payload, size_t maxlen)¶
解析 SSH 帧。
参数
const struct device *dev
用于日志记录的设备。
const struct ssam_span *source
要从中解析的源。
struct ssh_frame **frame
解析后的帧(输出)。
struct ssam_span *payload
解析后的有效负载(输出)。
size_t maxlen
支持的最大消息长度。
描述
从给定源解析并验证 SSH 帧,包括其有效负载。将提供的 **frame** 指针设置为帧的开始,并将帧有效负载的限制写入提供的 **payload** 范围指针。
此函数不复制任何数据,而只是验证消息数据并设置指针(和长度值)以指示各个部分。
如果找不到完整的 SSH 帧,则帧指针将设置为 NULL
指针,并且有效负载范围将设置为 null 范围(起始指针 NULL
,大小为零)。
返回
如果成功或帧不完整,则返回零;如果消息的开头无效,则返回 -ENOMSG
;如果任何(帧头或有效负载)CRC 无效,则返回 -EBADMSG
;如果 SSH 消息大于 **maxlen** 参数中指定的最大消息长度,则返回 -EMSGSIZE
。
-
int sshp_parse_command(const struct device *dev, const struct ssam_span *source, struct ssh_command **command, struct ssam_span *command_data)¶
解析 SSH 命令帧有效负载。
参数
const struct device *dev
用于日志记录的设备。
const struct ssam_span *source
要从中解析的源。
struct ssh_command **command
解析后的命令(输出)。
struct ssam_span *command_data
解析后的命令数据/有效负载(输出)。
描述
解析并验证 SSH 命令帧有效负载。将 **command** 指针设置为命令头,将 **command_data** 范围设置为命令数据(即命令的有效负载)。如果命令没有任何关联的数据/有效负载,这将导致零长度范围。此函数不检查帧有效负载类型字段,该字段应由调用者在调用此函数之前检查。
**source** 参数应是完整的帧有效负载,例如,由 sshp_parse_frame()
命令返回。
此函数不复制任何数据,而只是验证帧有效负载数据并设置指针(和长度值)以指示各个部分。
返回
如果成功则返回零,如果 **source** 不表示有效的命令类型帧有效负载(即太短)则返回 -ENOMSG
。
-
struct msgbuf¶
用于构造 SSH 消息的缓冲区结构。
定义:
struct msgbuf {
u8 *begin;
u8 *end;
u8 *ptr;
};
成员
begin
指向已分配缓冲区空间开头的指针。
end
指向已分配缓冲区空间末尾(最后一个元素的下一个位置)的指针。
ptr
指向缓冲区中第一个空闲元素的指针。
参数
struct msgbuf *msgb
要初始化的缓冲区结构体
u8 *ptr
指向缓冲区底层内存的指针,缓冲区将基于此内存。
size_t cap
底层内存的大小。
描述
使用提供的内存作为后备,初始化给定的消息缓冲区结构体。
参数
const struct msgbuf *msgb
消息缓冲区。
参数
struct msgbuf *msgb
消息缓冲区。
u16 value
要压入缓冲区的值。
参数
struct msgbuf *msgb
消息缓冲区。
参数
struct msgbuf *msgb
消息缓冲区。
const u8 *buf
要压入缓冲区的数据。
size_t len
要压入缓冲区的数据长度。
参数
struct msgbuf *msgb
消息缓冲区。
const u8 *buf
应该计算 CRC 的数据。
size_t len
应该计算 CRC 的数据长度。
参数
struct msgbuf *msgb
消息缓冲区
u8 ty
帧的类型。
u16 len
帧的有效负载长度。
u8 seq
帧/数据包的序列 ID。
参数
struct msgbuf *msgb
消息缓冲区
u8 seq
要 ACK 的帧/数据包的序列 ID。
参数
struct msgbuf *msgb
消息缓冲区
-
void msgb_push_cmd(struct msgbuf *msgb, u8 seq, u16 rqid, const struct ssam_request *rqst)¶
将带有有效负载的 SSH 命令帧压入缓冲区。
参数
struct msgbuf *msgb
消息缓冲区。
u8 seq
帧/数据包的序列 ID (SEQ)。
u16 rqid
帧中包含的请求的请求 ID (RQID)。
const struct ssam_request *rqst
要封装在帧中的请求。
-
enum ssh_ptl_state_flags¶
struct ssh_ptl
的状态标志。
常量
SSH_PTL_SF_SHUTDOWN_BIT
表示数据包传输层已关闭或正在关闭,不应接受任何新的数据包/数据。
-
struct ssh_ptl_ops¶
数据包传输层的回调操作。
定义:
struct ssh_ptl_ops {
void (*data_received)(struct ssh_ptl *p, const struct ssam_span *data);
};
成员
data_received
当收到数据包时调用的函数。 该函数会收到数据包所在的层和数据包的有效负载数据。
-
struct ssh_ptl¶
SSH 数据包传输层。
定义:
struct ssh_ptl {
struct serdev_device *serdev;
unsigned long state;
struct {
spinlock_t lock;
struct list_head head;
} queue;
struct {
spinlock_t lock;
struct list_head head;
atomic_t count;
} pending;
struct {
atomic_t running;
struct task_struct *thread;
struct completion thread_cplt_tx;
struct completion thread_cplt_pkt;
struct wait_queue_head packet_wq;
} tx;
struct {
struct task_struct *thread;
struct wait_queue_head wq;
struct kfifo fifo;
struct sshp_buf buf;
struct {
u16 seqs[8];
u16 offset;
} blocked;
} rx;
struct {
spinlock_t lock;
ktime_t timeout;
ktime_t expires;
struct delayed_work reaper;
} rtx_timeout;
struct ssh_ptl_ops ops;
};
成员
serdev
提供底层数据传输的串行设备。
state
传输层的状态(标志)。
queue
数据包提交队列。
queue.lock
用于修改数据包提交队列的锁。
queue.head
数据包提交队列的列表头。
pending
待处理数据包的集合/列表。
pending.lock
用于修改待处理集合的锁。
pending.head
待处理集合/列表的列表头。
pending.count
当前待处理的数据包数量。
tx
发送器子系统。
tx.running
指示(期望的)发送器线程状态的标志。
tx.thread
发送器线程。
tx.thread_cplt_tx
用于等待传输的发送器线程的完成。
tx.thread_cplt_pkt
用于等待数据包的发送器线程的完成。
tx.packet_wq
用于数据包传输完成的等待队列头。
rx
接收器子系统。
rx.thread
接收器线程。
rx.wq
接收器线程的等待队列头。
rx.fifo
用于接收数据/将数据推送到接收器线程的缓冲区。
rx.buf
用于评估接收器线程上数据的缓冲区。
rx.blocked
用于检测重传的最近/被阻止的序列 ID 列表。
rx.blocked.seqs
被阻止的序列 ID 数组。
rx.blocked.offset
指示应插入新 ID 的偏移量。
rtx_timeout
重传超时子系统。
rtx_timeout.lock
用于修改重传超时收割器的锁。
rtx_timeout.timeout
重传的超时时间间隔。
rtx_timeout.expires
指定何时下次调度收割器工作的时间。
rtx_timeout.reaper
执行超时检查和后续操作的工作。
ops
数据包层操作。
参数
struct ssh_ptl *ptl
数据包传输层。
返回
返回给定数据包传输层所构建的设备。
参数
struct ssh_ptl *ptl
数据包传输层。
描述
唤醒数据包发送器线程,通知它底层传输有更多空间可用于发送数据。如果数据包传输层已关闭,则对此函数的调用将被忽略。
-
bool ssh_ptl_should_drop_ack_packet(void)¶
用于丢弃 ACK 包的错误注入钩子。
参数
void
无参数
描述
用于测试 EC 自动重传的检测和处理。特别是对于 EC 认为未 ACK 的数据包,但驱动程序已认为 ACK 的数据包(由于丢弃了 ACK)。在这种情况下,EC 会重传要被 ACK 的数据包,驱动程序应将其检测为重复/已处理。请注意,驱动程序仍应为重传的数据包发送 ACK。
-
bool ssh_ptl_should_drop_nak_packet(void)¶
用于丢弃 NAK 包的错误注入钩子。
参数
void
无参数
描述
用于测试/强制 EC 的自动(基于超时)重传。特别是,对于尚未完全到达驱动程序/具有有效校验和的数据包。仅在接收(注入的)错误数据的情况下才有用。
-
bool ssh_ptl_should_drop_dsq_packet(void)¶
用于丢弃序列数据包的错误注入钩子。
参数
void
无参数
描述
用于测试驱动程序的重传超时。如果数据包在一定时间后未被 ACK,则驱动程序应重传数据包,重传次数上限为 SSH_PTL_MAX_PACKET_TRIES 中定义的次数。
-
int ssh_ptl_should_fail_write(void)¶
用于使 serdev_device_write() 失败的错误注入钩子。
参数
void
无参数
描述
用于模拟发送数据包时 serdev_device_write 中的错误的钩子。
-
bool ssh_ptl_should_corrupt_tx_data(void)¶
用于模拟发送到 EC 的无效数据的错误注入钩子。
参数
void
无参数
描述
用于模拟从主机(驱动程序)发送到 EC 的损坏/无效数据的钩子。导致数据包数据被预定义的值主动覆盖而被破坏,从而使其失效,导致 EC 以 NAK 数据包响应。用于测试驱动程序接收到的 NAK 数据包的处理。
-
bool ssh_ptl_should_corrupt_rx_syn(void)¶
用于模拟 EC 发送的无效数据的错误注入钩子。
参数
void
无参数
描述
用于模拟无效的 SYN 字节,即消息的无效开头,并测试驱动程序中对此的处理。
-
bool ssh_ptl_should_corrupt_rx_data(void)¶
用于模拟 EC 发送的无效数据的错误注入钩子。
参数
void
无参数
描述
用于模拟消息帧的无效数据/校验和,并测试驱动程序中对此的处理的钩子。
-
void ssh_packet_init(struct ssh_packet *packet, unsigned long type, u8 priority, const struct ssh_packet_ops *ops)¶
初始化 SSH 数据包。
参数
struct ssh_packet *packet
要初始化的数据包。
unsigned long type
数据包的类型标志。
u8 priority
数据包的优先级。有关详细信息,请参见
SSH_PACKET_PRIORITY()
。const struct ssh_packet_ops *ops
数据包操作。
描述
初始化给定的 SSH 数据包。将传输缓冲区指针设置为 NULL
,并将传输缓冲区长度设置为零。对于数据类型数据包,此缓冲区必须通过 ssh_packet_set_data()
单独设置,然后才能提交,并且必须包含有效的 SSH 消息,即具有可选的任何类型有效负载的帧。
-
int ssh_ctrl_packet_cache_init(void)¶
初始化控制数据包缓存。
参数
void
无参数
-
void ssh_ctrl_packet_cache_destroy(void)¶
取消初始化控制数据包缓存。
参数
void
无参数
-
int ssh_ctrl_packet_alloc(struct ssh_packet **packet, struct ssam_span *buffer, gfp_t flags)¶
从控制数据包缓存分配数据包。
参数
struct ssh_packet **packet
应存储指向新分配的数据包的指针的位置。
struct ssam_span *buffer
与此数据包对应的缓冲区。
gfp_t flags
用于分配的标志。
描述
从控制数据包缓存分配数据包和相应的传输缓冲区。将数据包的缓冲区引用设置为分配的缓冲区。必须通过 ssh_ctrl_packet_free()
释放数据包,这将同时释放相应的缓冲区。不得单独释放相应的缓冲区。旨在与 ssh_ptl_ctrl_packet_ops
用作数据包操作。
返回
成功返回零,如果分配失败,则返回 -ENOMEM
。
-
void ssh_ctrl_packet_free(struct ssh_packet *p)¶
释放从控制数据包缓存分配的数据包。
参数
struct ssh_packet *p
要释放的数据包。
参数
struct ssh_ptl *ptl
数据包传输层。
描述
唤醒数据包发送器线程,通知它已收到一个新数据包并准备好进行传输。如果数据包传输层已关闭,则对此函数的调用将被忽略。
参数
struct ssh_ptl *ptl
数据包传输层。
返回
成功返回零,失败返回负错误代码。
参数
struct ssh_ptl *ptl
数据包传输层。
返回
成功返回零,失败返回负错误代码。
-
int ssh_ptl_submit(struct ssh_ptl *ptl, struct ssh_packet *p)¶
将数据包提交到传输层。
参数
struct ssh_ptl *ptl
要将数据包提交到的数据包传输层。
struct ssh_packet *p
要提交的数据包。
描述
将新数据包提交到传输层,将其排队等待发送。此函数不应用于重新提交。
返回
成功时返回零,如果数据包字段无效或数据包在提交前已被取消,则返回 -EINVAL
;如果数据包已提交,则返回 -EALREADY
;如果数据包传输层已关闭,则返回 -ESHUTDOWN
。
-
void ssh_ptl_cancel(struct ssh_packet *p)¶
取消数据包。
参数
struct ssh_packet *p
要取消的数据包。
描述
取消数据包。不保证何时调用完成和释放回调。这可能在此函数执行期间发生,也可能在稍后的任何时间点发生。
请注意,如果数据包被另一个进程同时完成,则不保证数据包实际被取消。此函数的唯一保证是数据包将在合理的时间范围内完成(成功、失败或取消)并从传输层释放。
可以在数据包提交之前调用,在这种情况下,任何后续的数据包提交都会失败。
参数
struct ssh_ptl *ptl
数据包传输层。
返回
成功返回零,失败返回负错误代码。
参数
struct ssh_ptl *ptl
数据包传输层。
返回
成功返回零,失败返回负错误代码。
参数
struct ssh_ptl *ptl
数据包传输层。
const u8 *buf
指向要推送到该层的数据的指针。
size_t n
要推送到该层的数据大小(以字节为单位)。
描述
将来自底层传输的数据推送到数据包层的接收器 fifo 缓冲区,并通知接收器线程。一旦数据包层关闭,对此函数的调用将被忽略。
返回
成功时返回传输的字节数(正数或零)。如果数据包层已关闭,则返回 -ESHUTDOWN
。
参数
struct ssh_ptl *ptl
数据包传输层。
描述
关闭数据包传输层,删除并取消所有已排队和挂起的数据包。由此操作取消的数据包将以 -ESHUTDOWN
作为状态完成。接收器和发送器线程将停止。
由于此函数,传输层将被标记为关闭。在传输层关闭后提交数据包将失败并返回 -ESHUTDOWN
。
-
int ssh_ptl_init(struct ssh_ptl *ptl, struct serdev_device *serdev, struct ssh_ptl_ops *ops)¶
初始化数据包传输层。
参数
struct ssh_ptl *ptl
要初始化的数据包传输层。
struct serdev_device *serdev
底层串行设备,即底层传输。
struct ssh_ptl_ops *ops
数据包层操作。
描述
初始化给定的数据包传输层。在数据包层初始化且底层传输层设置好后,必须分别通过 ssh_ptl_tx_start()
和 ssh_ptl_rx_start()
启动发送器和接收器线程。
返回
成功时返回零,失败时返回非零错误代码。
参数
struct ssh_ptl *ptl
要取消初始化的数据包传输层。
描述
取消初始化给定的数据包传输层并释放与其关联的资源。如果已启动接收器和/或发送器线程,则必须先通过 ssh_ptl_shutdown()
关闭该层,然后才能调用此函数。
请求传输层¶
-
enum ssh_rtl_state_flags¶
struct ssh_rtl
的状态标志。
常量
SSH_RTL_SF_SHUTDOWN_BIT
指示请求传输层已关闭或正在关闭,不应接受任何新请求。
-
struct ssh_rtl_ops¶
请求传输层的回调操作。
定义:
struct ssh_rtl_ops {
void (*handle_event)(struct ssh_rtl *rtl, const struct ssh_command *cmd, const struct ssam_span *data);
};
成员
handle_event
收到 SSH 事件时调用的函数。指定的函数将请求层、接收到的命令结构和相应的有效负载作为参数。如果事件没有有效负载,则有效负载跨度为空(不是
NULL
)。
-
struct ssh_rtl¶
SSH 请求传输层。
定义:
struct ssh_rtl {
struct ssh_ptl ptl;
unsigned long state;
struct {
spinlock_t lock;
struct list_head head;
} queue;
struct {
spinlock_t lock;
struct list_head head;
atomic_t count;
} pending;
struct {
struct work_struct work;
} tx;
struct {
spinlock_t lock;
ktime_t timeout;
ktime_t expires;
struct delayed_work reaper;
} rtx_timeout;
struct ssh_rtl_ops ops;
};
成员
ptl
底层数据包传输层。
state
传输层的状态(标志)。
queue
请求提交队列。
queue.lock
用于修改请求提交队列的锁。
queue.head
请求提交队列的列表头。
pending
挂起请求的集合/列表。
pending.lock
用于修改请求集的锁。
pending.head
待处理集合/列表的列表头。
pending.count
当前挂起的请求数。
tx
发送器子系统。
tx.work
发送器工作项。
rtx_timeout
重传超时子系统。
rtx_timeout.lock
用于修改重传超时收割器的锁。
rtx_timeout.timeout
重传的超时时间间隔。
rtx_timeout.expires
指定何时下次调度收割器工作的时间。
rtx_timeout.reaper
执行超时检查和后续操作的工作。
ops
请求层操作。
参数
struct ssh_rtl *rtl
请求传输层。
返回
返回给定请求传输层所构建的设备。
-
struct ssh_rtl *ssh_request_rtl(struct ssh_request *rqst)¶
获取与请求关联的请求传输层。
-
bool ssh_rtl_should_drop_response(void)¶
用于丢弃请求响应的错误注入钩子。
参数
void
无参数
描述
通过丢弃对请求的响应,可用于在驱动程序中导致请求传输超时。
-
int ssh_rtl_submit(struct ssh_rtl *rtl, struct ssh_request *rqst)¶
向传输层提交请求。
参数
struct ssh_rtl *rtl
请求传输层。
struct ssh_request *rqst
要提交的请求。
描述
向传输层提交请求。单个请求在未重新初始化的情况下不能多次提交。
返回
成功时返回零,如果请求类型无效或请求在提交前已被取消,则返回 -EINVAL
,如果请求已提交,则返回 -EALREADY
,如果请求传输层已关闭,则返回 -ESHUTDOWN
。
-
bool ssh_rtl_cancel(struct ssh_request *rqst, bool pending)¶
取消请求。
参数
struct ssh_request *rqst
要取消的请求。
bool pending
是否也取消待处理的请求。
描述
取消给定的请求。如果 pending 为 false
,则不会取消待处理的请求,即已提交到数据包层但尚未完成的请求。如果 pending 为 true
,则无论给定请求处于何种状态,都会取消它。
如果请求已通过调用此函数取消,则请求的完成和释放回调都将在合理的时间范围内执行。这可能会在此函数执行期间发生,但是,不能保证这一点。例如,当前正在传输的请求仅在传输完成后才会被取消/完成,并且相应的回调将在发送器线程上执行,这可能会在取消函数执行期间发生,但也可能在执行后一段时间发生。
返回
如果给定的请求已通过此函数或在调用此函数之前被取消或完成,则返回 true
,否则返回 false
。如果 pending 为 true
,则此函数将始终返回 true
。
-
int ssh_request_init(struct ssh_request *rqst, enum ssam_request_flags flags, const struct ssh_request_ops *ops)¶
初始化 SSH 请求。
参数
struct ssh_request *rqst
要初始化的请求。
enum ssam_request_flags flags
请求标志,确定请求的类型。
const struct ssh_request_ops *ops
请求操作。
描述
初始化给定的 SSH 请求和底层数据包。将消息缓冲区指针设置为 NULL
,并将消息缓冲区长度设置为零。此缓冲区必须在提交之前通过 ssh_request_set_data()
单独设置,并且必须包含有效的 SSH 请求消息。
返回
成功时返回零,如果给定的标志无效,则返回 -EINVAL
。
-
int ssh_rtl_init(struct ssh_rtl *rtl, struct serdev_device *serdev, const struct ssh_rtl_ops *ops)¶
初始化请求传输层。
参数
struct ssh_rtl *rtl
要初始化的请求传输层。
struct serdev_device *serdev
底层串行设备,即底层传输。
const struct ssh_rtl_ops *ops
请求传输层操作。
描述
初始化给定的请求传输层和关联的数据包传输层。在初始化请求层并设置了较低级别的串行设备层之后,必须通过 ssh_rtl_start()
单独启动发送器和接收器线程。
返回
成功时返回零,失败时返回非零错误代码。
参数
struct ssh_rtl *rtl
要取消初始化的请求传输层。
描述
取消初始化给定的请求传输层并释放与其关联的资源。如果已启动接收器和/或发送器线程,则必须先通过 ssh_rtl_shutdown()
关闭该层,然后才能调用此函数。
参数
struct ssh_rtl *rtl
请求传输层。
返回
成功返回零,失败返回负错误代码。
参数
struct ssh_rtl *rtl
请求传输层
unsigned long timeout
刷新操作的超时时间(以 jiffies 为单位)
描述
排队一个特殊的刷新请求并等待其完成。此请求将在所有其他当前排队和待处理的请求完成后完成。此请求不是提交普通数据包,而是提交特殊的刷新数据包,这意味着完成后,底层数据包传输层也将被刷新。
刷新请求层保证在此调用返回之前,所有先前提交的请求都已完全完成。此外,刷新会阻止所有稍后提交的请求的执行,直到刷新完成。
如果调用方确保在调用此函数后不会提交任何新请求,则保证在调用返回时,请求传输层没有剩余的请求。相同的保证不适用于数据包层,在此调用之后,控制数据包仍可能在其中排队。
返回
成功时返回零,如果刷新超时并且由于超时而被取消,则返回 -ETIMEDOUT
,如果数据包和/或请求传输层在此调用之前已关闭,则返回 -ESHUTDOWN
。如果底层数据包传输被中断,也可能返回 -EINTR
。
参数
struct ssh_rtl *rtl
请求传输层。
描述
关闭请求传输层,删除并取消所有排队和待处理的请求。通过此操作取消的请求将以 -ESHUTDOWN
作为状态完成。接收器和发送器线程将被停止,较低级别的数据包层将被关闭。
此函数执行后,传输层将被标记为已关闭。在传输层关闭后提交请求将失败,并返回 -ESHUTDOWN
。
控制器¶
-
struct ssh_seq_counter¶
用于 SSH 序列 ID 的安全计数器。
定义:
struct ssh_seq_counter {
u8 value;
};
成员
value
当前计数器值。
-
struct ssh_rqid_counter¶
用于 SSH 请求 ID 的安全计数器。
定义:
struct ssh_rqid_counter {
u16 value;
};
成员
value
当前计数器值。
-
struct ssam_nf_head¶
用于 SSAM 事件的通知器头。
定义:
struct ssam_nf_head {
struct srcu_struct srcu;
struct list_head head;
};
成员
srcu
用于同步的 SRCU 结构。
head
在此头下注册的通知器块的列表头。
-
struct ssam_nf¶
用于 SSAM 事件的通知器回调和激活注册表。
定义:
struct ssam_nf {
struct mutex lock;
struct rb_root refcount;
struct ssam_nf_head head[SSH_NUM_EVENTS];
};
成员
lock
保护通知器块(取消)注册的锁。注意:此锁不需要在通知器调用时持有,仅在注册和注销时需要。
refcount
用于引用计数已启用事件/通知的 RB 树的根。
head
用于事件/通知回调的通知器头列表。
-
struct ssam_event_item¶
用于事件排队和完成的结构。
定义:
struct ssam_event_item {
struct list_head node;
u16 rqid;
struct {
void (*free)(struct ssam_event_item *event);
} ops;
struct ssam_event event;
};
成员
node
队列中的节点。
rqid
事件的请求 ID。
ops
实例特定的函数。
ops.free
用于释放此事件项的回调。
event
实际事件数据。
-
struct ssam_event_queue¶
用于完成接收事件的队列。
定义:
struct ssam_event_queue {
struct ssam_cplt *cplt;
spinlock_t lock;
struct list_head head;
struct work_struct work;
};
成员
cplt
引用此队列在其上处于活动状态的完成系统。
lock
用于队列上任何操作的锁。
head
队列的列表头。
work
执行此队列完成工作的
struct work_struct
。
-
struct ssam_event_target¶
用于单个 SSH 目标 ID 的队列集合。
定义:
struct ssam_event_target {
struct ssam_event_queue queue[SSH_NUM_EVENTS];
};
成员
queue
队列数组,每个事件 ID 一个队列。
-
struct ssam_cplt¶
SSAM 事件/异步请求完成系统。
定义:
struct ssam_cplt {
struct device *dev;
struct workqueue_struct *wq;
struct {
struct ssam_event_target target[SSH_NUM_TARGETS];
struct ssam_nf notif;
} event;
};
成员
dev
与此系统关联的设备。仅用于记录日志。
wq
在其上排队所有完成工作项的
struct workqueue_struct
。event
事件完成管理。
event.target
struct ssam_event_target
的数组,每个目标一个。event.notif
通知器回调和事件激活引用计数。
-
enum ssam_controller_state¶
struct ssam_controller
的状态值。
常量
SSAM_CONTROLLER_UNINITIALIZED
控制器尚未初始化或已取消初始化。
SSAM_CONTROLLER_INITIALIZED
控制器已初始化,但尚未启动。
SSAM_CONTROLLER_STARTED
控制器已启动,可以使用。
SSAM_CONTROLLER_STOPPED
控制器已停止。
SSAM_CONTROLLER_SUSPENDED
控制器已挂起。
-
struct ssam_controller_caps¶
控制器设备功能。
定义:
struct ssam_controller_caps {
u32 ssh_power_profile;
u32 ssh_buffer_size;
u32 screen_on_sleep_idle_timeout;
u32 screen_off_sleep_idle_timeout;
u32 d3_closes_handle:1;
};
成员
ssh_power_profile
SSH 电源配置文件。
ssh_buffer_size
SSH 驱动程序 UART 缓冲区大小。
screen_on_sleep_idle_timeout
SAM UART 屏幕开启休眠空闲超时。
screen_off_sleep_idle_timeout
SAM UART 屏幕关闭休眠空闲超时。
d3_closes_handle
SAM 在 D3 中关闭 UART 句柄。
描述
在 ACPI 中找到的控制器和 SSH 设备功能。
-
struct ssam_controller¶
SSAM 控制器设备。
定义:
struct ssam_controller {
struct kref kref;
struct rw_semaphore lock;
enum ssam_controller_state state;
struct ssh_rtl rtl;
struct ssam_cplt cplt;
struct {
struct ssh_seq_counter seq;
struct ssh_rqid_counter rqid;
} counter;
struct {
int num;
bool wakeup_enabled;
} irq;
struct ssam_controller_caps caps;
};
成员
kref
控制器的引用计数。
lock
控制器的主要锁,用于保护状态更改。
state
控制器状态。
rtl
用于 SSH I/O 的请求传输层。
cplt
用于 SSH/SSAM 事件和异步请求的完成系统。
counter
安全 SSH 消息 ID 计数器。
counter.seq
序列 ID 计数器。
counter.rqid
请求 ID 计数器。
irq
唤醒 IRQ 资源。
irq.num
唤醒 IRQ 编号。
irq.wakeup_enabled
是否在挂起期间启用通过 IRQ 唤醒。
caps
控制器设备功能。
-
ssize_t ssam_controller_receive_buf(struct ssam_controller *ctrl, const u8 *buf, size_t n)¶
向控制器提供输入数据。
参数
struct ssam_controller *ctrl
控制器。
const u8 *buf
输入缓冲区。
size_t n
输入缓冲区中的字节数。
描述
提供要由控制器评估的输入数据,这些数据已通过较低级别的传输接收。
返回
返回已使用的字节数,或者,如果控制器的包传输层已关闭,则返回 -ESHUTDOWN
。
-
void ssam_controller_write_wakeup(struct ssam_controller *ctrl)¶
通知控制器底层设备有空间可用于写入数据。
参数
struct ssam_controller *ctrl
控制器。
-
void ssh_seq_reset(struct ssh_seq_counter *c)¶
重置/初始化序列 ID 计数器。
参数
struct ssh_seq_counter *c
要重置的计数器。
-
u8 ssh_seq_next(struct ssh_seq_counter *c)¶
获取下一个序列 ID。
参数
struct ssh_seq_counter *c
提供序列 ID 的计数器。
返回
返回计数器的下一个序列 ID。
-
void ssh_rqid_reset(struct ssh_rqid_counter *c)¶
重置/初始化请求 ID 计数器。
参数
struct ssh_rqid_counter *c
要重置的计数器。
-
u16 ssh_rqid_next(struct ssh_rqid_counter *c)¶
获取下一个请求 ID。
参数
struct ssh_rqid_counter *c
提供请求 ID 的计数器。
返回
返回计数器的下一个请求 ID,跳过任何保留的请求 ID。
-
bool ssam_event_matches_notifier(const struct ssam_event_notifier *n, const struct ssam_event *event)¶
测试事件是否与通知器匹配。
参数
const struct ssam_event_notifier *n
要测试的事件通知器。
const struct ssam_event *event
要测试的事件。
返回
如果给定的事件与给定的通知器根据通知器的事件掩码中设置的规则匹配,则返回 true
,否则返回 false
。
-
int ssam_nfblk_call_chain(struct ssam_nf_head *nh, struct ssam_event *event)¶
调用给定链的事件通知器回调。
参数
struct ssam_nf_head *nh
应该调用通知器回调的通知器头。
struct ssam_event *event
提供给回调的事件数据。
描述
按照优先级顺序调用所有已注册的通知器回调,直到没有剩余的通知器或通知器返回一个设置了 SSAM_NOTIF_STOP
位的数值。请注意,此位通过 ssam_notifier_from_errno()
在任何非零错误值上自动设置。
返回
返回通知器状态值,其中包含通知器状态位(SSAM_NOTIF_HANDLED
和 SSAM_NOTIF_STOP
)以及上次执行的通知器回调返回的潜在错误值。使用 ssam_notifier_to_errno()
将此值转换为原始错误值。
-
int ssam_nfblk_insert(struct ssam_nf_head *nh, struct ssam_notifier_block *nb)¶
将新的通知器块插入到给定的通知器列表中。
参数
struct ssam_nf_head *nh
应该插入块的通知器头。
struct ssam_notifier_block *nb
要添加的通知器块。
注意
此函数必须由调用者同步,以使用 struct ssam_nf.lock
来处理其他插入、查找和/或删除调用。
返回
成功时返回零,如果通知器块已经注册,则返回 -EEXIST
。
-
bool ssam_nfblk_find(struct ssam_nf_head *nh, struct ssam_notifier_block *nb)¶
检查通知器块是否在给定的通知器头列表上注册。
参数
struct ssam_nf_head *nh
要搜索的通知器头。
struct ssam_notifier_block *nb
要搜索的通知器块。
注意
此函数必须由调用者同步,以使用 struct ssam_nf.lock
来处理其他插入、查找和/或删除调用。
返回
如果给定的通知器块在给定的通知器头上注册,则返回 true,否则返回 false。
-
void ssam_nfblk_remove(struct ssam_notifier_block *nb)¶
从其通知器列表中删除通知器块。
参数
struct ssam_notifier_block *nb
要删除的通知器块。
注意
此函数必须由调用者同步,以使用 struct ssam_nf.lock
来处理其他插入、查找和/或删除调用。此外,调用者*必须*通过在离开临界区后使用 nh->srcu
调用 synchronize_srcu()
来确保 SRCU 同步,以确保删除的通知器块不再使用。
-
int ssam_nf_head_init(struct ssam_nf_head *nh)¶
初始化给定的通知器头。
参数
struct ssam_nf_head *nh
要初始化的通知器头。
-
void ssam_nf_head_destroy(struct ssam_nf_head *nh)¶
取消初始化给定的通知器头。
参数
struct ssam_nf_head *nh
要取消初始化的通知器头。
-
struct ssam_nf_refcount_key¶
用于事件激活引用计数的键。
定义:
struct ssam_nf_refcount_key {
struct ssam_event_registry reg;
struct ssam_event_id id;
};
成员
reg
通过该注册表启用/禁用事件。
id
唯一描述事件的 ID。
-
struct ssam_nf_refcount_entry¶
用于引用计数事件激活的 RB 树条目。
定义:
struct ssam_nf_refcount_entry {
struct rb_node node;
struct ssam_nf_refcount_key key;
int refcount;
u8 flags;
};
成员
node
此条目在 rb 树中的节点。
key
事件的键。
refcount
事件的引用计数。
flags
启用事件时使用的标志。
-
struct ssam_nf_refcount_entry *ssam_nf_refcount_inc(struct ssam_nf *nf, struct ssam_event_registry reg, struct ssam_event_id id)¶
递增给定事件的引用计数/激活计数。
参数
struct ssam_nf *nf
通知器系统引用。
struct ssam_event_registry reg
用于启用/禁用事件的注册表。
struct ssam_event_id id
事件 ID。
描述
递增与指定的事件类型/ID 关联的引用计数/激活计数,如有必要,为该事件 ID 分配一个新条目。新分配的条目的引用计数将为 1。
注意
调用此函数时必须持有 nf->lock
。
返回
成功时返回引用计数条目。如果指定 ID 和类型的事件已经注册了 INT_MAX
个,则返回带有 -ENOSPC
的错误指针;如果无法分配该条目,则返回带有 -ENOMEM
的错误指针。
-
struct ssam_nf_refcount_entry *ssam_nf_refcount_dec(struct ssam_nf *nf, struct ssam_event_registry reg, struct ssam_event_id id)¶
递减给定事件的引用计数/激活计数。
参数
struct ssam_nf *nf
通知器系统引用。
struct ssam_event_registry reg
用于启用/禁用事件的注册表。
struct ssam_event_id id
事件 ID。
描述
递减指定事件的引用计数/激活计数,返回其条目。如果返回的条目的引用计数为零,则调用者负责使用 kfree()
释放它。
注意
调用此函数时必须持有 nf->lock
。
返回
成功时返回引用计数条目,如果未找到该条目,则返回 NULL
。
-
void ssam_nf_refcount_dec_free(struct ssam_nf *nf, struct ssam_event_registry reg, struct ssam_event_id id)¶
递减给定事件的引用计数/激活计数,如果引用计数达到零,则释放其条目。
参数
struct ssam_nf *nf
通知器系统引用。
struct ssam_event_registry reg
用于启用/禁用事件的注册表。
struct ssam_event_id id
事件 ID。
描述
递减指定事件的引用计数/激活计数,如果计数达到零,则释放其条目。
注意
调用此函数时必须持有 nf->lock
。
参数
struct ssam_nf *nf
通知系统。
-
void ssam_nf_call(struct ssam_nf *nf, struct device *dev, u16 rqid, struct ssam_event *event)¶
为提供的事件调用通知回调。
参数
struct ssam_nf *nf
通知程序系统
struct device *dev
关联的设备,仅用于日志记录。
u16 rqid
事件的请求 ID。
struct ssam_event *event
提供给回调的事件。
描述
按照优先级顺序执行已注册的回调,直到没有剩余的回调,或者回调返回一个设置了 SSAM_NOTIF_STOP
位的数值为止。请注意,当通过 ssam_notifier_from_errno()
将非零错误值转换为通知程序值时,会自动设置此位。
另请注意,任何可以处理事件的回调都应返回一个设置了 SSAM_NOTIF_HANDLED
位的数值,表示该事件不会被未处理/忽略。如果没有任何已注册的回调可以处理事件,此函数将发出警告。
如果回调失败,此函数将发出错误消息。
参数
struct ssam_nf *nf
要初始化的通知程序系统。
参数
struct ssam_nf *nf
要取消初始化的通知程序系统。
-
int ssam_event_item_cache_init(void)¶
初始化事件项缓存。
参数
void
无参数
-
void ssam_event_item_cache_destroy(void)¶
取消初始化事件项缓存。
参数
void
无参数
-
void ssam_event_item_free(struct ssam_event_item *item)¶
释放提供的事件项。
参数
struct ssam_event_item *item
要释放的事件项。
-
struct ssam_event_item *ssam_event_item_alloc(size_t len, gfp_t flags)¶
分配具有给定有效负载大小的事件项。
参数
size_t len
事件有效负载长度。
gfp_t flags
用于分配的标志。
描述
分配具有给定有效负载大小的事件项,如果有效负载足够小(即小于 SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN
),则优先从事件项缓存分配。设置项目操作和有效负载长度值。在此调用之后,不应覆盖项目释放回调(ops.free
)。
返回
返回新分配的事件项。
-
void ssam_event_queue_push(struct ssam_event_queue *q, struct ssam_event_item *item)¶
将事件项推送到事件队列。
参数
struct ssam_event_queue *q
事件队列。
struct ssam_event_item *item
要添加的项目。
-
struct ssam_event_item *ssam_event_queue_pop(struct ssam_event_queue *q)¶
从事件队列中弹出下一个事件项。
参数
struct ssam_event_queue *q
事件队列。
描述
从队列中返回并删除下一个事件项。如果没有剩余的事件项,则返回 NULL
。
-
bool ssam_event_queue_is_empty(struct ssam_event_queue *q)¶
检查事件队列是否为空。
参数
struct ssam_event_queue *q
事件队列。
-
struct ssam_event_queue *ssam_cplt_get_event_queue(struct ssam_cplt *cplt, u8 tid, u16 rqid)¶
获取给定参数的事件队列。
参数
struct ssam_cplt *cplt
在其上查找队列的完成系统。
u8 tid
队列的目标 ID。
u16 rqid
表示要获取队列的事件 ID 的请求 ID。
返回
返回由给定参数描述的事件类型对应的事件队列。如果请求 ID 不表示事件,则此函数返回 NULL
。如果目标 ID 不受支持,则此函数将回退到默认目标 ID(tid = 1
)。
参数
struct ssam_cplt *cplt
完成系统。
struct work_struct *work
要提交的工作项。
-
int ssam_cplt_submit_event(struct ssam_cplt *cplt, struct ssam_event_item *item)¶
将事件提交到完成系统。
参数
struct ssam_cplt *cplt
完成系统。
struct ssam_event_item *item
要提交的事件项。
描述
通过将事件排队到事件项队列,并将相应的事件队列工作项排队到完成工作队列中,将事件提交到完成系统,最终完成事件。
返回
成功时返回零,如果不存在可以处理给定事件项的事件队列,则返回 -EINVAL
。
参数
struct ssam_cplt *cplt
完成系统。
描述
通过等待直到所有当前提交的工作项都已完成来刷新完成系统。
此操作仅旨在在关闭之前的正常操作期间,尝试完成大多数事件和请求,以便在系统仍在完全运行时将其从系统中取出。它不旨在保证所有事件都已被处理。
注意
此函数不保证一旦此调用终止,所有事件都将被处理。如果存在大量待完成的事件,事件队列工作函数可能会重新安排其工作项,而此刷新操作将忽略该项。
-
void ssam_event_queue_init(struct ssam_cplt *cplt, struct ssam_event_queue *evq)¶
初始化事件队列。
参数
struct ssam_cplt *cplt
队列所在的完成系统。
struct ssam_event_queue *evq
要初始化的事件队列。
参数
struct ssam_cplt *cplt
要初始化的完成系统。
struct device *dev
用于日志记录的设备。
参数
struct ssam_cplt *cplt
要取消初始化的完成系统。
描述
取消初始化给定的完成系统,并确保所有待处理的(即尚未完成的)事件项和请求都已被处理。
-
void ssam_controller_lock(struct ssam_controller *c)¶
获取主控制器锁。
参数
struct ssam_controller *c
要锁定的控制器。
描述
对于任何状态转换,包括转换为挂起/恢复状态和在关闭期间,必须持有此锁。有关控制器锁定的更多详细信息,请参见 ssam_controller_statelock()
。
有关相应的解锁函数,请参见 ssam_controller_unlock()。
-
int ssam_controller_caps_load_from_acpi(acpi_handle handle, struct ssam_controller_caps *caps)¶
从 ACPI _DSM 加载控制器功能。
参数
acpi_handle handle
ACPI 控制器/SSH 设备的句柄。
struct ssam_controller_caps *caps
将功能存储在何处。
描述
使用默认值初始化给定的控制器功能,然后检查,如果相应的 _DSM 函数可用,则从 _DSM 加载实际功能。
返回
成功返回零,失败返回负错误代码。
-
int ssam_controller_caps_load_from_of(struct device *dev, struct ssam_controller_caps *caps)¶
从 OF/DT 加载控制器功能。
参数
struct device *dev
指向控制器设备的指针
struct ssam_controller_caps *caps
将功能存储在何处。
返回
成功返回零,失败返回负错误代码。
-
int ssam_controller_caps_load(struct device *dev, struct ssam_controller_caps *caps)¶
加载控制器功能
参数
struct device *dev
指向控制器设备的指针
struct ssam_controller_caps *caps
将功能存储在何处。
返回
成功返回零,失败返回负错误代码。
-
int ssam_controller_init(struct ssam_controller *ctrl, struct serdev_device *serdev)¶
初始化 SSAM 控制器。
参数
struct ssam_controller *ctrl
要初始化的控制器。
struct serdev_device *serdev
表示底层数据传输的串行设备。
描述
初始化给定的控制器。不启动接收器或发送器线程。调用此函数后,必须通过 struct serdev_device_ops
将控制器单独连接到 serdev 核心,将调用转发到 ssam_controller_receive_buf()
和 ssam_controller_write_wakeup()
。控制器连接后,可以通过 ssam_controller_start()
启动发送器和接收器线程。这些设置步骤需要在控制器用于请求之前完成。
-
int ssam_controller_start(struct ssam_controller *ctrl)¶
启动控制器的接收器和发送器线程。
参数
struct ssam_controller *ctrl
控制器。
注意
调用此函数时,应通过 struct serdev_device_ops
将控制器正确连接到 serdev 核心。有关控制器初始化的更多详细信息,请参阅 ssam_controller_init()
。
描述
必须在持有主控制器锁的情况下调用此函数(即通过调用 ssam_controller_lock()
)。
-
void ssam_controller_shutdown(struct ssam_controller *ctrl)¶
关闭控制器。
参数
struct ssam_controller *ctrl
控制器。
描述
通过刷新所有挂起的请求并停止发送器和接收器线程来关闭控制器。在此调用之后提交的所有请求都将失败,并返回 -ESHUTDOWN
。虽然不建议这样做,但此函数可以安全地与正在进行的请求提交并行使用。
在此关闭过程中,所有当前注册的通知器都将被注销。但是,强烈建议不要依赖此行为,注册通知器的一方应在控制器关闭之前注销它,例如通过 SSAM 总线,它保证客户端设备在关闭之前被移除。
请注意,在此调用之后,事件可能仍在挂起,但是,由于通知器已注销,当随后通过 ssam_controller_destroy()
销毁控制器时,这些事件将被丢弃。
必须在持有主控制器锁的情况下调用此函数(即通过调用 ssam_controller_lock()
)。
-
void ssam_controller_destroy(struct ssam_controller *ctrl)¶
销毁控制器并释放其资源。
参数
struct ssam_controller *ctrl
控制器。
描述
确保释放与控制器关联的所有资源。仅在通过 ssam_controller_shutdown()
停止控制器后,才应调用此函数。通常,不应直接调用此函数。直接调用此函数的唯一有效位置是在初始化期间,在控制器完全初始化并传递给其他进程之前。当控制器的引用计数达到零时,将自动调用此函数。
必须在持有主控制器锁的情况下调用此函数(即通过调用 ssam_controller_lock()
)。
-
int ssam_controller_suspend(struct ssam_controller *ctrl)¶
挂起控制器。
参数
struct ssam_controller *ctrl
要挂起的控制器。
描述
将控制器标记为已挂起。请注意,在通过此函数将控制器转换为挂起状态之前,必须手动发送显示关闭和 D0 退出通知。
有关相应的恢复函数,请参阅 ssam_controller_resume()
。
返回
如果控制器当前不处于“已启动”状态,则返回 -EINVAL
。
-
int ssam_controller_resume(struct ssam_controller *ctrl)¶
从挂起状态恢复控制器。
参数
struct ssam_controller *ctrl
要恢复的控制器。
描述
从通过 ssam_controller_suspend()
进入的挂起状态恢复控制器。此函数不发出显示开启和 D0 进入通知。如果需要,必须在此调用后手动发送这些通知。
返回
如果控制器当前未挂起,则返回 -EINVAL
。
-
struct ssh_notification_params¶
用于启用/禁用 SSH 通知的命令有效负载。
定义:
struct ssh_notification_params {
u8 target_category;
u8 flags;
__le16 request_id;
u8 instance_id;
};
成员
target_category
应为其启用/禁用通知的目标类别。
flags
确定如何发送通知的标志。
request_id
用于发送这些通知的请求 ID。
instance_id
应为其启用通知的给定目标类别中的特定实例。
-
int ssam_ssh_event_enable(struct ssam_controller *ctrl, struct ssam_event_registry reg, struct ssam_event_id id, u8 flags)¶
启用 SSH 事件。
参数
struct ssam_controller *ctrl
要为其启用事件的控制器。
struct ssam_event_registry reg
描述要用于启用和禁用事件的请求的事件注册表。
struct ssam_event_id id
事件标识符。
u8 flags
事件标志。
描述
在 EC 上启用指定的事件。此函数不管理已启用事件的引用计数,并且基本上只是原始 EC 请求的包装器。如果指定的事件已启用,则 EC 将忽略此请求。
返回
返回执行的 SAM 请求的状态(成功时为零,直接失败时为负数),如果请求响应指示失败,则返回 -EPROTO
。
-
int ssam_ssh_event_disable(struct ssam_controller *ctrl, struct ssam_event_registry reg, struct ssam_event_id id, u8 flags)¶
禁用 SSH 事件。
参数
struct ssam_controller *ctrl
要为其禁用事件的控制器。
struct ssam_event_registry reg
描述要用于启用和禁用事件的请求的事件注册表(必须与启用事件时使用的相同)。
struct ssam_event_id id
事件标识符。
u8 flags
事件标志(可能在禁用事件时被忽略)。
描述
在 EC 上禁用指定的事件。此函数不管理已启用事件的引用计数,并且基本上只是原始 EC 请求的包装器。如果指定的事件已禁用,则 EC 将忽略此请求。
返回
返回执行的 SAM 请求的状态(成功时为零,直接失败时为负数),如果请求响应指示失败,则返回 -EPROTO
。
-
int ssam_get_firmware_version(struct ssam_controller *ctrl, u32 *version)¶
获取 SAM/EC 固件版本。
参数
struct ssam_controller *ctrl
控制器。
u32 *version
版本号的存储位置。
返回
成功时返回零,如果该请求失败,则返回执行的 SAM 请求的状态。
-
int ssam_ctrl_notif_display_off(struct ssam_controller *ctrl)¶
通知 EC 显示屏已关闭。
参数
struct ssam_controller *ctrl
控制器。
描述
通知 EC 显示屏已关闭,驱动程序可能会进入低功耗状态。这将阻止事件直接发送。相反,EC 通过将唤醒 GPIO 拉高来发出事件信号,只要有待处理的事件。然后需要通过 GPIO 回调请求手动逐个释放事件。在此状态期间累积的所有待处理事件也可以通过发出显示开启通知来释放,例如通过 ssam_ctrl_notif_display_on()
,这也会重置 GPIO。
在某些设备上,特别是那些带有集成键盘的设备,键盘背光将通过此调用关闭。
仅当 EC 支持显示通知时,此函数才会发送显示关闭通知命令。目前,所有已知设备都支持这些通知。
使用 ssam_ctrl_notif_display_on()
来反转此函数的效果。
返回
成功或未执行任何请求时返回零,如果该请求失败则返回执行的 SAM 请求的状态,如果收到意外响应则返回 -EPROTO
。
-
int ssam_ctrl_notif_display_on(struct ssam_controller *ctrl)¶
通知 EC 显示屏已开启。
参数
struct ssam_controller *ctrl
控制器。
描述
通知 EC 显示屏已重新开启,并且驱动程序已退出其低功耗状态。此通知是 通过 ssam_ctrl_notif_display_off()
发送的显示关闭通知的对应项,并将反转其效果,包括将事件重置为默认行为。
仅当 EC 支持显示通知时,此函数才会发送显示开启通知命令。目前,所有已知设备都支持这些通知。
有关更多详细信息,请参阅 ssam_ctrl_notif_display_off()
。
返回
成功或未执行任何请求时返回零,如果该请求失败则返回执行的 SAM 请求的状态,如果收到意外响应则返回 -EPROTO
。
-
int ssam_ctrl_notif_d0_exit(struct ssam_controller *ctrl)¶
通知 EC 驱动程序/设备退出 D0 电源状态。
参数
struct ssam_controller *ctrl
控制器
描述
通知 EC 驱动程序准备退出 D0 电源状态,转而进入低功耗状态。目前尚不清楚此函数与 EC 相关的确切效果。
仅当 EC 支持 D0 状态通知时,此函数才会发送 D0 退出通知命令。只有较新的 Surface 产品才支持这些通知。
使用 ssam_ctrl_notif_d0_entry()
来反转此函数的效果。
返回
成功或未执行任何请求时返回零,如果该请求失败则返回执行的 SAM 请求的状态,如果收到意外响应则返回 -EPROTO
。
-
int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)¶
通知 EC 驱动程序/设备进入 D0 电源状态。
参数
struct ssam_controller *ctrl
控制器
描述
通知 EC 驱动程序已退出低功耗状态并进入 D0 电源状态。目前尚不清楚此函数与 EC 相关的确切效果。
仅当 EC 支持 D0 状态通知时,此函数才会发送 D0 进入通知命令。只有较新的 Surface 产品才支持这些通知。
有关更多详细信息,请参阅 ssam_ctrl_notif_d0_exit()
。
返回
成功或未执行任何请求时返回零,如果该请求失败则返回执行的 SAM 请求的状态,如果收到意外响应则返回 -EPROTO
。
-
int ssam_nf_refcount_enable(struct ssam_controller *ctrl, struct ssam_nf_refcount_entry *entry, u8 flags)¶
如果引用计数条目尚未启用,则启用该事件。
参数
struct ssam_controller *ctrl
要启用事件的控制器。
struct ssam_nf_refcount_entry *entry
要启用事件的引用计数条目。
u8 flags
在 EC 上启用事件时使用的标志。
描述
如果引用计数等于 1(即,该事件之前未启用),则启用与给定引用计数条目关联的事件。如果该事件已启用(即,引用计数不等于 1),则检查用于启用的标志是否匹配,如果不匹配,则发出警告。
这不会修改引用计数本身,引用计数是通过 ssam_nf_refcount_inc()
/ ssam_nf_refcount_dec()
完成的。
注意
调用此函数时必须持有 nf->lock
。
返回
成功时返回零。如果此调用启用了该事件,则返回事件启用 EC 命令的状态。
-
int ssam_nf_refcount_disable_free(struct ssam_controller *ctrl, struct ssam_nf_refcount_entry *entry, u8 flags, bool ec)¶
如果引用计数条目不再使用,则禁用该事件并释放相应的条目。
参数
struct ssam_controller *ctrl
要禁用事件的控制器。
struct ssam_nf_refcount_entry *entry
要禁用事件的引用计数条目。
u8 flags
在 EC 上启用事件时使用的标志。
bool ec
一个标志,指定是否应该在 EC 上实际禁用事件。
描述
如果 ec
等于 true
且引用计数等于零(即,任何客户端不再请求该事件),则将通过相应的请求在 EC 上禁用指定的事件。
如果 ec
等于 false
,则不会向 EC 发送任何请求,并且该事件可以被视为处于分离状态(即,不再使用但仍处于启用状态)。对于热插拔设备,可能需要通过此方法禁用事件,在物理移除设备后,事件禁用请求可能会超时。
在这两种情况下,如果引用计数等于零,则将释放相应的引用计数条目。在调用此函数后,不得再使用引用计数条目。
还会检查用于禁用事件的标志是否与用于启用事件的标志匹配,如果不匹配,则发出警告(无论引用计数如何)。
这不会修改引用计数本身,引用计数是通过 ssam_nf_refcount_inc()
/ ssam_nf_refcount_dec()
完成的。
注意
调用此函数时必须持有 nf->lock
。
返回
成功时返回零。如果此调用禁用了该事件,则返回事件启用 EC 命令的状态。
-
int ssam_notifier_disable_registered(struct ssam_controller *ctrl)¶
禁用所有已注册通知器的事件。
参数
struct ssam_controller *ctrl
要为其禁用通知器/事件的控制器。
描述
禁用所有当前已注册通知器的事件。如果发生错误(EC 命令失败),则将恢复所有之前禁用的事件并返回错误代码。
此函数旨在在进入休眠之前禁用所有事件。请参阅 ssam_notifier_restore_registered()
以恢复/重新启用使用此函数禁用的所有事件。
请注意,此函数不会禁用在此函数调用之后注册的通知器的事件。因此,应确保在调用此函数之后和相应调用 ssam_notifier_restore_registered()
之前,不会添加新的通知器。
返回
成功时返回零。如果失败,则返回禁用事件的失败 EC 命令返回的错误代码。
-
void ssam_notifier_restore_registered(struct ssam_controller *ctrl)¶
恢复/重新启用所有已注册通知器的事件。
参数
struct ssam_controller *ctrl
要为其恢复通知器/事件的控制器。
描述
恢复/重新启用给定控制器上已注册通知器的所有事件。如果发生故障,则会记录错误,并且该函数会继续尝试启用其余事件。
此函数旨在恢复/重新启用休眠后所有已注册的事件。有关禁用事件的对应函数和更多详细信息,请参阅ssam_notifier_disable_registered()
。
-
bool ssam_notifier_is_empty(struct ssam_controller *ctrl)¶
检查是否有任何已注册的通知器。
参数
struct ssam_controller *ctrl
要检查的控制器。
返回
如果当前控制器上没有注册任何通知器,则返回 true
,否则返回 false
。
-
void ssam_notifier_unregister_all(struct ssam_controller *ctrl)¶
注销所有当前注册的通知器。
参数
struct ssam_controller *ctrl
要注销通知器的控制器。
描述
注销所有当前注册的通知器。此函数用于确保在关闭控制器时,所有通知器都将被注销,并且相关的条目/资源将被释放。
-
int ssam_irq_setup(struct ssam_controller *ctrl)¶
设置 SAM EC 唤醒 GPIO 中断。
参数
struct ssam_controller *ctrl
应为其设置 IRQ 的控制器。
描述
为 SAM EC 的唤醒 GPIO 引脚设置一个 IRQ。此 IRQ 可用于将设备从低功耗状态唤醒。
请注意,此 IRQ 只能在 EC 处于显示关闭状态时触发。在此状态下,事件不会以通常的方式发送到主机。相反,只要有待处理的事件,唤醒 GPIO 就会被拉高到“高”电平,并且这些事件需要通过 GPIO 回调请求逐个释放,直到没有剩余事件且 GPIO 复位,或者通过将 EC 转换为显示关闭状态之外的方式一次性释放所有事件,这也将清除 GPIO。
但是,并非所有事件都应触发完整的系统唤醒。相反,如有必要,驱动程序应检查并将每个事件转发到相应的子系统,然后由该子系统决定是否需要唤醒系统。此逻辑尚未实现,因此默认情况下应禁用此 IRQ 的唤醒,以避免由例如剩余电池百分比变化引起的虚假唤醒。有关如何实现此功能的更多详细信息,请参阅此函数中的注释以及相应的 IRQ 处理程序中的注释。
另请参阅ssam_ctrl_notif_display_off()
和 ssam_ctrl_notif_display_off()
,以了解将 EC 转换为显示关闭状态以及更多相关详细信息的函数。
默认情况下,IRQ 处于禁用状态,必须先通过 ssam_irq_arm_for_wakeup()
启用,然后才能从挂起状态唤醒设备。在拆卸时,应通过 ssam_irq_free()
释放 IRQ。
-
void ssam_irq_free(struct ssam_controller *ctrl)¶
释放 SAM EC 唤醒 GPIO 中断。
-
int ssam_irq_arm_for_wakeup(struct ssam_controller *ctrl)¶
如果启用,则为唤醒准备 EC IRQ。
参数
struct ssam_controller *ctrl
应准备 IRQ 的控制器。
描述
设置 IRQ,使其可用于唤醒设备。具体来说,此函数启用 irq,然后,如果允许设备唤醒系统,则调用 enable_irq_wake()。有关禁用 IRQ 的相应函数,请参阅 ssam_irq_disarm_wakeup()
。
此函数旨在在进入 S2idle 挂起之前准备 IRQ。
注意
对 ssam_irq_arm_for_wakeup()
和 ssam_irq_disarm_wakeup()
的调用必须平衡。
-
void ssam_irq_disarm_wakeup(struct ssam_controller *ctrl)¶
解除唤醒 IRQ 的准备。
参数
struct ssam_controller *ctrl
应解除 IRQ 准备的控制器。
描述
解除先前通过 ssam_irq_arm_for_wakeup()
设置的唤醒 IRQ。
此函数旨在在退出 S2idle 挂起后解除 IRQ 的准备。
注意
对 ssam_irq_arm_for_wakeup()
和 ssam_irq_disarm_wakeup()
的调用必须平衡。
客户端设备总线¶
-
bool ssam_device_id_compatible(const struct ssam_device_id *id, struct ssam_device_uid uid)¶
检查设备 ID 是否与 UID 匹配。
参数
const struct ssam_device_id *id
作为潜在匹配项的设备 ID。
struct ssam_device_uid uid
要匹配的设备 UID。
描述
检查给定的 ID 是否与给定的 UID 匹配,即具有所提供 UID 的设备是否与给定的 ID 兼容,遵循其 ssam_device_id.match_flags
成员中描述的匹配规则。
返回
如果给定的 UID 与给定的 ID 描述的匹配规则兼容,则返回 true
,否则返回 false
。
-
bool ssam_device_id_is_null(const struct ssam_device_id *id)¶
检查设备 ID 是否为空。
参数
const struct ssam_device_id *id
要检查的设备 ID。
描述
检查给定的设备 ID 是否为空,即全为零。用于检查 MODULE_DEVICE_TABLE(ssam, ...)
或类似列表的结尾。
返回
如果给定的 ID 表示空 ID,则返回 true
,否则返回 false
。
-
int ssam_bus_register(void)¶
注册并设置 SSAM 客户端设备总线。
参数
void
无参数
-
void ssam_bus_unregister(void)¶
注销 SSAM 客户端设备总线。
参数
void
无参数
核心¶
-
int ssam_try_set_controller(struct ssam_controller *ctrl)¶
尝试设置主控制器引用。
参数
struct ssam_controller *ctrl
该引用应指向的控制器。
描述
如果尚未设置主控制器引用,则将其设置为给定的指针。
返回
成功时返回零,如果已设置该引用,则返回 -EEXIST
。
-
void ssam_clear_controller(void)¶
移除/清除主控制器引用。
参数
void
无参数
描述
清除主控制器引用,即将其设置为 NULL
。应在关闭控制器之前调用此函数。
追踪辅助函数¶
-
void ssam_trace_ptr_uid(const void *ptr, char *uid_str)¶
将指针转换为非指针 UID 字符串。
参数
const void *ptr
要转换的指针。
char *uid_str
长度为 SSAM_PTR_UID_LEN 的缓冲区,UID 将存储在此处。
描述
将给定的指针转换为 UID 字符串,该字符串可以安全地与用户空间和日志共享,即不会泄露真实的内存位置。
-
u16 ssam_trace_get_packet_seq(const struct ssh_packet *p)¶
读取数据包的序列 ID。
参数
const struct ssh_packet *p
数据包。
返回
如果存在,则返回数据包的序列 ID (SEQ) 字段,否则返回 SSAM_SEQ_NOT_APPLICABLE
(例如,刷新数据包)。
-
u32 ssam_trace_get_request_id(const struct ssh_packet *p)¶
读取数据包的请求 ID。
参数
const struct ssh_packet *p
数据包。
返回
如果数据包表示带有命令数据的请求,则返回数据包的请求 ID (RQID) 字段,否则返回 SSAM_RQID_NOT_APPLICABLE
(例如,刷新请求、控制数据包)。
-
u32 ssam_trace_get_request_tid(const struct ssh_packet *p)¶
读取数据包的请求目标 ID。
参数
const struct ssh_packet *p
数据包。
返回
如果数据包表示带有命令数据的请求,则返回数据包的请求目标 ID (TID) 字段,否则返回 SSAM_SSH_TID_NOT_APPLICABLE
(例如,刷新请求、控制数据包)。
-
u32 ssam_trace_get_request_sid(const struct ssh_packet *p)¶
读取数据包的请求源 ID。
参数
const struct ssh_packet *p
数据包。
返回
如果数据包表示带有命令数据的请求,则返回数据包的请求源 ID (SID) 字段,否则返回 SSAM_SSH_TID_NOT_APPLICABLE
(例如,刷新请求、控制数据包)。
-
u32 ssam_trace_get_request_tc(const struct ssh_packet *p)¶
读取数据包的请求目标类别。
参数
const struct ssh_packet *p
数据包。
返回
如果数据包表示带有命令数据的请求,则返回数据包的请求目标类别 (TC) 字段,否则返回 SSAM_SSH_TC_NOT_APPLICABLE
(例如,刷新请求、控制数据包)。