hptiop.h revision 169412
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: head/sys/dev/hptiop/hptiop.h 169412 2007-05-09 07:07:26Z scottl $");
31
32#ifdef DBG
33int 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
52struct 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
70struct 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
81struct 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
112enum 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
130struct 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
145enum 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
154enum 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
165struct 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
179struct 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
188struct 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
195struct 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
214struct 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
226struct 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
240typedef struct cdev * ioctl_dev_t;
241#else
242typedef dev_t ioctl_dev_t;
243#endif
244
245#if __FreeBSD_version >= 500000
246typedef struct thread * ioctl_thread_t;
247#else
248typedef struct proc * ioctl_thread_t;
249#endif
250
251struct 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
300static __inline void hptiop_lock_adapter(struct hpt_iop_hba *hba)
301{
302	hba->hpt_splx = splcam();
303}
304static __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
315static  __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