]>
Commit | Line | Data |
---|---|---|
c21e0bbf MO |
1 | /* |
2 | * CXL Flash Device Driver | |
3 | * | |
4 | * Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation | |
5 | * Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation | |
6 | * | |
7 | * Copyright (C) 2015 IBM Corporation | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License | |
11 | * as published by the Free Software Foundation; either version | |
12 | * 2 of the License, or (at your option) any later version. | |
13 | */ | |
14 | ||
15 | #ifndef _CXLFLASH_COMMON_H | |
16 | #define _CXLFLASH_COMMON_H | |
17 | ||
18 | #include <linux/list.h> | |
19 | #include <linux/types.h> | |
20 | #include <scsi/scsi.h> | |
21 | #include <scsi/scsi_device.h> | |
22 | ||
23 | ||
24 | #define MAX_CONTEXT CXLFLASH_MAX_CONTEXT /* num contexts per afu */ | |
25 | ||
26 | #define CXLFLASH_BLOCK_SIZE 4096 /* 4K blocks */ | |
27 | #define CXLFLASH_MAX_XFER_SIZE 16777216 /* 16MB transfer */ | |
28 | #define CXLFLASH_MAX_SECTORS (CXLFLASH_MAX_XFER_SIZE/512) /* SCSI wants | |
29 | max_sectors | |
30 | in units of | |
31 | 512 byte | |
32 | sectors | |
33 | */ | |
34 | ||
35 | #define NUM_RRQ_ENTRY 16 /* for master issued cmds */ | |
36 | #define MAX_RHT_PER_CONTEXT (PAGE_SIZE / sizeof(struct sisl_rht_entry)) | |
37 | ||
38 | /* AFU command retry limit */ | |
39 | #define MC_RETRY_CNT 5 /* sufficient for SCSI check and | |
40 | certain AFU errors */ | |
41 | ||
42 | /* Command management definitions */ | |
43 | #define CXLFLASH_NUM_CMDS (2 * CXLFLASH_MAX_CMDS) /* Must be a pow2 for | |
44 | alignment and more | |
45 | efficient array | |
46 | index derivation | |
47 | */ | |
48 | ||
49 | #define CXLFLASH_MAX_CMDS 16 | |
50 | #define CXLFLASH_MAX_CMDS_PER_LUN CXLFLASH_MAX_CMDS | |
51 | ||
52 | ||
53 | static inline void check_sizes(void) | |
54 | { | |
55 | BUILD_BUG_ON_NOT_POWER_OF_2(CXLFLASH_NUM_CMDS); | |
56 | } | |
57 | ||
58 | /* AFU defines a fixed size of 4K for command buffers (borrow 4K page define) */ | |
59 | #define CMD_BUFSIZE SIZE_4K | |
60 | ||
61 | /* flags in IOA status area for host use */ | |
62 | #define B_DONE 0x01 | |
63 | #define B_ERROR 0x02 /* set with B_DONE */ | |
64 | #define B_TIMEOUT 0x04 /* set with B_DONE & B_ERROR */ | |
65 | ||
66 | enum cxlflash_lr_state { | |
67 | LINK_RESET_INVALID, | |
68 | LINK_RESET_REQUIRED, | |
69 | LINK_RESET_COMPLETE | |
70 | }; | |
71 | ||
72 | enum cxlflash_init_state { | |
73 | INIT_STATE_NONE, | |
74 | INIT_STATE_PCI, | |
75 | INIT_STATE_AFU, | |
76 | INIT_STATE_SCSI | |
77 | }; | |
78 | ||
5cdac81a MO |
79 | enum cxlflash_state { |
80 | STATE_NORMAL, /* Normal running state, everything good */ | |
81 | STATE_LIMBO, /* Limbo running state, trying to reset/recover */ | |
82 | STATE_FAILTERM /* Failed/terminating state, error out users/threads */ | |
83 | }; | |
84 | ||
c21e0bbf MO |
85 | /* |
86 | * Each context has its own set of resource handles that is visible | |
87 | * only from that context. | |
88 | */ | |
89 | ||
90 | struct cxlflash_cfg { | |
91 | struct afu *afu; | |
92 | struct cxl_context *mcctx; | |
93 | ||
94 | struct pci_dev *dev; | |
95 | struct pci_device_id *dev_id; | |
96 | struct Scsi_Host *host; | |
97 | ||
98 | ulong cxlflash_regs_pci; | |
99 | ||
c21e0bbf MO |
100 | struct work_struct work_q; |
101 | enum cxlflash_init_state init_state; | |
102 | enum cxlflash_lr_state lr_state; | |
103 | int lr_port; | |
104 | ||
105 | struct cxl_afu *cxl_afu; | |
106 | ||
107 | struct pci_pool *cxlflash_cmd_pool; | |
108 | struct pci_dev *parent_dev; | |
109 | ||
65be2c79 MO |
110 | atomic_t recovery_threads; |
111 | struct mutex ctx_recovery_mutex; | |
112 | struct mutex ctx_tbl_list_mutex; | |
113 | struct ctx_info *ctx_tbl[MAX_CONTEXT]; | |
114 | struct list_head ctx_err_recovery; /* contexts w/ recovery pending */ | |
115 | struct file_operations cxl_fops; | |
116 | ||
117 | atomic_t num_user_contexts; | |
118 | ||
2cb79266 MO |
119 | /* Parameters that are LUN table related */ |
120 | int last_lun_index[CXLFLASH_NUM_FC_PORTS]; | |
121 | int promote_lun_index; | |
65be2c79 MO |
122 | struct list_head lluns; /* list of llun_info structs */ |
123 | ||
c21e0bbf MO |
124 | wait_queue_head_t tmf_waitq; |
125 | bool tmf_active; | |
5cdac81a MO |
126 | wait_queue_head_t limbo_waitq; |
127 | enum cxlflash_state state; | |
c21e0bbf MO |
128 | }; |
129 | ||
130 | struct afu_cmd { | |
131 | struct sisl_ioarcb rcb; /* IOARCB (cache line aligned) */ | |
132 | struct sisl_ioasa sa; /* IOASA must follow IOARCB */ | |
133 | spinlock_t slock; | |
134 | struct completion cevent; | |
135 | char *buf; /* per command buffer */ | |
136 | struct afu *parent; | |
137 | int slot; | |
138 | atomic_t free; | |
139 | ||
140 | u8 cmd_tmf:1; | |
141 | ||
142 | /* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned. | |
143 | * However for performance reasons the IOARCB/IOASA should be | |
144 | * cache line aligned. | |
145 | */ | |
146 | } __aligned(cache_line_size()); | |
147 | ||
148 | struct afu { | |
149 | /* Stuff requiring alignment go first. */ | |
150 | ||
151 | u64 rrq_entry[NUM_RRQ_ENTRY]; /* 128B RRQ */ | |
152 | /* | |
153 | * Command & data for AFU commands. | |
154 | */ | |
155 | struct afu_cmd cmd[CXLFLASH_NUM_CMDS]; | |
156 | ||
157 | /* Beware of alignment till here. Preferably introduce new | |
158 | * fields after this point | |
159 | */ | |
160 | ||
161 | /* AFU HW */ | |
162 | struct cxl_ioctl_start_work work; | |
163 | struct cxlflash_afu_map *afu_map; /* entire MMIO map */ | |
164 | struct sisl_host_map *host_map; /* MC host map */ | |
165 | struct sisl_ctrl_map *ctrl_map; /* MC control map */ | |
166 | ||
167 | ctx_hndl_t ctx_hndl; /* master's context handle */ | |
168 | u64 *hrrq_start; | |
169 | u64 *hrrq_end; | |
170 | u64 *hrrq_curr; | |
171 | bool toggle; | |
172 | bool read_room; | |
173 | atomic64_t room; | |
174 | u64 hb; | |
175 | u32 cmd_couts; /* Number of command checkouts */ | |
176 | u32 internal_lun; /* User-desired LUN mode for this AFU */ | |
177 | ||
178 | char version[8]; | |
179 | u64 interface_version; | |
180 | ||
181 | struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */ | |
182 | ||
183 | }; | |
184 | ||
185 | static inline u64 lun_to_lunid(u64 lun) | |
186 | { | |
187 | u64 lun_id; | |
188 | ||
189 | int_to_scsilun(lun, (struct scsi_lun *)&lun_id); | |
190 | return swab64(lun_id); | |
191 | } | |
192 | ||
193 | int cxlflash_send_cmd(struct afu *, struct afu_cmd *); | |
194 | void cxlflash_wait_resp(struct afu *, struct afu_cmd *); | |
195 | int cxlflash_afu_reset(struct cxlflash_cfg *); | |
196 | struct afu_cmd *cxlflash_cmd_checkout(struct afu *); | |
197 | void cxlflash_cmd_checkin(struct afu_cmd *); | |
198 | int cxlflash_afu_sync(struct afu *, ctx_hndl_t, res_hndl_t, u8); | |
65be2c79 MO |
199 | void cxlflash_list_init(void); |
200 | void cxlflash_term_global_luns(void); | |
201 | void cxlflash_free_errpage(void); | |
202 | int cxlflash_ioctl(struct scsi_device *, int, void __user *); | |
203 | void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *); | |
204 | int cxlflash_mark_contexts_error(struct cxlflash_cfg *); | |
205 | void cxlflash_term_local_luns(struct cxlflash_cfg *); | |
2cb79266 | 206 | void cxlflash_restore_luntable(struct cxlflash_cfg *); |
65be2c79 | 207 | |
c21e0bbf | 208 | #endif /* ifndef _CXLFLASH_COMMON_H */ |