Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/ciss/cissreg.h
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2001 Michael Smith
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
/*
30
* Structure and I/O definitions for the Command Interface for SCSI-3 Support.
31
*
32
* Data in command CDBs are in big-endian format. All other data is little-endian.
33
* This header only supports little-endian hosts at this time.
34
*/
35
36
union ciss_device_address
37
{
38
struct /* MODE_PERIPHERAL and MODE_MASK_PERIPHERAL */
39
{
40
u_int32_t target:24; /* SCSI target */
41
u_int32_t bus:6; /* SCSI bus */
42
u_int32_t mode:2; /* CISS_HDR_ADDRESS_MODE_* */
43
u_int32_t extra_address; /* SCSI-3 level-2 and level-3 address bytes */
44
} physical;
45
struct /* MODE_LOGICAL */
46
{
47
u_int32_t lun:30; /* logical device ID */
48
u_int32_t mode:2; /* CISS_HDR_ADDRESS_MODE_LOGICAL */
49
u_int32_t :32; /* reserved */
50
} logical;
51
struct
52
{
53
u_int32_t :30;
54
u_int32_t mode:2;
55
u_int32_t :32;
56
} mode;
57
};
58
#define CISS_HDR_ADDRESS_MODE_PERIPHERAL 0x0
59
#define CISS_HDR_ADDRESS_MODE_LOGICAL 0x1
60
#define CISS_HDR_ADDRESS_MODE_MASK_PERIPHERAL 0x3
61
62
#define CISS_EXTRA_MODE2(extra) ((extra & 0xc0000000) >> 30)
63
#define CISS_EXTRA_BUS2(extra) ((extra & 0x3f000000) >> 24)
64
#define CISS_EXTRA_TARGET2(extra) ((extra & 0x00ff0000) >> 16)
65
#define CISS_EXTRA_MODE3(extra) ((extra & 0x0000c000) >> 14)
66
#define CISS_EXTRA_BUS3(extra) ((extra & 0x00003f00) >> 8)
67
#define CISS_EXTRA_TARGET3(extra) ((extra & 0x000000ff))
68
69
struct ciss_header
70
{
71
u_int8_t :8; /* reserved */
72
u_int8_t sg_in_list; /* SG's in the command structure */
73
u_int16_t sg_total; /* total count of SGs for this command */
74
u_int32_t host_tag; /* host identifier, bits 0&1 must be clear */
75
#define CISS_HDR_HOST_TAG_ERROR (1<<1)
76
u_int32_t host_tag_zeroes; /* tag is 64 bits, but interface only supports 32 */
77
union ciss_device_address address;
78
} __packed;
79
80
struct ciss_cdb
81
{
82
u_int8_t cdb_length; /* valid CDB bytes */
83
u_int8_t type:3;
84
#define CISS_CDB_TYPE_COMMAND 0
85
#define CISS_CDB_TYPE_MESSAGE 1
86
u_int8_t attribute:3;
87
#define CISS_CDB_ATTRIBUTE_UNTAGGED 0
88
#define CISS_CDB_ATTRIBUTE_SIMPLE 4
89
#define CISS_CDB_ATTRIBUTE_HEAD_OF_QUEUE 5
90
#define CISS_CDB_ATTRIBUTE_ORDERED 6
91
#define CISS_CDB_ATTRIBUTE_AUTO_CONTINGENT 7
92
u_int8_t direction:2;
93
#define CISS_CDB_DIRECTION_NONE 0
94
#define CISS_CDB_DIRECTION_WRITE 1
95
#define CISS_CDB_DIRECTION_READ 2
96
u_int16_t timeout; /* seconds */
97
#define CISS_CDB_BUFFER_SIZE 16
98
u_int8_t cdb[CISS_CDB_BUFFER_SIZE];
99
} __packed;
100
101
struct ciss_error_info_pointer
102
{
103
u_int64_t error_info_address; /* points to ciss_error_info structure */
104
u_int32_t error_info_length;
105
} __packed;
106
107
struct ciss_error_info
108
{
109
u_int8_t scsi_status;
110
#define CISS_SCSI_STATUS_GOOD 0x00 /* these are scsi-standard values */
111
#define CISS_SCSI_STATUS_CHECK_CONDITION 0x02
112
#define CISS_SCSI_STATUS_CONDITION_MET 0x04
113
#define CISS_SCSI_STATUS_BUSY 0x08
114
#define CISS_SCSI_STATUS_INDETERMINATE 0x10
115
#define CISS_SCSI_STATUS_INDETERMINATE_CM 0x14
116
#define CISS_SCSI_STATUS_RESERVATION_CONFLICT 0x18
117
#define CISS_SCSI_STATUS_COMMAND_TERMINATED 0x22
118
#define CISS_SCSI_STATUS_QUEUE_FULL 0x28
119
#define CISS_SCSI_STATUS_ACA_ACTIVE 0x30
120
u_int8_t sense_length;
121
u_int16_t command_status;
122
#define CISS_CMD_STATUS_SUCCESS 0
123
#define CISS_CMD_STATUS_TARGET_STATUS 1
124
#define CISS_CMD_STATUS_DATA_UNDERRUN 2
125
#define CISS_CMD_STATUS_DATA_OVERRUN 3
126
#define CISS_CMD_STATUS_INVALID_COMMAND 4
127
#define CISS_CMD_STATUS_PROTOCOL_ERROR 5
128
#define CISS_CMD_STATUS_HARDWARE_ERROR 6
129
#define CISS_CMD_STATUS_CONNECTION_LOST 7
130
#define CISS_CMD_STATUS_ABORTED 8
131
#define CISS_CMD_STATUS_ABORT_FAILED 9
132
#define CISS_CMD_STATUS_UNSOLICITED_ABORT 10
133
#define CISS_CMD_STATUS_TIMEOUT 11
134
#define CISS_CMD_STATUS_UNABORTABLE 12
135
u_int32_t residual_count;
136
union {
137
struct {
138
u_int8_t res1[3];
139
u_int8_t type;
140
u_int32_t error_info;
141
} __packed common_info;
142
struct {
143
u_int8_t res1[2];
144
u_int8_t offense_size;
145
u_int8_t offense_offset;
146
u_int32_t offense_value;
147
} __packed invalid_command;
148
} additional_error_info;
149
u_int8_t sense_info[0];
150
} __packed;
151
152
struct ciss_sg_entry
153
{
154
u_int64_t address;
155
#define CISS_SG_ADDRESS_BITBUCKET (~(u_int64_t)0)
156
u_int32_t length;
157
u_int32_t :31;
158
u_int32_t extension:1; /* address points to another s/g chain */
159
} __packed;
160
161
struct ciss_command
162
{
163
struct ciss_header header;
164
struct ciss_cdb cdb;
165
struct ciss_error_info_pointer error_info;
166
struct ciss_sg_entry sg[0];
167
} __packed;
168
169
#define CISS_OPCODE_REPORT_LOGICAL_LUNS 0xc2
170
#define CISS_OPCODE_REPORT_PHYSICAL_LUNS 0xc3
171
172
struct ciss_lun_report
173
{
174
u_int32_t list_size; /* big-endian */
175
u_int32_t :32;
176
union ciss_device_address lun[0];
177
} __packed;
178
179
#define CISS_VPD_LOGICAL_DRIVE_GEOMETRY 0xc1
180
struct ciss_ldrive_geometry
181
{
182
u_int8_t periph_qualifier:3;
183
u_int8_t periph_devtype:5;
184
u_int8_t page_code;
185
u_int8_t res1;
186
u_int8_t page_length;
187
u_int16_t cylinders; /* big-endian */
188
u_int8_t heads;
189
u_int8_t sectors;
190
u_int8_t fault_tolerance;
191
u_int8_t res2[3];
192
} __attribute__ ((packed));
193
194
struct ciss_report_cdb
195
{
196
u_int8_t opcode;
197
u_int8_t reserved[5];
198
u_int32_t length; /* big-endian */
199
u_int8_t :8;
200
u_int8_t control;
201
} __packed;
202
203
/*
204
* Note that it's not clear whether we have to set the detail field to
205
* the tag of the command to be aborted, or the tag field in the command itself;
206
* documentation conflicts on this.
207
*/
208
#define CISS_OPCODE_MESSAGE_ABORT 0x00
209
#define CISS_MESSAGE_ABORT_TASK 0x00
210
#define CISS_MESSAGE_ABORT_TASK_SET 0x01
211
#define CISS_MESSAGE_ABORT_CLEAR_ACA 0x02
212
#define CISS_MESSAGE_ABORT_CLEAR_TASK_SET 0x03
213
214
#define CISS_OPCODE_MESSAGE_RESET 0x01
215
#define CISS_MESSAGE_RESET_CONTROLLER 0x00
216
#define CISS_MESSAGE_RESET_BUS 0x01
217
#define CISS_MESSAGE_RESET_TARGET 0x03
218
#define CISS_MESSAGE_RESET_LOGICAL_UNIT 0x04
219
220
#define CISS_OPCODE_MESSAGE_SCAN 0x02
221
#define CISS_MESSAGE_SCAN_CONTROLLER 0x00
222
#define CISS_MESSAGE_SCAN_BUS 0x01
223
#define CISS_MESSAGE_SCAN_TARGET 0x03
224
#define CISS_MESSAGE_SCAN_LOGICAL_UNIT 0x04
225
226
#define CISS_OPCODE_MESSAGE_NOP 0x03
227
228
struct ciss_message_cdb
229
{
230
u_int8_t opcode;
231
u_int8_t type;
232
u_int16_t :16;
233
u_int32_t abort_tag; /* XXX endianness? */
234
u_int8_t reserved[8];
235
} __packed;
236
237
/*
238
* CISS vendor-specific commands/messages.
239
*
240
* Note that while messages and vendor-specific commands are
241
* differentiated, they are handled in basically the same way and can
242
* be considered to be basically the same thing, as long as the cdb
243
* type field is set correctly.
244
*/
245
#define CISS_OPCODE_READ 0xc0
246
#define CISS_OPCODE_WRITE 0xc1
247
#define CISS_COMMAND_NOTIFY_ON_EVENT 0xd0
248
#define CISS_COMMAND_ABORT_NOTIFY 0xd1
249
250
struct ciss_notify_cdb
251
{
252
u_int8_t opcode;
253
u_int8_t command;
254
u_int8_t res1[2];
255
u_int16_t timeout; /* seconds, little-endian */
256
u_int8_t res2; /* reserved */
257
u_int8_t synchronous:1; /* return immediately */
258
u_int8_t ordered:1; /* return events in recorded order */
259
u_int8_t seek_to_oldest:1; /* reset read counter to oldest event */
260
u_int8_t new_only:1; /* ignore any queued events */
261
u_int8_t :4;
262
u_int32_t length; /* must be 512, little-endian */
263
#define CISS_NOTIFY_DATA_SIZE 512
264
u_int8_t control;
265
} __packed;
266
267
#define CISS_NOTIFY_NOTIFIER 0
268
#define CISS_NOTIFY_NOTIFIER_STATUS 0
269
#define CISS_NOTIFY_NOTIFIER_PROTOCOL 1
270
271
#define CISS_NOTIFY_HOTPLUG 1
272
#define CISS_NOTIFY_HOTPLUG_PHYSICAL 0
273
#define CISS_NOTIFY_HOTPLUG_POWERSUPPLY 1
274
#define CISS_NOTIFY_HOTPLUG_FAN 2
275
#define CISS_NOTIFY_HOTPLUG_POWER 3
276
#define CISS_NOTIFY_HOTPLUG_REDUNDANT 4
277
#define CISS_NOTIFY_HOTPLUG_NONDISK 5
278
279
#define CISS_NOTIFY_HARDWARE 2
280
#define CISS_NOTIFY_HARDWARE_CABLES 0
281
#define CISS_NOTIFY_HARDWARE_MEMORY 1
282
#define CISS_NOTIFY_HARDWARE_FAN 2
283
#define CISS_NOTIFY_HARDWARE_VRM 3
284
285
#define CISS_NOTIFY_ENVIRONMENT 3
286
#define CISS_NOTIFY_ENVIRONMENT_TEMPERATURE 0
287
#define CISS_NOTIFY_ENVIRONMENT_POWERSUPPLY 1
288
#define CISS_NOTIFY_ENVIRONMENT_CHASSIS 2
289
#define CISS_NOTIFY_ENVIRONMENT_POWER 3
290
291
#define CISS_NOTIFY_PHYSICAL 4
292
#define CISS_NOTIFY_PHYSICAL_STATE 0
293
294
#define CISS_NOTIFY_LOGICAL 5
295
#define CISS_NOTIFY_LOGICAL_STATUS 0
296
#define CISS_NOTIFY_LOGICAL_ERROR 1
297
#define CISS_NOTIFY_LOGICAL_SURFACE 2
298
299
#define CISS_NOTIFY_REDUNDANT 6
300
#define CISS_NOTIFY_REDUNDANT_STATUS 0
301
302
#define CISS_NOTIFY_CISS 8
303
#define CISS_NOTIFY_CISS_REDUNDANT_CHANGE 0
304
#define CISS_NOTIFY_CISS_PATH_STATUS 1
305
#define CISS_NOTIFY_CISS_HARDWARE_ERROR 2
306
#define CISS_NOTIFY_CISS_LOGICAL 3
307
308
struct ciss_notify_drive
309
{
310
u_int16_t physical_drive_number;
311
u_int8_t configured_drive_flag;
312
u_int8_t spare_drive_flag;
313
u_int8_t big_physical_drive_number;
314
u_int8_t enclosure_bay_number;
315
} __packed;
316
317
struct ciss_notify_locator
318
{
319
u_int16_t port;
320
u_int16_t id;
321
u_int16_t box;
322
} __packed;
323
324
struct ciss_notify_redundant_controller
325
{
326
u_int16_t slot;
327
} __packed;
328
329
struct ciss_notify_logical_status
330
{
331
u_int16_t logical_drive;
332
u_int8_t previous_state;
333
u_int8_t new_state;
334
u_int8_t spare_state;
335
} __packed;
336
337
struct ciss_notify_rebuild_aborted
338
{
339
u_int16_t logical_drive;
340
u_int8_t replacement_drive;
341
u_int8_t error_drive;
342
u_int8_t big_replacement_drive;
343
u_int8_t big_error_drive;
344
} __packed;
345
346
struct ciss_notify_io_error
347
{
348
u_int16_t logical_drive;
349
u_int32_t lba;
350
u_int16_t block_count;
351
u_int8_t command;
352
u_int8_t failure_bus;
353
u_int8_t failure_drive;
354
u_int64_t big_lba;
355
} __packed;
356
357
struct ciss_notify_consistency_completed
358
{
359
u_int16_t logical_drive;
360
} __packed;
361
362
struct ciss_notify
363
{
364
u_int32_t timestamp; /* seconds since controller power-on */
365
u_int16_t class;
366
u_int16_t subclass;
367
u_int16_t detail;
368
union
369
{
370
struct ciss_notify_drive drive;
371
struct ciss_notify_locator location;
372
struct ciss_notify_redundant_controller redundant_controller;
373
struct ciss_notify_logical_status logical_status;
374
struct ciss_notify_rebuild_aborted rebuild_aborted;
375
struct ciss_notify_io_error io_error;
376
struct ciss_notify_consistency_completed consistency_completed;
377
u_int8_t data[64];
378
} data;
379
char message[80];
380
u_int32_t tag;
381
u_int16_t date;
382
u_int16_t year;
383
u_int32_t time;
384
u_int16_t pre_power_up_time;
385
union ciss_device_address device;
386
/* XXX pads to 512 bytes */
387
} __packed;
388
389
/*
390
* CISS config table, which describes the controller's
391
* supported interface(s) and capabilities.
392
*
393
* This is mapped directly via PCI.
394
*/
395
struct ciss_config_table
396
{
397
char signature[4]; /* "CISS" */
398
u_int32_t valence;
399
u_int32_t supported_methods;
400
#define CISS_TRANSPORT_METHOD_READY (1<<0)
401
#define CISS_TRANSPORT_METHOD_SIMPLE (1<<1)
402
#define CISS_TRANSPORT_METHOD_PERF (1<<2)
403
u_int32_t active_method;
404
u_int32_t requested_method;
405
u_int32_t command_physlimit;
406
u_int32_t interrupt_coalesce_delay;
407
u_int32_t interrupt_coalesce_count;
408
u_int32_t max_outstanding_commands;
409
u_int32_t bus_types;
410
#define CISS_TRANSPORT_BUS_TYPE_ULTRA2 (1<<0)
411
#define CISS_TRANSPORT_BUS_TYPE_ULTRA3 (1<<1)
412
#define CISS_TRANSPORT_BUS_TYPE_FIBRE1 (1<<8)
413
#define CISS_TRANSPORT_BUS_TYPE_FIBRE2 (1<<9)
414
u_int32_t transport_offset;
415
char server_name[16];
416
u_int32_t heartbeat;
417
u_int32_t host_driver;
418
#define CISS_DRIVER_SUPPORT_UNIT_ATTENTION (1<<0)
419
#define CISS_DRIVER_QUICK_INIT (1<<1)
420
#define CISS_DRIVER_INTERRUPT_ON_LOCKUP (1<<2)
421
#define CISS_DRIVER_SUPPORT_MIXED_Q_TAGS (1<<3)
422
#define CISS_DRIVER_HOST_IS_ALPHA (1<<4)
423
#define CISS_DRIVER_MULTI_LUN_SUPPORT (1<<5)
424
#define CISS_DRIVER_MESSAGE_REQUESTS_SUPPORTED (1<<7)
425
#define CISS_DRIVER_DAUGHTER_ATTACHED (1<<8)
426
#define CISS_DRIVER_SCSI_PREFETCH (1<<9)
427
u_int32_t max_sg_length; /* 31 in older firmware */
428
/*
429
* these fields appear in OpenCISS Spec 1.06
430
* http://cciss.sourceforge.net/#docs
431
*/
432
u_int32_t max_logical_supported;
433
u_int32_t max_physical_supported;
434
u_int32_t max_physical_per_logical;
435
u_int32_t max_perfomant_mode_cmds;
436
u_int32_t max_block_fetch_count;
437
} __packed;
438
439
/*
440
* Configuration table for the Performant transport. Only 4 request queues
441
* are mentioned in this table, though apparently up to 256 can exist.
442
*/
443
struct ciss_perf_config {
444
uint32_t fetch_count[8];
445
#define CISS_SG_FETCH_MAX 0
446
#define CISS_SG_FETCH_1 1
447
#define CISS_SG_FETCH_2 2
448
#define CISS_SG_FETCH_4 3
449
#define CISS_SG_FETCH_8 4
450
#define CISS_SG_FETCH_16 5
451
#define CISS_SG_FETCH_32 6
452
#define CISS_SG_FETCH_NONE 7
453
uint32_t rq_size;
454
uint32_t rq_count;
455
uint32_t rq_bank_lo;
456
uint32_t rq_bank_hi;
457
struct {
458
uint32_t rq_addr_lo;
459
uint32_t rq_addr_hi;
460
} __packed rq[4];
461
} __packed;
462
463
/*
464
* In a flagrant violation of what CISS seems to be meant to be about,
465
* Compaq recycle a goodly portion of their previous generation's
466
* command set (and all the legacy baggage related to a design
467
* originally aimed at narrow SCSI) through the Array Controller Read
468
* and Array Controller Write interface.
469
*
470
* Command ID values here can be looked up for in the
471
* publically-available documentation for the older controllers; note
472
* that the command layout is necessarily different to fit within the
473
* CDB.
474
*/
475
#define CISS_ARRAY_CONTROLLER_READ 0x26
476
#define CISS_ARRAY_CONTROLLER_WRITE 0x27
477
478
#define CISS_BMIC_ID_LDRIVE 0x10
479
#define CISS_BMIC_ID_CTLR 0x11
480
#define CISS_BMIC_ID_LSTATUS 0x12
481
#define CISS_BMIC_ID_PDRIVE 0x15
482
#define CISS_BMIC_BLINK_PDRIVE 0x16
483
#define CISS_BMIC_SENSE_BLINK_PDRIVE 0x17
484
#define CISS_BMIC_SOFT_RESET 0x40
485
#define CISS_BMIC_FLUSH_CACHE 0xc2
486
#define CISS_BMIC_ACCEPT_MEDIA 0xe0
487
488
/*
489
* When numbering drives, the original design assumed that
490
* drives 0-7 are on the first SCSI bus, 8-15 on the second,
491
* and so forth. In order to handle modern SCSI configurations,
492
* the MSB is set in the drive ID field, in which case the
493
* modulus changes from 8 to the number of supported drives
494
* per SCSI bus (as obtained from the ID_CTLR command).
495
* This feature is referred to as BIG_MAP support, and we assume
496
* that all CISS controllers support it.
497
*/
498
499
#define CISS_BIG_MAP_ID(sc, bus, target) \
500
(0x80 | \
501
((sc)->ciss_id->drives_per_scsi_bus * (bus)) | \
502
(target))
503
504
#define CISS_BIG_MAP_BUS(sc, id) \
505
(((id) & 0x80) ? (((id) & ~0x80) / (sc)->ciss_id->drives_per_scsi_bus) : -1)
506
507
#define CISS_BIG_MAP_TARGET(sc, id) \
508
(((id) & 0x80) ? (((id) & ~0x80) % (sc)->ciss_id->drives_per_scsi_bus) : -1)
509
510
#define CISS_BIG_MAP_ENTRIES 128 /* number of entries in a BIG_MAP */
511
512
/*
513
* In the device address of a logical volume, the bus number
514
* is encoded into the logical lun volume number starting
515
* at the second byte, with the first byte defining the
516
* logical drive number.
517
*/
518
#define CISS_LUN_TO_BUS(x) (((x) >> 16) & 0xFF)
519
#define CISS_LUN_TO_TARGET(x) ((x) & 0xFF)
520
521
/*
522
* BMIC CDB
523
*
524
* Note that the phys_drive/res1 field is nominally the 32-bit
525
* "block number" field, but the only BMIC command(s) of interest
526
* implemented overload the MSB (note big-endian format here)
527
* to be the physical drive ID, so we define accordingly.
528
*/
529
struct ciss_bmic_cdb {
530
u_int8_t opcode;
531
u_int8_t log_drive;
532
u_int8_t phys_drive;
533
u_int8_t res1[3];
534
u_int8_t bmic_opcode;
535
u_int16_t size; /* big-endian */
536
u_int8_t res2;
537
} __packed;
538
539
/*
540
* BMIC command command/return structures.
541
*/
542
543
/* CISS_BMIC_ID_LDRIVE */
544
struct ciss_bmic_id_ldrive {
545
u_int16_t block_size;
546
u_int32_t blocks_available;
547
u_int8_t drive_parameter_table[16]; /* XXX define */
548
u_int8_t fault_tolerance;
549
#define CISS_LDRIVE_RAID0 0
550
#define CISS_LDRIVE_RAID4 1
551
#define CISS_LDRIVE_RAID1 2
552
#define CISS_LDRIVE_RAID5 3
553
#define CISS_LDRIVE_RAID51 4
554
#define CISS_LDRIVE_RAIDADG 5
555
u_int8_t res1;
556
u_int8_t bios_disable_flag;
557
u_int8_t res2;
558
u_int32_t logical_drive_identifier;
559
char logical_drive_label[64];
560
u_int64_t big_blocks_available;
561
u_int8_t res3[410];
562
} __packed;
563
564
/* CISS_BMIC_ID_LSTATUS */
565
struct ciss_bmic_id_lstatus {
566
u_int8_t status;
567
#define CISS_LSTATUS_OK 0
568
#define CISS_LSTATUS_FAILED 1
569
#define CISS_LSTATUS_NOT_CONFIGURED 2
570
#define CISS_LSTATUS_INTERIM_RECOVERY 3
571
#define CISS_LSTATUS_READY_RECOVERY 4
572
#define CISS_LSTATUS_RECOVERING 5
573
#define CISS_LSTATUS_WRONG_PDRIVE 6
574
#define CISS_LSTATUS_MISSING_PDRIVE 7
575
#define CISS_LSTATUS_EXPANDING 10
576
#define CISS_LSTATUS_BECOMING_READY 11
577
#define CISS_LSTATUS_QUEUED_FOR_EXPANSION 12
578
u_int32_t deprecated_drive_failure_map;
579
u_int8_t res1[416];
580
u_int32_t blocks_to_recover;
581
u_int8_t deprecated_drive_rebuilding;
582
u_int16_t deprecated_remap_count[32];
583
u_int32_t deprecated_replacement_map;
584
u_int32_t deprecated_active_spare_map;
585
u_int8_t spare_configured:1;
586
u_int8_t spare_rebuilding:1;
587
u_int8_t spare_rebuilt:1;
588
u_int8_t spare_failed:1;
589
u_int8_t spare_switched:1;
590
u_int8_t spare_available:1;
591
u_int8_t res2:2;
592
u_int8_t deprecated_spare_to_replace_map[32];
593
u_int32_t deprecated_replaced_marked_ok_map;
594
u_int8_t media_exchanged;
595
u_int8_t cache_failure;
596
u_int8_t expand_failure;
597
u_int8_t rebuild_read_failure:1;
598
u_int8_t rebuild_write_failure:1;
599
u_int8_t res3:6;
600
u_int8_t drive_failure_map[CISS_BIG_MAP_ENTRIES / 8];
601
u_int16_t remap_count[CISS_BIG_MAP_ENTRIES];
602
u_int8_t replacement_map[CISS_BIG_MAP_ENTRIES / 8];
603
u_int8_t active_spare_map[CISS_BIG_MAP_ENTRIES / 8];
604
u_int8_t spare_to_replace_map[CISS_BIG_MAP_ENTRIES];
605
u_int8_t replaced_marked_ok_map[CISS_BIG_MAP_ENTRIES / 8];
606
u_int8_t drive_rebuilding;
607
u_int64_t big_blocks_to_recover;
608
u_int8_t res4[28];
609
} __packed;
610
611
/* CISS_BMIC_ID_CTLR */
612
struct ciss_bmic_id_table {
613
u_int8_t configured_logical_drives;
614
u_int32_t config_signature;
615
char running_firmware_revision[4];
616
char stored_firmware_revision[4];
617
u_int8_t hardware_revision;
618
u_int8_t boot_block_revision[4];
619
u_int32_t deprecated_drive_present_map;
620
u_int32_t deprecated_external_drive_present_map;
621
u_int32_t board_id;
622
u_int8_t swapped_error_cable;
623
u_int32_t deprecated_non_disk_map;
624
u_int8_t bad_host_ram_addr;
625
u_int8_t cpu_revision;
626
u_int8_t res3[3];
627
char marketting_revision;
628
u_int8_t controller_flags;
629
#define CONTROLLER_FLAGS_FLASH_ROM_INSTALLED 0x01
630
#define CONTROLLER_FLAGS_DIAGS_MODE_BIT 0x02
631
#define CONTROLLER_FLAGS_EXPAND_32MB_FX 0x04
632
#define CONTROLLER_FLAGS_MORE_THAN_7_SUPPORT 0x08
633
#define CONTROLLER_FLAGS_DAISY_SUPPORT_BIT 0x10
634
#define CONTROLLER_FLAGS_RES6 0x20
635
#define CONTROLLER_FLAGS_RES7 0x40
636
#define CONTROLLER_FLAGS_BIG_MAP_SUPPORT 0x80
637
u_int8_t host_flags;
638
#define HOST_FLAGS_SDB_ASIC_WORK_AROUND 0x01
639
#define HOST_FLAGS_PCI_DATA_BUS_PARITY_SUPPORT 0x02
640
#define HOST_FLAGS_RES3 0x04
641
#define HOST_FLAGS_RES4 0x08
642
#define HOST_FLAGS_RES5 0x10
643
#define HOST_FLAGS_RES6 0x20
644
#define HOST_FLAGS_RES7 0x30
645
#define HOST_FLAGS_RES8 0x40
646
u_int8_t expand_disable_code;
647
#define EXPAND_DISABLE_NOT_NEEDED 0x01
648
#define EXPAND_DISABLE_MISSING_CACHE_BOARD 0x02
649
#define EXPAND_DISABLE_WCXC_FATAL_CACHE_BITS 0x04
650
#define EXPAND_DISABLE_CACHE_PERM_DISABLED 0x08
651
#define EXPAND_DISABLE_RAM_ALLOCATION_FAILED 0x10
652
#define EXPAND_DISABLE_BATTEREIS_DISCHARGED 0x20
653
#define EXPAND_DISABLE_RES7 0x40
654
#define EXPAND_DISABLE_REBUILD_RUNNING 0x80
655
u_int8_t scsi_chip_count;
656
u_int32_t maximum_blocks;
657
u_int32_t controller_clock;
658
u_int8_t drives_per_scsi_bus;
659
u_int8_t big_drive_present_map[CISS_BIG_MAP_ENTRIES / 8];
660
u_int8_t big_external_drive_present_map[CISS_BIG_MAP_ENTRIES / 8];
661
u_int8_t big_non_disk_map[CISS_BIG_MAP_ENTRIES / 8];
662
663
u_int16_t task_flags; /* used for FW debugging */
664
u_int8_t ICL_bus_map; /* Bitmap used for ICL between controllers */
665
u_int8_t redund_ctlr_modes_support; /* See REDUNDANT MODE VALUES */
666
u_int8_t curr_redund_ctlr_mode;
667
u_int8_t redund_ctlr_status;
668
u_int8_t redund_op_failure_code;
669
670
u_int8_t unsupported_nile_bus;
671
u_int8_t host_i2c_autorev;
672
u_int8_t cpld_revision;
673
u_int8_t fibre_chip_count;
674
u_int8_t daughterboard_type;
675
u_int8_t more_swapped_config_cable_error;
676
677
u_int8_t license_key_status;
678
u_int8_t access_module_status;
679
u_int8_t features_supported[12];
680
u_int8_t rec_rom_inact_rev[4]; /* Recovery ROM inactive f/w revision */
681
u_int8_t rec_rom_act_status; /* Recovery ROM flags */
682
u_int8_t pci_to_pci_status; /* PCI to PCI bridge status */
683
u_int32_t redundant_server_info; /* Reserved for future use */
684
u_int8_t percent_write_cache; /* Percent of memory allocated to write cache */
685
u_int16_t daughterboard_size_mb; /* Total size (MB) of cache board */
686
u_int8_t cache_batter_count; /* Number of cache batteries */
687
u_int16_t total_controller_mem_mb; /* Total size (MB) of attached memory */
688
u_int8_t more_controller_flags; /* Additional controller flags byte */
689
u_int8_t x_board_host_i2c_rev; /* 2nd byte of 3 byte autorev field */
690
u_int8_t battery_pic_rev; /* BBWC PIC revision */
691
/*
692
* Below here I have no documentation on the rest of this data structure. It is
693
* inferred from the opensource cciss_vol_status application. I assume that this
694
* data structure is 512 bytes in total size, do not exceed it.
695
*/
696
u_int8_t bDdffVersion[4]; /* DDFF update engine version */
697
u_int16_t usMaxLogicalUnits; /* Maximum logical units supported */
698
u_int16_t usExtLogicalUnitCount; /* Big num configured logical units */
699
u_int16_t usMaxPhysicalDevices; /* Maximum physical devices supported */
700
u_int16_t usMaxPhyDrvPerLogicalUnit; /* Max physical drive per logical unit */
701
u_int8_t bEnclosureCount; /* Number of attached enclosures */
702
u_int8_t bExpanderCount; /* Number of expanders detected */
703
u_int16_t usOffsetToEDPbitmap; /* Offset to extended drive present map*/
704
u_int16_t usOffsetToEEDPbitmap; /* Offset to extended external drive present map */
705
u_int16_t usOffsetToENDbitmap; /* Offset to extended non-disk map */
706
u_int8_t bInternalPortStatus[8]; /* Internal port status bytes */
707
u_int8_t bExternalPortStatus[8]; /* External port status bytes */
708
u_int32_t uiYetMoreControllerFlags;/* Yet More Controller flags */
709
#define YMORE_CONTROLLER_FLAGS_JBOD_SUPPORTED \
710
( 1 << 25 ) /* Controller has JBOD support */
711
712
u_int8_t bLastLockup; /* Last lockup code */
713
u_int8_t bSlot; /* PCI slot according to option ROM*/
714
u_int16_t usBuildNum; /* Build number */
715
u_int32_t uiMaxSafeFullStripeSize; /* Maximum safe full stripe size */
716
u_int32_t uiTotalLength; /* Total structure length */
717
u_int8_t bVendorID[8]; /* Vendor ID */
718
u_int8_t bProductID[16]; /* Product ID */
719
/*
720
* These are even more obscure as they seem to only be available in cciss_vol_status
721
*/
722
u_int32_t ExtendedLastLockupCode;
723
u_int16_t MaxRaid;
724
u_int16_t MaxParity;
725
u_int16_t MaxADGStripSize;
726
u_int16_t YetMoreSwappedCables;
727
u_int8_t MaxDevicePaths;
728
u_int8_t PowerUPNvramFlags;
729
#define PWR_UP_FLAG_JBOD_ENABLED 0x08 /*JBOD mode is enabled, all RAID features off */
730
731
u_int16_t ZonedOffset;
732
u_int32_t FixedFieldsLength;
733
u_int8_t FWCompileTimeStamp[24];
734
u_int32_t EvenMoreControllerFlags;
735
u_int8_t padding[240];
736
} __packed;
737
738
/* CISS_BMIC_ID_PDRIVE */
739
struct ciss_bmic_id_pdrive {
740
u_int8_t scsi_bus;
741
u_int8_t scsi_id;
742
u_int16_t block_size;
743
u_int32_t total_blocks;
744
u_int32_t reserved_blocks;
745
char model[40];
746
char serial[40];
747
char revision[8];
748
u_int8_t inquiry_bits;
749
u_int8_t res1[2];
750
u_int8_t drive_present:1;
751
u_int8_t non_disk:1;
752
u_int8_t wide:1;
753
u_int8_t synchronous:1;
754
u_int8_t narrow:1;
755
u_int8_t wide_downgraded_to_narrow:1;
756
u_int8_t ultra:1;
757
u_int8_t ultra2:1;
758
u_int8_t SMART:1;
759
u_int8_t SMART_errors_recorded:1;
760
u_int8_t SMART_errors_enabled:1;
761
u_int8_t SMART_errors_detected:1;
762
u_int8_t external:1;
763
u_int8_t configured:1;
764
u_int8_t configured_spare:1;
765
u_int8_t cache_saved_enabled:1;
766
u_int8_t res2;
767
u_int8_t res3:6;
768
u_int8_t cache_currently_enabled:1;
769
u_int8_t cache_safe:1;
770
u_int8_t res4[5];
771
char connector[2];
772
u_int8_t res5;
773
u_int8_t bay;
774
u_int16_t rpm;
775
u_int8_t drive_type;
776
u_int8_t res6[393];
777
} __packed;
778
779
/* CISS_BMIC_BLINK_PDRIVE */
780
/* CISS_BMIC_SENSE_BLINK_PDRIVE */
781
struct ciss_bmic_blink_pdrive {
782
u_int32_t blink_duration; /* 10ths of a second */
783
u_int32_t duration_elapsed; /* only for sense command */
784
u_int8_t blinktab[256];
785
#define CISS_BMIC_BLINK_ALL 1
786
#define CISS_BMIC_BLINK_TIMED 2
787
u_int8_t res2[248];
788
} __packed;
789
790
/* CISS_BMIC_FLUSH_CACHE */
791
struct ciss_bmic_flush_cache {
792
u_int16_t flag;
793
#define CISS_BMIC_FLUSH_AND_ENABLE 0
794
#define CISS_BMIC_FLUSH_AND_DISABLE 1
795
u_int8_t res1[510];
796
} __packed;
797
798
#ifdef _KERNEL
799
/*
800
* CISS "simple" transport layer.
801
*
802
* Note that there are two slightly different versions of this interface
803
* with different interrupt mask bits. There's nothing like consistency...
804
*/
805
#define CISS_TL_SIMPLE_BAR_REGS 0x10 /* BAR pointing to register space */
806
#define CISS_TL_SIMPLE_BAR_CFG 0x14 /* BAR pointing to space containing config table */
807
808
#define CISS_TL_SIMPLE_IDBR 0x20 /* inbound doorbell register */
809
#define CISS_TL_SIMPLE_IDBR_CFG_TABLE (1<<0) /* notify controller of config table update */
810
811
#define CISS_TL_SIMPLE_ISR 0x30 /* interrupt status register */
812
#define CISS_TL_SIMPLE_IMR 0x34 /* interrupt mask register */
813
#define CISS_TL_SIMPLE_INTR_OPQ_SA5 (1<<3) /* OPQ not empty interrupt, SA5 boards */
814
#define CISS_TL_SIMPLE_INTR_OPQ_SA5B (1<<2) /* OPQ not empty interrupt, SA5B boards */
815
816
#define CISS_TL_SIMPLE_IPQ 0x40 /* inbound post queue */
817
#define CISS_TL_SIMPLE_OPQ 0x44 /* outbound post queue */
818
#define CISS_TL_SIMPLE_OPQ_EMPTY (~(u_int32_t)0)
819
820
#define CISS_TL_SIMPLE_OSR 0x9c /* outbound status register */
821
#define CISS_TL_SIMPLE_ODC 0xa0 /* outbound doorbell clear register */
822
#define CISS_TL_SIMPLE_ODC_CLEAR (0x1)
823
824
#define CISS_TL_SIMPLE_CFG_BAR 0xb4 /* should be 0x14 */
825
#define CISS_TL_SIMPLE_CFG_OFF 0xb8 /* offset in BAR at which config table is located */
826
827
/*
828
* Register access primitives.
829
*/
830
#define CISS_TL_SIMPLE_READ(sc, ofs) \
831
bus_space_read_4(sc->ciss_regs_btag, sc->ciss_regs_bhandle, ofs)
832
#define CISS_TL_SIMPLE_WRITE(sc, ofs, val) \
833
bus_space_write_4(sc->ciss_regs_btag, sc->ciss_regs_bhandle, ofs, val)
834
835
#define CISS_TL_SIMPLE_POST_CMD(sc, phys) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, phys)
836
#define CISS_TL_SIMPLE_FETCH_CMD(sc) CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_OPQ)
837
838
#define CISS_TL_PERF_INTR_OPQ (CISS_TL_SIMPLE_INTR_OPQ_SA5 | CISS_TL_SIMPLE_INTR_OPQ_SA5B)
839
#define CISS_TL_PERF_INTR_MSI 0x01
840
841
#define CISS_TL_PERF_POST_CMD(sc, cr) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, cr->cr_ccphys | (cr)->cr_sg_tag)
842
#define CISS_TL_PERF_FLUSH_INT(sc) CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_OSR)
843
#define CISS_TL_PERF_CLEAR_INT(sc) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_ODC, CISS_TL_SIMPLE_ODC_CLEAR)
844
#define CISS_CYCLE_MASK 0x00000001
845
846
/* Only need one MSI/MSI-X vector */
847
#define CISS_MSI_COUNT 1
848
849
#define CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc) \
850
CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \
851
CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) | (sc)->ciss_interrupt_mask)
852
#define CISS_TL_SIMPLE_ENABLE_INTERRUPTS(sc) \
853
CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \
854
CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) & ~(sc)->ciss_interrupt_mask)
855
856
#endif /* _KERNEL */
857
858