xref: /freebsd/sys/dev/hptiop/hptiop.h (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 /*
2  * HighPoint RR3xxx RAID Driver for FreeBSD
3  * Copyright (C) 2005-2007 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 #ifdef DBG
33 int hpt_dbg_level = 0;
34 #define KdPrint(x)  do { if (hpt_dbg_level) printf x; } while (0)
35 #define HPT_ASSERT(x) assert(x)
36 #else
37 #define KdPrint(x)
38 #define HPT_ASSERT(x)
39 #endif
40 
41 #define HPT_SRB_MAX_REQ_SIZE                600
42 #define HPT_SRB_MAX_QUEUE_SIZE              0x100
43 
44 /* beyond 64G mem */
45 #define HPT_SRB_FLAG_HIGH_MEM_ACESS         0x1
46 #define HPT_SRB_MAX_SIZE  ((sizeof(struct hpt_iop_srb) + 0x1f) & ~0x1f)
47 
48 #define HPT_IOCTL_MAGIC   0xA1B2C3D4
49 #define HPT_IOCTL_MAGIC32 0x1A2B3C4D
50 
51 
52 struct hpt_iopmu
53 {
54 	u_int32_t resrved0[4];
55 	u_int32_t inbound_msgaddr0;
56 	u_int32_t inbound_msgaddr1;
57 	u_int32_t outbound_msgaddr0;
58 	u_int32_t outbound_msgaddr1;
59 	u_int32_t inbound_doorbell;
60 	u_int32_t inbound_intstatus;
61 	u_int32_t inbound_intmask;
62 	u_int32_t outbound_doorbell;
63 	u_int32_t outbound_intstatus;
64 	u_int32_t outbound_intmask;
65 	u_int32_t reserved1[2];
66 	u_int32_t inbound_queue;
67 	u_int32_t outbound_queue;
68 };
69 
70 struct hpt_iop_ioctl_param {
71 	u_int32_t        Magic;                 /* used to check if it's a valid ioctl packet */
72 	u_int32_t        dwIoControlCode;       /* operation control code */
73 	unsigned long   lpInBuffer;            /* input data buffer */
74 	u_int32_t        nInBufferSize;         /* size of input data buffer */
75 	unsigned long   lpOutBuffer;           /* output data buffer */
76 	u_int32_t        nOutBufferSize;        /* size of output data buffer */
77 	unsigned long   lpBytesReturned;       /* count of HPT_U8s returned */
78 } __attribute__((packed));
79 
80 
81 struct hpt_iop_srb {
82 	u_int8_t           req[HPT_SRB_MAX_REQ_SIZE];
83 	struct hpt_iop_hba     *hba;
84 	union ccb        *ccb;
85 	struct hpt_iop_srb *    next;
86 	bus_dmamap_t     dma_map;
87 	u_int32_t          phy_addr;
88 	u_int32_t          srb_flag;
89 	int              index;
90 };
91 
92 #define IOPMU_QUEUE_EMPTY            0xffffffff
93 #define IOPMU_QUEUE_MASK_HOST_BITS   0xf0000000
94 #define IOPMU_QUEUE_ADDR_HOST_BIT    0x80000000
95 #define IOPMU_QUEUE_REQUEST_SIZE_BIT    0x40000000
96 #define IOPMU_QUEUE_REQUEST_RESULT_BIT   0x40000000
97 #define IOPMU_MAX_MEM_SUPPORT_MASK_64G 0xfffffff000000000ull
98 #define IOPMU_MAX_MEM_SUPPORT_MASK_32G 0xfffffff800000000ull
99 
100 #define IOPMU_OUTBOUND_INT_MSG0      1
101 #define IOPMU_OUTBOUND_INT_MSG1      2
102 #define IOPMU_OUTBOUND_INT_DOORBELL  4
103 #define IOPMU_OUTBOUND_INT_POSTQUEUE 8
104 #define IOPMU_OUTBOUND_INT_PCI       0x10
105 
106 #define IOPMU_INBOUND_INT_MSG0       1
107 #define IOPMU_INBOUND_INT_MSG1       2
108 #define IOPMU_INBOUND_INT_DOORBELL   4
109 #define IOPMU_INBOUND_INT_ERROR      8
110 #define IOPMU_INBOUND_INT_POSTQUEUE  0x10
111 
112 enum hpt_iopmu_message {
113 	/* host-to-iop messages */
114 	IOPMU_INBOUND_MSG0_NOP = 0,
115 	IOPMU_INBOUND_MSG0_RESET,
116 	IOPMU_INBOUND_MSG0_FLUSH,
117 	IOPMU_INBOUND_MSG0_SHUTDOWN,
118 	IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
119 	IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
120 	IOPMU_INBOUND_MSG0_MAX = 0xff,
121 	/* iop-to-host messages */
122 	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
123 	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff,
124 	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200,
125 	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff,
126 	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300,
127 	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff,
128 };
129 
130 struct hpt_iop_request_header
131 {
132 	u_int32_t size;
133 	u_int32_t type;
134 	u_int32_t flags;
135 	u_int32_t result;
136 	u_int32_t context; /* host context */
137 	u_int32_t context_hi32;
138 };
139 
140 #define IOP_REQUEST_FLAG_SYNC_REQUEST 1
141 #define IOP_REQUEST_FLAG_BIST_REQUEST 2
142 #define IOP_REQUEST_FLAG_REMAPPED     4
143 #define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
144 
145 enum hpt_iop_request_type {
146 	IOP_REQUEST_TYPE_GET_CONFIG = 0,
147 	IOP_REQUEST_TYPE_SET_CONFIG,
148 	IOP_REQUEST_TYPE_BLOCK_COMMAND,
149 	IOP_REQUEST_TYPE_SCSI_COMMAND,
150 	IOP_REQUEST_TYPE_IOCTL_COMMAND,
151 	IOP_REQUEST_TYPE_MAX
152 };
153 
154 enum hpt_iop_result_type {
155 	IOP_RESULT_PENDING = 0,
156 	IOP_RESULT_SUCCESS,
157 	IOP_RESULT_FAIL,
158 	IOP_RESULT_BUSY,
159 	IOP_RESULT_RESET,
160 	IOP_RESULT_INVALID_REQUEST,
161 	IOP_RESULT_BAD_TARGET,
162 	IOP_RESULT_MODE_SENSE_CHECK_CONDITION,
163 };
164 
165 struct hpt_iop_request_get_config
166 {
167 	struct hpt_iop_request_header header;
168 	u_int32_t interface_version;
169 	u_int32_t firmware_version;
170 	u_int32_t max_requests;
171 	u_int32_t request_size;
172 	u_int32_t max_sg_count;
173 	u_int32_t data_transfer_length;
174 	u_int32_t alignment_mask;
175 	u_int32_t max_devices;
176 	u_int32_t sdram_size;
177 };
178 
179 struct hpt_iop_request_set_config
180 {
181 	struct hpt_iop_request_header header;
182 	u_int32_t iop_id;
183 	u_int16_t vbus_id;
184 	u_int16_t max_host_request_size;
185 	u_int32_t reserve[6];
186 };
187 
188 struct hpt_iopsg
189 {
190 	u_int32_t size;
191 	u_int32_t eot; /* non-zero: end of table */
192 	u_int64_t pci_address;
193 };
194 
195 struct hpt_iop_request_block_command
196 {
197 	struct hpt_iop_request_header header;
198 	u_int8_t     channel;
199 	u_int8_t     target;
200 	u_int8_t     lun;
201 	u_int8_t     pad1;
202 	u_int16_t   command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */
203 	u_int16_t   sectors;
204 	u_int64_t   lba;
205 	struct hpt_iopsg sg_list[1];
206 };
207 
208 #define IOP_BLOCK_COMMAND_READ     1
209 #define IOP_BLOCK_COMMAND_WRITE    2
210 #define IOP_BLOCK_COMMAND_VERIFY   3
211 #define IOP_BLOCK_COMMAND_FLUSH    4
212 #define IOP_BLOCK_COMMAND_SHUTDOWN 5
213 
214 struct hpt_iop_request_scsi_command
215 {
216 	struct hpt_iop_request_header header;
217 	u_int8_t     channel;
218 	u_int8_t     target;
219 	u_int8_t     lun;
220 	u_int8_t     pad1;
221 	u_int8_t     cdb[16];
222 	u_int32_t   dataxfer_length;
223 	struct hpt_iopsg sg_list[1];
224 };
225 
226 struct hpt_iop_request_ioctl_command
227 {
228 	struct hpt_iop_request_header header;
229 	u_int32_t    ioctl_code;
230 	u_int32_t    inbuf_size;
231 	u_int32_t    outbuf_size;
232 	u_int32_t    bytes_returned;
233 	u_int8_t     buf[1];
234 	/* out data should be put at buf[(inbuf_size+3)&~3] */
235 };
236 
237 #define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00)
238 
239 #if __FreeBSD_version>503000
240 typedef struct cdev * ioctl_dev_t;
241 #else
242 typedef dev_t ioctl_dev_t;
243 #endif
244 
245 #if __FreeBSD_version >= 500000
246 typedef struct thread * ioctl_thread_t;
247 #else
248 typedef struct proc * ioctl_thread_t;
249 #endif
250 
251 struct hpt_iop_hba {
252 	struct hpt_iopmu    *iop;
253 	struct hpt_iop_hba *next;
254 
255 	u_int32_t             firmware_version;
256 	u_int32_t             interface_version;
257 	u_int32_t             max_devices;
258 	u_int32_t             max_requests;
259 	u_int32_t             max_request_size;
260 	u_int32_t             max_sg_count;
261 
262 	int                 msg_done;
263 
264 	device_t            pcidev;
265 	u_int32_t           pciunit;
266 	ioctl_dev_t         ioctl_dev;
267 
268 	struct resource    *bar0_res;
269 	int                 bar0_rid;
270 
271 	bus_dma_tag_t       parent_dmat;
272 	bus_dma_tag_t       io_dmat;
273 	bus_dma_tag_t       srb_dmat;
274 	bus_dmamap_t        srb_dmamap;
275 	/* to release */
276 	u_int8_t              *uncached_ptr;
277 	/* for scsi request block */
278 	struct hpt_iop_srb   *srb_list;
279 	/* for interrupt */
280 	struct resource     *irq_res;
281 	void                *irq_handle;
282 	/* other resources */
283 	struct cam_sim      *sim;
284 	struct cam_path     *path;
285 	void                *req;
286 #if (__FreeBSD_version >= 500000)
287 	struct mtx          lock;
288 #else
289 	int                 hpt_splx;
290 #endif
291 #define HPT_IOCTL_FLAG_OPEN     1
292 	u_int32_t             flag;
293 	struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE];
294 };
295 
296 #if __FreeBSD_version >= 500000
297 #define hptiop_lock_adapter(hba)   mtx_lock(&(hba)->lock)
298 #define hptiop_unlock_adapter(hba) mtx_unlock(&(hba)->lock)
299 #else
300 static __inline void hptiop_lock_adapter(struct hpt_iop_hba *hba)
301 {
302 	hba->hpt_splx = splcam();
303 }
304 static __inline void hptiop_unlock_adapter(struct hpt_iop_hba *hba)
305 {
306 	splx(hba->hpt_splx);
307 }
308 #endif
309 
310 #define HPT_OSM_TIMEOUT (20*hz)  /* timeout value for OS commands */
311 
312 #define HPT_DO_IOCONTROL    _IOW('H', 0, struct hpt_iop_ioctl_param)
313 #define HPT_SCAN_BUS        _IO('H', 1)
314 
315 static  __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident,
316 				int priority, const char *wmesg, int timo)
317 {
318 
319 	int retval;
320 
321 #if __FreeBSD_version >= 500000
322 	retval = msleep(ident, &hba->lock, priority, wmesg, timo);
323 #else
324 	asleep(ident, priority, wmesg, timo);
325 	hptiop_unlock_adapter(hba);
326 	retval = await(priority, timo);
327 	hptiop_lock_adapter(hba);
328 #endif
329 
330 	return retval;
331 
332 }
333 
334 #if __FreeBSD_version < 501000
335 #define READ_16             0x88
336 #define WRITE_16            0x8a
337 #define SERVICE_ACTION_IN   0x9e
338 #endif
339 
340 #define HPT_DEV_MAJOR   200
341 
342 #endif
343 
344