]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/hptiop/hptiop.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / hptiop / hptiop.h
1 /*
2  * HighPoint RR3xxx/4xxx RAID Driver for FreeBSD
3  * Copyright (C) 2007-2012 HighPoint Technologies, Inc. All Rights Reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 #ifndef _HPTIOP_H
27 #define _HPTIOP_H
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #define DBG 0
33
34 #ifdef DBG
35 int hpt_iop_dbg_level = 0;
36 #define KdPrint(x)  do { if (hpt_iop_dbg_level) printf x; } while (0)
37 #define HPT_ASSERT(x) assert(x)
38 #else
39 #define KdPrint(x)
40 #define HPT_ASSERT(x)
41 #endif
42
43 #define HPT_SRB_MAX_REQ_SIZE                600
44 #define HPT_SRB_MAX_QUEUE_SIZE              0x100
45
46 /* beyond 64G mem */
47 #define HPT_SRB_FLAG_HIGH_MEM_ACESS         0x1
48 #define HPT_SRB_MAX_SIZE  ((sizeof(struct hpt_iop_srb) + 0x1f) & ~0x1f)
49 #ifndef offsetof
50 #define offsetof(TYPE, MEM) ((size_t)&((TYPE*)0)->MEM)
51 #endif
52
53 #ifndef MIN
54 #define MIN(a, b)               ((a) < (b) ? (a) : (b))
55 #endif
56
57 #define HPT_IOCTL_MAGIC   0xA1B2C3D4
58 #define HPT_IOCTL_MAGIC32   0x1A2B3C4D
59
60 struct hpt_iopmu_itl {
61         u_int32_t resrved0[4];
62         u_int32_t inbound_msgaddr0;
63         u_int32_t inbound_msgaddr1;
64         u_int32_t outbound_msgaddr0;
65         u_int32_t outbound_msgaddr1;
66         u_int32_t inbound_doorbell;
67         u_int32_t inbound_intstatus;
68         u_int32_t inbound_intmask;
69         u_int32_t outbound_doorbell;
70         u_int32_t outbound_intstatus;
71         u_int32_t outbound_intmask;
72         u_int32_t reserved1[2];
73         u_int32_t inbound_queue;
74         u_int32_t outbound_queue;
75 };
76
77 #define IOPMU_QUEUE_EMPTY            0xffffffff
78 #define IOPMU_QUEUE_MASK_HOST_BITS   0xf0000000
79 #define IOPMU_QUEUE_ADDR_HOST_BIT    0x80000000
80 #define IOPMU_QUEUE_REQUEST_SIZE_BIT    0x40000000
81 #define IOPMU_QUEUE_REQUEST_RESULT_BIT   0x40000000
82 #define IOPMU_MAX_MEM_SUPPORT_MASK_64G 0xfffffff000000000ull
83 #define IOPMU_MAX_MEM_SUPPORT_MASK_32G 0xfffffff800000000ull
84
85 #define IOPMU_OUTBOUND_INT_MSG0      1
86 #define IOPMU_OUTBOUND_INT_MSG1      2
87 #define IOPMU_OUTBOUND_INT_DOORBELL  4
88 #define IOPMU_OUTBOUND_INT_POSTQUEUE 8
89 #define IOPMU_OUTBOUND_INT_PCI       0x10
90
91 #define IOPMU_INBOUND_INT_MSG0       1
92 #define IOPMU_INBOUND_INT_MSG1       2
93 #define IOPMU_INBOUND_INT_DOORBELL   4
94 #define IOPMU_INBOUND_INT_ERROR      8
95 #define IOPMU_INBOUND_INT_POSTQUEUE  0x10
96
97 #define MVIOP_QUEUE_LEN  512
98 struct hpt_iopmu_mv {
99         u_int32_t inbound_head;
100         u_int32_t inbound_tail;
101         u_int32_t outbound_head;
102         u_int32_t outbound_tail;
103         u_int32_t inbound_msg;
104         u_int32_t outbound_msg;
105         u_int32_t reserve[10];
106         u_int64_t inbound_q[MVIOP_QUEUE_LEN];
107         u_int64_t outbound_q[MVIOP_QUEUE_LEN];
108 };
109
110 struct hpt_iopmv_regs {
111         u_int32_t reserved[0x20400 / 4];
112         u_int32_t inbound_doorbell;
113         u_int32_t inbound_intmask;
114         u_int32_t outbound_doorbell;
115         u_int32_t outbound_intmask;
116 };
117
118 #define CL_POINTER_TOGGLE        0x00004000
119 #define CPU_TO_F0_DRBL_MSG_A_BIT 0x02000000
120
121 #pragma pack(1)
122 struct hpt_iopmu_mvfrey {
123         u_int32_t reserved[0x4000 / 4];
124
125         /* hpt_frey_com_reg */
126         u_int32_t inbound_base; /* 0x4000 : 0 */
127         u_int32_t inbound_base_high; /* 4 */
128         u_int32_t reserved2[(0x18 - 8)/ 4];
129         u_int32_t inbound_write_ptr; /* 0x18 */
130         u_int32_t inbound_read_ptr; /* 0x1c */
131         u_int32_t reserved3[(0x2c - 0x20) / 4];
132         u_int32_t inbound_conf_ctl; /* 0x2c */
133         u_int32_t reserved4[(0x50 - 0x30) / 4];
134         u_int32_t outbound_base; /* 0x50 */
135         u_int32_t outbound_base_high; /* 0x54 */
136         u_int32_t outbound_shadow_base; /* 0x58 */
137         u_int32_t outbound_shadow_base_high; /* 0x5c */
138         u_int32_t reserved5[(0x68 - 0x60) / 4];
139         u_int32_t outbound_write; /* 0x68 */
140         u_int32_t reserved6[(0x70 - 0x6c) / 4];
141         u_int32_t outbound_read; /* 0x70 */
142         u_int32_t reserved7[(0x88 - 0x74) / 4];
143         u_int32_t isr_cause; /* 0x88 */
144         u_int32_t isr_enable; /* 0x8c */
145
146         u_int32_t reserved8[(0x10200 - 0x4090) / 4];
147
148         /* hpt_frey_intr_ctl intr_ctl */
149         u_int32_t main_int_cuase; /* 0x10200: 0 */
150         u_int32_t main_irq_enable; /* 4 */
151         u_int32_t main_fiq_enable; /* 8 */
152         u_int32_t pcie_f0_int_enable; /* 0xc */
153         u_int32_t pcie_f1_int_enable; /* 0x10 */
154         u_int32_t pcie_f2_int_enable; /* 0x14 */
155         u_int32_t pcie_f3_int_enable; /* 0x18 */
156
157         u_int32_t reserved9[(0x10400 - 0x1021c) / 4];
158
159         /* hpt_frey_msg_drbl */
160         u_int32_t f0_to_cpu_msg_a; /* 0x10400: 0 */
161         u_int32_t reserved10[(0x20 - 4) / 4];
162         u_int32_t cpu_to_f0_msg_a; /* 0x20 */
163         u_int32_t reserved11[(0x80 - 0x24) / 4];
164         u_int32_t f0_doorbell; /* 0x80 */
165         u_int32_t f0_doorbell_enable; /* 0x84 */
166 };
167
168 struct mvfrey_inlist_entry {
169         u_int64_t addr;
170         u_int32_t intrfc_len;
171         u_int32_t reserved;
172 };
173
174 struct mvfrey_outlist_entry {
175         u_int32_t val;
176 };
177
178 #pragma pack()
179
180 #define MVIOP_IOCTLCFG_SIZE     0x800
181 #define MVIOP_MU_QUEUE_ADDR_HOST_MASK   (~(0x1full))
182 #define MVIOP_MU_QUEUE_ADDR_HOST_BIT    4
183
184 #define MVIOP_MU_QUEUE_ADDR_IOP_HIGH32  0xffffffff
185 #define MVIOP_MU_QUEUE_REQUEST_RESULT_BIT   1
186 #define MVIOP_MU_QUEUE_REQUEST_RETURN_CONTEXT 2
187
188 #define MVIOP_MU_INBOUND_INT_MSG        1
189 #define MVIOP_MU_INBOUND_INT_POSTQUEUE  2
190 #define MVIOP_MU_OUTBOUND_INT_MSG       1
191 #define MVIOP_MU_OUTBOUND_INT_POSTQUEUE 2
192
193 #define MVIOP_CMD_TYPE_GET_CONFIG (1 << 5)
194 #define MVIOP_CMD_TYPE_SET_CONFIG (1 << 6)
195 #define MVIOP_CMD_TYPE_SCSI (1 << 7)
196 #define MVIOP_CMD_TYPE_IOCTL (1 << 8)
197 #define MVIOP_CMD_TYPE_BLOCK (1 << 9)
198
199 #define MVIOP_REQUEST_NUMBER_START_BIT 16
200
201 #define MVFREYIOPMU_QUEUE_REQUEST_RESULT_BIT   0x40000000
202
203 enum hpt_iopmu_message {
204         /* host-to-iop messages */
205         IOPMU_INBOUND_MSG0_NOP = 0,
206         IOPMU_INBOUND_MSG0_RESET,
207         IOPMU_INBOUND_MSG0_FLUSH,
208         IOPMU_INBOUND_MSG0_SHUTDOWN,
209         IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
210         IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
211         IOPMU_INBOUND_MSG0_RESET_COMM,
212         IOPMU_INBOUND_MSG0_MAX = 0xff,
213         /* iop-to-host messages */
214         IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
215         IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff,
216         IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200,
217         IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff,
218         IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300,
219         IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff,
220 };
221
222 #define IOP_REQUEST_FLAG_SYNC_REQUEST 1
223 #define IOP_REQUEST_FLAG_BIST_REQUEST 2
224 #define IOP_REQUEST_FLAG_REMAPPED     4
225 #define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
226
227 #define IOP_REQUEST_FLAG_ADDR_BITS 0x40 /* flags[31:16] is phy_addr[47:32] */
228
229 enum hpt_iop_request_type {
230         IOP_REQUEST_TYPE_GET_CONFIG = 0,
231         IOP_REQUEST_TYPE_SET_CONFIG,
232         IOP_REQUEST_TYPE_BLOCK_COMMAND,
233         IOP_REQUEST_TYPE_SCSI_COMMAND,
234         IOP_REQUEST_TYPE_IOCTL_COMMAND,
235         IOP_REQUEST_TYPE_MAX
236 };
237
238 enum hpt_iop_result_type {
239         IOP_RESULT_PENDING = 0,
240         IOP_RESULT_SUCCESS,
241         IOP_RESULT_FAIL,
242         IOP_RESULT_BUSY,
243         IOP_RESULT_RESET,
244         IOP_RESULT_INVALID_REQUEST,
245         IOP_RESULT_BAD_TARGET,
246         IOP_RESULT_CHECK_CONDITION,
247 };
248
249 #pragma pack(1)
250 struct hpt_iop_request_header {
251         u_int32_t size;
252         u_int32_t type;
253         u_int32_t flags;
254         u_int32_t result;
255         u_int64_t context; /* host context */
256 };
257
258 struct hpt_iop_request_get_config {
259         struct hpt_iop_request_header header;
260         u_int32_t interface_version;
261         u_int32_t firmware_version;
262         u_int32_t max_requests;
263         u_int32_t request_size;
264         u_int32_t max_sg_count;
265         u_int32_t data_transfer_length;
266         u_int32_t alignment_mask;
267         u_int32_t max_devices;
268         u_int32_t sdram_size;
269 };
270
271 struct hpt_iop_request_set_config {
272         struct hpt_iop_request_header header;
273         u_int32_t iop_id;
274         u_int16_t vbus_id;
275         u_int16_t max_host_request_size;
276         u_int32_t reserve[6];
277 };
278
279 struct hpt_iopsg {
280         u_int32_t size;
281         u_int32_t eot; /* non-zero: end of table */
282         u_int64_t pci_address;
283 };
284
285 #define IOP_BLOCK_COMMAND_READ     1
286 #define IOP_BLOCK_COMMAND_WRITE    2
287 #define IOP_BLOCK_COMMAND_VERIFY   3
288 #define IOP_BLOCK_COMMAND_FLUSH    4
289 #define IOP_BLOCK_COMMAND_SHUTDOWN 5
290 struct hpt_iop_request_block_command {
291         struct hpt_iop_request_header header;
292         u_int8_t     channel;
293         u_int8_t     target;
294         u_int8_t     lun;
295         u_int8_t     pad1;
296         u_int16_t    command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */
297         u_int16_t    sectors;
298         u_int64_t    lba;
299         struct hpt_iopsg sg_list[1];
300 };
301
302 struct hpt_iop_request_scsi_command {
303         struct hpt_iop_request_header header;
304         u_int8_t     channel;
305         u_int8_t     target;
306         u_int8_t     lun;
307         u_int8_t     pad1;
308         u_int8_t     cdb[16];
309         u_int32_t    dataxfer_length;
310         struct hpt_iopsg sg_list[1];
311 };
312
313 struct hpt_iop_request_ioctl_command {
314         struct hpt_iop_request_header header;
315         u_int32_t    ioctl_code;
316         u_int32_t    inbuf_size;
317         u_int32_t    outbuf_size;
318         u_int32_t    bytes_returned;
319         u_int8_t     buf[1];
320         /* out data should be put at buf[(inbuf_size+3)&~3] */
321 };
322
323 struct hpt_iop_ioctl_param {
324         u_int32_t        Magic;                 /* used to check if it's a valid ioctl packet */
325         u_int32_t        dwIoControlCode;       /* operation control code */
326         unsigned long    lpInBuffer;            /* input data buffer */
327         u_int32_t        nInBufferSize;         /* size of input data buffer */
328         unsigned long    lpOutBuffer;           /* output data buffer */
329         u_int32_t        nOutBufferSize;        /* size of output data buffer */
330         unsigned long    lpBytesReturned;       /* count of HPT_U8s returned */
331 } __packed;
332
333 #define HPT_IOCTL_FLAG_OPEN 1
334 #define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00)
335
336 typedef struct cdev * ioctl_dev_t;
337
338 typedef struct thread * ioctl_thread_t;
339
340 struct hpt_iop_hba {
341         struct hptiop_adapter_ops *ops;
342         union {
343                 struct {
344                         struct hpt_iopmu_itl *mu;
345                 } itl;
346                 struct {
347                         struct hpt_iopmv_regs *regs;
348                         struct hpt_iopmu_mv *mu;
349                 } mv;
350                 struct {
351                         struct hpt_iop_request_get_config *config;
352                         struct hpt_iopmu_mvfrey *mu;
353
354                         int internal_mem_size;
355                         int list_count;
356                         struct mvfrey_inlist_entry *inlist;
357                         u_int64_t inlist_phy;
358                         u_int32_t inlist_wptr;
359                         struct mvfrey_outlist_entry *outlist;
360                         u_int64_t outlist_phy;
361                         u_int32_t *outlist_cptr; /* copy pointer shadow */
362                         u_int64_t outlist_cptr_phy;
363                         u_int32_t outlist_rptr;
364                 } mvfrey;
365         } u;
366         
367         struct hpt_iop_hba    *next;
368         
369         u_int32_t             firmware_version;
370         u_int32_t             interface_version;
371         u_int32_t             max_devices;
372         u_int32_t             max_requests;
373         u_int32_t             max_request_size;
374         u_int32_t             max_sg_count;
375
376         u_int32_t             msg_done;
377
378         device_t              pcidev;
379         u_int32_t             pciunit;
380         ioctl_dev_t           ioctl_dev;
381
382         bus_dma_tag_t         parent_dmat;
383         bus_dma_tag_t         io_dmat;
384         bus_dma_tag_t         srb_dmat;
385         bus_dma_tag_t         ctlcfg_dmat;
386         
387         bus_dmamap_t          srb_dmamap;
388         bus_dmamap_t          ctlcfg_dmamap;
389
390         struct resource       *bar0_res;
391         bus_space_tag_t       bar0t;
392         bus_space_handle_t    bar0h;
393         int                   bar0_rid;
394
395         struct resource       *bar2_res;
396         bus_space_tag_t       bar2t;
397         bus_space_handle_t    bar2h;
398         int                   bar2_rid;
399         
400         /* to release */
401         u_int8_t              *uncached_ptr;
402         void                  *ctlcfg_ptr;
403         /* for scsi request block */
404         struct hpt_iop_srb    *srb_list;
405         /* for interrupt */
406         struct resource       *irq_res;
407         void                  *irq_handle;
408
409         /* for ioctl and set/get config */
410         struct resource       *ctlcfg_res;
411         void                  *ctlcfg_handle;
412         u_int64_t             ctlcfgcmd_phy;
413         u_int32_t             config_done; /* can be negative value */
414         u_int32_t             initialized:1;
415
416         /* other resources */
417         struct cam_sim        *sim;
418         struct cam_path       *path;
419         void                  *req;
420         struct mtx            lock;
421 #define HPT_IOCTL_FLAG_OPEN     1
422         u_int32_t             flag;
423         struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE];
424 };
425 #pragma pack()
426
427 enum hptiop_family {
428         INTEL_BASED_IOP = 0,
429         MV_BASED_IOP,
430         MVFREY_BASED_IOP,
431         UNKNOWN_BASED_IOP = 0xf
432 };
433
434 struct hptiop_adapter_ops {
435         enum hptiop_family family;
436         int  (*iop_wait_ready)(struct hpt_iop_hba *hba, u_int32_t millisec);
437         int  (*internal_memalloc)(struct hpt_iop_hba *hba);
438         int  (*internal_memfree)(struct hpt_iop_hba *hba);
439         int  (*alloc_pci_res)(struct hpt_iop_hba *hba);
440         void (*release_pci_res)(struct hpt_iop_hba *hba);
441         void (*enable_intr)(struct hpt_iop_hba *hba);
442         void (*disable_intr)(struct hpt_iop_hba *hba);
443         int  (*get_config)(struct hpt_iop_hba *hba,
444                                 struct hpt_iop_request_get_config *config);
445         int  (*set_config)(struct hpt_iop_hba *hba,
446                                 struct hpt_iop_request_set_config *config);
447         int  (*iop_intr)(struct hpt_iop_hba *hba);
448         void (*post_msg)(struct hpt_iop_hba *hba, u_int32_t msg);
449         void (*post_req)(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs);
450         int (*do_ioctl)(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param * pParams);
451         int (*reset_comm)(struct hpt_iop_hba *hba);
452 };
453
454 struct hpt_iop_srb {
455         u_int8_t             req[HPT_SRB_MAX_REQ_SIZE];
456         struct hpt_iop_hba   *hba;
457         union ccb            *ccb;
458         struct hpt_iop_srb   *next;
459         bus_dmamap_t         dma_map;
460         u_int64_t            phy_addr;
461         u_int32_t            srb_flag;
462         int                  index;
463         struct callout_handle   timeout_ch;
464 };
465
466 #define hptiop_lock_adapter(hba)   mtx_lock(&(hba)->lock)
467 #define hptiop_unlock_adapter(hba) mtx_unlock(&(hba)->lock)
468
469 #define HPT_OSM_TIMEOUT (20*hz)  /* timeout value for OS commands */
470
471 #define HPT_DO_IOCONTROL    _IOW('H', 0, struct hpt_iop_ioctl_param)
472 #define HPT_SCAN_BUS        _IO('H', 1)
473
474 static  __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident,
475                                 int priority, const char *wmesg, int timo)
476 {
477
478         int retval;
479
480         retval = msleep(ident, &hba->lock, priority, wmesg, timo);
481
482         return retval;
483
484 }
485
486
487 #define HPT_DEV_MAJOR   200
488
489 #endif
490