xref: /dragonfly/sys/dev/raid/hptiop/hptiop.h (revision 4353aa4e)
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  * $FreeBSD: src/sys/dev/hptiop/hptiop.h,v 1.5 2009/03/25 06:27:56 delphij Exp $
26  */
27 
28 #ifndef _HPTIOP_H
29 #define _HPTIOP_H
30 
31 #define DBG 0
32 
33 #ifdef DBG
34 int hpt_iop_dbg_level = 0;
35 #define KdPrint(x)  do { if (hpt_iop_dbg_level) kprintf x; } while (0)
36 #else
37 #define KdPrint(x)
38 #endif
39 
40 #define HPT_SRB_MAX_REQ_SIZE                600
41 #define HPT_SRB_MAX_QUEUE_SIZE              0x100
42 
43 /* beyond 64G mem */
44 #define HPT_SRB_FLAG_HIGH_MEM_ACESS         0x1
45 #define HPT_SRB_MAX_SIZE  ((sizeof(struct hpt_iop_srb) + 0x1f) & ~0x1f)
46 #ifndef offsetof
47 #define offsetof(TYPE, MEM) ((size_t)&((TYPE*)0)->MEM)
48 #endif
49 
50 #ifndef MIN
51 #define MIN(a, b)		((a) < (b) ? (a) : (b))
52 #endif
53 
54 #define HPT_IOCTL_MAGIC   0xA1B2C3D4
55 #define HPT_IOCTL_MAGIC32   0x1A2B3C4D
56 
57 struct hpt_iopmu_itl {
58 	u_int32_t resrved0[4];
59 	u_int32_t inbound_msgaddr0;
60 	u_int32_t inbound_msgaddr1;
61 	u_int32_t outbound_msgaddr0;
62 	u_int32_t outbound_msgaddr1;
63 	u_int32_t inbound_doorbell;
64 	u_int32_t inbound_intstatus;
65 	u_int32_t inbound_intmask;
66 	u_int32_t outbound_doorbell;
67 	u_int32_t outbound_intstatus;
68 	u_int32_t outbound_intmask;
69 	u_int32_t reserved1[2];
70 	u_int32_t inbound_queue;
71 	u_int32_t outbound_queue;
72 };
73 
74 #define IOPMU_QUEUE_EMPTY            0xffffffff
75 #define IOPMU_QUEUE_MASK_HOST_BITS   0xf0000000
76 #define IOPMU_QUEUE_ADDR_HOST_BIT    0x80000000
77 #define IOPMU_QUEUE_REQUEST_SIZE_BIT    0x40000000
78 #define IOPMU_QUEUE_REQUEST_RESULT_BIT   0x40000000
79 #define IOPMU_MAX_MEM_SUPPORT_MASK_64G 0xfffffff000000000ull
80 #define IOPMU_MAX_MEM_SUPPORT_MASK_32G 0xfffffff800000000ull
81 
82 #define IOPMU_OUTBOUND_INT_MSG0      1
83 #define IOPMU_OUTBOUND_INT_MSG1      2
84 #define IOPMU_OUTBOUND_INT_DOORBELL  4
85 #define IOPMU_OUTBOUND_INT_POSTQUEUE 8
86 #define IOPMU_OUTBOUND_INT_PCI       0x10
87 
88 #define IOPMU_INBOUND_INT_MSG0       1
89 #define IOPMU_INBOUND_INT_MSG1       2
90 #define IOPMU_INBOUND_INT_DOORBELL   4
91 #define IOPMU_INBOUND_INT_ERROR      8
92 #define IOPMU_INBOUND_INT_POSTQUEUE  0x10
93 
94 #define MVIOP_QUEUE_LEN  512
95 struct hpt_iopmu_mv {
96 	u_int32_t inbound_head;
97 	u_int32_t inbound_tail;
98 	u_int32_t outbound_head;
99 	u_int32_t outbound_tail;
100 	u_int32_t inbound_msg;
101 	u_int32_t outbound_msg;
102 	u_int32_t reserve[10];
103 	u_int64_t inbound_q[MVIOP_QUEUE_LEN];
104 	u_int64_t outbound_q[MVIOP_QUEUE_LEN];
105 };
106 
107 struct hpt_iopmv_regs {
108 	u_int32_t reserved[0x20400 / 4];
109 	u_int32_t inbound_doorbell;
110 	u_int32_t inbound_intmask;
111 	u_int32_t outbound_doorbell;
112 	u_int32_t outbound_intmask;
113 };
114 
115 #define MVIOP_IOCTLCFG_SIZE	0x800
116 #define MVIOP_MU_QUEUE_ADDR_HOST_MASK   (~(0x1full))
117 #define MVIOP_MU_QUEUE_ADDR_HOST_BIT    4
118 
119 #define MVIOP_MU_QUEUE_ADDR_IOP_HIGH32  0xffffffff
120 #define MVIOP_MU_QUEUE_REQUEST_RESULT_BIT   1
121 #define MVIOP_MU_QUEUE_REQUEST_RETURN_CONTEXT 2
122 
123 #define MVIOP_MU_INBOUND_INT_MSG        1
124 #define MVIOP_MU_INBOUND_INT_POSTQUEUE  2
125 #define MVIOP_MU_OUTBOUND_INT_MSG       1
126 #define MVIOP_MU_OUTBOUND_INT_POSTQUEUE 2
127 
128 #define MVIOP_CMD_TYPE_GET_CONFIG (1 << 5)
129 #define MVIOP_CMD_TYPE_SET_CONFIG (1 << 6)
130 #define MVIOP_CMD_TYPE_SCSI (1 << 7)
131 #define MVIOP_CMD_TYPE_IOCTL (1 << 8)
132 #define MVIOP_CMD_TYPE_BLOCK (1 << 9)
133 
134 #define MVIOP_REQUEST_NUMBER_START_BIT 16
135 
136 enum hpt_iopmu_message {
137 	/* host-to-iop messages */
138 	IOPMU_INBOUND_MSG0_NOP = 0,
139 	IOPMU_INBOUND_MSG0_RESET,
140 	IOPMU_INBOUND_MSG0_FLUSH,
141 	IOPMU_INBOUND_MSG0_SHUTDOWN,
142 	IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
143 	IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
144 	IOPMU_INBOUND_MSG0_MAX = 0xff,
145 	/* iop-to-host messages */
146 	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
147 	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff,
148 	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200,
149 	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff,
150 	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300,
151 	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff,
152 };
153 
154 #define IOP_REQUEST_FLAG_SYNC_REQUEST 1
155 #define IOP_REQUEST_FLAG_BIST_REQUEST 2
156 #define IOP_REQUEST_FLAG_REMAPPED     4
157 #define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
158 
159 enum hpt_iop_request_type {
160 	IOP_REQUEST_TYPE_GET_CONFIG = 0,
161 	IOP_REQUEST_TYPE_SET_CONFIG,
162 	IOP_REQUEST_TYPE_BLOCK_COMMAND,
163 	IOP_REQUEST_TYPE_SCSI_COMMAND,
164 	IOP_REQUEST_TYPE_IOCTL_COMMAND,
165 	IOP_REQUEST_TYPE_MAX
166 };
167 
168 enum hpt_iop_result_type {
169 	IOP_RESULT_PENDING = 0,
170 	IOP_RESULT_SUCCESS,
171 	IOP_RESULT_FAIL,
172 	IOP_RESULT_BUSY,
173 	IOP_RESULT_RESET,
174 	IOP_RESULT_INVALID_REQUEST,
175 	IOP_RESULT_BAD_TARGET,
176 	IOP_RESULT_CHECK_CONDITION,
177 };
178 
179 struct hpt_iop_request_header {
180 	u_int32_t size;
181 	u_int32_t type;
182 	u_int32_t flags;
183 	u_int32_t result;
184 	u_int64_t context; /* host context */
185 };
186 
187 struct hpt_iop_request_get_config {
188 	struct hpt_iop_request_header header;
189 	u_int32_t interface_version;
190 	u_int32_t firmware_version;
191 	u_int32_t max_requests;
192 	u_int32_t request_size;
193 	u_int32_t max_sg_count;
194 	u_int32_t data_transfer_length;
195 	u_int32_t alignment_mask;
196 	u_int32_t max_devices;
197 	u_int32_t sdram_size;
198 };
199 
200 struct hpt_iop_request_set_config {
201 	struct hpt_iop_request_header header;
202 	u_int32_t iop_id;
203 	u_int16_t vbus_id;
204 	u_int16_t max_host_request_size;
205 	u_int32_t reserve[6];
206 };
207 
208 struct hpt_iopsg {
209 	u_int32_t size;
210 	u_int32_t eot; /* non-zero: end of table */
211 	u_int64_t pci_address;
212 };
213 
214 #define IOP_BLOCK_COMMAND_READ     1
215 #define IOP_BLOCK_COMMAND_WRITE    2
216 #define IOP_BLOCK_COMMAND_VERIFY   3
217 #define IOP_BLOCK_COMMAND_FLUSH    4
218 #define IOP_BLOCK_COMMAND_SHUTDOWN 5
219 struct hpt_iop_request_block_command {
220 	struct hpt_iop_request_header header;
221 	u_int8_t     channel;
222 	u_int8_t     target;
223 	u_int8_t     lun;
224 	u_int8_t     pad1;
225 	u_int16_t    command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */
226 	u_int16_t    sectors;
227 	u_int64_t    lba;
228 	struct hpt_iopsg sg_list[1];
229 };
230 
231 struct hpt_iop_request_scsi_command {
232 	struct hpt_iop_request_header header;
233 	u_int8_t     channel;
234 	u_int8_t     target;
235 	u_int8_t     lun;
236 	u_int8_t     pad1;
237 	u_int8_t     cdb[16];
238 	u_int32_t    dataxfer_length;
239 	struct hpt_iopsg sg_list[1];
240 };
241 
242 struct hpt_iop_request_ioctl_command {
243 	struct hpt_iop_request_header header;
244 	u_int32_t    ioctl_code;
245 	u_int32_t    inbuf_size;
246 	u_int32_t    outbuf_size;
247 	u_int32_t    bytes_returned;
248 	u_int8_t     buf[1];
249 	/* out data should be put at buf[(inbuf_size+3)&~3] */
250 };
251 
252 struct hpt_iop_ioctl_param {
253 	u_int32_t        Magic;                 /* used to check if it's a valid ioctl packet */
254 	u_int32_t        dwIoControlCode;       /* operation control code */
255 	unsigned long    lpInBuffer;            /* input data buffer */
256 	u_int32_t        nInBufferSize;         /* size of input data buffer */
257 	unsigned long    lpOutBuffer;           /* output data buffer */
258 	u_int32_t        nOutBufferSize;        /* size of output data buffer */
259 	unsigned long    lpBytesReturned;       /* count of HPT_U8s returned */
260 } __packed;
261 
262 #define HPT_IOCTL_FLAG_OPEN 1
263 #define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00)
264 
265 typedef struct cdev * ioctl_dev_t;
266 
267 typedef struct thread * ioctl_thread_t;
268 
269 struct hpt_iop_hba {
270 	struct hptiop_adapter_ops *ops;
271 	union {
272 		struct {
273 			struct hpt_iopmu_itl *mu;
274 		} itl;
275 		struct {
276 			struct hpt_iopmv_regs *regs;
277 			struct hpt_iopmu_mv *mu;
278 		} mv;
279 	} u;
280 
281 	struct hpt_iop_hba    *next;
282 
283 	u_int32_t             firmware_version;
284 	u_int32_t             interface_version;
285 	u_int32_t             max_devices;
286 	u_int32_t             max_requests;
287 	u_int32_t             max_request_size;
288 	u_int32_t             max_sg_count;
289 
290 	u_int32_t             msg_done;
291 
292 	device_t              pcidev;
293 	ioctl_dev_t           ioctl_dev;
294 
295 	bus_dma_tag_t         parent_dmat;
296 	bus_dma_tag_t         io_dmat;
297 	bus_dma_tag_t         srb_dmat;
298 	bus_dma_tag_t	      ctlcfg_dmat;
299 
300 	bus_dmamap_t          srb_dmamap;
301 	bus_dmamap_t          ctlcfg_dmamap;
302 
303 	struct resource       *bar0_res;
304 	bus_space_tag_t       bar0t;
305 	bus_space_handle_t    bar0h;
306 	int                   bar0_rid;
307 
308 	struct resource       *bar2_res;
309 	bus_space_tag_t	      bar2t;
310 	bus_space_handle_t    bar2h;
311 	int                   bar2_rid;
312 
313 	/* to release */
314 	u_int8_t              *uncached_ptr;
315 	void		      *ctlcfg_ptr;
316 	/* for scsi request block */
317 	struct hpt_iop_srb    *srb_list;
318 	/* for interrupt */
319 	struct resource       *irq_res;
320 	void                  *irq_handle;
321 
322 	/* for ioctl and set/get config */
323 	struct resource	      *ctlcfg_res;
324 	void		      *ctlcfg_handle;
325 	u_int64_t             ctlcfgcmd_phy;
326 	u_int32_t             config_done;
327 
328 	/* other resources */
329 	struct cam_sim        *sim;
330 	struct cam_path       *path;
331 	void                  *req;
332 	struct lock           lock;
333 #define HPT_IOCTL_FLAG_OPEN     1
334 	u_int32_t             flag;
335 	struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE];
336 };
337 
338 struct hptiop_adapter_ops {
339 	int  (*iop_wait_ready)(struct hpt_iop_hba *hba, u_int32_t millisec);
340 	int  (*internal_memalloc)(struct hpt_iop_hba *hba);
341 	int  (*internal_memfree)(struct hpt_iop_hba *hba);
342 	int  (*alloc_pci_res)(struct hpt_iop_hba *hba);
343 	void (*release_pci_res)(struct hpt_iop_hba *hba);
344 	void (*enable_intr)(struct hpt_iop_hba *hba);
345 	void (*disable_intr)(struct hpt_iop_hba *hba);
346 	int  (*get_config)(struct hpt_iop_hba *hba,
347 				struct hpt_iop_request_get_config *config);
348 	int  (*set_config)(struct hpt_iop_hba *hba,
349 				struct hpt_iop_request_set_config *config);
350 	int  (*iop_intr)(struct hpt_iop_hba *hba);
351 	void (*post_msg)(struct hpt_iop_hba *hba, u_int32_t msg);
352 	void (*post_req)(struct hpt_iop_hba *hba, struct hpt_iop_srb *srb, bus_dma_segment_t *segs, int nsegs);
353 	int (*do_ioctl)(struct hpt_iop_hba *hba, struct hpt_iop_ioctl_param * pParams);
354 };
355 
356 struct hpt_iop_srb {
357 	u_int8_t             req[HPT_SRB_MAX_REQ_SIZE];
358 	struct hpt_iop_hba   *hba;
359 	union ccb            *ccb;
360 	struct hpt_iop_srb   *next;
361 	bus_dmamap_t         dma_map;
362 	u_int64_t            phy_addr;
363 	u_int32_t            srb_flag;
364 	int                  index;
365 };
366 
367 #define hptiop_lock_adapter(hba)   lockmgr(&(hba)->lock, LK_EXCLUSIVE)
368 #define hptiop_unlock_adapter(hba) lockmgr(&(hba)->lock, LK_RELEASE)
369 
370 #define HPT_OSM_TIMEOUT (20*hz)  /* timeout value for OS commands */
371 
372 #define HPT_DO_IOCONTROL    _IOW('H', 0, struct hpt_iop_ioctl_param)
373 #define HPT_SCAN_BUS        _IO('H', 1)
374 
375 static  __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident,
376 				int priority, const char *wmesg, int timo)
377 {
378 
379 	int retval;
380 
381 	retval = lksleep(ident, &hba->lock, priority, wmesg, timo);
382 
383 	return retval;
384 
385 }
386 
387 #endif
388