1 /*- 2 * Copyright (c) 2001 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: src/sys/dev/ciss/cissreg.h,v 1.1.2.2 2003/02/06 21:42:59 ps Exp $ 27 * $DragonFly: src/sys/dev/raid/ciss/cissreg.h,v 1.2 2003/06/17 04:28:23 dillon Exp $ 28 */ 29 30 /* 31 * Structure and I/O definitions for the Command Interface for SCSI-3 Support. 32 * 33 * Data in command CDBs are in big-endian format. All other data is little-endian. 34 * This header only supports little-endian hosts at this time. 35 */ 36 37 union ciss_device_address 38 { 39 struct /* MODE_PERIPHERAL and MODE_MASK_PERIPHERAL */ 40 { 41 u_int32_t target:24; /* SCSI target */ 42 u_int32_t bus:6; /* SCSI bus */ 43 u_int32_t mode:2; /* CISS_HDR_ADDRESS_MODE_* */ 44 u_int32_t extra_address; /* SCSI-3 level-2 and level-3 address bytes */ 45 } physical; 46 struct /* MODE_LOGICAL */ 47 { 48 u_int32_t lun:30; /* logical device ID */ 49 u_int32_t mode:2; /* CISS_HDR_ADDRESS_MODE_LOGICAL */ 50 u_int32_t :32; /* reserved */ 51 } logical; 52 struct 53 { 54 u_int32_t :30; 55 u_int32_t mode:2; 56 u_int32_t :32; 57 } mode; 58 }; 59 #define CISS_HDR_ADDRESS_MODE_PERIPHERAL 0x0 60 #define CISS_HDR_ADDRESS_MODE_LOGICAL 0x1 61 #define CISS_HDR_ADDRESS_MODE_MASK_PERIPHERAL 0x3 62 63 struct ciss_header 64 { 65 u_int8_t :8; /* reserved */ 66 u_int8_t sg_in_list; /* SG's in the command structure */ 67 u_int16_t sg_total; /* total count of SGs for this command */ 68 u_int32_t host_tag; /* host identifier, bits 0&1 must be clear */ 69 #define CISS_HDR_HOST_TAG_ERROR (1<<1) 70 u_int32_t host_tag_zeroes; /* tag is 64 bits, but interface only supports 32 */ 71 union ciss_device_address address; 72 } __attribute__ ((packed)); 73 74 struct ciss_cdb 75 { 76 u_int8_t cdb_length; /* valid CDB bytes */ 77 u_int8_t type:3; 78 #define CISS_CDB_TYPE_COMMAND 0 79 #define CISS_CDB_TYPE_MESSAGE 1 80 u_int8_t attribute:3; 81 #define CISS_CDB_ATTRIBUTE_UNTAGGED 0 82 #define CISS_CDB_ATTRIBUTE_SIMPLE 4 83 #define CISS_CDB_ATTRIBUTE_HEAD_OF_QUEUE 5 84 #define CISS_CDB_ATTRIBUTE_ORDERED 6 85 #define CISS_CDB_ATTRIBUTE_AUTO_CONTINGENT 7 86 u_int8_t direction:2; 87 #define CISS_CDB_DIRECTION_NONE 0 88 #define CISS_CDB_DIRECTION_READ 1 89 #define CISS_CDB_DIRECTION_WRITE 2 90 u_int16_t timeout; /* seconds */ 91 #define CISS_CDB_BUFFER_SIZE 16 92 u_int8_t cdb[CISS_CDB_BUFFER_SIZE]; 93 } __attribute__ ((packed)); 94 95 struct ciss_error_info_pointer 96 { 97 u_int64_t error_info_address; /* points to ciss_error_info structure */ 98 u_int32_t error_info_length; 99 } __attribute__ ((packed)); 100 101 struct ciss_error_info 102 { 103 u_int8_t scsi_status; 104 #define CISS_SCSI_STATUS_GOOD 0x00 /* these are scsi-standard values */ 105 #define CISS_SCSI_STATUS_CHECK_CONDITION 0x02 106 #define CISS_SCSI_STATUS_CONDITION_MET 0x04 107 #define CISS_SCSI_STATUS_BUSY 0x08 108 #define CISS_SCSI_STATUS_INDETERMINATE 0x10 109 #define CISS_SCSI_STATUS_INDETERMINATE_CM 0x14 110 #define CISS_SCSI_STATUS_RESERVATION_CONFLICT 0x18 111 #define CISS_SCSI_STATUS_COMMAND_TERMINATED 0x22 112 #define CISS_SCSI_STATUS_QUEUE_FULL 0x28 113 #define CISS_SCSI_STATUS_ACA_ACTIVE 0x30 114 u_int8_t sense_length; 115 u_int16_t command_status; 116 #define CISS_CMD_STATUS_SUCCESS 0 117 #define CISS_CMD_STATUS_TARGET_STATUS 1 118 #define CISS_CMD_STATUS_DATA_UNDERRUN 2 119 #define CISS_CMD_STATUS_DATA_OVERRUN 3 120 #define CISS_CMD_STATUS_INVALID_COMMAND 4 121 #define CISS_CMD_STATUS_PROTOCOL_ERROR 5 122 #define CISS_CMD_STATUS_HARDWARE_ERROR 6 123 #define CISS_CMD_STATUS_CONNECTION_LOST 7 124 #define CISS_CMD_STATUS_ABORTED 8 125 #define CISS_CMD_STATUS_ABORT_FAILED 9 126 #define CISS_CMD_STATUS_UNSOLICITED_ABORT 10 127 #define CISS_CMD_STATUS_TIMEOUT 11 128 #define CISS_CMD_STATUS_UNABORTABLE 12 129 u_int32_t residual_count; 130 union { 131 struct { 132 u_int8_t res1[3]; 133 u_int8_t type; 134 u_int32_t error_info; 135 } common_info __attribute__ ((packed)); 136 struct { 137 u_int8_t res1[2]; 138 u_int8_t offense_size; 139 u_int8_t offense_offset; 140 u_int32_t offense_value; 141 } invalid_command __attribute__ ((packed)); 142 } additional_error_info; 143 u_int8_t sense_info[0]; 144 } __attribute__ ((packed)); 145 146 struct ciss_sg_entry 147 { 148 u_int64_t address; 149 #define CISS_SG_ADDRESS_BITBUCKET (~(u_int64_t)0) 150 u_int32_t length; 151 u_int32_t :31; 152 u_int32_t extension:1; /* address points to another s/g chain */ 153 } __attribute__ ((packed)); 154 155 struct ciss_command 156 { 157 struct ciss_header header; 158 struct ciss_cdb cdb; 159 struct ciss_error_info_pointer error_info; 160 struct ciss_sg_entry sg[0]; 161 } __attribute__ ((packed)); 162 163 #define CISS_OPCODE_REPORT_LOGICAL_LUNS 0xc2 164 #define CISS_OPCODE_REPORT_PHYSICAL_LUNS 0xc3 165 166 struct ciss_lun_report 167 { 168 u_int32_t list_size; /* big-endian */ 169 u_int32_t :32; 170 union ciss_device_address lun[0]; 171 } __attribute__ ((packed)); 172 173 #define CISS_VPD_LOGICAL_DRIVE_GEOMETRY 0xc1 174 struct ciss_ldrive_geometry 175 { 176 u_int8_t periph_qualifier:3; 177 u_int8_t periph_devtype:5; 178 u_int8_t page_code; 179 u_int8_t res1; 180 u_int8_t page_length; 181 u_int16_t cylinders; /* big-endian */ 182 u_int8_t heads; 183 u_int8_t sectors; 184 u_int8_t fault_tolerance; 185 u_int8_t res2[3]; 186 } __attribute__ ((packed)); 187 188 struct ciss_report_cdb 189 { 190 u_int8_t opcode; 191 u_int8_t reserved[5]; 192 u_int32_t length; /* big-endian */ 193 u_int8_t :8; 194 u_int8_t control; 195 } __attribute__ ((packed)); 196 197 /* 198 * Note that it's not clear whether we have to set the detail field to 199 * the tag of the command to be aborted, or the tag field in the command itself; 200 * documentation conflicts on this. 201 */ 202 #define CISS_OPCODE_MESSAGE_ABORT 0x00 203 #define CISS_MESSAGE_ABORT_TASK 0x00 204 #define CISS_MESSAGE_ABORT_TASK_SET 0x01 205 #define CISS_MESSAGE_ABORT_CLEAR_ACA 0x02 206 #define CISS_MESSAGE_ABORT_CLEAR_TASK_SET 0x03 207 208 #define CISS_OPCODE_MESSAGE_RESET 0x01 209 #define CISS_MESSAGE_RESET_CONTROLLER 0x00 210 #define CISS_MESSAGE_RESET_BUS 0x01 211 #define CISS_MESSAGE_RESET_TARGET 0x03 212 #define CISS_MESSAGE_RESET_LOGICAL_UNIT 0x04 213 214 #define CISS_OPCODE_MESSAGE_SCAN 0x02 215 #define CISS_MESSAGE_SCAN_CONTROLLER 0x00 216 #define CISS_MESSAGE_SCAN_BUS 0x01 217 #define CISS_MESSAGE_SCAN_TARGET 0x03 218 #define CISS_MESSAGE_SCAN_LOGICAL_UNIT 0x04 219 220 #define CISS_OPCODE_MESSAGE_NOP 0x03 221 222 struct ciss_message_cdb 223 { 224 u_int8_t opcode; 225 u_int8_t type; 226 u_int16_t :16; 227 u_int32_t abort_tag; /* XXX endianness? */ 228 u_int8_t reserved[8]; 229 } __attribute__ ((packed)); 230 231 /* 232 * CISS vendor-specific commands/messages. 233 * 234 * Note that while messages and vendor-specific commands are 235 * differentiated, they are handled in basically the same way and can 236 * be considered to be basically the same thing, as long as the cdb 237 * type field is set correctly. 238 */ 239 #define CISS_OPCODE_READ 0xc0 240 #define CISS_OPCODE_WRITE 0xc1 241 #define CISS_COMMAND_NOTIFY_ON_EVENT 0xd0 242 #define CISS_COMMAND_ABORT_NOTIFY 0xd1 243 244 struct ciss_notify_cdb 245 { 246 u_int8_t opcode; 247 u_int8_t command; 248 u_int8_t res1[2]; 249 u_int16_t timeout; /* seconds, little-endian */ 250 u_int8_t res2; /* reserved */ 251 u_int8_t synchronous:1; /* return immediately */ 252 u_int8_t ordered:1; /* return events in recorded order */ 253 u_int8_t seek_to_oldest:1; /* reset read counter to oldest event */ 254 u_int8_t new_only:1; /* ignore any queued events */ 255 u_int8_t :4; 256 u_int32_t length; /* must be 512, little-endian */ 257 #define CISS_NOTIFY_DATA_SIZE 512 258 u_int8_t control; 259 } __attribute__ ((packed)); 260 261 #define CISS_NOTIFY_NOTIFIER 0 262 #define CISS_NOTIFY_NOTIFIER_STATUS 0 263 #define CISS_NOTIFY_NOTIFIER_PROTOCOL 1 264 265 #define CISS_NOTIFY_HOTPLUG 1 266 #define CISS_NOTIFY_HOTPLUG_PHYSICAL 0 267 #define CISS_NOTIFY_HOTPLUG_POWERSUPPLY 1 268 #define CISS_NOTIFY_HOTPLUG_FAN 2 269 #define CISS_NOTIFY_HOTPLUG_POWER 3 270 #define CISS_NOTIFY_HOTPLUG_REDUNDANT 4 271 272 #define CISS_NOTIFY_HARDWARE 2 273 #define CISS_NOTIFY_HARDWARE_CABLES 0 274 #define CISS_NOTIFY_HARDWARE_MEMORY 1 275 #define CISS_NOTIFY_HARDWARE_FAN 2 276 #define CISS_NOTIFY_HARDWARE_VRM 3 277 278 #define CISS_NOTIFY_ENVIRONMENT 3 279 #define CISS_NOTIFY_ENVIRONMENT_TEMPERATURE 0 280 #define CISS_NOTIFY_ENVIRONMENT_POWERSUPPLY 1 281 #define CISS_NOTIFY_ENVIRONMENT_CHASSIS 2 282 #define CISS_NOTIFY_ENVIRONMENT_POWER 3 283 284 #define CISS_NOTIFY_PHYSICAL 4 285 #define CISS_NOTIFY_PHYSICAL_STATE 0 286 287 #define CISS_NOTIFY_LOGICAL 5 288 #define CISS_NOTIFY_LOGICAL_STATUS 0 289 #define CISS_NOTIFY_LOGICAL_ERROR 1 290 #define CISS_NOTIFY_LOGICAL_SURFACE 2 291 292 #define CISS_NOTIFY_REDUNDANT 6 293 #define CISS_NOTIFY_REDUNDANT_STATUS 0 294 295 #define CISS_NOTIFY_CISS 8 296 #define CISS_NOTIFY_CISS_REDUNDANT_CHANGE 0 297 #define CISS_NOTIFY_CISS_PATH_STATUS 1 298 #define CISS_NOTIFY_CISS_HARDWARE_ERROR 2 299 #define CISS_NOTIFY_CISS_LOGICAL 3 300 301 struct ciss_notify_drive 302 { 303 u_int16_t physical_drive_number; 304 u_int8_t configured_drive_flag; 305 u_int8_t spare_drive_flag; 306 u_int8_t big_physical_drive_number; 307 u_int8_t enclosure_bay_number; 308 } __attribute__ ((packed)); 309 310 struct ciss_notify_locator 311 { 312 u_int16_t port; 313 u_int16_t id; 314 u_int16_t box; 315 } __attribute__ ((packed)); 316 317 struct ciss_notify_redundant_controller 318 { 319 u_int16_t slot; 320 } __attribute__ ((packed)); 321 322 struct ciss_notify_logical_status 323 { 324 u_int16_t logical_drive; 325 u_int8_t previous_state; 326 u_int8_t new_state; 327 u_int8_t spare_state; 328 } __attribute__ ((packed)); 329 330 struct ciss_notify_rebuild_aborted 331 { 332 u_int16_t logical_drive; 333 u_int8_t replacement_drive; 334 u_int8_t error_drive; 335 u_int8_t big_replacement_drive; 336 u_int8_t big_error_drive; 337 } __attribute__ ((packed)); 338 339 struct ciss_notify_io_error 340 { 341 u_int16_t logical_drive; 342 u_int32_t lba; 343 u_int16_t block_count; 344 u_int8_t command; 345 u_int8_t failure_bus; 346 u_int8_t failure_drive; 347 u_int64_t big_lba; 348 } __attribute__ ((packed)); 349 350 struct ciss_notify_consistency_completed 351 { 352 u_int16_t logical_drive; 353 } __attribute__ ((packed)); 354 355 struct ciss_notify 356 { 357 u_int32_t timestamp; /* seconds since controller power-on */ 358 u_int16_t class; 359 u_int16_t subclass; 360 u_int16_t detail; 361 union 362 { 363 struct ciss_notify_drive drive; 364 struct ciss_notify_locator location; 365 struct ciss_notify_redundant_controller redundant_controller; 366 struct ciss_notify_logical_status logical_status; 367 struct ciss_notify_rebuild_aborted rebuild_aborted; 368 struct ciss_notify_io_error io_error; 369 struct ciss_notify_consistency_completed consistency_completed; 370 u_int8_t data[64]; 371 } data; 372 char message[80]; 373 u_int32_t tag; 374 u_int16_t date; 375 u_int16_t year; 376 u_int32_t time; 377 u_int16_t pre_power_up_time; 378 union ciss_device_address device; 379 /* XXX pads to 512 bytes */ 380 } __attribute__ ((packed)); 381 382 /* 383 * CISS config table, which describes the controller's 384 * supported interface(s) and capabilities. 385 * 386 * This is mapped directly via PCI. 387 */ 388 struct ciss_config_table 389 { 390 char signature[4]; /* "CISS" */ 391 u_int32_t valence; 392 #define CISS_MIN_VALENCE 1 /* only value currently supported */ 393 #define CISS_MAX_VALENCE 1 394 u_int32_t supported_methods; 395 #define CISS_TRANSPORT_METHOD_READY (1<<0) 396 #define CISS_TRANSPORT_METHOD_SIMPLE (1<<1) 397 u_int32_t active_method; 398 u_int32_t requested_method; 399 u_int32_t command_physlimit; 400 u_int32_t interrupt_coalesce_delay; 401 u_int32_t interrupt_coalesce_count; 402 u_int32_t max_outstanding_commands; 403 u_int32_t bus_types; 404 #define CISS_TRANSPORT_BUS_TYPE_ULTRA2 (1<<0) 405 #define CISS_TRANSPORT_BUS_TYPE_ULTRA3 (1<<1) 406 #define CISS_TRANSPORT_BUS_TYPE_FIBRE1 (1<<8) 407 #define CISS_TRANSPORT_BUS_TYPE_FIBRE2 (1<<9) 408 u_int32_t host_driver; 409 #define CISS_DRIVER_SUPPORT_UNIT_ATTENTION (1<<0) 410 #define CISS_DRIVER_QUICK_INIT (1<<1) 411 #define CISS_DRIVER_INTERRUPT_ON_LOCKUP (1<<2) 412 #define CISS_DRIVER_SUPPORT_MIXED_Q_TAGS (1<<3) 413 #define CISS_DRIVER_HOST_IS_ALPHA (1<<4) 414 char server_name[16]; 415 u_int32_t heartbeat; 416 } __attribute__ ((packed)); 417 418 /* 419 * In a flagrant violation of what CISS seems to be meant to be about, 420 * Compaq recycle a goodly portion of their previous generation's 421 * command set (and all the legacy baggage related to a design 422 * originally aimed at narrow SCSI) through the Array Controller Read 423 * and Array Controller Write interface. 424 * 425 * Command ID values here can be looked up for in the 426 * publically-available documentation for the older controllers; note 427 * that the command layout is necessarily different to fit within the 428 * CDB. 429 */ 430 #define CISS_ARRAY_CONTROLLER_READ 0x26 431 #define CISS_ARRAY_CONTROLLER_WRITE 0x27 432 433 #define CISS_BMIC_ID_LDRIVE 0x10 434 #define CISS_BMIC_ID_CTLR 0x11 435 #define CISS_BMIC_ID_LSTATUS 0x12 436 #define CISS_BMIC_ID_PDRIVE 0x15 437 #define CISS_BMIC_BLINK_PDRIVE 0x16 438 #define CISS_BMIC_SENSE_BLINK_PDRIVE 0x17 439 #define CISS_BMIC_FLUSH_CACHE 0xc2 440 #define CISS_BMIC_ACCEPT_MEDIA 0xe0 441 442 /* 443 * When numbering drives, the original design assumed that 444 * drives 0-7 are on the first SCSI bus, 8-15 on the second, 445 * and so forth. In order to handle modern SCSI configurations, 446 * the MSB is set in the drive ID field, in which case the 447 * modulus changes from 8 to the number of supported drives 448 * per SCSI bus (as obtained from the ID_CTLR command). 449 * This feature is referred to as BIG_MAP support, and we assume 450 * that all CISS controllers support it. 451 */ 452 453 #define CISS_BIG_MAP_ID(sc, bus, target) \ 454 (0x80 | \ 455 ((sc)->ciss_id->drives_per_scsi_bus * (bus)) | \ 456 (target)) 457 458 #define CISS_BIG_MAP_BUS(sc, id) \ 459 (((id) & 0x80) ? (((id) & ~0x80) / (sc)->ciss_id->drives_per_scsi_bus) : -1) 460 461 #define CISS_BIG_MAP_TARGET(sc, id) \ 462 (((id) & 0x80) ? (((id) & ~0x80) % (sc)->ciss_id->drives_per_scsi_bus) : -1) 463 464 #define CISS_BIG_MAP_ENTRIES 128 /* number of entries in a BIG_MAP */ 465 466 /* 467 * BMIC CDB 468 * 469 * Note that the phys_drive/res1 field is nominally the 32-bit 470 * "block number" field, but the only BMIC command(s) of interest 471 * implemented overload the MSB (note big-endian format here) 472 * to be the physical drive ID, so we define accordingly. 473 */ 474 struct ciss_bmic_cdb { 475 u_int8_t opcode; 476 u_int8_t log_drive; 477 u_int8_t phys_drive; 478 u_int8_t res1[3]; 479 u_int8_t bmic_opcode; 480 u_int16_t size; /* big-endian */ 481 u_int8_t res2; 482 } __attribute__ ((packed)); 483 484 /* 485 * BMIC command command/return structures. 486 */ 487 488 /* CISS_BMIC_ID_LDRIVE */ 489 struct ciss_bmic_id_ldrive { 490 u_int16_t block_size; 491 u_int32_t blocks_available; 492 u_int8_t drive_parameter_table[16]; /* XXX define */ 493 u_int8_t fault_tolerance; 494 #define CISS_LDRIVE_RAID0 0 495 #define CISS_LDRIVE_RAID4 1 496 #define CISS_LDRIVE_RAID1 2 497 #define CISS_LDRIVE_RAID5 3 498 u_int8_t res1[2]; 499 #if 0 /* only for identify logical drive extended (0x18) */ 500 u_int32_t logical_drive_identifier; 501 char logical_drive_label[64]; 502 #endif 503 } __attribute__ ((packed)); 504 505 /* CISS_BMIC_ID_LSTATUS */ 506 struct ciss_bmic_id_lstatus { 507 u_int8_t status; 508 #define CISS_LSTATUS_OK 0 509 #define CISS_LSTATUS_FAILED 1 510 #define CISS_LSTATUS_NOT_CONFIGURED 2 511 #define CISS_LSTATUS_INTERIM_RECOVERY 3 512 #define CISS_LSTATUS_READY_RECOVERY 4 513 #define CISS_LSTATUS_RECOVERING 5 514 #define CISS_LSTATUS_WRONG_PDRIVE 6 515 #define CISS_LSTATUS_MISSING_PDRIVE 7 516 #define CISS_LSTATUS_EXPANDING 10 517 #define CISS_LSTATUS_BECOMING_READY 11 518 #define CISS_LSTATUS_QUEUED_FOR_EXPANSION 12 519 u_int32_t deprecated_drive_failure_map; 520 u_int8_t res1[416]; 521 u_int32_t blocks_to_recover; 522 u_int8_t deprecated_drive_rebuilding; 523 u_int16_t deprecated_remap_count[32]; 524 u_int32_t deprecated_replacement_map; 525 u_int32_t deprecated_active_spare_map; 526 u_int8_t spare_configured:1; 527 u_int8_t spare_rebuilding:1; 528 u_int8_t spare_rebuilt:1; 529 u_int8_t spare_failed:1; 530 u_int8_t spare_switched:1; 531 u_int8_t spare_available:1; 532 u_int8_t res2:2; 533 u_int8_t deprecated_spare_to_replace_map[32]; 534 u_int32_t deprecated_replaced_marked_ok_map; 535 u_int8_t media_exchanged; 536 u_int8_t cache_failure; 537 u_int8_t expand_failure; 538 u_int8_t rebuild_read_failure:1; 539 u_int8_t rebuild_write_failure:1; 540 u_int8_t res3:6; 541 u_int8_t drive_failure_map[CISS_BIG_MAP_ENTRIES / 8]; 542 u_int16_t remap_count[CISS_BIG_MAP_ENTRIES]; 543 u_int8_t replacement_map[CISS_BIG_MAP_ENTRIES / 8]; 544 u_int8_t active_spare_map[CISS_BIG_MAP_ENTRIES / 8]; 545 u_int8_t spare_to_replace_map[CISS_BIG_MAP_ENTRIES]; 546 u_int8_t replaced_marked_ok_map[CISS_BIG_MAP_ENTRIES / 8]; 547 u_int8_t drive_rebuilding; 548 } __attribute__ ((packed)); 549 550 /* CISS_BMIC_ID_CTLR */ 551 struct ciss_bmic_id_table { 552 u_int8_t configured_logical_drives; 553 u_int32_t config_signature; 554 char running_firmware_revision[4]; 555 char stored_firmware_revision[4]; 556 u_int8_t hardware_revision; 557 u_int8_t res1[4]; 558 u_int32_t deprecated_drive_present_map; 559 u_int32_t deprecated_external_drive_present_map; 560 u_int32_t board_id; 561 u_int8_t res2; 562 u_int32_t deprecated_non_disk_map; 563 u_int8_t res3[5]; 564 char marketting_revision; 565 u_int8_t res4:3; 566 u_int8_t more_than_seven_supported:1; 567 u_int8_t res5:3; 568 u_int8_t big_map_supported:1; /* must be set! */ 569 u_int8_t res6[2]; 570 u_int8_t scsi_bus_count; 571 u_int32_t res7; 572 u_int32_t controller_clock; 573 u_int8_t drives_per_scsi_bus; 574 u_int8_t big_drive_present_map[CISS_BIG_MAP_ENTRIES / 8]; 575 u_int8_t big_external_drive_present_map[CISS_BIG_MAP_ENTRIES / 8]; 576 u_int8_t big_non_disk_map[CISS_BIG_MAP_ENTRIES / 8]; 577 } __attribute__ ((packed)); 578 579 /* CISS_BMIC_ID_PDRIVE */ 580 struct ciss_bmic_id_pdrive { 581 u_int8_t scsi_bus; 582 u_int8_t scsi_id; 583 u_int16_t block_size; 584 u_int32_t total_blocks; 585 u_int32_t reserved_blocks; 586 char model[40]; 587 char serial[40]; 588 char revision[8]; 589 u_int8_t inquiry_bits; 590 u_int8_t res1[2]; 591 u_int8_t drive_present:1; 592 u_int8_t non_disk:1; 593 u_int8_t wide:1; 594 u_int8_t synchronous:1; 595 u_int8_t narrow:1; 596 u_int8_t wide_downgraded_to_narrow:1; 597 u_int8_t ultra:1; 598 u_int8_t ultra2:1; 599 u_int8_t SMART:1; 600 u_int8_t SMART_errors_recorded:1; 601 u_int8_t SMART_errors_enabled:1; 602 u_int8_t SMART_errors_detected:1; 603 u_int8_t external:1; 604 u_int8_t configured:1; 605 u_int8_t configured_spare:1; 606 u_int8_t cache_saved_enabled:1; 607 u_int8_t res2; 608 u_int8_t res3:6; 609 u_int8_t cache_currently_enabled:1; 610 u_int8_t cache_safe:1; 611 u_int8_t res4[5]; 612 char connector[2]; 613 u_int8_t res5; 614 u_int8_t bay; 615 } __attribute__ ((packed)); 616 617 /* CISS_BMIC_BLINK_PDRIVE */ 618 /* CISS_BMIC_SENSE_BLINK_PDRIVE */ 619 struct ciss_bmic_blink_pdrive { 620 u_int32_t blink_duration; /* 10ths of a second */ 621 u_int32_t duration_elapsed; /* only for sense command */ 622 u_int8_t blinktab[256]; 623 #define CISS_BMIC_BLINK_ALL 1 624 #define CISS_BMIC_BLINK_TIMED 2 625 u_int8_t res2[248]; 626 } __attribute__ ((packed)); 627 628 /* CISS_BMIC_FLUSH_CACHE */ 629 struct ciss_bmic_flush_cache { 630 u_int16_t flag; 631 #define CISS_BMIC_FLUSH_AND_ENABLE 0 632 #define CISS_BMIC_FLUSH_AND_DISABLE 1 633 u_int8_t res1[510]; 634 } __attribute__ ((packed)); 635 636 #ifdef _KERNEL 637 /* 638 * CISS "simple" transport layer. 639 * 640 * Note that there are two slightly different versions of this interface 641 * with different interrupt mask bits. There's nothing like consistency... 642 */ 643 #define CISS_TL_SIMPLE_BAR_REGS 0x10 /* BAR pointing to register space */ 644 #define CISS_TL_SIMPLE_BAR_CFG 0x14 /* BAR pointing to space containing config table */ 645 646 #define CISS_TL_SIMPLE_IDBR 0x20 /* inbound doorbell register */ 647 #define CISS_TL_SIMPLE_IDBR_CFG_TABLE (1<<0) /* notify controller of config table update */ 648 649 #define CISS_TL_SIMPLE_ISR 0x30 /* interrupt status register */ 650 #define CISS_TL_SIMPLE_IMR 0x34 /* interrupt mask register */ 651 #define CISS_TL_SIMPLE_INTR_OPQ_SA5 (1<<3) /* OPQ not empty interrupt, SA5 boards */ 652 #define CISS_TL_SIMPLE_INTR_OPQ_SA5B (1<<2) /* OPQ not empty interrupt, SA5B boards */ 653 654 #define CISS_TL_SIMPLE_IPQ 0x40 /* inbound post queue */ 655 #define CISS_TL_SIMPLE_OPQ 0x44 /* outbound post queue */ 656 #define CISS_TL_SIMPLE_OPQ_EMPTY (~(u_int32_t)0) 657 658 #define CISS_TL_SIMPLE_CFG_BAR 0xb4 /* should be 0x14 */ 659 #define CISS_TL_SIMPLE_CFG_OFF 0xb8 /* offset in BAR at which config table is located */ 660 661 /* 662 * Register access primitives. 663 */ 664 #define CISS_TL_SIMPLE_READ(sc, ofs) \ 665 bus_space_read_4(sc->ciss_regs_btag, sc->ciss_regs_bhandle, ofs) 666 #define CISS_TL_SIMPLE_WRITE(sc, ofs, val) \ 667 bus_space_write_4(sc->ciss_regs_btag, sc->ciss_regs_bhandle, ofs, val) 668 669 #define CISS_TL_SIMPLE_POST_CMD(sc, phys) CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IPQ, phys) 670 #define CISS_TL_SIMPLE_FETCH_CMD(sc) CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_OPQ) 671 672 /* 673 * XXX documentation conflicts with the Linux driver as to whether setting or clearing 674 * bits masks interrupts 675 */ 676 #define CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc) \ 677 CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \ 678 CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) | (sc)->ciss_interrupt_mask) 679 #define CISS_TL_SIMPLE_ENABLE_INTERRUPTS(sc) \ 680 CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \ 681 CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IMR) & ~(sc)->ciss_interrupt_mask) 682 683 #define CISS_TL_SIMPLE_OPQ_INTERRUPT(sc) \ 684 (CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_ISR) & (sc)->ciss_interrupt_mask) 685 686 #endif /* _KERNEL */ 687