summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/scsi/adapters/smrt/smrt_scsi.h
blob: 45c4c844073a73e0a1b553394cf58390cbf6d51b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
 * Copyright (c) 2017 Joyent, Inc.
 */

#ifndef	_SMRT_SCSI_H
#define	_SMRT_SCSI_H

#include <sys/types.h>

#include <sys/scsi/adapters/smrt/smrt_ciss.h>

#ifdef	__cplusplus
extern "C" {
#endif

/* CISS LUN Addressing MODEs */
#define	PERIPHERIAL_DEV_ADDR			0x0
#define	LOGICAL_VOL_ADDR			0x1
#define	MASK_PERIPHERIAL_DEV_ADDR		0x3
#define	CISS_PHYS_MODE				0x0

/*
 * Vendor-specific SCSI Commands
 *
 * These command opcodes are for use in the opcode byte of the CDB in a request
 * of type CISS_TYPE_CMD.  They are custom SCSI commands, using the
 * vendor-specific part of the opcode space; i.e., 0xC0 through 0xFF.
 */
#define	CISS_SCMD_READ				0xC0
#define	CISS_SCMD_WRITE				0xC1
#define	CISS_SCMD_REPORT_LOGICAL_LUNS		0xC2
#define	CISS_SCMD_REPORT_PHYSICAL_LUNS		0xC3

/*
 * These command opcodes are _not_ in the usual vendor-specific space, but are
 * nonetheless vendor-specific.  They allow BMIC commands to be written to and
 * read from the controller.  If a command transfers no data, the specification
 * suggests that BMIC_WRITE (0x27) is appropriate.
 */
#define	CISS_SCMD_BMIC_READ			0x26
#define	CISS_SCMD_BMIC_WRITE			0x27

/*
 * CISS Messages
 *
 * The CISS specification describes several directives that do not behave like
 * SCSI commands.  They are sent in requests of type CISS_TYPE_MSG.
 *
 * The Abort, Reset, and Nop, messages are defined in "8. Messages" in the CISS
 * Specification.
 */
#define	CISS_MSG_ABORT				0x0
#define	CISS_ABORT_TASK				0x0
#define	CISS_ABORT_TASKSET			0x1

#define	CISS_MSG_RESET				0x1
#define	CISS_RESET_CTLR				0x0
#define	CISS_RESET_BUS				0x1
#define	CISS_RESET_TGT				0x3
#define	CISS_RESET_LUN				0x4

#define	CISS_MSG_NOP				0x3

/*
 * BMIC Commands
 *
 * These commands allow for the use of non-standard facilities specific to the
 * Smart Array firmware.  They are sent to the controller through a specially
 * constructed CDB with the CISS_SCMD_BMIC_READ or CISS_SCMD_BMIC_WRITE opcode.
 */
#define	CISS_BMIC_IDENTIFY_CONTROLLER		0x11
#define	CISS_BMIC_IDENTIFY_PHYSICAL_DEVICE	0x15
#define	CISS_BMIC_NOTIFY_ON_EVENT		0xD0
#define	CISS_BMIC_NOTIFY_ON_EVENT_CANCEL	0xD1

/*
 * Device and Phy type codes.  These are used across many commands, including
 * IDENTIFY PHYSICAL DEVICE and the REPORT PHYSICAL LUN extended reporting.
 */
#define	SMRT_DTYPE_PSCSI			0x00
#define	SMRT_DTYPE_SATA				0x01
#define	SMRT_DTYPE_SAS				0x02
#define	SMRT_DTYPE_SATA_BW			0x03
#define	SMRT_DTYPE_SAS_BW			0x04
#define	SMRT_DTYPE_EXPANDER			0x05
#define	SMRT_DTYPE_SES				0x06
#define	SMRT_DTYPE_CONTROLLER			0x07
#define	SMRT_DTYPE_SGPIO			0x08
#define	SMRT_DTYPE_NVME				0x09
#define	SMRT_DTYPE_NOPHY			0xFF

/*
 * The following packed structures are used to ease the manipulation of SCSI
 * and BMIC commands sent to, and status information returned from, the
 * controller.
 */
#pragma pack(1)

typedef struct smrt_report_logical_lun_ent {
	LogDevAddr_t smrle_addr;
} smrt_report_logical_lun_ent_t;

typedef struct smrt_report_logical_lun_extent {
	LogDevAddr_t smrle_addr;
	uint8_t smrle_wwn[16];
} smrt_report_logical_lun_extent_t;

typedef struct smrt_report_logical_lun {
	uint32_t smrll_datasize; /* Big Endian */
	uint8_t smrll_extflag;
	uint8_t smrll_reserved1[3];
	union {
		smrt_report_logical_lun_ent_t ents[SMRT_MAX_LOGDRV];
		smrt_report_logical_lun_extent_t extents[SMRT_MAX_LOGDRV];
	} smrll_data;
} smrt_report_logical_lun_t;

typedef struct smrt_report_logical_lun_req {
	uint8_t smrllr_opcode;
	uint8_t smrllr_extflag;
	uint8_t smrllr_reserved1[4];
	uint32_t smrllr_datasize; /* Big Endian */
	uint8_t smrllr_reserved2;
	uint8_t smrllr_control;
} smrt_report_logical_lun_req_t;

typedef struct smrt_report_physical_lun_ent {
	PhysDevAddr_t srple_addr;
} smrt_report_physical_lun_ent_t;

/*
 * This structure represents the 'physical node identifier' extended option for
 * REPORT PHYSICAL LUNS.  This is triggered when the extended flags is set to
 * 0x1.  Note that for SAS the other structure should always be used.
 */
typedef struct smrt_report_physical_pnid {
	uint8_t srpp_node[8];
	uint8_t srpp_port[8];
} smrt_report_physical_pnid_t;

/*
 * This structure represents the 'other physical device info' extended option
 * for report physical luns.  This is triggered when the extended flags is set
 * to 0x2.
 */
typedef struct smrt_report_physical_opdi {
	uint8_t srpo_wwid[8];
	uint8_t srpo_dtype;
	uint8_t srpo_flags;
	uint8_t srpo_multilun;
	uint8_t srpo_paths;
	uint32_t srpo_iohdl;
} smrt_report_physical_opdi_t;

typedef struct smrt_report_physical_lun_extent {
	PhysDevAddr_t srple_addr;
	union {
		smrt_report_physical_pnid_t srple_pnid;
		smrt_report_physical_opdi_t srple_opdi;
	} srple_extdata;
} smrt_report_physical_lun_extent_t;

/*
 * Values that can be ORed together into smrllr_extflag. smprl_extflag indicates
 * if any extended processing was done or not.
 */
#define	SMRT_REPORT_PHYSICAL_LUN_EXT_NONE	0x00
#define	SMRT_REPORT_PHYSICAL_LUN_EXT_PNID	0x01
#define	SMRT_REPORT_PHYSICAL_LUN_EXT_OPDI	0x02
#define	SMRT_REPORT_PHYSICAL_LUN_EXT_MASK	0x0f
#define	SMRT_REPORT_PHYSICAL_LUN_CTRL_ONLY	(1 << 6)
#define	SMRT_REPORT_PHYSICAL_LUN_ALL_PATHS	(1 << 7)

typedef struct smrt_report_physical_lun {
	uint32_t smrpl_datasize; /* Big Endian */
	uint8_t smrpl_extflag;
	uint8_t smrpl_reserved1[3];
	union {
		smrt_report_physical_lun_ent_t ents[SMRT_MAX_PHYSDEV];
		smrt_report_physical_lun_extent_t extents[SMRT_MAX_PHYSDEV];
	} smrpl_data;
} smrt_report_physical_lun_t;


typedef struct smrt_report_physical_lun_req {
	uint8_t smrplr_opcode;
	uint8_t smrplr_extflag;
	uint8_t smrplr_reserved[1];
	uint32_t smrplr_datasize; /* Big Endian */
	uint8_t smrplr_reserved2;
	uint8_t smrplr_control;
} smrt_report_physical_lun_req_t;

/*
 * Request structure for the BMIC command IDENTIFY CONTROLLER.  This structure
 * is written into the CDB with the CISS_SCMD_BMIC_READ SCSI opcode.  Reserved
 * fields should be filled with zeroes.
 */
typedef struct smrt_identify_controller_req {
	uint8_t smicr_opcode;
	uint8_t smicr_lun;
	uint8_t smicr_reserved1[4];
	uint8_t smicr_command;
	uint8_t smicr_reserved2[2];
	uint8_t smicr_reserved3[1];
	uint8_t smicr_reserved4[6];
} smrt_identify_controller_req_t;

/*
 * Response structure for IDENTIFY CONTROLLER.  This structure is used to
 * interpret the response the controller will write into the data buffer.
 */
typedef struct smrt_identify_controller {
	uint8_t smic_logical_drive_count;
	uint32_t smic_config_signature;
	uint8_t smic_firmware_rev[4];
	uint8_t smic_recovery_rev[4];
	uint8_t smic_hardware_version;
	uint8_t smic_bootblock_rev[4];

	/*
	 * These are obsolete for SAS controllers:
	 */
	uint32_t smic_drive_present_map;
	uint32_t smic_external_drive_map;

	uint32_t smic_board_id;
} smrt_identify_controller_t;

/*
 * Request structure for IDENTIFY PHYSICAL DEVICE.  This structure is written
 * into the CDB with the CISS_SCMD_BMIC_READ SCSI opcode.  Reserved fields
 * should be filled with zeroes.  Note, the lower 8 bits of the BMIC ID are in
 * index1, whereas the upper 8 bites are in index2; however, the controller may
 * only support 8 bits worth of devices (and this driver does not support that
 * many devices).
 */
typedef struct smrt_identify_physical_drive_req {
	uint8_t sipdr_opcode;
	uint8_t sipdr_lun;
	uint8_t	sipdr_bmic_index1;
	uint8_t sipdr_reserved1[3];
	uint8_t sipdr_command;
	uint8_t sipdr_reserved2[2];
	uint8_t sipdr_bmic_index2;
	uint8_t sipdr_reserved4[6];
} smrt_identify_physical_drive_req_t;

/*
 * Relevant values for the sipd_more_flags member.
 */
#define	SMRT_MORE_FLAGS_LOGVOL	(1 << 5)
#define	SMRT_MORE_FLAGS_SPARE	(1 << 6)

/*
 * Response structure for IDENTIFY PHYSICAL DEVICE.  This structure is used to
 * describe aspects of a physical drive. Note, not all fields are valid in all
 * firmware revisions.
 */
typedef struct smrt_identify_physical_drive {
	uint8_t		sipd_scsi_bus;	/* Invalid for SAS */
	uint8_t		sipd_scsi_id;	/* Invalid for SAS */
	uint16_t	sipd_lblk_size;
	uint32_t	sipd_nblocks;
	uint32_t	sipd_rsrvd_blocsk;
	uint8_t		sipd_model[40];
	uint8_t		sipd_serial[40];
	uint8_t		sipd_firmware[8];
	uint8_t		sipd_scsi_inquiry;
	uint8_t		sipd_compaq_stamp;
	uint8_t		sipd_last_failure;
	uint8_t		sipd_flags;
	uint8_t		sipd_more_flags;
	uint8_t		sipd_scsi_lun;	/* Invalid for SAS */
	uint8_t		sipd_yet_more_flags;
	uint8_t		sipd_even_more_flags;
	uint32_t	sipd_spi_speed_rules;
	uint8_t		sipd_phys_connector[2];
	uint8_t		sipd_phys_box_on_bus;
	uint8_t		sipd_phys_bay_in_box;
	uint32_t	sipd_rpm;
	uint8_t		sipd_device_type;
	uint8_t		sipd_sata_version;
	uint64_t	sipd_big_nblocks;
	uint64_t	sipd_ris_slba;
	uint32_t	sipd_ris_size;
	uint8_t		sipd_wwid[20];
	uint8_t		sipd_controller_phy_map[32];
	uint16_t	sipd_phy_count;
	uint8_t		sipd_phy_connected_dev_type[256];
	uint8_t		sipd_phy_to_drive_bay[256];
	uint16_t	sipd_phy_to_attached_dev[256];
	uint8_t		sipd_box_index;
	uint8_t		sipd_drive_support;
	uint16_t	sipd_extra_flags;
	uint8_t		sipd_neogiated_link_rate[256];
	uint8_t		sipd_phy_to_phy_map[256];
	uint8_t		sipd_pad[312];
} smrt_identify_physical_drive_t;

/*
 * Note that this structure describes the CISS version of the command. There
 * also exists a BMIC version, but it has a slightly different structure.  This
 * structure is also used for the cancellation request; however, in that case,
 * the senr_flags field is reserved.
 */
typedef struct smrt_event_notify_req {
	uint8_t		senr_opcode;
	uint8_t		senr_subcode;
	uint8_t		senr_reserved1[2];
	uint32_t	senr_flags;	/* Big Endian */
	uint32_t	senr_size;	/* Big Endian */
	uint8_t		senr_control;
} smrt_event_notify_req_t;

/*
 * When receiving event notifications, the buffer size must be 512 bytes large.
 * We make sure that we always allocate a buffer of this size, even though we
 * define a structure that is much shorter and only uses the fields that we end
 * up caring about.  This size requirement comes from the specification.
 */
#define	SMRT_EVENT_NOTIFY_BUFLEN	512

#define	SMRT_EVENT_CLASS_PROTOCOL		0
#define	SMRT_EVENT_PROTOCOL_SUBCLASS_ERROR	1

#define	SMRT_EVENT_CLASS_HOTPLUG		1
#define	SMRT_EVENT_HOTPLUG_SUBCLASS_DRIVE	0

#define	SMRT_EVENT_CLASS_HWERROR		2
#define	SMRT_EVENT_CLASS_ENVIRONMENT		3

#define	SMRT_EVENT_CLASS_PHYS			4
#define	SMRT_EVENT_PHYS_SUBCLASS_STATE		0

#define	SMRT_EVENT_CLASS_LOGVOL			5

typedef struct smrt_event_notify {
	uint32_t	sen_timestamp;
	uint16_t	sen_class;
	uint16_t	sen_subclass;
	uint16_t	sen_detail;
	uint8_t		sen_data[64];
	char		sen_message[80];
	uint32_t	sen_tag;
	uint16_t	sen_date;
	uint16_t	sen_year;
	uint32_t	sen_time;
	uint16_t	sen_pre_power_time;
	LUNAddr_t	sen_addr;
} smrt_event_notify_t;

#pragma pack()

#ifdef	__cplusplus
}
#endif

#endif	/* _SMRT_SCSI_H */