Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
0002 /*
0003  * Copyright (C) 2005-2014 Intel Corporation
0004  * Copyright (C) 2015-2017 Intel Deutschland GmbH
0005  */
0006 #ifndef __iwl_notif_wait_h__
0007 #define __iwl_notif_wait_h__
0008 
0009 #include <linux/wait.h>
0010 
0011 #include "iwl-trans.h"
0012 
0013 struct iwl_notif_wait_data {
0014     struct list_head notif_waits;
0015     spinlock_t notif_wait_lock;
0016     wait_queue_head_t notif_waitq;
0017 };
0018 
0019 #define MAX_NOTIF_CMDS  5
0020 
0021 /**
0022  * struct iwl_notification_wait - notification wait entry
0023  * @list: list head for global list
0024  * @fn: Function called with the notification. If the function
0025  *  returns true, the wait is over, if it returns false then
0026  *  the waiter stays blocked. If no function is given, any
0027  *  of the listed commands will unblock the waiter.
0028  * @cmds: command IDs
0029  * @n_cmds: number of command IDs
0030  * @triggered: waiter should be woken up
0031  * @aborted: wait was aborted
0032  *
0033  * This structure is not used directly, to wait for a
0034  * notification declare it on the stack, and call
0035  * iwl_init_notification_wait() with appropriate
0036  * parameters. Then do whatever will cause the ucode
0037  * to notify the driver, and to wait for that then
0038  * call iwl_wait_notification().
0039  *
0040  * Each notification is one-shot. If at some point we
0041  * need to support multi-shot notifications (which
0042  * can't be allocated on the stack) we need to modify
0043  * the code for them.
0044  */
0045 struct iwl_notification_wait {
0046     struct list_head list;
0047 
0048     bool (*fn)(struct iwl_notif_wait_data *notif_data,
0049            struct iwl_rx_packet *pkt, void *data);
0050     void *fn_data;
0051 
0052     u16 cmds[MAX_NOTIF_CMDS];
0053     u8 n_cmds;
0054     bool triggered, aborted;
0055 };
0056 
0057 
0058 /* caller functions */
0059 void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data);
0060 bool iwl_notification_wait(struct iwl_notif_wait_data *notif_data,
0061                struct iwl_rx_packet *pkt);
0062 void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data);
0063 
0064 static inline void
0065 iwl_notification_notify(struct iwl_notif_wait_data *notif_data)
0066 {
0067     wake_up_all(&notif_data->notif_waitq);
0068 }
0069 
0070 static inline void
0071 iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
0072                  struct iwl_rx_packet *pkt)
0073 {
0074     if (iwl_notification_wait(notif_data, pkt))
0075         iwl_notification_notify(notif_data);
0076 }
0077 
0078 /* user functions */
0079 void __acquires(wait_entry)
0080 iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data,
0081                struct iwl_notification_wait *wait_entry,
0082                const u16 *cmds, int n_cmds,
0083                bool (*fn)(struct iwl_notif_wait_data *notif_data,
0084                       struct iwl_rx_packet *pkt, void *data),
0085                void *fn_data);
0086 
0087 int __must_check __releases(wait_entry)
0088 iwl_wait_notification(struct iwl_notif_wait_data *notif_data,
0089               struct iwl_notification_wait *wait_entry,
0090               unsigned long timeout);
0091 
0092 void __releases(wait_entry)
0093 iwl_remove_notification(struct iwl_notif_wait_data *notif_data,
0094             struct iwl_notification_wait *wait_entry);
0095 
0096 #endif /* __iwl_notif_wait_h__ */