From Erik Habbinga:
[mirror/scst/.git] / mpt / mpt_scst.h
1 #ifndef __MPT_SCST_H
2 #define __MPT_SCST_H
3
4 #if defined(MODULE) && !defined(__GENKSYMS__)
5 #include <linux/config.h>
6 #include <linux/module.h>
7 #endif
8
9 #ifdef __linux__
10 #include <linux/delay.h>
11 #include <linux/errno.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/miscdevice.h>
16 #include <linux/proc_fs.h>
17 #include <linux/smp_lock.h>
18 #include <linux/highmem.h>
19
20 #include <asm/uaccess.h>
21 #include <asm/io.h>
22 #include <asm/div64.h>
23 #endif
24
25 #define _HS_SLEEP ,0
26 #define _IOC_ID ioc
27 #define _HANDLE_IOC_ID ioc
28
29 #ifndef MPT_STM_64_BIT_DMA  /* determines the size of DMA addresses */
30 #define MPT_STM_64_BIT_DMA 1
31 #endif
32
33 #include "linux_compat.h"
34 #include "mptbase.h"
35
36 #ifndef MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED
37 #define MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED 0x24000002
38 #endif
39
40 #define MF_TO_INDEX(mf) le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx)
41
42 #include "scsi3.h"
43
44 /*****************************************************************************/
45 #ifdef MPI_STM_IO_DEBUG
46 #define dioprintk printk
47 #else
48 #define dioprintk printk
49 #endif
50
51 typedef MPI_TARGET_FCP_CMD_BUFFER FCP_CMD;
52
53 typedef MPI_TARGET_SCSI_SPI_CMD_BUFFER SCSI_CMD;
54
55 #define SSP_CMD_FRAME           0x06
56 #define SSP_TASK_FRAME          0x16
57
58 typedef MPI_TARGET_SSP_CMD_BUFFER SSP_CMD;
59 typedef MPI_TARGET_SSP_TASK_BUFFER SSP_TASK;
60
61 #define FCP_REQUEST_CONFIRM     (1<<4)
62 #define FCP_RESID_UNDER         (1<<3)
63 #define FCP_RESID_OVER          (1<<2)
64 #define FCP_SENSE_LEN_VALID     (1<<1)
65 #define FCP_RSP_LEN_VALID       (1<<0)
66
67 typedef struct _FCP_RSP  /* this struct is wrong in rev 1.02.04 of mpi_targ.h */
68 {
69     U8      Reserved0[8];                               /* 00h */
70     U8      Reserved1[2];                               /* 08h */
71     U8      FcpFlags;                                   /* 0Ah */
72     U8      FcpStatus;                                  /* 0Bh */
73     U32     FcpResid;                                   /* 0Ch */
74     U32     FcpSenseLength;                             /* 10h */
75     U32     FcpResponseLength;                          /* 14h */
76     U8      FcpResponseData[8];                         /* 18h */
77     U8      FcpSenseData[32]; /* Pad to 64 bytes */     /* 20h */
78 } FCP_RSP;
79
80 #define SCSI_SENSE_LEN_VALID    (1<<1)
81 #define SCSI_RSP_LEN_VALID      (1<<0)
82
83 typedef MPI_TARGET_SCSI_SPI_STATUS_IU SCSI_RSP;
84
85 #define SSP_SENSE_LEN_VALID     (1<<1)
86 #define SSP_RSP_LEN_VALID       (1<<0)
87
88 typedef MPI_TARGET_SSP_RSP_IU SSP_RSP;
89
90
91 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
92
93 /*
94  *  Fusion MPT STM private structures
95  */
96
97 #define IsFc(priv)      \
98     (priv->ioc->pfacts[0].PortType == MPI_PORTFACTS_PORTTYPE_FC)
99 #define IsScsi(priv)    \
100     (priv->ioc->pfacts[0].PortType == MPI_PORTFACTS_PORTTYPE_SCSI)
101 #define IsSas(priv)    \
102     (priv->ioc->pfacts[0].PortType == MPI_PORTFACTS_PORTTYPE_SAS)
103
104 #define ABORT_ALL               (-1)
105
106 #define NUM_CMD_BUFFERS         128
107 #define NUM_ELS_BUFFERS         64
108
109 #define NUM_ALIASES             0  /* 0 to 125, hardware restriction */
110
111 #define ELS                     0x22
112 #define FC4LS                   0x32
113 #define ABTS                    0x81
114 #define BA_ACC                  0x84
115
116 #define LS_RJT                  0x01
117 #define LS_ACC                  0x02
118 #define PLOGI                   0x03
119 #define LOGO                    0x05
120 #define SRR                     0x14
121 #define PRLI                    0x20
122 #define PRLO                    0x21
123 #define ADISC                   0x52
124 #define RSCN                    0x61
125
126 typedef struct _MPT_SGE
127 {
128     u32                 length;
129 #if MPT_STM_64_BIT_DMA
130     u64                 address;
131 #else
132     u32                 address;
133 #endif
134 } MPT_SGE;
135
136 #define NUM_SGES        64
137 #define NUM_CHAINS      (NUM_SGES/8)    /* one chain for every 8 SGEs */
138
139 typedef struct _CMD {
140     u8                  cmd[64];
141     u8                  rsp[64];
142     MPT_SGE             chain_sge[NUM_SGES+NUM_CHAINS];
143     u32                 reply_word;
144     int                 alias;
145     int                 lun;
146     int                 tag;
147 } CMD;
148
149 typedef struct _FC_ELS {
150     u32                 fc_els[32];
151 } FC_ELS;
152
153 typedef struct _MPT_STM_HW {
154     CMD                 cmd_buf[NUM_CMD_BUFFERS];
155     FC_ELS              fc_link_serv_buf[NUM_ELS_BUFFERS];
156     u32                 config_buf[256];
157     u32                 ctsend_buf[256];
158     u32                 exlink_buf[32];
159 } MPT_STM_HW;
160
161 typedef struct _MPT_SGL
162 {
163     u32                 num_sges;
164     MPT_SGE             sge[NUM_SGES];
165 } MPT_SGL;
166
167 typedef struct _MPT_STM_PRIV
168 {
169     MPT_ADAPTER         *ioc;
170     int                 enable_target_mode;
171     int                 fcp2_capable;
172     int                 num_sge_chain;
173     int                 num_sge_target_assist;
174     int                 num_cmd_buffers;
175     int                 num_els_buffers;
176     int                 num_aliases;
177     MPT_STM_HW          *hw;
178     dma_addr_t          hw_dma;
179     U64                 wwnn;
180     U64                 wwpn;
181     int                 port_id;
182     int                 scsi_port_config;
183     int                 scsi_id_config;
184     int                 protocol;
185     volatile int        port_flags;
186     volatile int        port_speed;
187     volatile int        port_state;
188     volatile int        device_changed;
189     int                 port_enable_loginfo;
190     volatile int        port_enable_pending;
191     volatile int        target_mode_abort_pending;
192     volatile int        link_serv_abort_pending;
193     volatile int        fc_primitive_send_pending;
194     volatile int        ex_link_service_send_pending;
195     volatile int        config_pending;
196     volatile int        in_reset;
197     volatile int        poll_enabled;
198     volatile int        exiting;
199     MPT_FRAME_HDR       *config_mf;
200     ConfigReply_t       config_rep;
201     volatile int        io_state[NUM_CMD_BUFFERS];
202     volatile int        els_state[NUM_ELS_BUFFERS];
203     MPT_FRAME_HDR       *current_mf[NUM_CMD_BUFFERS];
204     MPT_FRAME_HDR       *status_deferred_mf[NUM_CMD_BUFFERS];
205     MPT_SGL             sgl;
206     SCSIPortPage0_t SCSIPortPage0;
207     SCSIPortPage1_t SCSIPortPage1;
208     SCSIPortPage2_t SCSIPortPage2;
209 #define NUM_SCSI_DEVICES       16
210     SCSIDevicePage1_t SCSIDevicePage1[NUM_SCSI_DEVICES];
211     struct mpt_tgt *tgt;
212     struct scst_cmd *scst_cmd[NUM_CMD_BUFFERS];
213     atomic_t pending_sense[NUM_SCSI_DEVICES];
214     u8 pending_sense_buffer[NUM_SCSI_DEVICES][SCSI_SENSE_BUFFERSIZE];
215 } MPT_STM_PRIV;
216
217 #define IO_STATE_POSTED                 0x1
218 #define IO_STATE_DATA_SENT              0x2
219 #define IO_STATE_STATUS_SENT            0x4
220 #define IO_STATE_STATUS_DEFERRED        0x8
221 #define IO_STATE_INCOMPLETE             0x10
222 #define IO_STATE_AUTO_REPOST            0x20
223 #define IO_STATE_ABORTED                0x40
224 #define IO_STATE_HIGH_PRIORITY          0x80
225 #define IO_STATE_REQUEST_ABORTED        0x100
226 #define IO_STATE_REISSUE_REQUEST        0x200
227 #define IO_STATE_ADJUST_OFFSET          0x400
228 #define IO_STATE_CONVERT_TA_TO_TSS      0x800
229 #define IO_STATE_REDO_COMMAND           0x1000
230
231 #define get2bytes(x, y) ((x[y] << 8) + x[y+1])
232 #define get3bytes(x, y) ((x[y] << 16) + (x[y+1] << 8) + x[y+2])
233 #define get4bytes(x, y) ((x[y] << 24) + (x[y+1] << 16) + (x[y+2] << 8) + x[y+3])
234 #define get8bytes(x, y) (((u64)get4bytes(x, y) << 32) + get4bytes(x, y+4))
235
236 #define InitiatorIndex_0100 Reserved_0100_InitiatorIndex
237 #define FWVersion_0101 Reserved_0101_FWVersion
238 #define EventDataSasPhyLinkStatus_t MpiEventDataSasPhyLinkStatus_t
239
240 #ifndef MPI_FCPORTPAGE1_FLAGS_FORCE_USE_NOSEEPROM_WWNS 
241 #define MPI_FCPORTPAGE1_FLAGS_FORCE_USE_NOSEEPROM_WWNS  (0x02000000)
242 #endif
243
244 #ifndef PRIORITY_REASON_TARGET_BUSY
245 #define PRIORITY_REASON_TARGET_BUSY             (0x09)
246 #endif
247
248 #if MPT_STM_64_BIT_DMA
249 #define MPT_STM_SIMPLE SGESimple64_t
250 #define MPT_STM_CHAIN SGEChain64_t
251 #define MPI_SGE_FLAGS_MPT_STM_ADDRESSING MPI_SGE_FLAGS_64_BIT_ADDRESSING
252 #define stm_get_dma_addr(x, y)                \
253     x = le32_to_cpu(y.Low);                   \
254     if (sizeof(dma_addr_t) == sizeof(u64))    \
255         x |= (u64)le32_to_cpu(y.High)<<32;
256 #define stm_set_dma_addr(x, y)                \
257     x.Low = cpu_to_le32(y);                   \
258     if (sizeof(dma_addr_t) == sizeof(u64))    \
259         x.High = cpu_to_le32((u64)y>>32);     \
260     else                                      \
261         x.High = 0;
262 #else
263 #define MPT_STM_SIMPLE SGESimple32_t
264 #define MPT_STM_CHAIN SGEChain32_t
265 #define MPI_SGE_FLAGS_MPT_STM_ADDRESSING MPI_SGE_FLAGS_32_BIT_ADDRESSING
266 #define stm_get_dma_addr(x, y)                \
267     x = le32_to_cpu(y);
268 #define stm_set_dma_addr(x, y)                \
269     x = cpu_to_le32(y);
270 #endif
271
272 #ifndef MPT_MAX_ADAPTERS
273 #define MPT_MAX_ADAPTERS 18
274 #endif
275
276 #ifndef MPI_MANUFACTPAGE_DEVICEID_FC949X
277 #define MPI_MANUFACTPAGE_DEVICEID_FC949X 0x640
278 #endif
279 #ifndef MPI_MANUFACTPAGE_DEVICEID_FC939X
280 #define MPI_MANUFACTPAGE_DEVICEID_FC939X 0x642
281 #endif
282
283 #ifndef MPI_IOCSTATUS_EEDP_GUARD_ERROR
284 #define MPI_IOCSTATUS_EEDP_GUARD_ERROR 0x4d
285 #endif
286 #ifndef MPI_IOCSTATUS_EEDP_REF_TAG_ERROR
287 #define MPI_IOCSTATUS_EEDP_REF_TAG_ERROR 0x4e
288 #endif
289 #ifndef MPI_IOCSTATUS_EEDP_APP_TAG_ERROR
290 #define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR 0x4f
291 #endif
292
293 #define MPT_MAX_CDB_LEN 16
294 #define MPT_TIMEOUT 30
295
296 /* Immediate notify status constants */
297 #define IMM_NTFY_LIP_RESET          MPI_EVENT_LOOP_STATE_CHANGE
298 #define IMM_NTFY_IOCB_OVERFLOW      0x0016
299 #define IMM_NTFY_ABORT_TASK         0x0020
300 #define IMM_NTFY_PORT_LOGOUT        MPI_EVENT_LOGOUT
301 #define IMM_NTFY_PORT_CONFIG        MPI_EVENT_LINK_STATUS_CHANGE
302 #define IMM_NTFY_GLBL_TPRLO         MPI_EVENT_LINK_STATUS_CHANGE
303 #define IMM_NTFY_GLBL_LOGO          MPI_EVENT_LINK_STATUS_CHANGE
304 #define IMM_NTFY_RESOURCE           0x0034
305 #define IMM_NTFY_MSG_RX             0x0036
306
307 /* Immediate notify task flags */
308 #define IMM_NTFY_ABORT_TS           0x01
309 #define IMM_NTFY_CLEAR_TS           0x04
310 #define IMM_NTFY_LUN_RESET1         0x08
311 #define IMM_NTFY_LUN_RESET2         0x10
312 #define IMM_NTFY_TARGET_RESET       0x20
313 #define IMM_NTFY_CLEAR_ACA          0x40
314
315 /* Command's states */
316 #define MPT_STATE_NEW              1    /* New command and SCST processes it */
317 #define MPT_STATE_NEED_DATA        2    /* SCST needs data to process */
318 #define MPT_STATE_DATA_IN          3    /* Data arrived and SCST processes it */
319 #define MPT_STATE_DATA_OUT         4
320 #define MPT_STATE_PROCESSED        5    /* SCST done processing */
321
322 /* Target's flags */
323 #define MPT_TGT_SHUTDOWN            0   /* The driver is being released */
324 #define MPT_TGT_ENABLE_64BIT_ADDR   1   /* 64-bits PCI addressing anables */
325
326 /* Session's flags */
327 #define MPT_SESS_INITING            0   /* The session is being unregistered */
328 #define MPT_SESS_SHUTDOWN           1   /* The session is being unregistered */
329
330 /* pending sense states */
331 #define MPT_STATUS_SENSE_IDLE      0 /* no cached pending sense */
332 #define MPT_STATUS_SENSE_ATTEMPT   1 /* attempt to send status and sense */
333 #define MPT_STATUS_SENSE_NOT_SENT  2 /* sense couldn't be sent with status */
334 #define MPT_STATUS_SENSE_HANDLE_RQ 3 /* REQUEST SENSE handled with cached sense */
335
336 struct mpt_cmd 
337 {
338         struct mpt_sess *sess;
339         struct scst_cmd *scst_cmd;
340         MPT_STM_PRIV *priv;
341         CMD *CMD;
342         u32 reply_word;
343         struct list_head delayed_cmds_entry;
344         int state;
345         dma_addr_t dma_handle;
346 };
347
348 struct mpt_sess 
349 {
350         struct scst_session *scst_sess;
351         struct mpt_tgt *tgt;
352         int init_index;
353         unsigned long sess_flags;
354         struct list_head delayed_cmds;
355 };
356
357 struct mpt_tgt
358 {
359         struct scst_tgt *scst_tgt;
360         MPT_STM_PRIV *priv;
361         int datasegs_per_cmd, datasegs_per_cont;
362         unsigned long tgt_flags;
363         atomic_t sess_count;
364         wait_queue_head_t waitQ;
365         struct mpt_sess *sess[256];
366         int target_enable;
367 };
368
369 struct mpt_mgmt_cmd
370 {
371         struct mpt_sess *sess;
372         int task_mgmt;
373 };
374         
375 #endif