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