/* * include/scst_event.h * * Copyright (C) 2014 - 2018 Western Digital Corporation * * Contains constants and data structures for scst_event module. */ #ifndef __SCST_EVENT_H #define __SCST_EVENT_H #ifdef __KERNEL__ #include #endif #ifdef INSIDE_KERNEL_TREE #include #else #include "scst_const.h" #endif #define SCST_EVENT_NAME "scst_event" #define SCST_EVENT_PATH "/dev/" #define SCST_EVENT_DEV SCST_EVENT_PATH SCST_EVENT_NAME #define SCST_EVENT_VERSION_NAME SCST_VERSION_NAME #define SCST_EVENT_VERSION \ SCST_EVENT_VERSION_NAME "$Revision: 2454 $" SCST_CONST_VERSION #ifndef aligned_u64 #define aligned_u64 uint64_t __attribute__((aligned(8))) #endif /* * Due to variable size, this structure must always be last in any outer * structure! */ struct scst_event { int32_t payload_len; uint32_t event_code; uint32_t event_id; /* ID uniquely identifying this event */ /* * Event's issuer's name, i.e. SCST name of the corresponding module * (target driver or dev handler). SCST_EVENT_SCST_CORE_ISSUER for SCST * core. */ char issuer_name[SCST_MAX_NAME]; uint8_t payload[]; /* event's payload */ }; #ifdef __KERNEL__ typedef void (*scst_event_done_notify_fn) (struct scst_event *event, void *priv, int status); struct scst_event_entry { struct list_head events_list_entry; scst_event_done_notify_fn event_notify_fn; void *notify_fn_priv; unsigned long event_timeout; /* in jiffies */ int *pqueued_events_cnt; union { struct work_struct scst_event_queue_work; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) struct work_struct event_timeout_work; #else struct delayed_work event_timeout_work; #endif }; struct scst_event event; /* event's payload */ }; #endif struct scst_event_user { int32_t max_event_size; struct scst_event out_event; }; struct scst_event_notify_done { uint32_t event_id; int status; }; /* IOCTLs */ #define SCST_EVENT_ALLOW_EVENT _IOW('u', 1, struct scst_event) #define SCST_EVENT_DISALLOW_EVENT _IOW('u', 2, struct scst_event) #define SCST_EVENT_GET_NEXT_EVENT _IOWR('u', 3, struct scst_event_user) #define SCST_EVENT_NOTIFY_DONE _IOW('u', 4, struct scst_event_notify_done) #ifdef __KERNEL__ void scst_event_queue(uint32_t event_code, const char *issuer_name, struct scst_event_entry *e); #endif /************************************************************* ** SCST events *************************************************************/ /* SCST core issuer name */ #define SCST_EVENT_SCST_CORE_ISSUER "SCST core" /** SCST core's events **/ #define SCST_EVENT_LUN_NOT_FOUND 1 struct scst_event_lun_not_found_payload { aligned_u64 lun; uint8_t initiator_name[SCST_MAX_EXTERNAL_NAME]; uint8_t target_name[SCST_MAX_EXTERNAL_NAME]; }; #define SCST_EVENT_NEGATIVE_LUNS_INQUIRY 2 struct scst_event_negative_luns_inquiry_payload { uint8_t initiator_name[SCST_MAX_EXTERNAL_NAME]; uint8_t target_name[SCST_MAX_EXTERNAL_NAME]; }; #define SCST_EVENT_EXT_BLOCKING_DONE 3 struct scst_event_ext_blocking_done_payload { uint8_t device_name[SCST_MAX_EXTERNAL_NAME]; uint32_t data_len; uint8_t data[]; }; #define SCST_EVENT_TM_FN_RECEIVED 4 struct scst_event_tm_fn_received_payload { uint32_t fn; /* TM fn */ aligned_u64 lun; uint8_t device_name[SCST_MAX_EXTERNAL_NAME]; uint8_t initiator_name[SCST_MAX_EXTERNAL_NAME]; uint8_t target_name[SCST_MAX_EXTERNAL_NAME]; uint8_t session_sysfs_name[SCST_MAX_EXTERNAL_NAME]; struct { /* if ABORT TASK, then tag and CDB of cmd to abort */ aligned_u64 cmd_to_abort_tag; uint8_t cdb[SCST_MAX_CDB_SIZE]; }; }; #define SCST_EVENT_STPG_USER_INVOKE 5 struct scst_event_stpg_descr { uint16_t group_id; /* * Better to keep below fields as small as possible to fit * in single page as many descriptors as possible. */ uint8_t prev_state[32]; uint8_t new_state[32]; uint8_t dg_name[64]; uint8_t tg_name[64]; }; struct scst_event_stpg_payload { aligned_u64 stpg_cmd_tag; uint8_t device_name[64]; uint16_t stpg_descriptors_cnt; struct scst_event_stpg_descr stpg_descriptors[0]; }; #endif /* __SCST_EVENT_H */