xref: /illumos-gate/usr/src/uts/common/io/scsi/adapters/smartpqi/smartpqi_hw.h (revision 8226594fdd4479be135127f43632f1f995074654)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2018 Nexenta Systems, Inc.
14  */
15 
16 #ifndef _SMARTPQI_HW_H
17 #define	_SMARTPQI_HW_H
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #include <sys/types.h>
24 #include <sys/ccompile.h>
25 
26 /* ---- for submission of legacy SIS commands ---- */
27 #define	SIS_REENABLE_SIS_MODE			0x1
28 #define	SIS_ENABLE_MSIX				0x40
29 #define	SIS_ENABLE_INTX				0x80
30 #define	SIS_SOFT_RESET				0x100
31 #define	SIS_TRIGGER_SHUTDOWN			0x800000
32 #define	SIS_CMD_READY				0x200
33 #define	SIS_CMD_COMPLETE			0x1000
34 #define	SIS_CLEAR_CTRL_TO_HOST_DOORBELL		0x1000
35 #define	SIS_CMD_STATUS_SUCCESS			0x1
36 #define	SIS_CMD_COMPLETE_TIMEOUT_SECS		30
37 #define	SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS	10
38 
39 /* ---- SOP data direction flags ---- */
40 #define	SOP_NO_DIRECTION_FLAG	0
41 #define	SOP_WRITE_FLAG		1	/* host writes data to Data-Out */
42 					/* buffer */
43 #define	SOP_READ_FLAG		2	/* host receives data from Data-In */
44 					/* buffer */
45 #define	SOP_BIDIRECTIONAL	3	/* data is transferred from the */
46 					/* Data-Out buffer and data is */
47 					/* transferred to the Data-In buffer */
48 
49 #define	SOP_TASK_ATTRIBUTE_SIMPLE		0
50 #define	SOP_TASK_ATTRIBUTE_HEAD_OF_QUEUE	1
51 #define	SOP_TASK_ATTRIBUTE_ORDERED		2
52 #define	SOP_TASK_ATTRIBUTE_ACA			4
53 
54 #define	SOP_TMF_COMPLETE		0x0
55 #define	SOP_TMF_FUNCTION_SUCCEEDED	0x8
56 
57 #define	SOP_TASK_MANAGEMENT_LUN_RESET	0x08
58 
59 /* ---- CISS commands ---- */
60 #define	CISS_READ				0xc0
61 #define	CISS_REPORT_LOG				0xc2
62 #define	CISS_REPORT_PHYS			0xc3
63 #define	CISS_GET_RAID_MAP			0xc8
64 
65 /* constants for CISS_REPORT_LOG/CISS_REPORT_PHYS commands */
66 #define	CISS_REPORT_LOG_EXTENDED		0x1
67 #define	CISS_REPORT_PHYS_EXTENDED		0x2
68 
69 /* BMIC commands */
70 #define	BMIC_IDENTIFY_CONTROLLER		0x11
71 #define	BMIC_IDENTIFY_PHYSICAL_DEVICE		0x15
72 #define	BMIC_READ				0x26
73 #define	BMIC_WRITE				0x27
74 #define	BMIC_SENSE_CONTROLLER_PARAMETERS	0x64
75 #define	BMIC_SENSE_SUBSYSTEM_INFORMATION	0x66
76 #define	BMIC_WRITE_HOST_WELLNESS		0xa5
77 #define	BMIC_CACHE_FLUSH			0xc2
78 
79 #define	PQI_DATA_IN_OUT_GOOD					0x0
80 #define	PQI_DATA_IN_OUT_UNDERFLOW				0x1
81 #define	PQI_DATA_IN_OUT_BUFFER_ERROR				0x40
82 #define	PQI_DATA_IN_OUT_BUFFER_OVERFLOW				0x41
83 #define	PQI_DATA_IN_OUT_BUFFER_OVERFLOW_DESCRIPTOR_AREA		0x42
84 #define	PQI_DATA_IN_OUT_BUFFER_OVERFLOW_BRIDGE			0x43
85 #define	PQI_DATA_IN_OUT_PCIE_FABRIC_ERROR			0x60
86 #define	PQI_DATA_IN_OUT_PCIE_COMPLETION_TIMEOUT			0x61
87 #define	PQI_DATA_IN_OUT_PCIE_COMPLETER_ABORT_RECEIVED		0x62
88 #define	PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST_RECEIVED	0x63
89 #define	PQI_DATA_IN_OUT_PCIE_ECRC_CHECK_FAILED			0x64
90 #define	PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST		0x65
91 #define	PQI_DATA_IN_OUT_PCIE_ACS_VIOLATION			0x66
92 #define	PQI_DATA_IN_OUT_PCIE_TLP_PREFIX_BLOCKED			0x67
93 #define	PQI_DATA_IN_OUT_PCIE_POISONED_MEMORY_READ		0x6F
94 #define	PQI_DATA_IN_OUT_ERROR					0xf0
95 #define	PQI_DATA_IN_OUT_PROTOCOL_ERROR				0xf1
96 #define	PQI_DATA_IN_OUT_HARDWARE_ERROR				0xf2
97 #define	PQI_DATA_IN_OUT_UNSOLICITED_ABORT			0xf3
98 #define	PQI_DATA_IN_OUT_ABORTED					0xf4
99 #define	PQI_DATA_IN_OUT_TIMEOUT					0xf5
100 
101 /* ---- additional CDB bytes usage field codes ---- */
102 #define	SOP_ADDITIONAL_CDB_BYTES_0	0	/* 16-byte CDB */
103 #define	SOP_ADDITIONAL_CDB_BYTES_4	1	/* 20-byte CDB */
104 #define	SOP_ADDITIONAL_CDB_BYTES_8	2	/* 24-byte CDB */
105 #define	SOP_ADDITIONAL_CDB_BYTES_12	3	/* 28-byte CDB */
106 #define	SOP_ADDITIONAL_CDB_BYTES_16	4	/* 32-byte CDB */
107 
108 /* ---- These values are defined by the PQI spec ---- */
109 #define	PQI_MAX_NUM_ELEMENTS_ADMIN_QUEUE		255
110 #define	PQI_MAX_NUM_ELEMENTS_OPERATIONAL_QUEUE		65535
111 #define	PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT		64
112 #define	PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT		16
113 #define	PQI_ADMIN_INDEX_ALIGNMENT			64
114 #define	PQI_OPERATIONAL_INDEX_ALIGNMENT			4
115 
116 /* ---- These values are based on our implementation ---- */
117 #define	PQI_ADMIN_IQ_NUM_ELEMENTS			8
118 #define	PQI_ADMIN_OQ_NUM_ELEMENTS			20
119 #define	PQI_ADMIN_IQ_ELEMENT_LENGTH			64
120 #define	PQI_ADMIN_OQ_ELEMENT_LENGTH			64
121 
122 #define	PQI_OPERATIONAL_IQ_ELEMENT_LENGTH		128
123 #define	PQI_OPERATIONAL_OQ_ELEMENT_LENGTH		16
124 
125 #define	PQI_NUM_EVENT_QUEUE_ELEMENTS			32
126 #define	PQI_EVENT_OQ_ELEMENT_LENGTH	sizeof (struct pqi_event_response)
127 
128 #define	PQI_MAX_EMBEDDED_SG_DESCRIPTORS			4
129 
130 #define	PQI_EXTRA_SGL_MEMORY	(12 * sizeof (pqi_sg_entry_t))
131 
132 typedef uint32_t	pqi_index_t;
133 
134 /*
135  * The purpose of this structure is to obtain proper alignment of objects in
136  * an admin queue pair.
137  * NOTE: Make sure to not move this structure to within the
138  *    #pragma pack(1)
139  * directives below. Those directives will override the __aligned directives
140  * which in turn will cause the driver to fail.
141  */
142 typedef struct pqi_admin_queues_aligned {
143 	__aligned(PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT)
144 	uint8_t	iq_element_array[PQI_ADMIN_IQ_NUM_ELEMENTS]
145 	    [PQI_ADMIN_IQ_ELEMENT_LENGTH];
146 	__aligned(PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT)
147 	uint8_t	oq_element_array[PQI_ADMIN_OQ_NUM_ELEMENTS]
148 	    [PQI_ADMIN_OQ_ELEMENT_LENGTH];
149 	__aligned(PQI_ADMIN_INDEX_ALIGNMENT) pqi_index_t iq_ci;
150 	__aligned(PQI_ADMIN_INDEX_ALIGNMENT) pqi_index_t oq_pi;
151 } pqi_admin_queues_aligned_t;
152 
153 /*
154  * NOTE:
155  * From here to the end of the file #pragma pack(1) is set to maintain
156  * the structure alignment required by the hardware. Don't change that.
157  */
158 #pragma pack(1)
159 /* ---- This structure is defined by the PQI specification. ---- */
160 struct pqi_device_registers {
161 	uint64_t	signature;
162 	uint64_t	function_and_status_code;
163 	uint8_t		max_admin_iq_elements;
164 	uint8_t		max_admin_oq_elements;
165 	uint8_t		admin_iq_element_length; /* in 16-byte units */
166 	uint8_t		admin_oq_element_length; /* in 16-byte units */
167 	uint16_t	max_reset_timeout;	/* in 100-millisecond units */
168 	uint8_t		reserved1[2];
169 	uint32_t	legacy_intx_status;
170 	uint32_t	legacy_intx_mask_set;
171 	uint32_t	legacy_intx_mask_clear;
172 	uint8_t		reserved2[28];
173 	uint32_t	device_status;
174 	uint8_t		reserved3[4];
175 	uint64_t	admin_iq_pi_offset;
176 	uint64_t	admin_oq_ci_offset;
177 	uint64_t	admin_iq_element_array_addr;
178 	uint64_t	admin_oq_element_array_addr;
179 	uint64_t	admin_iq_ci_addr;
180 	uint64_t	admin_oq_pi_addr;
181 	/*
182 	 * byte 0 -- iq number of elements
183 	 * byte 1 -- oq number of elements
184 	 * byte 2 -- interrupt message number (IMN)
185 	 * byte 3 -- 3 upper bits for IMN and MSIX disable bit
186 	 */
187 	uint32_t	admin_queue_params;
188 	uint8_t		reserved4[4];
189 	uint32_t	device_error;
190 	uint8_t		reserved5[4];
191 	uint64_t	error_details;
192 	uint32_t	device_reset;
193 	uint32_t	power_action;
194 	uint8_t		reserved6[104];
195 };
196 
197 /*
198  * controller registers
199  *
200  * These are defined by the Microsemi implementation.
201  *
202  * Some registers (those named sis_*) are only used when in
203  * legacy SIS mode before we transition the controller into
204  * PQI mode.  There are a number of other SIS mode registers,
205  * but we don't use them, so only the SIS registers that we
206  * care about are defined here.  The offsets mentioned in the
207  * comments are the offsets from the PCIe BAR 0.
208  */
209 typedef struct pqi_ctrl_registers {
210 	uint8_t		reserved[0x20];
211 	uint32_t	sis_host_to_ctrl_doorbell;		/* 20h */
212 	uint8_t		reserved1[0x34 - (0x20 + sizeof (uint32_t))];
213 	uint32_t	sis_interrupt_mask;			/* 34h */
214 	uint8_t		reserved2[0x9c - (0x34 + sizeof (uint32_t))];
215 	uint32_t	sis_ctrl_to_host_doorbell;		/* 9Ch */
216 	/* uint8_t	reserved3[0xa0 - (0x9c + sizeof (uint32_t))]; */
217 	uint32_t	sis_ctrl_to_host_doorbell_clear;	/* A0h */
218 	uint8_t		reserved4[0xb0 - (0xa0 + sizeof (uint32_t))];
219 	uint32_t	sis_driver_scratch;			/* B0h */
220 	uint8_t		reserved5[0xbc - (0xb0 + sizeof (uint32_t))];
221 	uint32_t	sis_firmware_status;			/* BCh */
222 	uint8_t		reserved6[0x1000 - (0xbc + sizeof (uint32_t))];
223 	uint32_t	sis_mailbox[8];				/* 1000h */
224 	uint8_t		reserved7[0x4000 - (0x1000 + (sizeof (uint32_t) * 8))];
225 
226 	/*
227 	 * The PQI spec states that the PQI registers should be at
228 	 * offset 0 from the PCIe BAR 0.  However, we can't map
229 	 * them at offset 0 because that would break compatibility
230 	 * with the SIS registers.  So we map them at offset 4000h.
231 	 */
232 	struct pqi_device_registers pqi_registers;		/* 4000h */
233 } pqi_ctrl_regs_t;
234 #define	PQI_DEVICE_REGISTERS_OFFSET	0x4000
235 
236 typedef struct pqi_iu_header {
237 	uint8_t		iu_type;
238 	uint8_t		reserved;
239 
240 	/* in bytes - does not include the length of this header */
241 	uint16_t	iu_length;
242 
243 	/* specifies the OQ where the response IU is to be delivered */
244 	uint16_t	iu_id;
245 
246 	uint8_t		work_area[2];	/* reserved for driver use */
247 } pqi_iu_header_t;
248 
249 typedef struct pqi_sg_entry {
250 	uint64_t  sg_addr;
251 	uint32_t  sg_len;
252 	uint32_t  sg_flags;
253 } pqi_sg_entry_t;
254 
255 typedef struct pqi_raid_path_request {
256 	pqi_iu_header_t	header;
257 	uint16_t	rp_id;
258 	uint16_t	rp_nexus_id;
259 	uint32_t	rp_data_len;
260 	uint8_t		rp_lun[8];
261 	uint16_t	protocol_specific;
262 	uint8_t		rp_data_dir : 2;
263 	uint8_t		rp_partial : 1;
264 	uint8_t		reserved1 : 4;
265 	uint8_t		rp_fence : 1;
266 	uint16_t	rp_error_index;
267 	uint8_t		reserved2;
268 	uint8_t		rp_task_attr : 3;
269 	uint8_t		rp_pri : 4;
270 	uint8_t		reserved3 : 1;
271 	uint8_t		reserved4 : 2;
272 	uint8_t		rp_additional_cdb : 3;
273 	uint8_t		reserved5 : 3;
274 	uint8_t		rp_cdb[32];
275 	pqi_sg_entry_t	rp_sglist[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
276 } pqi_raid_path_request_t;
277 
278 typedef struct pqi_aio_path_request {
279 	pqi_iu_header_t	header;
280 	uint16_t	request_id;
281 	uint8_t		reserved1[2];
282 	uint32_t	nexus_id;
283 	uint32_t	buffer_length;
284 	uint8_t		data_direction : 2;
285 	uint8_t		partial : 1;
286 	uint8_t		memory_type : 1;
287 	uint8_t		fence : 1;
288 	uint8_t		encryption_enable : 1;
289 	uint8_t		reserved2 : 2;
290 	uint8_t		task_attribute : 3;
291 	uint8_t		command_priority : 4;
292 	uint8_t		reserved3 : 1;
293 	uint16_t	data_encryption_key_index;
294 	uint32_t	encrypt_tweak_lower;
295 	uint32_t	encrypt_tweak_upper;
296 	uint8_t		cdb[16];
297 	uint16_t	error_index;
298 	uint8_t		num_sg_descriptors;
299 	uint8_t		cdb_length;
300 	uint8_t		lun_number[8];
301 	uint8_t		reserved4[4];
302 	pqi_sg_entry_t	ap_sglist[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
303 } pqi_aio_path_request_t;
304 
305 typedef struct pqi_io_response {
306 	pqi_iu_header_t	header;
307 	uint16_t	request_id;
308 	uint16_t	error_index;
309 	uint8_t		reserved2[4];
310 } pqi_io_response_t;
311 
312 typedef struct pqi_raid_error_info {
313 	uint8_t		data_in_result;
314 	uint8_t		data_out_result;
315 	uint8_t		reserved[3];
316 	uint8_t		status;
317 	uint16_t	status_qualifier;
318 	uint16_t	sense_data_length;
319 	uint16_t	response_data_length;
320 	uint32_t	data_in_transferred;
321 	uint32_t	data_out_transferred;
322 	uint8_t		data[256];
323 } *pqi_raid_error_info_t;
324 
325 #define	PQI_GENERAL_ADMIN_FUNCTION_REPORT_DEVICE_CAPABILITY	0x0
326 #define	PQI_GENERAL_ADMIN_FUNCTION_CREATE_IQ			0x10
327 #define	PQI_GENERAL_ADMIN_FUNCTION_CREATE_OQ			0x11
328 #define	PQI_GENERAL_ADMIN_FUNCTION_DELETE_IQ			0x12
329 #define	PQI_GENERAL_ADMIN_FUNCTION_DELETE_OQ			0x13
330 #define	PQI_GENERAL_ADMIN_FUNCTION_CHANGE_IQ_PROPERTY		0x14
331 
332 #define	PQI_GENERAL_ADMIN_STATUS_SUCCESS	0x0
333 #define	PQI_GENERAL_ADMIN_IU_LENGTH		0x3c
334 #define	PQI_PROTOCOL_SOP			0x0
335 
336 #define	PQI_IQ_PROPERTY_IS_AIO_QUEUE		0x1
337 
338 typedef struct pqi_iu_layer_descriptor {
339 	uint8_t		inbound_spanning_supported : 1;
340 	uint8_t		reserved : 7;
341 	uint8_t		reserved1[5];
342 	uint16_t	max_inbound_iu_length;
343 	uint8_t		outbound_spanning_supported : 1;
344 	uint8_t		reserved2 : 7;
345 	uint8_t		reserved3[5];
346 	uint16_t	max_outbound_iu_length;
347 } pqi_iu_layer_descriptor_t;
348 
349 typedef struct pqi_device_capability {
350 	uint16_t	data_length;
351 	uint8_t		reserved[6];
352 	uint8_t		iq_arbitration_priority_support_bitmask;
353 	uint8_t		maximum_aw_a;
354 	uint8_t		maximum_aw_b;
355 	uint8_t		maximum_aw_c;
356 	uint8_t		max_arbitration_burst : 3;
357 	uint8_t		reserved1 : 4;
358 	uint8_t		iqa : 1;
359 	uint8_t		reserved2[2];
360 	uint8_t		iq_freeze : 1;
361 	uint8_t		reserved3 : 7;
362 	uint16_t	max_inbound_queues;
363 	uint16_t	max_elements_per_iq;
364 	uint8_t		reserved4[4];
365 	uint16_t	max_iq_element_length;
366 	uint16_t	min_iq_element_length;
367 	uint8_t		reserved5[2];
368 	uint16_t	max_outbound_queues;
369 	uint16_t	max_elements_per_oq;
370 	uint16_t	intr_coalescing_time_granularity;
371 	uint16_t	max_oq_element_length;
372 	uint16_t	min_oq_element_length;
373 	uint8_t		reserved6[24];
374 	pqi_iu_layer_descriptor_t iu_layer_descriptors[32];
375 } pqi_device_capability_t;
376 
377 typedef struct pqi_general_management_request {
378 	pqi_iu_header_t	header;
379 	uint16_t  request_id;
380 	union {
381 		struct {
382 			uint8_t		reserved[2];
383 			uint32_t	buffer_length;
384 			pqi_sg_entry_t	sg_descriptors[3];
385 		} report_event_configuration;
386 
387 		struct {
388 			uint16_t	global_event_oq_id;
389 			uint32_t	buffer_length;
390 			pqi_sg_entry_t	sg_descriptors[3];
391 		} set_event_configuration;
392 	} data;
393 } pqi_general_mgmt_rqst_t;
394 
395 #define	RAID_CTLR_LUNID		"\0\0\0\0\0\0\0\0"
396 
397 typedef struct pqi_config_table {
398 	uint8_t		signature[8];		/* "CFGTABLE" */
399 	/* offset in bytes from the base address of this table to the */
400 	/* first section */
401 	uint32_t	first_section_offset;
402 } pqi_config_table_t;
403 
404 typedef struct pqi_config_table_section_header {
405 	/* as defined by the PQI_CONFIG_TABLE_SECTION_* manifest */
406 	/* constants above */
407 	uint16_t	section_id;
408 
409 	/* offset in bytes from base address of the table of the */
410 	/* next section or 0 if last entry */
411 	uint16_t	next_section_offset;
412 } pqi_config_table_section_header_t;
413 
414 struct pqi_config_table_general_info {
415 	pqi_config_table_section_header_t	header;
416 
417 	/* size of this section in bytes including the section header */
418 	uint32_t	section_length;
419 
420 	/* max. outstanding commands supported by the controller */
421 	uint32_t	max_outstanding_requests;
422 
423 	/* max. transfer size of a single command */
424 	uint32_t	max_sg_size;
425 
426 	/* max. number of scatter-gather entries supported in a single cmd */
427 	uint32_t	max_sg_per_request;
428 };
429 
430 typedef struct pqi_config_table_heartbeat {
431 	pqi_config_table_section_header_t	header;
432 	uint32_t				heartbeat_counter;
433 } pqi_config_table_heartbeat_t;
434 
435 typedef struct pqi_general_admin_request {
436 	pqi_iu_header_t	header;
437 	uint16_t	request_id;
438 	uint8_t		function_code;
439 	union {
440 		struct {
441 			uint8_t		reserved[33];
442 			uint32_t	buffer_length;
443 			pqi_sg_entry_t	sg_descriptor;
444 		} report_device_capability;
445 
446 		struct {
447 			uint8_t		reserved;
448 			uint16_t	queue_id;
449 			uint8_t		reserved1[2];
450 			uint64_t	element_array_addr;
451 			uint64_t	ci_addr;
452 			uint16_t	num_elements;
453 			uint16_t	element_length;
454 			uint8_t		queue_protocol;
455 			uint8_t		reserved2[23];
456 			uint32_t	vendor_specific;
457 		} create_operational_iq;
458 
459 		struct {
460 			uint8_t		reserved;
461 			uint16_t	queue_id;
462 			uint8_t		reserved1[2];
463 			uint64_t	element_array_addr;
464 			uint64_t	pi_addr;
465 			uint16_t	num_elements;
466 			uint16_t	element_length;
467 			uint8_t		queue_protocol;
468 			uint8_t		reserved2[3];
469 			uint16_t	int_msg_num;
470 			uint16_t	coalescing_count;
471 			uint32_t	min_coalescing_time;
472 			uint32_t	max_coalescing_time;
473 			uint8_t		reserved3[8];
474 			uint32_t	vendor_specific;
475 		} create_operational_oq;
476 
477 		struct {
478 			uint8_t		reserved;
479 			uint16_t	queue_id;
480 			uint8_t		reserved1[50];
481 		} delete_operational_queue;
482 
483 		struct {
484 			uint8_t		reserved;
485 			uint16_t	queue_id;
486 			uint8_t		reserved1[46];
487 			uint32_t	vendor_specific;
488 		} change_operational_iq_properties;
489 
490 	} data;
491 } pqi_general_admin_request_t;
492 
493 #define	PQI_RESPONSE_IU_GENERAL_MANAGEMENT		0x81
494 #define	PQI_RESPONSE_IU_TASK_MANAGEMENT			0x93
495 #define	PQI_RESPONSE_IU_GENERAL_ADMIN			0xe0
496 #define	PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS		0xf0
497 #define	PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS		0xf1
498 #define	PQI_RESPONSE_IU_RAID_PATH_IO_ERROR		0xf2
499 #define	PQI_RESPONSE_IU_AIO_PATH_IO_ERROR		0xf3
500 #define	PQI_RESPONSE_IU_AIO_PATH_DISABLED		0xf4
501 #define	PQI_RESPONSE_IU_VENDOR_EVENT			0xf5
502 
503 typedef struct pqi_general_admin_response {
504 	pqi_iu_header_t header;
505 	uint16_t	request_id;
506 	uint8_t		function_code;
507 	uint8_t		status;
508 	union {
509 		struct {
510 			uint8_t		status_descriptor[4];
511 			uint64_t	iq_pi_offset;
512 			uint8_t		reserved[40];
513 		} create_operational_iq;
514 
515 		struct {
516 			uint8_t		status_descriptor[4];
517 			uint64_t	oq_ci_offset;
518 			uint8_t		reserved[40];
519 		} create_operational_oq;
520 	} data;
521 } pqi_general_admin_response_t;
522 
523 typedef struct pqi_task_management_rqst {
524 	pqi_iu_header_t	header;
525 	uint16_t	request_id;
526 	uint16_t	nexus_id;
527 	uint8_t		reserved[4];
528 	uint8_t		lun_number[8];
529 	uint16_t	protocol_specific;
530 	uint16_t	outbound_queue_id_to_manage;
531 	uint16_t	request_id_to_manage;
532 	uint8_t		task_management_function;
533 	uint8_t		reserved2 : 7;
534 	uint8_t		fence : 1;
535 } pqi_task_management_rqst_t;
536 
537 /* ---- Support event types ---- */
538 #define	PQI_EVENT_TYPE_HOTPLUG			0x1
539 #define	PQI_EVENT_TYPE_HARDWARE			0x2
540 #define	PQI_EVENT_TYPE_PHYSICAL_DEVICE		0x4
541 #define	PQI_EVENT_TYPE_LOGICAL_DEVICE		0x5
542 #define	PQI_EVENT_TYPE_AIO_STATE_CHANGE		0xfd
543 #define	PQI_EVENT_TYPE_AIO_CONFIG_CHANGE		0xfe
544 #define	PQI_EVENT_TYPE_HEARTBEAT			0xff
545 
546 typedef struct pqi_event_response {
547 	pqi_iu_header_t	header;
548 	uint8_t		event_type;
549 	uint8_t		reserved2 : 7;
550 	uint8_t		request_acknowlege : 1;
551 	uint16_t	event_id;
552 	uint32_t	additional_event_id;
553 	uint8_t		data[16];
554 } pqi_event_response_t;
555 
556 typedef struct pqi_event_acknowledge_request {
557 	pqi_iu_header_t	header;
558 	uint8_t		event_type;
559 	uint8_t		reserved2;
560 	uint16_t	event_id;
561 	uint32_t	additional_event_id;
562 } pqi_event_acknowledge_request_t;
563 
564 typedef struct pqi_event_descriptor {
565 	uint8_t		event_type;
566 	uint8_t		reserved;
567 	uint16_t	oq_id;
568 } pqi_event_descriptor_t;
569 
570 typedef struct pqi_event_config {
571 	uint8_t			reserved[2];
572 	uint8_t			num_event_descriptors;
573 	uint8_t			reserved1;
574 	pqi_event_descriptor_t	descriptors[1];
575 } pqi_event_config_t;
576 
577 typedef struct bmic_identify_controller {
578 	uint8_t		configured_logical_drive_count;
579 	uint32_t	configuration_signature;
580 	uint8_t		firmware_version[4];
581 	uint8_t		reserved[145];
582 	uint16_t	extended_logical_unit_count;
583 	uint8_t		reserved1[34];
584 	uint16_t	firmware_build_number;
585 	uint8_t		reserved2[100];
586 	uint8_t		controller_mode;
587 	uint8_t		reserved3[32];
588 } bmic_identify_controller_t;
589 
590 #define	CISS_GET_LEVEL_2_BUS(lunid)		((lunid)[7] & 0x3f)
591 #define	CISS_GET_LEVEL_2_TARGET(lunid)		((lunid)[6])
592 #define	CISS_GET_DRIVE_NUMBER(lunid)		\
593 	(((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \
594 	CISS_GET_LEVEL_2_TARGET((lunid)))
595 
596 typedef struct bmic_identify_physical_device {
597 	uint8_t		scsi_bus;	/* SCSI Bus number on controller */
598 	uint8_t		scsi_id;	/* SCSI ID on this bus */
599 	uint16_t	block_size;	/* sector size in bytes */
600 	uint32_t	total_blocks;	/* number for sectors on drive */
601 	uint32_t	reserved_blocks;	/* controller reserved (RIS) */
602 	uint8_t		model[40];	/* Physical Drive Model */
603 	uint8_t		serial_number[40];	/* Drive Serial Number */
604 	uint8_t		firmware_revision[8];	/* drive firmware revision */
605 	uint8_t		scsi_inquiry_bits;	/* inquiry byte 7 bits */
606 	uint8_t		compaq_drive_stamp;	/* 0 means drive not stamped */
607 	uint8_t		last_failure_reason;
608 	uint8_t		flags;
609 	uint8_t		more_flags;
610 	uint8_t		scsi_lun;	/* SCSI LUN for phys drive */
611 	uint8_t		yet_more_flags;
612 	uint8_t		even_more_flags;
613 	uint32_t	spi_speed_rules;
614 	uint8_t		phys_connector[2]; /* connector number on controller */
615 	uint8_t		phys_box_on_bus; /* phys enclosure this drive resides */
616 	uint8_t		phys_bay_in_box; /* phys drv bay this drive resides */
617 	uint32_t	rpm;		/* drive rotational speed in RPM */
618 	uint8_t		device_type;	/* type of drive */
619 	uint8_t		sata_version;	/* only valid when device_type = */
620 	/* BMIC_DEVICE_TYPE_SATA */
621 	uint64_t	big_total_block_count;
622 	uint64_t	ris_starting_lba;
623 	uint32_t	ris_size;
624 	uint8_t		wwid[20];
625 	uint8_t		controller_phy_map[32];
626 	uint16_t	phy_count;
627 	uint8_t		phy_connected_dev_type[256];
628 	uint8_t		phy_to_drive_bay_num[256];
629 	uint16_t	phy_to_attached_dev_index[256];
630 	uint8_t		box_index;
631 	uint8_t		reserved;
632 	uint16_t	extra_physical_drive_flags;
633 	uint8_t		negotiated_link_rate[256];
634 	uint8_t		phy_to_phy_map[256];
635 	uint8_t		redundant_path_present_map;
636 	uint8_t		redundant_path_failure_map;
637 	uint8_t		active_path_number;
638 	uint16_t	alternate_paths_phys_connector[8];
639 	uint8_t		alternate_paths_phys_box_on_port[8];
640 	uint8_t		multi_lun_device_lun_count;
641 	uint8_t		minimum_good_fw_revision[8];
642 	uint8_t		unique_inquiry_bytes[20];
643 	uint8_t		current_temperature_degrees;
644 	uint8_t		temperature_threshold_degrees;
645 	uint8_t		max_temperature_degrees;
646 	uint8_t		logical_blocks_per_phys_block_exp;
647 	uint16_t	current_queue_depth_limit;
648 	uint8_t		switch_name[10];
649 	uint16_t	switch_port;
650 	uint8_t		alternate_paths_switch_name[40];
651 	uint8_t		alternate_paths_switch_port[8];
652 	uint16_t	power_on_hours;
653 	uint16_t	percent_endurance_used;
654 	uint8_t		drive_authentication;
655 	uint8_t		smart_carrier_authentication;
656 	uint8_t		smart_carrier_app_fw_version;
657 	uint8_t		smart_carrier_bootloader_fw_version;
658 	uint8_t		sanitize_flags;
659 	uint8_t		encryption_key_flags;
660 	uint8_t		encryption_key_name[64];
661 	uint32_t	misc_drive_flags;
662 	uint16_t	dek_index;
663 	uint16_t	hba_drive_encryption_flags;
664 	uint16_t	max_overwrite_time;
665 	uint16_t	max_block_erase_time;
666 	uint16_t	max_crypto_erase_time;
667 	uint8_t		connector_info[5];
668 	uint8_t		connector_name[8][8];
669 	uint8_t		page_83_identifier[16];
670 	uint8_t		maximum_link_rate[256];
671 	uint8_t		negotiated_physical_link_rate[256];
672 	uint8_t		box_connector_name[8];
673 	uint8_t	padding_to_multiple_of_512[9];
674 } bmic_identify_physical_device_t;
675 
676 typedef struct bmic_host_wellness_driver_version {
677 	uint8_t		start_tag[4];
678 	uint8_t		drv_tag[2];
679 	uint16_t	driver_version_length;
680 	char		driver_version[32];
681 	uint8_t		end_tag[2];
682 } bmic_host_wellness_driver_version_t;
683 
684 typedef struct bmic_host_wellness_time {
685 	uint8_t		start_tag[4];
686 	uint8_t		time_tag[2];
687 	uint16_t	time_length;
688 	uint8_t		time[8];
689 	uint8_t		dont_write_tag[2];
690 	uint8_t		end_tag[2];
691 } bmic_host_wellness_time_t;
692 
693 #define	PQI_MAX_EVENT_DESCRIPTORS	255
694 
695 typedef struct report_lun_header {
696 	uint32_t	list_length;
697 	uint8_t		extended_response;
698 	uint8_t		reserved[3];
699 } report_lun_header_t;
700 
701 typedef struct report_log_lun_extended_entry {
702 	uint8_t		lunid[8];
703 	uint8_t		volume_id[16];
704 } report_log_lun_extended_entry_t;
705 
706 typedef struct report_log_lun_extended {
707 	report_lun_header_t		header;
708 	report_log_lun_extended_entry_t	lun_entries[1];
709 } report_log_lun_extended_t;
710 
711 typedef struct report_phys_lun_extended_entry {
712 	uint8_t		lunid[8];
713 	uint64_t	wwid;
714 	uint8_t		device_type;
715 	uint8_t		device_flags;
716 	uint8_t		lun_count; /* number of LUNs in a multi-LUN device */
717 	uint8_t		redundant_paths;
718 	uint32_t	aio_handle;
719 } report_phys_lun_extended_entry_t;
720 
721 /* ---- Zoned Block Device ---- */
722 #define	TYPE_ZBC	0x14
723 
724 /* for device_flags field of struct report_phys_lun_extended_entry */
725 #define	REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED	0x8
726 
727 typedef struct report_phys_lun_extended {
728 	report_lun_header_t			header;
729 	report_phys_lun_extended_entry_t	lun_entries[1];
730 } report_phys_lun_extended_t;
731 #pragma pack()
732 
733 #ifdef __cplusplus
734 }
735 #endif
736 
737 #endif /* _SMARTPQI_HW_H */
738