98 lines · c
1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */2/*3 * Copyright (C) 2005-2014, 2023 Intel Corporation4 * Copyright (C) 2015-2017 Intel Deutschland GmbH5 */6#ifndef __iwl_notif_wait_h__7#define __iwl_notif_wait_h__8 9#include <linux/wait.h>10 11#include "iwl-trans.h"12 13struct iwl_notif_wait_data {14 struct list_head notif_waits;15 spinlock_t notif_wait_lock;16 wait_queue_head_t notif_waitq;17};18 19#define MAX_NOTIF_CMDS 520 21/**22 * struct iwl_notification_wait - notification wait entry23 * @list: list head for global list24 * @fn: Function called with the notification. If the function25 * returns true, the wait is over, if it returns false then26 * the waiter stays blocked. If no function is given, any27 * of the listed commands will unblock the waiter.28 * @fn_data: pointer to pass to the @fn's data argument29 * @cmds: command IDs30 * @n_cmds: number of command IDs31 * @triggered: waiter should be woken up32 * @aborted: wait was aborted33 *34 * This structure is not used directly, to wait for a35 * notification declare it on the stack, and call36 * iwl_init_notification_wait() with appropriate37 * parameters. Then do whatever will cause the ucode38 * to notify the driver, and to wait for that then39 * call iwl_wait_notification().40 *41 * Each notification is one-shot. If at some point we42 * need to support multi-shot notifications (which43 * can't be allocated on the stack) we need to modify44 * the code for them.45 */46struct iwl_notification_wait {47 struct list_head list;48 49 bool (*fn)(struct iwl_notif_wait_data *notif_data,50 struct iwl_rx_packet *pkt, void *data);51 void *fn_data;52 53 u16 cmds[MAX_NOTIF_CMDS];54 u8 n_cmds;55 bool triggered, aborted;56};57 58 59/* caller functions */60void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data);61bool iwl_notification_wait(struct iwl_notif_wait_data *notif_data,62 struct iwl_rx_packet *pkt);63void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data);64 65static inline void66iwl_notification_notify(struct iwl_notif_wait_data *notif_data)67{68 wake_up_all(¬if_data->notif_waitq);69}70 71static inline void72iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,73 struct iwl_rx_packet *pkt)74{75 if (iwl_notification_wait(notif_data, pkt))76 iwl_notification_notify(notif_data);77}78 79/* user functions */80void __acquires(wait_entry)81iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data,82 struct iwl_notification_wait *wait_entry,83 const u16 *cmds, int n_cmds,84 bool (*fn)(struct iwl_notif_wait_data *notif_data,85 struct iwl_rx_packet *pkt, void *data),86 void *fn_data);87 88int __must_check __releases(wait_entry)89iwl_wait_notification(struct iwl_notif_wait_data *notif_data,90 struct iwl_notification_wait *wait_entry,91 unsigned long timeout);92 93void __releases(wait_entry)94iwl_remove_notification(struct iwl_notif_wait_data *notif_data,95 struct iwl_notification_wait *wait_entry);96 97#endif /* __iwl_notif_wait_h__ */98