1333019Ssbruno/*-
2333019Ssbruno * Copyright (c) 2018 Microsemi Corporation.
3333019Ssbruno * All rights reserved.
4333019Ssbruno *
5333019Ssbruno * Redistribution and use in source and binary forms, with or without
6333019Ssbruno * modification, are permitted provided that the following conditions
7333019Ssbruno * are met:
8333019Ssbruno * 1. Redistributions of source code must retain the above copyright
9333019Ssbruno *    notice, this list of conditions and the following disclaimer.
10333019Ssbruno * 2. Redistributions in binary form must reproduce the above copyright
11333019Ssbruno *    notice, this list of conditions and the following disclaimer in the
12333019Ssbruno *    documentation and/or other materials provided with the distribution.
13333019Ssbruno *
14333019Ssbruno * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15333019Ssbruno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16333019Ssbruno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17333019Ssbruno * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18333019Ssbruno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19333019Ssbruno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20333019Ssbruno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21333019Ssbruno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22333019Ssbruno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23333019Ssbruno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24333019Ssbruno * SUCH DAMAGE.
25333019Ssbruno */
26333019Ssbruno
27333019Ssbruno/* $FreeBSD: stable/11/sys/dev/smartpqi/smartpqi_defines.h 346376 2019-04-19 12:40:21Z kib $ */
28333019Ssbruno
29333019Ssbruno#ifndef _PQI_DEFINES_H
30333019Ssbruno#define _PQI_DEFINES_H
31333019Ssbruno
32333019Ssbruno#define PQI_STATUS_FAILURE			-1
33333019Ssbruno#define PQI_STATUS_TIMEOUT			-2
34333019Ssbruno#define PQI_STATUS_QFULL			-3
35333019Ssbruno#define PQI_STATUS_SUCCESS			0
36333019Ssbruno
37333019Ssbruno#define PQISRC_CMD_TIMEOUT_CNT			1200000 /* 500usec * 1200000 = 5 min  */
38333019Ssbruno
39333019Ssbruno/* #define SHARE_EVENT_QUEUE_FOR_IO		1 */
40333019Ssbruno
41333019Ssbruno#define	INVALID_ELEM				0xffff
42333019Ssbruno#ifndef MIN
43333019Ssbruno#define MIN(a,b)                                ((a) < (b) ? (a) : (b))
44333019Ssbruno#endif
45333019Ssbruno
46333019Ssbruno#ifndef MAX
47333019Ssbruno#define MAX(a,b)                                ((a) > (b) ? (a) : (b))
48333019Ssbruno#endif
49333019Ssbruno
50333019Ssbruno#define PQISRC_ROUNDUP(x, y)			(((x) + (y) - 1) / (y) * (y))
51333019Ssbruno#define PQISRC_DIV_ROUND_UP(x, y)		(((x) + (y) - 1) / (y))
52333019Ssbruno
53333019Ssbruno#define ALIGN_BOUNDARY(a, n)	{	\
54333019Ssbruno		if (a % n)	\
55333019Ssbruno			a = a + (n - a % n);	\
56333019Ssbruno	}
57333019Ssbruno
58333019Ssbruno/* Busy wait timeout on a condition */
59333019Ssbruno#define	COND_BUSYWAIT(cond, timeout /* in millisecond */) { \
60333019Ssbruno		if (!(cond)) { \
61333019Ssbruno			while (timeout) { \
62333019Ssbruno				OS_BUSYWAIT(1000); \
63333019Ssbruno				if (cond) \
64333019Ssbruno					break; \
65333019Ssbruno				timeout--; \
66333019Ssbruno			} \
67333019Ssbruno		} \
68333019Ssbruno	}
69333019Ssbruno
70333019Ssbruno/* Wait timeout on a condition*/
71333019Ssbruno#define	COND_WAIT(cond, timeout /* in millisecond */) { \
72333019Ssbruno		if (!(cond)) { \
73333019Ssbruno			while (timeout) { \
74333019Ssbruno				OS_SLEEP(1000); \
75333019Ssbruno				if (cond) \
76333019Ssbruno					break; \
77333019Ssbruno				timeout--; \
78333019Ssbruno			} \
79333019Ssbruno		} \
80333019Ssbruno	}
81333019Ssbruno
82333019Ssbruno#define FILL_QUEUE_ARRAY_ADDR(q,virt,dma) { 	\
83333019Ssbruno			q->array_virt_addr = virt;	\
84333019Ssbruno			q->array_dma_addr = dma;	\
85333019Ssbruno		}
86333019Ssbruno
87333019Ssbruno#define	true	1
88333019Ssbruno#define false	0
89333019Ssbruno
90333019Ssbrunoenum INTR_TYPE {
91333019Ssbruno	LOCK_INTR,
92333019Ssbruno	LOCK_SLEEP
93333019Ssbruno};
94333019Ssbruno
95333019Ssbruno#define LOCKNAME_SIZE		32
96333019Ssbruno
97333019Ssbruno#define INTR_TYPE_FIXED		0x1
98333019Ssbruno#define INTR_TYPE_MSI		0x2
99333019Ssbruno#define INTR_TYPE_MSIX		0x4
100333019Ssbruno#define SIS_ENABLE_MSIX		0x40
101333019Ssbruno
102333019Ssbruno#define DMA_TO_VIRT(mem)	((mem)->virt_addr)
103333019Ssbruno#define DMA_PHYS_LOW(mem)	(((mem)->dma_addr)  & 0x00000000ffffffff)
104333019Ssbruno#define DMA_PHYS_HIGH(mem)	((((mem)->dma_addr) & 0xffffffff00000000) >> 32)
105333019Ssbruno
106333019Ssbruno
107333019Ssbrunotypedef enum REQUEST_STATUS {
108333019Ssbruno	REQUEST_SUCCESS = 0,
109333019Ssbruno	REQUEST_PENDING = -1,
110333019Ssbruno	REQUEST_FAILED = -2,
111333019Ssbruno}REQUEST_STATUS_T;
112333019Ssbruno
113333019Ssbrunotypedef enum IO_PATH {
114333019Ssbruno	AIO_PATH,
115333019Ssbruno	RAID_PATH
116333019Ssbruno}IO_PATH_T;
117333019Ssbruno
118333019Ssbrunotypedef enum device_type
119333019Ssbruno{
120333019Ssbruno	DISK_DEVICE,
121333019Ssbruno	TAPE_DEVICE,
122333019Ssbruno	ROM_DEVICE = 5,
123333019Ssbruno	MEDIUM_CHANGER_DEVICE = 8,
124333019Ssbruno	RAID_DEVICE = 0x0c,
125333019Ssbruno	ENCLOSURE_DEVICE,
126333019Ssbruno	ZBC_DEVICE = 0x14
127333019Ssbruno} device_type_t;
128333019Ssbruno
129333019Ssbrunotypedef enum controller_state {
130333019Ssbruno	PQI_UP_RUNNING,
131333019Ssbruno	PQI_BUS_RESET,
132333019Ssbruno}controller_state_t;
133333019Ssbruno
134333019Ssbruno
135333019Ssbruno#define PQISRC_MAX_MSIX_SUPPORTED		64
136333019Ssbruno
137333019Ssbruno/* SIS Specific */
138333019Ssbruno#define PQISRC_INIT_STRUCT_REVISION		9
139333019Ssbruno#define	PQISRC_SECTOR_SIZE			512
140333019Ssbruno#define	PQISRC_BLK_SIZE				PQISRC_SECTOR_SIZE
141333019Ssbruno#define	PQISRC_DEFAULT_DMA_ALIGN		4
142333019Ssbruno#define	PQISRC_DMA_ALIGN_MASK			(PQISRC_DEFAULT_DMA_ALIGN - 1)
143333019Ssbruno#define PQISRC_ERR_BUF_DMA_ALIGN		32
144333019Ssbruno#define PQISRC_ERR_BUF_ELEM_SIZE		MAX(sizeof(raid_path_error_info_elem_t),sizeof(aio_path_error_info_elem_t))
145333019Ssbruno#define	PQISRC_INIT_STRUCT_DMA_ALIGN		16
146333019Ssbruno
147333019Ssbruno#define SIS_CMD_GET_ADAPTER_PROPERTIES		0x19
148333019Ssbruno#define SIS_CMD_GET_COMM_PREFERRED_SETTINGS	0x26
149333019Ssbruno#define SIS_CMD_GET_PQI_CAPABILITIES		0x3000
150333019Ssbruno#define SIS_CMD_INIT_BASE_STRUCT_ADDRESS	0x1b
151333019Ssbruno
152333019Ssbruno#define SIS_SUPPORT_EXT_OPT			0x00800000
153333019Ssbruno#define SIS_SUPPORT_PQI				0x00000004
154333019Ssbruno#define SIS_SUPPORT_PQI_RESET_QUIESCE		0x00000008
155333019Ssbruno
156333019Ssbruno#define SIS_PQI_RESET_QUIESCE			0x1000000
157333019Ssbruno
158333019Ssbruno#define SIS_STATUS_OK_TIMEOUT			120000	/* in milli sec, 5 sec */
159333019Ssbruno
160333019Ssbruno#define SIS_CMD_COMPLETE_TIMEOUT   		30000  /* in milli sec, 30 secs */
161333019Ssbruno#define SIS_POLL_START_WAIT_TIME		20000  /* in micro sec, 20 milli sec */
162333019Ssbruno#define SIS_DB_BIT_CLEAR_TIMEOUT_CNT		120000	/* 500usec * 120000 = 60 sec */
163333019Ssbruno
164333019Ssbruno#define SIS_ENABLE_TIMEOUT			3000
165333019Ssbruno#define REENABLE_SIS				0x1
166333019Ssbruno#define TRIGGER_NMI_SIS				0x800000
167333019Ssbruno/*SIS Register status defines */
168333019Ssbruno
169333019Ssbruno#define PQI_CTRL_KERNEL_UP_AND_RUNNING		0x80
170333019Ssbruno#define PQI_CTRL_KERNEL_PANIC			0x100
171333019Ssbruno
172333019Ssbruno#define SIS_CTL_TO_HOST_DB_DISABLE_ALL		0xFFFFFFFF
173333019Ssbruno#define SIS_CTL_TO_HOST_DB_CLEAR		0x00001000
174333019Ssbruno#define	SIS_CMD_SUBMIT				0x00000200  /* Bit 9 */
175333019Ssbruno#define SIS_CMD_COMPLETE			0x00001000  /* Bit 12 */
176333019Ssbruno#define SIS_CMD_STATUS_SUCCESS			0x1
177333019Ssbruno
178333019Ssbruno/* PQI specific */
179333019Ssbruno
180333019Ssbruno/* defines */
181333019Ssbruno#define PQISRC_PQI_REG_OFFSET				0x4000
182333019Ssbruno#define	PQISRC_MAX_OUTSTANDING_REQ			4096
183333019Ssbruno#define	PQISRC_MAX_ADMIN_IB_QUEUE_ELEM_NUM		16
184333019Ssbruno#define	PQISRC_MAX_ADMIN_OB_QUEUE_ELEM_NUM		16
185333019Ssbruno
186333019Ssbruno
187333019Ssbruno
188333019Ssbruno#define PQI_MIN_OP_IB_QUEUE_ID				1
189333019Ssbruno#define PQI_OP_EVENT_QUEUE_ID				1
190333019Ssbruno#define PQI_MIN_OP_OB_QUEUE_ID				2
191333019Ssbruno
192333019Ssbruno#define	PQISRC_MAX_SUPPORTED_OP_IB_Q		128
193333019Ssbruno#define PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q	(PQISRC_MAX_SUPPORTED_OP_IB_Q / 2)
194333019Ssbruno#define PQISRC_MAX_SUPPORTED_OP_AIO_IB_Q	(PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q)
195333019Ssbruno#define	PQISRC_MAX_OP_IB_QUEUE_ELEM_NUM		(PQISRC_MAX_OUTSTANDING_REQ / PQISRC_MAX_SUPPORTED_OP_IB_Q)
196333019Ssbruno#define	PQISRC_MAX_OP_OB_QUEUE_ELEM_NUM		PQISRC_MAX_OUTSTANDING_REQ
197333019Ssbruno#define	PQISRC_MIN_OP_OB_QUEUE_ELEM_NUM		2
198333019Ssbruno#define	PQISRC_MAX_SUPPORTED_OP_OB_Q		64
199333019Ssbruno#define PQISRC_OP_MAX_IBQ_ELEM_SIZE		8 /* 8 * 16  = 128 bytes */
200333019Ssbruno#define PQISRC_OP_MIN_IBQ_ELEM_SIZE		2 /* 2 * 16  = 32 bytes */
201333019Ssbruno#define PQISRC_OP_OBQ_ELEM_SIZE			1 /* 16 bytes */
202333019Ssbruno#define PQISRC_ADMIN_IBQ_ELEM_SIZE		2 /* 2 * 16  = 32 bytes */
203333019Ssbruno#define PQISRC_INTR_COALSC_GRAN			0
204333019Ssbruno#define PQISRC_PROTO_BIT_MASK			0
205333019Ssbruno#define PQISRC_SGL_SUPPORTED_BIT_MASK		0
206333019Ssbruno
207333019Ssbruno#define PQISRC_NUM_EVENT_Q_ELEM			32
208333019Ssbruno#define PQISRC_EVENT_Q_ELEM_SIZE		32
209333019Ssbruno
210333019Ssbruno/* PQI Registers state status */
211333019Ssbruno
212333019Ssbruno#define PQI_RESET_ACTION_RESET			0x1
213333019Ssbruno#define PQI_RESET_ACTION_COMPLETED		0x2
214333019Ssbruno#define PQI_RESET_TYPE_NO_RESET			0x0
215333019Ssbruno#define PQI_RESET_TYPE_SOFT_RESET		0x1
216333019Ssbruno#define PQI_RESET_TYPE_FIRM_RESET		0x2
217333019Ssbruno#define PQI_RESET_TYPE_HARD_RESET		0x3
218333019Ssbruno
219333019Ssbruno#define PQI_RESET_POLL_INTERVAL 		100000 /*100 msec*/
220333019Ssbruno
221333019Ssbrunoenum pqisrc_ctrl_mode{
222333019Ssbruno	CTRL_SIS_MODE = 0,
223333019Ssbruno	CTRL_PQI_MODE
224333019Ssbruno};
225333019Ssbruno
226333019Ssbruno/* PQI device performing internal initialization (e.g., POST). */
227333019Ssbruno#define PQI_DEV_STATE_POWER_ON_AND_RESET	0x0
228333019Ssbruno/* Upon entry to this state PQI device initialization begins. */
229333019Ssbruno#define PQI_DEV_STATE_PQI_STATUS_AVAILABLE	0x1
230333019Ssbruno/* PQI device Standard registers are available to the driver. */
231333019Ssbruno#define PQI_DEV_STATE_ALL_REGISTERS_READY	0x2
232333019Ssbruno/* PQI device is initialized and ready to process any PCI transactions. */
233333019Ssbruno#define PQI_DEV_STATE_ADMIN_QUEUE_PAIR_READY	0x3
234333019Ssbruno/* The PQI Device Error register indicates the error. */
235333019Ssbruno#define PQI_DEV_STATE_ERROR			0x4
236333019Ssbruno
237333019Ssbruno#define PQI_DEV_STATE_AT_INIT			( PQI_DEV_STATE_PQI_STATUS_AVAILABLE | \
238333019Ssbruno						  PQI_DEV_STATE_ALL_REGISTERS_READY | \
239333019Ssbruno						  PQI_DEV_STATE_ADMIN_QUEUE_PAIR_READY )
240333019Ssbruno
241333019Ssbruno#define PQISRC_PQI_DEVICE_SIGNATURE		"PQI DREG"
242333019Ssbruno#define	PQI_ADMINQ_ELEM_ARRAY_ALIGN		64
243333019Ssbruno#define	PQI_ADMINQ_CI_PI_ALIGN			64
244333019Ssbruno#define	PQI_OPQ_ELEM_ARRAY_ALIGN		64
245333019Ssbruno#define	PQI_OPQ_CI_PI_ALIGN				4
246333019Ssbruno#define	PQI_ADDR_ALIGN_MASK_64			0x3F /* lsb 6 bits */
247333019Ssbruno#define	PQI_ADDR_ALIGN_MASK_4			0x3  /* lsb 2 bits */
248333019Ssbruno
249333019Ssbruno#define	PQISRC_PQIMODE_READY_TIMEOUT   		(30 * 1000 ) /* 30 secs */
250333019Ssbruno#define	PQISRC_MODE_READY_POLL_INTERVAL		1000 /* 1 msec */
251333019Ssbruno
252333019Ssbruno#define PRINT_PQI_SIGNATURE(sign)		{ int i = 0; \
253333019Ssbruno						  char si[9]; \
254333019Ssbruno						  for(i=0;i<8;i++) \
255333019Ssbruno							si[i] = *((char *)&(sign)+i); \
256333019Ssbruno						  si[i] = '\0'; \
257333019Ssbruno						  DBG_INFO("Signature is %s",si); \
258333019Ssbruno						}
259333019Ssbruno#define PQI_CONF_TABLE_MAX_LEN		((uint16_t)~0)
260333019Ssbruno#define PQI_CONF_TABLE_SIGNATURE	"CFGTABLE"
261333019Ssbruno
262333019Ssbruno/* PQI configuration table section IDs */
263333019Ssbruno#define PQI_CONF_TABLE_SECTION_GENERAL_INFO		0
264333019Ssbruno#define PQI_CONF_TABLE_SECTION_FIRMWARE_FEATURES	1
265333019Ssbruno#define PQI_CONF_TABLE_SECTION_FIRMWARE_ERRATA		2
266333019Ssbruno#define PQI_CONF_TABLE_SECTION_DEBUG			3
267333019Ssbruno#define PQI_CONF_TABLE_SECTION_HEARTBEAT		4
268333019Ssbruno
269333019Ssbruno#define CTRLR_HEARTBEAT_CNT(softs)		LE_64(PCI_MEM_GET64(softs, softs->heartbeat_counter_abs_addr, softs->heartbeat_counter_off))
270333019Ssbruno#define	PQI_NEW_HEARTBEAT_MECHANISM(softs)	1
271333019Ssbruno
272333019Ssbruno /* pqi-2r00a table 36 */
273333019Ssbruno#define PQI_ADMIN_QUEUE_MSIX_DISABLE		(0x80000000)
274333019Ssbruno#define PQI_ADMIN_QUEUE_MSIX_ENABLE		(0 << 31)
275333019Ssbruno
276333019Ssbruno#define	PQI_ADMIN_QUEUE_CONF_FUNC_CREATE_Q_PAIR	0x01
277333019Ssbruno#define	PQI_ADMIN_QUEUE_CONF_FUNC_DEL_Q_PAIR	0x02
278333019Ssbruno#define	PQI_ADMIN_QUEUE_CONF_FUNC_STATUS_IDLE	0x00
279333019Ssbruno#define PQISRC_ADMIN_QUEUE_CREATE_TIMEOUT	1000  /* in miLLI sec, 1 sec, 100 ms is standard */
280333019Ssbruno#define PQISRC_ADMIN_QUEUE_DELETE_TIMEOUT	100  /* 100 ms is standard */
281333019Ssbruno#define	PQISRC_ADMIN_CMD_RESP_TIMEOUT		3000 /* 3 sec  */
282333019Ssbruno#define PQISRC_RAIDPATH_CMD_TIMEOUT		30000 /* 30 sec */
283333019Ssbruno
284333019Ssbruno#define REPORT_PQI_DEV_CAP_DATA_BUF_SIZE   	sizeof(pqi_dev_cap_t)
285333019Ssbruno#define REPORT_MANUFACTURER_INFO_DATA_BUF_SIZE	0x80   /* Data buffer size specified in bytes 0-1 of data buffer.  128 bytes. */
286333019Ssbruno/* PQI IUs */
287333019Ssbruno/* Admin IU request length not including header. */
288333019Ssbruno#define	PQI_STANDARD_IU_LENGTH			0x003C  /* 60 bytes. */
289333019Ssbruno#define PQI_IU_TYPE_GENERAL_ADMIN_REQUEST	0x60
290333019Ssbruno#define PQI_IU_TYPE_GENERAL_ADMIN_RESPONSE	0xe0
291333019Ssbruno
292333019Ssbruno/* PQI / Vendor specific IU */
293333019Ssbruno#define	PQI_FUNCTION_REPORT_DEV_CAP				0x00
294333019Ssbruno#define PQI_REQUEST_IU_TASK_MANAGEMENT				0x13
295333019Ssbruno#define PQI_IU_TYPE_RAID_PATH_IO_REQUEST			0x14
296333019Ssbruno#define PQI_IU_TYPE_AIO_PATH_IO_REQUEST				0x15
297333019Ssbruno#define PQI_REQUEST_IU_GENERAL_ADMIN				0x60
298333019Ssbruno#define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG		0x72
299333019Ssbruno#define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG			0x73
300333019Ssbruno#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT			0x81
301333019Ssbruno#define PQI_RESPONSE_IU_TASK_MANAGEMENT				0x93
302333019Ssbruno#define PQI_RESPONSE_IU_GENERAL_ADMIN				0xe0
303333019Ssbruno
304333019Ssbruno#define PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS			0xf0
305333019Ssbruno#define PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS			0xf1
306333019Ssbruno#define PQI_RESPONSE_IU_RAID_PATH_IO_ERROR			0xf2
307333019Ssbruno#define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR			0xf3
308333019Ssbruno#define PQI_RESPONSE_IU_AIO_PATH_IS_OFF				0xf4
309333019Ssbruno#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT			0xf6
310333019Ssbruno#define PQI_REQUEST_HEADER_LENGTH				4
311333019Ssbruno#define PQI_FUNCTION_CREATE_OPERATIONAL_IQ			0x10
312333019Ssbruno#define PQI_FUNCTION_CREATE_OPERATIONAL_OQ			0x11
313333019Ssbruno#define PQI_FUNCTION_DELETE_OPERATIONAL_IQ			0x12
314333019Ssbruno#define PQI_FUNCTION_DELETE_OPERATIONAL_OQ			0x13
315333019Ssbruno#define PQI_FUNCTION_CHANGE_OPERATIONAL_IQ_PROP			0x14
316333019Ssbruno#define PQI_CHANGE_OP_IQ_PROP_ASSIGN_AIO			1
317333019Ssbruno
318333019Ssbruno#define PQI_DEFAULT_IB_QUEUE					0
319333019Ssbruno/* Interface macros */
320333019Ssbruno
321333019Ssbruno#define GET_FW_STATUS(softs) \
322333019Ssbruno        (PCI_MEM_GET32(softs, &softs->ioa_reg->scratchpad3_fw_status, LEGACY_SIS_OMR))
323333019Ssbruno
324333019Ssbruno#define SIS_IS_KERNEL_PANIC(softs) \
325333019Ssbruno	(GET_FW_STATUS(softs) & PQI_CTRL_KERNEL_PANIC)
326333019Ssbruno
327333019Ssbruno#define SIS_IS_KERNEL_UP(softs) \
328333019Ssbruno	(GET_FW_STATUS(softs) & PQI_CTRL_KERNEL_UP_AND_RUNNING)
329333019Ssbruno
330333019Ssbruno#define PQI_GET_CTRL_MODE(softs) \
331333019Ssbruno	(PCI_MEM_GET32(softs, &softs->ioa_reg->scratchpad0, LEGACY_SIS_SCR0))
332333019Ssbruno
333333019Ssbruno#define PQI_SAVE_CTRL_MODE(softs, mode) \
334333019Ssbruno	PCI_MEM_PUT32(softs, &softs->ioa_reg->scratchpad0, LEGACY_SIS_SCR0, mode)
335333019Ssbruno
336333019Ssbruno#define PQISRC_MAX_TARGETID			1024
337333019Ssbruno#define PQISRC_MAX_TARGETLUN			64
338333019Ssbruno
339333019Ssbruno/* Vendor specific IU Type for Event config Cmds */
340333019Ssbruno#define PQI_REQUEST_IU_REPORT_EVENT_CONFIG		0x72
341333019Ssbruno#define PQI_REQUEST_IU_SET_EVENT_CONFIG			0x73
342333019Ssbruno#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT		0xf6
343333019Ssbruno#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT		0x81
344333019Ssbruno#define	PQI_MANAGEMENT_CMD_RESP_TIMEOUT			3000
345333019Ssbruno#define	PQISRC_EVENT_ACK_RESP_TIMEOUT			1000
346333019Ssbruno
347333019Ssbruno
348333019Ssbruno/* Supported Event types by controller */
349333019Ssbruno#define PQI_NUM_SUPPORTED_EVENTS		7
350333019Ssbruno
351333019Ssbruno#define PQI_EVENT_TYPE_HOTPLUG			0x1
352333019Ssbruno#define PQI_EVENT_TYPE_HARDWARE			0x2
353333019Ssbruno#define PQI_EVENT_TYPE_PHYSICAL_DEVICE		0x4
354333019Ssbruno#define PQI_EVENT_TYPE_LOGICAL_DEVICE		0x5
355333019Ssbruno#define PQI_EVENT_TYPE_AIO_STATE_CHANGE		0xfd
356333019Ssbruno#define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE	0xfe
357333019Ssbruno#define PQI_EVENT_TYPE_HEARTBEAT		0xff
358333019Ssbruno
359333019Ssbruno/* for indexing into the pending_events[] field of struct pqisrc_softstate */
360333019Ssbruno#define PQI_EVENT_HEARTBEAT		0
361333019Ssbruno#define PQI_EVENT_HOTPLUG		1
362333019Ssbruno#define PQI_EVENT_HARDWARE		2
363333019Ssbruno#define PQI_EVENT_PHYSICAL_DEVICE	3
364333019Ssbruno#define PQI_EVENT_LOGICAL_DEVICE	4
365333019Ssbruno#define PQI_EVENT_AIO_STATE_CHANGE	5
366333019Ssbruno#define PQI_EVENT_AIO_CONFIG_CHANGE	6
367333019Ssbruno
368333019Ssbruno#define PQI_MAX_HEARTBEAT_REQUESTS	5
369333019Ssbruno
370333019Ssbruno
371333019Ssbruno/* Device flags */
372333019Ssbruno#define	PQISRC_DFLAG_VALID			(1 << 0)
373333019Ssbruno#define	PQISRC_DFLAG_CONFIGURING		(1 << 1)
374333019Ssbruno
375333019Ssbruno#define MAX_EMBEDDED_SG_IN_FIRST_IU		4
376333019Ssbruno#define MAX_EMBEDDED_SG_IN_IU			8
377333019Ssbruno#define SG_FLAG_LAST				0x40000000
378333019Ssbruno#define SG_FLAG_CHAIN				0x80000000
379333019Ssbruno
380333019Ssbruno#define IN_PQI_RESET(softs)			(softs->ctlr_state & PQI_BUS_RESET)
381333019Ssbruno#define DEV_GONE(dev)				(!dev || (dev->invalid == true))
382333019Ssbruno#define IS_AIO_PATH(dev)				(dev->aio_enabled)
383333019Ssbruno#define IS_RAID_PATH(dev)				(!dev->aio_enabled)
384333019Ssbruno
385333019Ssbruno/* SOP data direction flags */
386333019Ssbruno#define SOP_DATA_DIR_NONE			0x00
387333019Ssbruno#define SOP_DATA_DIR_FROM_DEVICE		0x01
388333019Ssbruno#define SOP_DATA_DIR_TO_DEVICE			0x02
389333019Ssbruno#define SOP_DATA_DIR_BIDIRECTIONAL		0x03
390333019Ssbruno#define SOP_PARTIAL_DATA_BUFFER			0x04
391333019Ssbruno
392333019Ssbruno#define PQISRC_DMA_VALID			(1 << 0)
393333019Ssbruno#define PQISRC_CMD_NO_INTR			(1 << 1)
394333019Ssbruno
395333019Ssbruno#define SOP_TASK_ATTRIBUTE_SIMPLE		0
396333019Ssbruno#define SOP_TASK_ATTRIBUTE_HEAD_OF_QUEUE	1
397333019Ssbruno#define SOP_TASK_ATTRIBUTE_ORDERED		2
398333019Ssbruno#define SOP_TASK_ATTRIBUTE_ACA			4
399333019Ssbruno
400333019Ssbruno#define SOP_TASK_MANAGEMENT_FUNCTION_COMPLETE           0x0
401333019Ssbruno#define SOP_TASK_MANAGEMENT_FUNCTION_REJECTED           0x4
402333019Ssbruno#define SOP_TASK_MANAGEMENT_FUNCTION_FAILED		0x5
403333019Ssbruno#define SOP_TASK_MANAGEMENT_FUNCTION_SUCCEEDED          0x8
404333019Ssbruno#define SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK		0x01
405333019Ssbruno#define SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK_SET	0x02
406333019Ssbruno#define SOP_TASK_MANAGEMENT_LUN_RESET			0x8
407333019Ssbruno
408333019Ssbruno
409333019Ssbruno/* Additional CDB bytes  */
410333019Ssbruno#define PQI_ADDITIONAL_CDB_BYTES_0		0	/* 16 byte CDB */
411333019Ssbruno#define PQI_ADDITIONAL_CDB_BYTES_4		1	/* 20 byte CDB */
412333019Ssbruno#define PQI_ADDITIONAL_CDB_BYTES_8		2	/* 24 byte CDB */
413333019Ssbruno#define PQI_ADDITIONAL_CDB_BYTES_12		3	/* 28 byte CDB */
414333019Ssbruno#define PQI_ADDITIONAL_CDB_BYTES_16		4	/* 32 byte CDB */
415333019Ssbruno
416333019Ssbruno#define PQI_PROTOCOL_SOP			0x0
417333019Ssbruno
418333019Ssbruno#define PQI_AIO_STATUS_GOOD			0x0
419333019Ssbruno#define PQI_AIO_STATUS_CHECK_CONDITION		0x2
420333019Ssbruno#define PQI_AIO_STATUS_CONDITION_MET		0x4
421333019Ssbruno#define PQI_AIO_STATUS_DEVICE_BUSY		0x8
422333019Ssbruno#define PQI_AIO_STATUS_INT_GOOD			0x10
423333019Ssbruno#define PQI_AIO_STATUS_INT_COND_MET		0x14
424333019Ssbruno#define PQI_AIO_STATUS_RESERV_CONFLICT		0x18
425333019Ssbruno#define PQI_AIO_STATUS_CMD_TERMINATED		0x22
426333019Ssbruno#define PQI_AIO_STATUS_QUEUE_FULL		0x28
427333019Ssbruno#define PQI_AIO_STATUS_TASK_ABORTED		0x40
428333019Ssbruno#define PQI_AIO_STATUS_UNDERRUN			0x51
429333019Ssbruno#define PQI_AIO_STATUS_OVERRUN			0x75
430333019Ssbruno/* Status when Target Failure */
431333019Ssbruno#define PQI_AIO_STATUS_IO_ERROR			0x1
432333019Ssbruno#define PQI_AIO_STATUS_IO_ABORTED		0x2
433333019Ssbruno#define PQI_AIO_STATUS_IO_NO_DEVICE		0x3
434333019Ssbruno#define PQI_AIO_STATUS_INVALID_DEVICE		0x4
435333019Ssbruno#define PQI_AIO_STATUS_AIO_PATH_DISABLED	0xe
436333019Ssbruno
437333019Ssbruno/* Service Response */
438333019Ssbruno#define PQI_AIO_SERV_RESPONSE_COMPLETE			0
439333019Ssbruno#define PQI_AIO_SERV_RESPONSE_FAILURE			1
440333019Ssbruno#define PQI_AIO_SERV_RESPONSE_TMF_COMPLETE		2
441333019Ssbruno#define PQI_AIO_SERV_RESPONSE_TMF_SUCCEEDED		3
442333019Ssbruno#define PQI_AIO_SERV_RESPONSE_TMF_REJECTED		4
443333019Ssbruno#define PQI_AIO_SERV_RESPONSE_TMF_INCORRECT_LUN		5
444333019Ssbruno
445333019Ssbruno#define PQI_TMF_WAIT_DELAY				10000000	/* 10 seconds */
446333019Ssbruno
447333019Ssbruno#define PQI_RAID_STATUS_GOOD				PQI_AIO_STATUS_GOOD
448333019Ssbruno#define PQI_RAID_STATUS_CHECK_CONDITION			PQI_AIO_STATUS_CHECK_CONDITION
449333019Ssbruno#define PQI_RAID_STATUS_CONDITION_MET			PQI_AIO_STATUS_CONDITION_MET
450333019Ssbruno#define PQI_RAID_STATUS_DEVICE_BUSY			PQI_AIO_STATUS_DEVICE_BUSY
451333019Ssbruno#define PQI_RAID_STATUS_INT_GOOD			PQI_AIO_STATUS_INT_GOOD
452333019Ssbruno#define PQI_RAID_STATUS_INT_COND_MET			PQI_AIO_STATUS_INT_COND_MET
453333019Ssbruno#define PQI_RAID_STATUS_RESERV_CONFLICT			PQI_AIO_STATUS_RESERV_CONFLICT
454333019Ssbruno#define PQI_RAID_STATUS_CMD_TERMINATED			PQI_AIO_STATUS_CMD_TERMINATED
455333019Ssbruno#define PQI_RAID_STATUS_QUEUE_FULL			PQI_AIO_STATUS_QUEUE_FULL
456333019Ssbruno#define PQI_RAID_STATUS_TASK_ABORTED			PQI_AIO_STATUS_TASK_ABORTED
457333019Ssbruno#define PQI_RAID_STATUS_UNDERRUN			PQI_AIO_STATUS_UNDERRUN
458333019Ssbruno#define PQI_RAID_STATUS_OVERRUN				PQI_AIO_STATUS_OVERRUN
459333019Ssbruno
460333019Ssbruno/* VPD inquiry pages */
461333019Ssbruno#define SCSI_VPD_SUPPORTED_PAGES	0x0	/* standard page */
462333019Ssbruno#define SCSI_VPD_DEVICE_ID		0x83	/* standard page */
463333019Ssbruno#define SA_VPD_PHYS_DEVICE_ID		0xc0	/* vendor-specific page */
464333019Ssbruno#define SA_VPD_LV_DEVICE_GEOMETRY	0xc1	/* vendor-specific page */
465333019Ssbruno#define SA_VPD_LV_IOACCEL_STATUS	0xc2	/* vendor-specific page */
466333019Ssbruno#define SA_VPD_LV_STATUS		0xc3	/* vendor-specific page */
467333019Ssbruno
468333019Ssbruno#define VPD_PAGE			(1 << 8)
469333019Ssbruno
470333019Ssbruno
471333019Ssbruno/* logical volume states */
472333019Ssbruno#define SA_LV_OK					0x0
473333019Ssbruno#define SA_LV_NOT_AVAILABLE				0xb
474333019Ssbruno#define SA_LV_UNDERGOING_ERASE				0xf
475333019Ssbruno#define SA_LV_UNDERGOING_RPI				0x12
476333019Ssbruno#define SA_LV_PENDING_RPI				0x13
477333019Ssbruno#define SA_LV_ENCRYPTED_NO_KEY				0x14
478333019Ssbruno#define SA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER	0x15
479333019Ssbruno#define SA_LV_UNDERGOING_ENCRYPTION			0x16
480333019Ssbruno#define SA_LV_UNDERGOING_ENCRYPTION_REKEYING		0x17
481333019Ssbruno#define SA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER	0x18
482333019Ssbruno#define SA_LV_PENDING_ENCRYPTION			0x19
483333019Ssbruno#define SA_LV_PENDING_ENCRYPTION_REKEYING		0x1a
484333019Ssbruno#define SA_LV_STATUS_VPD_UNSUPPORTED			0xff
485333019Ssbruno
486333019Ssbruno/*
487333019Ssbruno * assume worst case: SATA queue depth of 31 minus 4 internal firmware commands
488333019Ssbruno */
489333019Ssbruno#define PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH	27
490333019Ssbruno
491333019Ssbruno/* 0 = no limit */
492333019Ssbruno#define PQI_LOGICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH	0
493333019Ssbruno
494333019Ssbruno
495333019Ssbruno
496333019Ssbruno#define RAID_CTLR_LUNID		"\0\0\0\0\0\0\0\0"
497333019Ssbruno
498333019Ssbruno#define SA_CACHE_FLUSH		0x1
499333019Ssbruno#define SA_INQUIRY		0x12
500333019Ssbruno#define SA_REPORT_LOG		0xc2	/* Report Logical LUNs */
501333019Ssbruno#define SA_REPORT_PHYS		0xc3	/* Report Physical LUNs */
502333019Ssbruno#define SA_CISS_READ		0xc0
503333019Ssbruno#define SA_GET_RAID_MAP		0xc8
504333019Ssbruno
505333019Ssbruno#define SA_REPORT_LOG_EXTENDED		0x1
506333019Ssbruno#define SA_REPORT_PHYS_EXTENDED		0x2
507333019Ssbruno
508333019Ssbruno#define SA_CACHE_FLUSH_BUF_LEN		4
509333019Ssbruno
510333019Ssbruno#define REPORT_LUN_DEV_FLAG_AIO_ENABLED 		0x8
511333019Ssbruno#define PQI_MAX_TRANSFER_SIZE				(4 * 1024U * 1024U)
512333019Ssbruno#define RAID_MAP_MAX_ENTRIES				1024
513333019Ssbruno#define RAID_MAP_ENCRYPTION_ENABLED			0x1
514333019Ssbruno#define PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH	27
515333019Ssbruno
516333019Ssbruno#define ASC_LUN_NOT_READY				0x4
517333019Ssbruno#define ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS		0x4
518333019Ssbruno#define ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ		0x2
519333019Ssbruno
520333019Ssbruno
521333019Ssbruno#define OBDR_SIG_OFFSET		43
522333019Ssbruno#define OBDR_TAPE_SIG		"$DR-10"
523333019Ssbruno#define OBDR_SIG_LEN		(sizeof(OBDR_TAPE_SIG) - 1)
524333019Ssbruno#define OBDR_TAPE_INQ_SIZE	(OBDR_SIG_OFFSET + OBDR_SIG_LEN)
525333019Ssbruno
526333019Ssbruno
527333019Ssbruno#define IOACCEL_STATUS_BYTE	4
528333019Ssbruno#define OFFLOAD_CONFIGURED_BIT	0x1
529333019Ssbruno#define OFFLOAD_ENABLED_BIT	0x2
530333019Ssbruno
531333019Ssbruno#define PQI_RAID_DATA_IN_OUT_GOOD		0x0
532333019Ssbruno#define PQI_RAID_DATA_IN_OUT_UNDERFLOW		0x1
533333019Ssbruno#define PQI_RAID_DATA_IN_OUT_UNSOLICITED_ABORT	0xf3
534333019Ssbruno#define PQI_RAID_DATA_IN_OUT_ABORTED		0xf4
535333019Ssbruno
536333019Ssbruno#define PQI_PHYSICAL_DEVICE_BUS		0
537333019Ssbruno#define PQI_RAID_VOLUME_BUS		1
538333019Ssbruno#define PQI_HBA_BUS			2
539333019Ssbruno#define PQI_EXTERNAL_RAID_VOLUME_BUS	3
540333019Ssbruno#define PQI_MAX_BUS			PQI_EXTERNAL_RAID_VOLUME_BUS
541333019Ssbruno
542333019Ssbruno#define TEST_UNIT_READY		0x00
543333019Ssbruno#define SCSI_VPD_HEADER_LENGTH	64
544333019Ssbruno
545333019Ssbruno
546333019Ssbruno#define PQI_MAX_MULTILUN	256
547333019Ssbruno#define PQI_MAX_LOGICALS	64
548333019Ssbruno#define PQI_MAX_PHYSICALS	1024
549333019Ssbruno#define	PQI_MAX_DEVICES		(PQI_MAX_LOGICALS + PQI_MAX_PHYSICALS + 1) /* 1 for controller device entry */
550333019Ssbruno
551333019Ssbruno
552333019Ssbruno#define PQI_CTLR_INDEX		(PQI_MAX_DEVICES - 1)
553333019Ssbruno#define PQI_PD_INDEX(t)		(t + PQI_MAX_LOGICALS)
554333019Ssbruno
555333019Ssbruno#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
556333019Ssbruno#define MAX_TARGET_DEVICES 1024
557333019Ssbruno
558333019Ssbruno#define PQI_NO_MEM	2
559333019Ssbruno
560333019Ssbrunotypedef enum pqisrc_device_status {
561333019Ssbruno	DEVICE_NOT_FOUND,
562333019Ssbruno	DEVICE_CHANGED,
563333019Ssbruno	DEVICE_UNCHANGED,
564333019Ssbruno} device_status_t;
565333019Ssbruno
566333019Ssbruno#define SA_RAID_0			0
567333019Ssbruno#define SA_RAID_4			1
568333019Ssbruno#define SA_RAID_1			2	/* also used for RAID 10 */
569333019Ssbruno#define SA_RAID_5			3	/* also used for RAID 50 */
570333019Ssbruno#define SA_RAID_51			4
571333019Ssbruno#define SA_RAID_6			5	/* also used for RAID 60 */
572333019Ssbruno#define SA_RAID_ADM			6	/* also used for RAID 1+0 ADM */
573333019Ssbruno#define SA_RAID_MAX			SA_RAID_ADM
574333019Ssbruno#define SA_RAID_UNKNOWN			0xff
575333019Ssbruno
576333019Ssbruno/* BMIC commands */
577333019Ssbruno#define BMIC_IDENTIFY_CONTROLLER		0x11
578333019Ssbruno#define BMIC_IDENTIFY_PHYSICAL_DEVICE		0x15
579333019Ssbruno#define BMIC_READ				0x26
580333019Ssbruno#define BMIC_WRITE				0x27
581333019Ssbruno#define BMIC_SENSE_CONTROLLER_PARAMETERS	0x64
582333019Ssbruno#define BMIC_SENSE_SUBSYSTEM_INFORMATION	0x66
583333019Ssbruno#define BMIC_CACHE_FLUSH			0xc2
584333019Ssbruno#define BMIC_FLASH_FIRMWARE			0xf7
585333019Ssbruno#define BMIC_WRITE_HOST_WELLNESS		0xa5
586333019Ssbruno
587333019Ssbruno
588333019Ssbruno#define MASKED_DEVICE(lunid)			((lunid)[3] & 0xC0)
589333019Ssbruno#define BMIC_GET_LEVEL_2_BUS(lunid)		((lunid)[7] & 0x3F)
590333019Ssbruno#define BMIC_GET_LEVEL_TWO_TARGET(lunid)	((lunid)[6])
591333019Ssbruno#define BMIC_GET_DRIVE_NUMBER(lunid)		\
592333019Ssbruno	(((BMIC_GET_LEVEL_2_BUS((lunid)) - 1) << 8) +	\
593333019Ssbruno	BMIC_GET_LEVEL_TWO_TARGET((lunid)))
594333019Ssbruno#define NON_DISK_PHYS_DEV(rle)			\
595333019Ssbruno	(((reportlun_ext_entry_t *)(rle))->device_flags & 0x1)
596333019Ssbruno
597333019Ssbruno#define NO_TIMEOUT		((unsigned long) -1)
598333019Ssbruno
599333019Ssbruno#define BMIC_DEVICE_TYPE_SATA	0x1
600333019Ssbruno
601333019Ssbruno/* No of IO slots required for internal requests */
602333019Ssbruno#define PQI_RESERVED_IO_SLOTS_SYNC_REQUESTS	3
603333019Ssbruno#define PQI_RESERVED_IO_SLOTS_TMF		1
604333019Ssbruno#define PQI_RESERVED_IO_SLOTS_CNT		(PQI_NUM_SUPPORTED_EVENTS + \
605333019Ssbruno						PQI_RESERVED_IO_SLOTS_TMF + \
606333019Ssbruno						PQI_RESERVED_IO_SLOTS_SYNC_REQUESTS)
607333019Ssbruno
608333019Ssbrunostatic inline uint16_t GET_LE16(const uint8_t *p)
609333019Ssbruno{
610333019Ssbruno	return p[0] | p[1] << 8;
611333019Ssbruno}
612333019Ssbruno
613333019Ssbrunostatic inline uint32_t GET_LE32(const uint8_t *p)
614333019Ssbruno{
615333019Ssbruno	return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
616333019Ssbruno}
617333019Ssbruno
618333019Ssbrunostatic inline uint64_t GET_LE64(const uint8_t *p)
619333019Ssbruno{
620333019Ssbruno	return (((uint64_t)GET_LE32(p + 4) << 32) |
621333019Ssbruno		GET_LE32(p));
622333019Ssbruno}
623333019Ssbruno
624333019Ssbrunostatic inline uint16_t GET_BE16(const uint8_t *p)
625333019Ssbruno{
626333019Ssbruno        return p[0] << 8 | p[1];
627333019Ssbruno}
628333019Ssbruno
629333019Ssbrunostatic inline uint32_t GET_BE32(const uint8_t *p)
630333019Ssbruno{
631333019Ssbruno        return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
632333019Ssbruno}
633333019Ssbruno
634333019Ssbrunostatic inline uint64_t GET_BE64(const uint8_t *p)
635333019Ssbruno{
636333019Ssbruno        return (((uint64_t)GET_BE32(p) << 32) |
637333019Ssbruno               GET_BE32(p + 4));
638333019Ssbruno}
639333019Ssbruno
640333019Ssbrunostatic inline void PUT_BE16(uint16_t val, uint8_t *p)
641333019Ssbruno{
642333019Ssbruno        *p++ = val >> 8;
643333019Ssbruno        *p++ = val;
644333019Ssbruno}
645333019Ssbruno
646333019Ssbrunostatic inline void PUT_BE32(uint32_t val, uint8_t *p)
647333019Ssbruno{
648333019Ssbruno        PUT_BE16(val >> 16, p);
649333019Ssbruno        PUT_BE16(val, p + 2);
650333019Ssbruno}
651333019Ssbruno
652333019Ssbrunostatic inline void PUT_BE64(uint64_t val, uint8_t *p)
653333019Ssbruno{
654333019Ssbruno        PUT_BE32(val >> 32, p);
655333019Ssbruno        PUT_BE32(val, p + 4);
656333019Ssbruno}
657333019Ssbruno
658333019Ssbruno
659333019Ssbruno#define OS_FREEBSD
660333019Ssbruno#define SIS_POLL_WAIT
661333019Ssbruno
662333019Ssbruno#define OS_ATTRIBUTE_PACKED         __attribute__((__packed__))
663333019Ssbruno#define OS_ATTRIBUTE_ALIGNED(n)     __attribute__((aligned(n)))
664333019Ssbruno
665333019Ssbruno
666333019Ssbruno/* Management Interface */
667333019Ssbruno#define CCISS_IOC_MAGIC		'C'
668333019Ssbruno#define SMARTPQI_IOCTL_BASE     'M'
669333019Ssbruno#define CCISS_GETDRIVVER       _IOWR(SMARTPQI_IOCTL_BASE, 0, driver_info)
670333019Ssbruno#define CCISS_GETPCIINFO       _IOWR(SMARTPQI_IOCTL_BASE, 1, pqi_pci_info_t)
671333019Ssbruno#define SMARTPQI_PASS_THRU     _IOWR(SMARTPQI_IOCTL_BASE, 2, IOCTL_Command_struct)
672333019Ssbruno#define CCISS_PASSTHRU         _IOWR('C', 210, IOCTL_Command_struct)
673333019Ssbruno#define CCISS_REGNEWD          _IO(CCISS_IOC_MAGIC, 14)
674333019Ssbruno
675333019Ssbruno/*IOCTL  pci_info structure */
676333019Ssbrunotypedef struct pqi_pci_info
677333019Ssbruno{
678333019Ssbruno       unsigned char   bus;
679333019Ssbruno       unsigned char   dev_fn;
680333019Ssbruno       unsigned short  domain;
681333019Ssbruno       uint32_t        board_id;
682333019Ssbruno       uint32_t        chip_id;
683333019Ssbruno}pqi_pci_info_t;
684333019Ssbruno
685333019Ssbrunotypedef struct _driver_info
686333019Ssbruno{
687333019Ssbruno	unsigned char 	major_version;
688333019Ssbruno	unsigned char 	minor_version;
689333019Ssbruno	unsigned char 	release_version;
690333019Ssbruno	unsigned long 	build_revision;
691333019Ssbruno	unsigned long 	max_targets;
692333019Ssbruno	unsigned long 	max_io;
693333019Ssbruno	unsigned long 	max_transfer_length;
694333019Ssbruno}driver_info, *pdriver_info;
695333019Ssbruno
696333019Ssbrunotypedef uint8_t *passthru_buf_type_t;
697333019Ssbruno
698333019Ssbruno
699333019Ssbruno#define PQISRC_DRIVER_MAJOR		1
700333019Ssbruno#define PQISRC_DRIVER_MINOR		0
701333019Ssbruno#define PQISRC_DRIVER_RELEASE		1
702333019Ssbruno# define PQISRC_DRIVER_REVISION 239
703333019Ssbruno
704333019Ssbruno#define STR(s)                          # s
705333019Ssbruno#define PQISRC_VERSION(a, b, c, d)      STR(a.b.c-d)
706333019Ssbruno#define PQISRC_DRIVER_VERSION           PQISRC_VERSION(PQISRC_DRIVER_MAJOR, \
707333019Ssbruno                                        PQISRC_DRIVER_MINOR, \
708333019Ssbruno                                        PQISRC_DRIVER_RELEASE, \
709333019Ssbruno                                        PQISRC_DRIVER_REVISION)
710333019Ssbruno
711333019Ssbruno/* End Management interface */
712333019Ssbruno
713333019Ssbruno#ifdef ASSERT
714333019Ssbruno#undef ASSERT
715333019Ssbruno#endif
716333019Ssbruno
717333019Ssbruno#define ASSERT(cond) {\
718333019Ssbruno        	if (!(cond)) { \
719333019Ssbruno			printf("Assertion failed at file %s line %d\n",__FILE__,__LINE__);	\
720333019Ssbruno		}	\
721333019Ssbruno		}
722333019Ssbruno
723333019Ssbruno
724333019Ssbruno#define PQI_MAX_MSIX            64      /* vectors */
725333019Ssbruno#define PQI_MSI_CTX_SIZE        sizeof(pqi_intr_ctx)+1
726333019Ssbruno#define IS_POLLING_REQUIRED(softs)	if (cold) {\
727333019Ssbruno					pqisrc_process_event_intr_src(softs, 0);\
728333019Ssbruno					pqisrc_process_response_queue(softs, 1);\
729333019Ssbruno				}
730333019Ssbruno
731333019Ssbruno#define OS_GET_TASK_ATTR(rcb)		os_get_task_attr(rcb)
732333019Ssbruno#define OS_FW_HEARTBEAT_TIMER_INTERVAL (5)
733333019Ssbruno
734333019Ssbrunotypedef struct PCI_ACC_HANDLE {
735333019Ssbruno        bus_space_tag_t         pqi_btag;
736333019Ssbruno        bus_space_handle_t      pqi_bhandle;
737333019Ssbruno} PCI_ACC_HANDLE_T;
738333019Ssbruno
739333019Ssbruno/*
740333019Ssbruno * Legacy SIS Register definitions for the Adaptec PMC SRC/SRCv/smartraid adapters.
741333019Ssbruno */
742333019Ssbruno/* accessible via BAR0 */
743333019Ssbruno#define LEGACY_SIS_IOAR		0x18	/* IOA->host interrupt register */
744333019Ssbruno#define LEGACY_SIS_IDBR		0x20	/* inbound doorbell register */
745333019Ssbruno#define LEGACY_SIS_IISR		0x24	/* inbound interrupt status register */
746333019Ssbruno#define LEGACY_SIS_OIMR		0x34	/* outbound interrupt mask register */
747333019Ssbruno#define LEGACY_SIS_ODBR_R	0x9c	/* outbound doorbell register read */
748333019Ssbruno#define LEGACY_SIS_ODBR_C	0xa0	/* outbound doorbell register clear */
749333019Ssbruno
750333019Ssbruno#define LEGACY_SIS_SCR0		0xb0	/* scratchpad 0 */
751333019Ssbruno#define LEGACY_SIS_OMR		0xbc	/* outbound message register */
752333019Ssbruno#define LEGACY_SIS_IQUE64_L	0xc0	/* inbound queue address 64-bit (low) */
753333019Ssbruno#define LEGACY_SIS_IQUE64_H	0xc4	/* inbound queue address 64-bit (high)*/
754333019Ssbruno#define LEGACY_SIS_ODBR_MSI	0xc8	/* MSI register for sync./AIF */
755333019Ssbruno#define LEGACY_SIS_IQN_L	0xd0	/* inbound queue native mode (low) */
756333019Ssbruno#define LEGACY_SIS_IQN_H	0xd4	/* inbound queue native mode (high)*/
757333019Ssbruno#define LEGACY_SIS_MAILBOX	0x7fc60	/* mailbox (20 bytes) */
758333019Ssbruno#define LEGACY_SIS_SRCV_MAILBOX	0x1000	/* mailbox (20 bytes) */
759333019Ssbruno
760333019Ssbruno#define LEGACY_SIS_ODR_SHIFT 	12	/* outbound doorbell shift */
761333019Ssbruno#define LEGACY_SIS_IDR_SHIFT 	9	/* inbound doorbell shift */
762333019Ssbruno
763333019Ssbruno
764333019Ssbruno/*
765333019Ssbruno * PQI Register definitions for the smartraid adapters
766333019Ssbruno */
767333019Ssbruno/* accessible via BAR0 */
768333019Ssbruno#define PQI_SIGNATURE                  0x4000
769333019Ssbruno#define PQI_ADMINQ_CONFIG              0x4008
770333019Ssbruno#define PQI_ADMINQ_CAP                 0x4010
771333019Ssbruno#define PQI_LEGACY_INTR_STATUS         0x4018
772333019Ssbruno#define PQI_LEGACY_INTR_MASK_SET       0x401C
773333019Ssbruno#define PQI_LEGACY_INTR_MASK_CLR       0x4020
774333019Ssbruno#define PQI_DEV_STATUS                 0x4040
775333019Ssbruno#define PQI_ADMIN_IBQ_PI_OFFSET        0x4048
776333019Ssbruno#define PQI_ADMIN_OBQ_CI_OFFSET        0x4050
777333019Ssbruno#define PQI_ADMIN_IBQ_ELEM_ARRAY_ADDR  0x4058
778333019Ssbruno#define PQI_ADMIN_OBQ_ELEM_ARRAY_ADDR  0x4060
779333019Ssbruno#define PQI_ADMIN_IBQ_CI_ADDR          0x4068
780333019Ssbruno#define PQI_ADMIN_OBQ_PI_ADDR          0x4070
781333019Ssbruno#define PQI_ADMINQ_PARAM               0x4078
782333019Ssbruno#define PQI_DEV_ERR                    0x4080
783333019Ssbruno#define PQI_DEV_ERR_DETAILS            0x4088
784333019Ssbruno#define PQI_DEV_RESET                  0x4090
785333019Ssbruno#define PQI_POWER_ACTION               0x4094
786333019Ssbruno
787333019Ssbruno/* Busy wait micro seconds */
788333019Ssbruno#define OS_BUSYWAIT(x) DELAY(x)
789333019Ssbruno#define OS_SLEEP(timeout)	\
790333019Ssbruno	DELAY(timeout);
791333019Ssbruno
792333019Ssbruno#define OS_HOST_WELLNESS_TIMEOUT	(24 * 3600)
793333019Ssbruno
794333019Ssbruno
795333019Ssbruno#define LE_16(x) htole16(x)
796333019Ssbruno#define LE_32(x) htole32(x)
797333019Ssbruno#define LE_64(x) htole64(x)
798333019Ssbruno#define BE_16(x) htobe16(x)
799333019Ssbruno#define BE_32(x) htobe32(x)
800333019Ssbruno#define BE_64(x) htobe64(x)
801333019Ssbruno
802333019Ssbruno#define PQI_HWIF_SRCV           0
803333019Ssbruno#define PQI_HWIF_UNKNOWN        -1
804333019Ssbruno
805333019Ssbruno
806333019Ssbruno#define SMART_STATE_SUSPEND     	(1<<0)
807333019Ssbruno#define SMART_STATE_UNUSED0     	(1<<1)
808333019Ssbruno#define SMART_STATE_INTERRUPTS_ON       (1<<2)
809333019Ssbruno#define SMART_STATE_AIF_SLEEPER 	(1<<3)
810333019Ssbruno#define SMART_STATE_RESET               (1<<4)
811333019Ssbruno
812333019Ssbruno#define PQI_FLAG_BUSY 			(1<<0)
813333019Ssbruno#define PQI_MSI_ENABLED 		(1<<1)
814333019Ssbruno#define PQI_SIM_REGISTERED 		(1<<2)
815333019Ssbruno#define PQI_MTX_INIT	 		(1<<3)
816333019Ssbruno
817333019Ssbruno
818333019Ssbruno#define PQI_CMD_MAPPED 			(1<<2)
819333019Ssbruno
820333019Ssbruno/* Interrupt context to get oq_id */
821333019Ssbrunotypedef struct pqi_intr_ctx {
822333019Ssbruno        int 	 oq_id;
823333019Ssbruno        device_t pqi_dev;
824333019Ssbruno}pqi_intr_ctx_t;
825333019Ssbruno
826333019Ssbrunotypedef uint8_t os_dev_info_t;
827333019Ssbruno
828333019Ssbrunotypedef struct OS_SPECIFIC {
829333019Ssbruno	device_t                pqi_dev;
830333019Ssbruno	struct resource		*pqi_regs_res0; /* reg. if. window */
831333019Ssbruno	int			pqi_regs_rid0;		/* resource ID */
832333019Ssbruno	bus_dma_tag_t		pqi_parent_dmat;	/* parent DMA tag */
833333019Ssbruno	bus_dma_tag_t           pqi_buffer_dmat;
834333019Ssbruno
835333019Ssbruno	/* controller hardware interface */
836333019Ssbruno	int			pqi_hwif;
837333019Ssbruno	struct resource         *pqi_irq[PQI_MAX_MSIX];  /* interrupt */
838333019Ssbruno	int                     pqi_irq_rid[PQI_MAX_MSIX];
839333019Ssbruno	void                    *intrcookie[PQI_MAX_MSIX];
840333019Ssbruno	bool                    intr_registered[PQI_MAX_MSIX];
841333019Ssbruno	bool			msi_enabled;            /* MSI/MSI-X enabled */
842333019Ssbruno	pqi_intr_ctx_t		*msi_ctx;
843333019Ssbruno	int			oq_id;
844333019Ssbruno	int			pqi_state;
845333019Ssbruno	uint32_t		pqi_flags;
846333019Ssbruno	struct mtx              cam_lock;
847333019Ssbruno	struct mtx              map_lock;
848333019Ssbruno	int                     mtx_init;
849333019Ssbruno	int                     sim_registered;
850333019Ssbruno	struct cam_devq         *devq;
851333019Ssbruno	struct cam_sim          *sim;
852333019Ssbruno	struct cam_path         *path;
853333019Ssbruno	struct task		event_task;
854333019Ssbruno	struct cdev             *cdev;
855333019Ssbruno	struct callout_handle   wellness_periodic;	/* periodic event handling */
856333019Ssbruno	struct callout_handle   heartbeat_timeout_id;	/* heart beat event handling */
857333019Ssbruno	eventhandler_tag        eh;
858333019Ssbruno} OS_SPECIFIC_T;
859333019Ssbruno
860333019Ssbrunotypedef bus_addr_t dma_addr_t;
861333019Ssbruno
862333019Ssbruno/* Atomic */
863333019Ssbrunotypedef volatile uint64_t OS_ATOMIC64_T;
864333019Ssbruno#define OS_ATOMIC64_SET(_softs, target, val)	atomic_set_long(&(_softs)->target, val)
865333019Ssbruno#define OS_ATOMIC64_READ(_softs, target)	atomic_load_acq_64(&(_softs)->target)
866333019Ssbruno#define OS_ATOMIC64_INC(_softs, target)		atomic_add_64(&(_softs)->target, 1)
867333019Ssbruno
868333019Ssbruno/* Register access macros */
869333019Ssbruno#define PCI_MEM_GET32( _softs, _absaddr, _offset ) \
870333019Ssbruno    bus_space_read_4(_softs->pci_mem_handle.pqi_btag, \
871333019Ssbruno        _softs->pci_mem_handle.pqi_bhandle, _offset)
872333019Ssbruno
873333019Ssbruno#define PCI_MEM_GET64( _softs, _absaddr, _offset ) \
874333019Ssbruno    bus_space_read_8(_softs->pci_mem_handle.pqi_btag, \
875333019Ssbruno        _softs->pci_mem_handle.pqi_bhandle, _offset)
876333019Ssbruno
877333019Ssbruno#define PCI_MEM_PUT32( _softs, _absaddr, _offset, _val ) \
878333019Ssbruno    bus_space_write_4(_softs->pci_mem_handle.pqi_btag, \
879333019Ssbruno        _softs->pci_mem_handle.pqi_bhandle, _offset, _val)
880333019Ssbruno
881333019Ssbruno#define PCI_MEM_PUT64( _softs, _absaddr, _offset, _val ) \
882333019Ssbruno    bus_space_write_8(_softs->pci_mem_handle.pqi_btag, \
883333019Ssbruno        _softs->pci_mem_handle.pqi_bhandle, _offset, _val)
884333019Ssbruno
885333019Ssbruno#define PCI_MEM_GET_BUF(_softs, _absaddr, _offset, buf, size) \
886333019Ssbruno	bus_space_read_region_1(_softs->pci_mem_handle.pqi_btag,\
887333019Ssbruno	_softs->pci_mem_handle.pqi_bhandle, _offset, buf, size)
888333019Ssbruno
889333019Ssbruno/* Lock */
890333019Ssbrunotypedef struct mtx OS_LOCK_T;
891333019Ssbrunotypedef struct sema OS_SEMA_LOCK_T;
892333019Ssbruno
893333019Ssbruno#define OS_ACQUIRE_SPINLOCK(_lock) mtx_lock_spin(_lock)
894333019Ssbruno#define OS_RELEASE_SPINLOCK(_lock) mtx_unlock_spin(_lock)
895333019Ssbruno
896333019Ssbruno#define PQI_LOCK(_lock) OS_ACQUIRE_SPINLOCK(_lock)
897333019Ssbruno#define PQI_UNLOCK(_lock) OS_RELEASE_SPINLOCK(_lock)
898333019Ssbruno
899333019Ssbruno#define OS_INIT_PQILOCK(_softs,_lock,_lockname) os_init_spinlock(_softs,_lock,_lockname)
900333019Ssbruno#define OS_UNINIT_PQILOCK(_lock) os_uninit_spinlock(_lock)
901333019Ssbruno
902333019Ssbruno#define OS_GET_CDBP(rcb)	((rcb->cm_ccb->ccb_h.flags & CAM_CDB_POINTER) ? rcb->cm_ccb->csio.cdb_io.cdb_ptr : rcb->cm_ccb->csio.cdb_io.cdb_bytes)
903333019Ssbruno#define GET_SCSI_BUFFLEN(rcb)	(rcb->cm_ccb->csio.dxfer_len)
904333019Ssbruno
905333019Ssbruno#define OS_GET_IO_QINDEX(softs,rcb)	curcpu % softs->num_op_obq
906333019Ssbruno#define OS_GET_IO_RESP_QID(softs,rcb)	(softs->op_ob_q[(OS_GET_IO_QINDEX(softs,rcb))].q_id)
907333019Ssbruno#define OS_GET_IO_REQ_QINDEX(softs,rcb)	OS_GET_IO_QINDEX(softs,rcb)
908333019Ssbruno#define OS_GET_TMF_RESP_QID		OS_GET_IO_RESP_QID
909333019Ssbruno#define OS_GET_TMF_REQ_QINDEX		OS_GET_IO_REQ_QINDEX
910333019Ssbruno/* sg elements addr, len, flags */
911333019Ssbruno#define OS_GET_IO_SG_COUNT(rcb)		rcb->nseg
912333019Ssbruno#define OS_GET_IO_SG_ADDR(rcb,i)	rcb->sgt[i].addr
913333019Ssbruno#define OS_GET_IO_SG_LEN(rcb,i)		rcb->sgt[i].len
914333019Ssbruno
915333019Ssbruno/* scsi commands used in pqilib for RAID bypass*/
916333019Ssbruno#define SCMD_READ_6	READ_6
917333019Ssbruno#define SCMD_WRITE_6	WRITE_6
918333019Ssbruno#define SCMD_READ_10	READ_10
919333019Ssbruno#define SCMD_WRITE_10	WRITE_10
920333019Ssbruno#define SCMD_READ_12	READ_12
921333019Ssbruno#define SCMD_WRITE_12	WRITE_12
922333019Ssbruno#define SCMD_READ_16	READ_16
923333019Ssbruno#define SCMD_WRITE_16	WRITE_16
924333019Ssbruno
925333019Ssbruno/* Debug facility */
926333019Ssbruno
927333019Ssbruno#define PQISRC_LOG_LEVEL  0x30
928333019Ssbruno
929333019Ssbrunostatic int logging_level  = PQISRC_LOG_LEVEL;
930333019Ssbruno
931333019Ssbruno#define	PQISRC_FLAGS_MASK		0x0000ffff
932333019Ssbruno#define	PQISRC_FLAGS_INIT 		0x00000001
933333019Ssbruno#define	PQISRC_FLAGS_INFO 		0x00000002
934333019Ssbruno#define	PQISRC_FLAGS_FUNC		0x00000004
935333019Ssbruno#define	PQISRC_FLAGS_TRACEIO		0x00000008
936333019Ssbruno#define	PQISRC_FLAGS_WARN		0x00000010
937333019Ssbruno#define	PQISRC_FLAGS_ERROR		0x00000020
938333019Ssbruno
939333019Ssbruno
940333019Ssbruno#define	DBG_INIT(fmt,args...)						\
941333019Ssbruno		do {							\
942333019Ssbruno			if (logging_level & PQISRC_FLAGS_INIT) { 	\
943333019Ssbruno				printf("[INIT]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args);			\
944333019Ssbruno			}						\
945333019Ssbruno		}while(0);
946333019Ssbruno
947333019Ssbruno#define	DBG_INFO(fmt,args...)						\
948333019Ssbruno		do {							\
949333019Ssbruno			if (logging_level & PQISRC_FLAGS_INFO) { 	\
950333019Ssbruno				printf("[INFO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args);			\
951333019Ssbruno			}						\
952333019Ssbruno		}while(0);
953333019Ssbruno
954333019Ssbruno#define	DBG_FUNC(fmt,args...)						\
955333019Ssbruno		do {							\
956333019Ssbruno			if (logging_level & PQISRC_FLAGS_FUNC) { 	\
957333019Ssbruno				printf("[FUNC]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args);			\
958333019Ssbruno			}						\
959333019Ssbruno		}while(0);
960333019Ssbruno
961333019Ssbruno#define	DBG_TRACEIO(fmt,args...)					\
962333019Ssbruno		do {							\
963333019Ssbruno			if (logging_level & PQISRC_FLAGS_TRACEIO) { 	\
964333019Ssbruno				printf("[TRACEIO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args);			\
965333019Ssbruno			}						\
966333019Ssbruno		}while(0);
967333019Ssbruno
968333019Ssbruno#define	DBG_WARN(fmt,args...)						\
969333019Ssbruno		do {							\
970333019Ssbruno			if (logging_level & PQISRC_FLAGS_WARN) { 	\
971333019Ssbruno				printf("[WARN]:[%u:%u.%u][CPU %d][%s][%d]:"fmt,softs->bus_id,softs->device_id,softs->func_id,curcpu,__func__,__LINE__,##args);\
972333019Ssbruno			}						\
973333019Ssbruno		}while(0);
974333019Ssbruno
975333019Ssbruno#define	DBG_ERR(fmt,args...)						\
976333019Ssbruno		do {							\
977333019Ssbruno			if (logging_level & PQISRC_FLAGS_ERROR) { 	\
978333019Ssbruno				printf("[ERROR]::[%u:%u.%u][CPU %d][%s][%d]:"fmt,softs->bus_id,softs->device_id,softs->func_id,curcpu,__func__,__LINE__,##args); \
979333019Ssbruno			}						\
980333019Ssbruno		}while(0);
981333019Ssbruno#define	DBG_IO(fmt,args...)						\
982333019Ssbruno		do {							\
983333019Ssbruno			if (logging_level & PQISRC_FLAGS_TRACEIO) { 	\
984333019Ssbruno				printf("[IO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args);			\
985333019Ssbruno			}						\
986333019Ssbruno		}while(0);
987333019Ssbruno
988333019Ssbruno#define	DBG_ERR_BTL(device,fmt,args...)						\
989333019Ssbruno		do {							\
990333019Ssbruno			if (logging_level & PQISRC_FLAGS_ERROR) { 	\
991333019Ssbruno				printf("[ERROR]::[%u:%u.%u][%u,%u,%u][CPU %d][%s][%d]:"fmt, softs->bus_id, softs->device_id, softs->func_id, device->bus, device->target, device->lun,curcpu,__func__,__LINE__,##args); \
992333019Ssbruno			}						\
993333019Ssbruno		}while(0);
994333019Ssbruno
995333019Ssbruno#define	DBG_WARN_BTL(device,fmt,args...)						\
996333019Ssbruno		do {							\
997333019Ssbruno			if (logging_level & PQISRC_FLAGS_WARN) { 	\
998333019Ssbruno				printf("[WARN]:[%u:%u.%u][%u,%u,%u][CPU %d][%s][%d]:"fmt, softs->bus_id, softs->device_id, softs->func_id, device->bus, device->target, device->lun,curcpu,__func__,__LINE__,##args);\
999333019Ssbruno			}						\
1000333019Ssbruno		}while(0);
1001333019Ssbruno
1002333019Ssbruno#endif // _PQI_DEFINES_H
1003