]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/hptiop/hptiop.h
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / hptiop / hptiop.h
1 /*
2  * HighPoint RR3xxx/4xxx RAID Driver for FreeBSD
3  * Copyright (C) 2007-2008 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 MVIOP_IOCTLCFG_SIZE     0x800
119 #define MVIOP_MU_QUEUE_ADDR_HOST_MASK   (~(0x1full))
120 #define MVIOP_MU_QUEUE_ADDR_HOST_BIT    4
121
122 #define MVIOP_MU_QUEUE_ADDR_IOP_HIGH32  0xffffffff
123 #define MVIOP_MU_QUEUE_REQUEST_RESULT_BIT   1
124 #define MVIOP_MU_QUEUE_REQUEST_RETURN_CONTEXT 2
125
126 #define MVIOP_MU_INBOUND_INT_MSG        1
127 #define MVIOP_MU_INBOUND_INT_POSTQUEUE  2
128 #define MVIOP_MU_OUTBOUND_INT_MSG       1
129 #define MVIOP_MU_OUTBOUND_INT_POSTQUEUE 2
130
131 #define MVIOP_CMD_TYPE_GET_CONFIG (1 << 5)
132 #define MVIOP_CMD_TYPE_SET_CONFIG (1 << 6)
133 #define MVIOP_CMD_TYPE_SCSI (1 << 7)
134 #define MVIOP_CMD_TYPE_IOCTL (1 << 8)
135 #define MVIOP_CMD_TYPE_BLOCK (1 << 9)
136
137 #define MVIOP_REQUEST_NUMBER_START_BIT 16
138
139 enum hpt_iopmu_message {
140         /* host-to-iop messages */
141         IOPMU_INBOUND_MSG0_NOP = 0,
142         IOPMU_INBOUND_MSG0_RESET,
143         IOPMU_INBOUND_MSG0_FLUSH,
144         IOPMU_INBOUND_MSG0_SHUTDOWN,
145         IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
146         IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
147         IOPMU_INBOUND_MSG0_MAX = 0xff,
148         /* iop-to-host messages */
149         IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
150         IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff,
151         IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200,
152         IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff,
153         IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300,
154         IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff,
155 };
156
157 #define IOP_REQUEST_FLAG_SYNC_REQUEST 1
158 #define IOP_REQUEST_FLAG_BIST_REQUEST 2
159 #define IOP_REQUEST_FLAG_REMAPPED     4
160 #define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
161
162 enum hpt_iop_request_type {
163         IOP_REQUEST_TYPE_GET_CONFIG = 0,
164         IOP_REQUEST_TYPE_SET_CONFIG,
165         IOP_REQUEST_TYPE_BLOCK_COMMAND,
166         IOP_REQUEST_TYPE_SCSI_COMMAND,
167         IOP_REQUEST_TYPE_IOCTL_COMMAND,
168         IOP_REQUEST_TYPE_MAX
169 };
170
171 enum hpt_iop_result_type {
172         IOP_RESULT_PENDING = 0,
173         IOP_RESULT_SUCCESS,
174         IOP_RESULT_FAIL,
175         IOP_RESULT_BUSY,
176         IOP_RESULT_RESET,
177         IOP_RESULT_INVALID_REQUEST,
178         IOP_RESULT_BAD_TARGET,
179         IOP_RESULT_CHECK_CONDITION,
180 };
181
182 struct hpt_iop_request_header {
183         u_int32_t size;
184         u_int32_t type;
185         u_int32_t flags;
186         u_int32_t result;
187         u_int64_t context; /* host context */
188 };
189
190 struct hpt_iop_request_get_config {
191         struct hpt_iop_request_header header;
192         u_int32_t interface_version;
193         u_int32_t firmware_version;
194         u_int32_t max_requests;
195         u_int32_t request_size;
196         u_int32_t max_sg_count;
197         u_int32_t data_transfer_length;
198         u_int32_t alignment_mask;
199         u_int32_t max_devices;
200         u_int32_t sdram_size;
201 };
202
203 struct hpt_iop_request_set_config {
204         struct hpt_iop_request_header header;
205         u_int32_t iop_id;
206         u_int16_t vbus_id;
207         u_int16_t max_host_request_size;
208         u_int32_t reserve[6];
209 };
210
211 struct hpt_iopsg {
212         u_int32_t size;
213         u_int32_t eot; /* non-zero: end of table */
214         u_int64_t pci_address;
215 };
216
217 #define IOP_BLOCK_COMMAND_READ     1
218 #define IOP_BLOCK_COMMAND_WRITE    2
219 #define IOP_BLOCK_COMMAND_VERIFY   3
220 #define IOP_BLOCK_COMMAND_FLUSH    4
221 #define IOP_BLOCK_COMMAND_SHUTDOWN 5
222 struct hpt_iop_request_block_command {
223         struct hpt_iop_request_header header;
224         u_int8_t     channel;
225         u_int8_t     target;
226         u_int8_t     lun;
227         u_int8_t     pad1;
228         u_int16_t    command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */
229         u_int16_t    sectors;
230         u_int64_t    lba;
231         struct hpt_iopsg sg_list[1];
232 };
233
234 struct hpt_iop_request_scsi_command {
235         struct hpt_iop_request_header header;
236         u_int8_t     channel;
237         u_int8_t     target;
238         u_int8_t     lun;
239         u_int8_t     pad1;
240         u_int8_t     cdb[16];
241         u_int32_t    dataxfer_length;
242         struct hpt_iopsg sg_list[1];
243 };
244
245 struct hpt_iop_request_ioctl_command {
246         struct hpt_iop_request_header header;
247         u_int32_t    ioctl_code;
248         u_int32_t    inbuf_size;
249         u_int32_t    outbuf_size;
250         u_int32_t    bytes_returned;
251         u_int8_t     buf[1];
252         /* out data should be put at buf[(inbuf_size+3)&~3] */
253 };
254
255 struct hpt_iop_ioctl_param {
256         u_int32_t        Magic;                 /* used to check if it's a valid ioctl packet */
257         u_int32_t        dwIoControlCode;       /* operation control code */
258         unsigned long    lpInBuffer;            /* input data buffer */
259         u_int32_t        nInBufferSize;         /* size of input data buffer */
260         unsigned long    lpOutBuffer;           /* output data buffer */
261         u_int32_t        nOutBufferSize;        /* size of output data buffer */
262         unsigned long    lpBytesReturned;       /* count of HPT_U8s returned */
263 } __packed;
264
265 #define HPT_IOCTL_FLAG_OPEN 1
266 #define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00)
267
268 #if __FreeBSD_version>503000
269 typedef struct cdev * ioctl_dev_t;
270 #else
271 typedef dev_t ioctl_dev_t;
272 #endif
273
274 #if __FreeBSD_version >= 500000
275 typedef struct thread * ioctl_thread_t;
276 #else
277 typedef struct proc * ioctl_thread_t;
278 #endif
279
280 struct hpt_iop_hba {
281         struct hptiop_adapter_ops *ops;
282         union {
283                 struct {
284                         struct hpt_iopmu_itl *mu;
285                 } itl;
286                 struct {
287                         struct hpt_iopmv_regs *regs;
288                         struct hpt_iopmu_mv *mu;
289                 } mv;
290         } u;
291         
292         struct hpt_iop_hba    *next;
293         
294         u_int32_t             firmware_version;
295         u_int32_t             interface_version;
296         u_int32_t             max_devices;
297         u_int32_t             max_requests;
298         u_int32_t             max_request_size;
299         u_int32_t             max_sg_count;
300
301         u_int32_t             msg_done;
302
303         device_t              pcidev;
304         u_int32_t             pciunit;
305         ioctl_dev_t           ioctl_dev;
306
307         bus_dma_tag_t         parent_dmat;
308         bus_dma_tag_t         io_dmat;
309         bus_dma_tag_t         srb_dmat;
310         bus_dma_tag_t         ctlcfg_dmat;
311         
312         bus_dmamap_t          srb_dmamap;
313         bus_dmamap_t          ctlcfg_dmamap;
314
315         struct resource       *bar0_res;
316         bus_space_tag_t       bar0t;
317         bus_space_handle_t    bar0h;
318         int                   bar0_rid;
319
320         struct resource       *bar2_res;
321         bus_space_tag_t       bar2t;
322         bus_space_handle_t    bar2h;
323         int                   bar2_rid;
324         
325         /* to release */
326         u_int8_t              *uncached_ptr;
327         void                  *ctlcfg_ptr;
328         /* for scsi request block */
329         struct hpt_iop_srb    *srb_list;
330         /* for interrupt */
331         struct resource       *irq_res;
332         void                  *irq_handle;
333
334         /* for ioctl and set/get config */
335         struct resource       *ctlcfg_res;
336         void                  *ctlcfg_handle;
337         u_int64_t             ctlcfgcmd_phy;
338         u_int32_t             config_done;
339
340         /* other resources */
341         struct cam_sim        *sim;
342         struct cam_path       *path;
343         void                  *req;
344 #if (__FreeBSD_version >= 500000)
345         struct mtx            lock;
346 #else
347         int                   hpt_splx;
348 #endif
349 #define HPT_IOCTL_FLAG_OPEN     1
350         u_int32_t             flag;
351         struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE];
352 };
353
354 struct hptiop_adapter_ops {
355         int  (*iop_wait_ready)(struct hpt_iop_hba *hba, u_int32_t millisec);
356         int  (*internal_memalloc)(struct hpt_iop_hba *hba);
357         int  (*internal_memfree)(struct hpt_iop_hba *hba);
358         int  (*alloc_pci_res)(struct hpt_iop_hba *hba);
359         void (*release_pci_res)(struct hpt_iop_hba *hba);
360         void (*enable_intr)(struct hpt_iop_hba *hba);
361         void (*disable_intr)(struct hpt_iop_hba *hba);
362         int  (*get_config)(struct hpt_iop_hba *hba,
363                                 struct hpt_iop_request_get_config *config);
364         int  (*set_config)(struct hpt_iop_hba *hba,
365                                 struct hpt_iop_request_set_config *config);
366         int  (*iop_intr)(struct hpt_iop_hba *hba);
367         void (*post_msg)(struct hpt_iop_hba *hba, u_int32_t msg);
368         void (*post_req)(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs);
369         int (*do_ioctl)(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param * pParams); 
370 };
371
372 struct hpt_iop_srb {
373         u_int8_t             req[HPT_SRB_MAX_REQ_SIZE];
374         struct hpt_iop_hba   *hba;
375         union ccb            *ccb;
376         struct hpt_iop_srb   *next;
377         bus_dmamap_t         dma_map;
378         u_int64_t            phy_addr;
379         u_int32_t            srb_flag;
380         int                  index;
381 };
382
383 #if __FreeBSD_version >= 500000
384 #define hptiop_lock_adapter(hba)   mtx_lock(&(hba)->lock)
385 #define hptiop_unlock_adapter(hba) mtx_unlock(&(hba)->lock)
386 #else
387 static __inline void hptiop_lock_adapter(struct hpt_iop_hba *hba)
388 {
389         hba->hpt_splx = splcam();
390 }
391 static __inline void hptiop_unlock_adapter(struct hpt_iop_hba *hba)
392 {
393         splx(hba->hpt_splx);
394 }
395 #endif
396
397 #define HPT_OSM_TIMEOUT (20*hz)  /* timeout value for OS commands */
398
399 #define HPT_DO_IOCONTROL    _IOW('H', 0, struct hpt_iop_ioctl_param)
400 #define HPT_SCAN_BUS        _IO('H', 1)
401
402 static  __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident,
403                                 int priority, const char *wmesg, int timo)
404 {
405
406         int retval;
407
408 #if __FreeBSD_version >= 500000
409         retval = msleep(ident, &hba->lock, priority, wmesg, timo);
410 #else
411         asleep(ident, priority, wmesg, timo);
412         hptiop_unlock_adapter(hba);
413         retval = await(priority, timo);
414         hptiop_lock_adapter(hba);
415 #endif
416
417         return retval;
418
419 }
420
421 #if __FreeBSD_version < 501000
422 #define READ_16             0x88
423 #define WRITE_16            0x8a
424 #define SERVICE_ACTION_IN   0x9e
425 #endif
426
427 #define HPT_DEV_MAJOR   200
428
429 #endif
430