hptiop.h revision 169412
1169412Sscottl/*
2169412Sscottl * HighPoint RR3xxx RAID Driver for FreeBSD
3169412Sscottl * Copyright (C) 2005-2007 HighPoint Technologies, Inc. All Rights Reserved.
4169412Sscottl * Redistribution and use in source and binary forms, with or without
5169412Sscottl * modification, are permitted provided that the following conditions
6169412Sscottl * are met:
7169412Sscottl * 1. Redistributions of source code must retain the above copyright
8169412Sscottl *    notice, this list of conditions and the following disclaimer.
9169412Sscottl * 2. Redistributions in binary form must reproduce the above copyright
10169412Sscottl *    notice, this list of conditions and the following disclaimer in the
11169412Sscottl *    documentation and/or other materials provided with the distribution.
12169412Sscottl *
13169412Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14169412Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15169412Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16169412Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17169412Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18169412Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19169412Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20169412Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21169412Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22169412Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23169412Sscottl * SUCH DAMAGE.
24169412Sscottl */
25169412Sscottl
26169412Sscottl#ifndef _HPTIOP_H
27169412Sscottl#define _HPTIOP_H
28169412Sscottl
29169412Sscottl#include <sys/cdefs.h>
30169412Sscottl__FBSDID("$FreeBSD: head/sys/dev/hptiop/hptiop.h 169412 2007-05-09 07:07:26Z scottl $");
31169412Sscottl
32169412Sscottl#ifdef DBG
33169412Sscottlint hpt_dbg_level = 0;
34169412Sscottl#define KdPrint(x)  do { if (hpt_dbg_level) printf x; } while (0)
35169412Sscottl#define HPT_ASSERT(x) assert(x)
36169412Sscottl#else
37169412Sscottl#define KdPrint(x)
38169412Sscottl#define HPT_ASSERT(x)
39169412Sscottl#endif
40169412Sscottl
41169412Sscottl#define HPT_SRB_MAX_REQ_SIZE                600
42169412Sscottl#define HPT_SRB_MAX_QUEUE_SIZE              0x100
43169412Sscottl
44169412Sscottl/* beyond 64G mem */
45169412Sscottl#define HPT_SRB_FLAG_HIGH_MEM_ACESS         0x1
46169412Sscottl#define HPT_SRB_MAX_SIZE  ((sizeof(struct hpt_iop_srb) + 0x1f) & ~0x1f)
47169412Sscottl
48169412Sscottl#define HPT_IOCTL_MAGIC   0xA1B2C3D4
49169412Sscottl#define HPT_IOCTL_MAGIC32 0x1A2B3C4D
50169412Sscottl
51169412Sscottl
52169412Sscottlstruct hpt_iopmu
53169412Sscottl{
54169412Sscottl	u_int32_t resrved0[4];
55169412Sscottl	u_int32_t inbound_msgaddr0;
56169412Sscottl	u_int32_t inbound_msgaddr1;
57169412Sscottl	u_int32_t outbound_msgaddr0;
58169412Sscottl	u_int32_t outbound_msgaddr1;
59169412Sscottl	u_int32_t inbound_doorbell;
60169412Sscottl	u_int32_t inbound_intstatus;
61169412Sscottl	u_int32_t inbound_intmask;
62169412Sscottl	u_int32_t outbound_doorbell;
63169412Sscottl	u_int32_t outbound_intstatus;
64169412Sscottl	u_int32_t outbound_intmask;
65169412Sscottl	u_int32_t reserved1[2];
66169412Sscottl	u_int32_t inbound_queue;
67169412Sscottl	u_int32_t outbound_queue;
68169412Sscottl};
69169412Sscottl
70169412Sscottlstruct hpt_iop_ioctl_param {
71169412Sscottl	u_int32_t        Magic;                 /* used to check if it's a valid ioctl packet */
72169412Sscottl	u_int32_t        dwIoControlCode;       /* operation control code */
73169412Sscottl	unsigned long   lpInBuffer;            /* input data buffer */
74169412Sscottl	u_int32_t        nInBufferSize;         /* size of input data buffer */
75169412Sscottl	unsigned long   lpOutBuffer;           /* output data buffer */
76169412Sscottl	u_int32_t        nOutBufferSize;        /* size of output data buffer */
77169412Sscottl	unsigned long   lpBytesReturned;       /* count of HPT_U8s returned */
78169412Sscottl} __attribute__((packed));
79169412Sscottl
80169412Sscottl
81169412Sscottlstruct hpt_iop_srb {
82169412Sscottl	u_int8_t           req[HPT_SRB_MAX_REQ_SIZE];
83169412Sscottl	struct hpt_iop_hba     *hba;
84169412Sscottl	union ccb        *ccb;
85169412Sscottl	struct hpt_iop_srb *    next;
86169412Sscottl	bus_dmamap_t     dma_map;
87169412Sscottl	u_int32_t          phy_addr;
88169412Sscottl	u_int32_t          srb_flag;
89169412Sscottl	int              index;
90169412Sscottl};
91169412Sscottl
92169412Sscottl#define IOPMU_QUEUE_EMPTY            0xffffffff
93169412Sscottl#define IOPMU_QUEUE_MASK_HOST_BITS   0xf0000000
94169412Sscottl#define IOPMU_QUEUE_ADDR_HOST_BIT    0x80000000
95169412Sscottl#define IOPMU_QUEUE_REQUEST_SIZE_BIT    0x40000000
96169412Sscottl#define IOPMU_QUEUE_REQUEST_RESULT_BIT   0x40000000
97169412Sscottl#define IOPMU_MAX_MEM_SUPPORT_MASK_64G 0xfffffff000000000ull
98169412Sscottl#define IOPMU_MAX_MEM_SUPPORT_MASK_32G 0xfffffff800000000ull
99169412Sscottl
100169412Sscottl#define IOPMU_OUTBOUND_INT_MSG0      1
101169412Sscottl#define IOPMU_OUTBOUND_INT_MSG1      2
102169412Sscottl#define IOPMU_OUTBOUND_INT_DOORBELL  4
103169412Sscottl#define IOPMU_OUTBOUND_INT_POSTQUEUE 8
104169412Sscottl#define IOPMU_OUTBOUND_INT_PCI       0x10
105169412Sscottl
106169412Sscottl#define IOPMU_INBOUND_INT_MSG0       1
107169412Sscottl#define IOPMU_INBOUND_INT_MSG1       2
108169412Sscottl#define IOPMU_INBOUND_INT_DOORBELL   4
109169412Sscottl#define IOPMU_INBOUND_INT_ERROR      8
110169412Sscottl#define IOPMU_INBOUND_INT_POSTQUEUE  0x10
111169412Sscottl
112169412Sscottlenum hpt_iopmu_message {
113169412Sscottl	/* host-to-iop messages */
114169412Sscottl	IOPMU_INBOUND_MSG0_NOP = 0,
115169412Sscottl	IOPMU_INBOUND_MSG0_RESET,
116169412Sscottl	IOPMU_INBOUND_MSG0_FLUSH,
117169412Sscottl	IOPMU_INBOUND_MSG0_SHUTDOWN,
118169412Sscottl	IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
119169412Sscottl	IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
120169412Sscottl	IOPMU_INBOUND_MSG0_MAX = 0xff,
121169412Sscottl	/* iop-to-host messages */
122169412Sscottl	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
123169412Sscottl	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff,
124169412Sscottl	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200,
125169412Sscottl	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff,
126169412Sscottl	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300,
127169412Sscottl	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff,
128169412Sscottl};
129169412Sscottl
130169412Sscottlstruct hpt_iop_request_header
131169412Sscottl{
132169412Sscottl	u_int32_t size;
133169412Sscottl	u_int32_t type;
134169412Sscottl	u_int32_t flags;
135169412Sscottl	u_int32_t result;
136169412Sscottl	u_int32_t context; /* host context */
137169412Sscottl	u_int32_t context_hi32;
138169412Sscottl};
139169412Sscottl
140169412Sscottl#define IOP_REQUEST_FLAG_SYNC_REQUEST 1
141169412Sscottl#define IOP_REQUEST_FLAG_BIST_REQUEST 2
142169412Sscottl#define IOP_REQUEST_FLAG_REMAPPED     4
143169412Sscottl#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
144169412Sscottl
145169412Sscottlenum hpt_iop_request_type {
146169412Sscottl	IOP_REQUEST_TYPE_GET_CONFIG = 0,
147169412Sscottl	IOP_REQUEST_TYPE_SET_CONFIG,
148169412Sscottl	IOP_REQUEST_TYPE_BLOCK_COMMAND,
149169412Sscottl	IOP_REQUEST_TYPE_SCSI_COMMAND,
150169412Sscottl	IOP_REQUEST_TYPE_IOCTL_COMMAND,
151169412Sscottl	IOP_REQUEST_TYPE_MAX
152169412Sscottl};
153169412Sscottl
154169412Sscottlenum hpt_iop_result_type {
155169412Sscottl	IOP_RESULT_PENDING = 0,
156169412Sscottl	IOP_RESULT_SUCCESS,
157169412Sscottl	IOP_RESULT_FAIL,
158169412Sscottl	IOP_RESULT_BUSY,
159169412Sscottl	IOP_RESULT_RESET,
160169412Sscottl	IOP_RESULT_INVALID_REQUEST,
161169412Sscottl	IOP_RESULT_BAD_TARGET,
162169412Sscottl	IOP_RESULT_MODE_SENSE_CHECK_CONDITION,
163169412Sscottl};
164169412Sscottl
165169412Sscottlstruct hpt_iop_request_get_config
166169412Sscottl{
167169412Sscottl	struct hpt_iop_request_header header;
168169412Sscottl	u_int32_t interface_version;
169169412Sscottl	u_int32_t firmware_version;
170169412Sscottl	u_int32_t max_requests;
171169412Sscottl	u_int32_t request_size;
172169412Sscottl	u_int32_t max_sg_count;
173169412Sscottl	u_int32_t data_transfer_length;
174169412Sscottl	u_int32_t alignment_mask;
175169412Sscottl	u_int32_t max_devices;
176169412Sscottl	u_int32_t sdram_size;
177169412Sscottl};
178169412Sscottl
179169412Sscottlstruct hpt_iop_request_set_config
180169412Sscottl{
181169412Sscottl	struct hpt_iop_request_header header;
182169412Sscottl	u_int32_t iop_id;
183169412Sscottl	u_int16_t vbus_id;
184169412Sscottl	u_int16_t max_host_request_size;
185169412Sscottl	u_int32_t reserve[6];
186169412Sscottl};
187169412Sscottl
188169412Sscottlstruct hpt_iopsg
189169412Sscottl{
190169412Sscottl	u_int32_t size;
191169412Sscottl	u_int32_t eot; /* non-zero: end of table */
192169412Sscottl	u_int64_t pci_address;
193169412Sscottl};
194169412Sscottl
195169412Sscottlstruct hpt_iop_request_block_command
196169412Sscottl{
197169412Sscottl	struct hpt_iop_request_header header;
198169412Sscottl	u_int8_t     channel;
199169412Sscottl	u_int8_t     target;
200169412Sscottl	u_int8_t     lun;
201169412Sscottl	u_int8_t     pad1;
202169412Sscottl	u_int16_t   command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */
203169412Sscottl	u_int16_t   sectors;
204169412Sscottl	u_int64_t   lba;
205169412Sscottl	struct hpt_iopsg sg_list[1];
206169412Sscottl};
207169412Sscottl
208169412Sscottl#define IOP_BLOCK_COMMAND_READ     1
209169412Sscottl#define IOP_BLOCK_COMMAND_WRITE    2
210169412Sscottl#define IOP_BLOCK_COMMAND_VERIFY   3
211169412Sscottl#define IOP_BLOCK_COMMAND_FLUSH    4
212169412Sscottl#define IOP_BLOCK_COMMAND_SHUTDOWN 5
213169412Sscottl
214169412Sscottlstruct hpt_iop_request_scsi_command
215169412Sscottl{
216169412Sscottl	struct hpt_iop_request_header header;
217169412Sscottl	u_int8_t     channel;
218169412Sscottl	u_int8_t     target;
219169412Sscottl	u_int8_t     lun;
220169412Sscottl	u_int8_t     pad1;
221169412Sscottl	u_int8_t     cdb[16];
222169412Sscottl	u_int32_t   dataxfer_length;
223169412Sscottl	struct hpt_iopsg sg_list[1];
224169412Sscottl};
225169412Sscottl
226169412Sscottlstruct hpt_iop_request_ioctl_command
227169412Sscottl{
228169412Sscottl	struct hpt_iop_request_header header;
229169412Sscottl	u_int32_t    ioctl_code;
230169412Sscottl	u_int32_t    inbuf_size;
231169412Sscottl	u_int32_t    outbuf_size;
232169412Sscottl	u_int32_t    bytes_returned;
233169412Sscottl	u_int8_t     buf[1];
234169412Sscottl	/* out data should be put at buf[(inbuf_size+3)&~3] */
235169412Sscottl};
236169412Sscottl
237169412Sscottl#define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00)
238169412Sscottl
239169412Sscottl#if __FreeBSD_version>503000
240169412Sscottltypedef struct cdev * ioctl_dev_t;
241169412Sscottl#else
242169412Sscottltypedef dev_t ioctl_dev_t;
243169412Sscottl#endif
244169412Sscottl
245169412Sscottl#if __FreeBSD_version >= 500000
246169412Sscottltypedef struct thread * ioctl_thread_t;
247169412Sscottl#else
248169412Sscottltypedef struct proc * ioctl_thread_t;
249169412Sscottl#endif
250169412Sscottl
251169412Sscottlstruct hpt_iop_hba {
252169412Sscottl	struct hpt_iopmu    *iop;
253169412Sscottl	struct hpt_iop_hba *next;
254169412Sscottl
255169412Sscottl	u_int32_t             firmware_version;
256169412Sscottl	u_int32_t             interface_version;
257169412Sscottl	u_int32_t             max_devices;
258169412Sscottl	u_int32_t             max_requests;
259169412Sscottl	u_int32_t             max_request_size;
260169412Sscottl	u_int32_t             max_sg_count;
261169412Sscottl
262169412Sscottl	int                 msg_done;
263169412Sscottl
264169412Sscottl	device_t            pcidev;
265169412Sscottl	u_int32_t           pciunit;
266169412Sscottl	ioctl_dev_t         ioctl_dev;
267169412Sscottl
268169412Sscottl	struct resource    *bar0_res;
269169412Sscottl	int                 bar0_rid;
270169412Sscottl
271169412Sscottl	bus_dma_tag_t       parent_dmat;
272169412Sscottl	bus_dma_tag_t       io_dmat;
273169412Sscottl	bus_dma_tag_t       srb_dmat;
274169412Sscottl	bus_dmamap_t        srb_dmamap;
275169412Sscottl	/* to release */
276169412Sscottl	u_int8_t              *uncached_ptr;
277169412Sscottl	/* for scsi request block */
278169412Sscottl	struct hpt_iop_srb   *srb_list;
279169412Sscottl	/* for interrupt */
280169412Sscottl	struct resource     *irq_res;
281169412Sscottl	void                *irq_handle;
282169412Sscottl	/* other resources */
283169412Sscottl	struct cam_sim      *sim;
284169412Sscottl	struct cam_path     *path;
285169412Sscottl	void                *req;
286169412Sscottl#if (__FreeBSD_version >= 500000)
287169412Sscottl	struct mtx          lock;
288169412Sscottl#else
289169412Sscottl	int                 hpt_splx;
290169412Sscottl#endif
291169412Sscottl#define HPT_IOCTL_FLAG_OPEN     1
292169412Sscottl	u_int32_t             flag;
293169412Sscottl	struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE];
294169412Sscottl};
295169412Sscottl
296169412Sscottl#if __FreeBSD_version >= 500000
297169412Sscottl#define hptiop_lock_adapter(hba)   mtx_lock(&(hba)->lock)
298169412Sscottl#define hptiop_unlock_adapter(hba) mtx_unlock(&(hba)->lock)
299169412Sscottl#else
300169412Sscottlstatic __inline void hptiop_lock_adapter(struct hpt_iop_hba *hba)
301169412Sscottl{
302169412Sscottl	hba->hpt_splx = splcam();
303169412Sscottl}
304169412Sscottlstatic __inline void hptiop_unlock_adapter(struct hpt_iop_hba *hba)
305169412Sscottl{
306169412Sscottl	splx(hba->hpt_splx);
307169412Sscottl}
308169412Sscottl#endif
309169412Sscottl
310169412Sscottl#define HPT_OSM_TIMEOUT (20*hz)  /* timeout value for OS commands */
311169412Sscottl
312169412Sscottl#define HPT_DO_IOCONTROL    _IOW('H', 0, struct hpt_iop_ioctl_param)
313169412Sscottl#define HPT_SCAN_BUS        _IO('H', 1)
314169412Sscottl
315169412Sscottlstatic  __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident,
316169412Sscottl				int priority, const char *wmesg, int timo)
317169412Sscottl{
318169412Sscottl
319169412Sscottl	int retval;
320169412Sscottl
321169412Sscottl#if __FreeBSD_version >= 500000
322169412Sscottl	retval = msleep(ident, &hba->lock, priority, wmesg, timo);
323169412Sscottl#else
324169412Sscottl	asleep(ident, priority, wmesg, timo);
325169412Sscottl	hptiop_unlock_adapter(hba);
326169412Sscottl	retval = await(priority, timo);
327169412Sscottl	hptiop_lock_adapter(hba);
328169412Sscottl#endif
329169412Sscottl
330169412Sscottl	return retval;
331169412Sscottl
332169412Sscottl}
333169412Sscottl
334169412Sscottl#if __FreeBSD_version < 501000
335169412Sscottl#define READ_16             0x88
336169412Sscottl#define WRITE_16            0x8a
337169412Sscottl#define SERVICE_ACTION_IN   0x9e
338169412Sscottl#endif
339169412Sscottl
340169412Sscottl#define HPT_DEV_MAJOR   200
341169412Sscottl
342169412Sscottl#endif
343169412Sscottl
344