^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __LIBSRP_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __LIBSRP_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kfifo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <scsi/srp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) enum srp_valid {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) INVALIDATE_CMD_RESP_EL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) VALID_CMD_RESP_EL = 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) VALID_INIT_MSG = 0xC0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) VALID_TRANS_EVENT = 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) enum srp_format {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) SRP_FORMAT = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) MAD_FORMAT = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) OS400_FORMAT = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) AIX_FORMAT = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) LINUX_FORMAT = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) MESSAGE_IN_CRQ = 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) enum srp_init_msg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) INIT_MSG = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) INIT_COMPLETE_MSG = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) enum srp_trans_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) UNUSED_FORMAT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) PARTNER_FAILED = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) PARTNER_DEREGISTER = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MIGRATED = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) PREPARE_FOR_SUSPEND = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) RESUME_FROM_SUSP = 0xA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) enum srp_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) CRQ_ENTRY_OVERWRITTEN = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) HEADER_DESCRIPTOR = 0xF1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) PING = 0xF5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) PING_RESPONSE = 0xF6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) enum srp_mad_version {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) MAD_VERSION_1 = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) enum srp_os_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) OS400 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) LINUX = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) AIX = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) OFW = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) enum srp_task_attributes {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) SRP_SIMPLE_TASK = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) SRP_HEAD_TASK = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) SRP_ORDERED_TASK = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) SRP_ACA_TASK = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) SRP_TASK_MANAGEMENT_FUNCTION_COMPLETE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) SRP_REQUEST_FIELDS_INVALID = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) SRP_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) SRP_TASK_MANAGEMENT_FUNCTION_FAILED = 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct srp_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) dma_addr_t dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct srp_queue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) void *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) void *items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct kfifo queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct srp_target {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct list_head cmd_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) size_t srp_iu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct srp_queue iu_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) size_t rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct srp_buf **rx_ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) void *ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct iu_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct srp_target *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct list_head ilist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) dma_addr_t remote_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct srp_buf *sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u16 iu_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct ibmvscsis_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) typedef int (srp_rdma_t)(struct ibmvscsis_cmd *, struct scatterlist *, int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct srp_direct_buf *, int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) enum dma_data_direction, unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int srp_target_alloc(struct srp_target *, struct device *, size_t, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) void srp_target_free(struct srp_target *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct iu_entry *srp_iu_get(struct srp_target *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void srp_iu_put(struct iu_entry *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int srp_transfer_data(struct ibmvscsis_cmd *, struct srp_cmd *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) srp_rdma_t, int, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u64 srp_data_length(struct srp_cmd *cmd, enum dma_data_direction dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int srp_get_desc_table(struct srp_cmd *srp_cmd, enum dma_data_direction *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u64 *data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static inline int srp_cmd_direction(struct srp_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #endif