cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

notif-wait.h (2894B)


      1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
      2/*
      3 * Copyright (C) 2005-2014 Intel Corporation
      4 * Copyright (C) 2015-2017 Intel Deutschland GmbH
      5 */
      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	5
     20
     21/**
     22 * struct iwl_notification_wait - notification wait entry
     23 * @list: list head for global list
     24 * @fn: Function called with the notification. If the function
     25 *	returns true, the wait is over, if it returns false then
     26 *	the waiter stays blocked. If no function is given, any
     27 *	of the listed commands will unblock the waiter.
     28 * @cmds: command IDs
     29 * @n_cmds: number of command IDs
     30 * @triggered: waiter should be woken up
     31 * @aborted: wait was aborted
     32 *
     33 * This structure is not used directly, to wait for a
     34 * notification declare it on the stack, and call
     35 * iwl_init_notification_wait() with appropriate
     36 * parameters. Then do whatever will cause the ucode
     37 * to notify the driver, and to wait for that then
     38 * call iwl_wait_notification().
     39 *
     40 * Each notification is one-shot. If at some point we
     41 * need to support multi-shot notifications (which
     42 * can't be allocated on the stack) we need to modify
     43 * the code for them.
     44 */
     45struct iwl_notification_wait {
     46	struct list_head list;
     47
     48	bool (*fn)(struct iwl_notif_wait_data *notif_data,
     49		   struct iwl_rx_packet *pkt, void *data);
     50	void *fn_data;
     51
     52	u16 cmds[MAX_NOTIF_CMDS];
     53	u8 n_cmds;
     54	bool triggered, aborted;
     55};
     56
     57
     58/* caller functions */
     59void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data);
     60bool iwl_notification_wait(struct iwl_notif_wait_data *notif_data,
     61			   struct iwl_rx_packet *pkt);
     62void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data);
     63
     64static inline void
     65iwl_notification_notify(struct iwl_notif_wait_data *notif_data)
     66{
     67	wake_up_all(&notif_data->notif_waitq);
     68}
     69
     70static inline void
     71iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
     72			     struct iwl_rx_packet *pkt)
     73{
     74	if (iwl_notification_wait(notif_data, pkt))
     75		iwl_notification_notify(notif_data);
     76}
     77
     78/* user functions */
     79void __acquires(wait_entry)
     80iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data,
     81			   struct iwl_notification_wait *wait_entry,
     82			   const u16 *cmds, int n_cmds,
     83			   bool (*fn)(struct iwl_notif_wait_data *notif_data,
     84				      struct iwl_rx_packet *pkt, void *data),
     85			   void *fn_data);
     86
     87int __must_check __releases(wait_entry)
     88iwl_wait_notification(struct iwl_notif_wait_data *notif_data,
     89		      struct iwl_notification_wait *wait_entry,
     90		      unsigned long timeout);
     91
     92void __releases(wait_entry)
     93iwl_remove_notification(struct iwl_notif_wait_data *notif_data,
     94			struct iwl_notification_wait *wait_entry);
     95
     96#endif /* __iwl_notif_wait_h__ */