2 * Copyright (c) 2001 Michael Smith
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
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 $
31 * Structure and I/O definitions for the Command Interface for SCSI-3 Support.
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.
37 union ciss_device_address
39 struct /* MODE_PERIPHERAL and MODE_MASK_PERIPHERAL */
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 */
46 struct /* MODE_LOGICAL */
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 */
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
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));
76 u_int8_t cdb_length; /* valid CDB bytes */
78 #define CISS_CDB_TYPE_COMMAND 0
79 #define CISS_CDB_TYPE_MESSAGE 1
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
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));
95 struct ciss_error_info_pointer
97 u_int64_t error_info_address; /* points to ciss_error_info structure */
98 u_int32_t error_info_length;
99 } __attribute__ ((packed));
101 struct ciss_error_info
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;
134 u_int32_t error_info;
135 } common_info __attribute__ ((packed));
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));
149 #define CISS_SG_ADDRESS_BITBUCKET (~(u_int64_t)0)
152 u_int32_t extension:1; /* address points to another s/g chain */
153 } __attribute__ ((packed));
157 struct ciss_header header;
159 struct ciss_error_info_pointer error_info;
160 struct ciss_sg_entry sg[0];
161 } __attribute__ ((packed));
163 #define CISS_OPCODE_REPORT_LOGICAL_LUNS 0xc2
164 #define CISS_OPCODE_REPORT_PHYSICAL_LUNS 0xc3
166 struct ciss_lun_report
168 u_int32_t list_size; /* big-endian */
170 union ciss_device_address lun[0];
171 } __attribute__ ((packed));
173 #define CISS_VPD_LOGICAL_DRIVE_GEOMETRY 0xc1
174 struct ciss_ldrive_geometry
176 u_int8_t periph_qualifier:3;
177 u_int8_t periph_devtype:5;
180 u_int8_t page_length;
181 u_int16_t cylinders; /* big-endian */
184 u_int8_t fault_tolerance;
186 } __attribute__ ((packed));
188 struct ciss_report_cdb
191 u_int8_t reserved[5];
192 u_int32_t length; /* big-endian */
195 } __attribute__ ((packed));
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.
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
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
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
220 #define CISS_OPCODE_MESSAGE_NOP 0x03
222 struct ciss_message_cdb
227 u_int32_t abort_tag; /* XXX endianness? */
228 u_int8_t reserved[8];
229 } __attribute__ ((packed));
232 * CISS vendor-specific commands/messages.
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.
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
244 struct ciss_notify_cdb
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 */
256 u_int32_t length; /* must be 512, little-endian */
257 #define CISS_NOTIFY_DATA_SIZE 512
259 } __attribute__ ((packed));
261 #define CISS_NOTIFY_NOTIFIER 0
262 #define CISS_NOTIFY_NOTIFIER_STATUS 0
263 #define CISS_NOTIFY_NOTIFIER_PROTOCOL 1
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
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
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
284 #define CISS_NOTIFY_PHYSICAL 4
285 #define CISS_NOTIFY_PHYSICAL_STATE 0
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
292 #define CISS_NOTIFY_REDUNDANT 6
293 #define CISS_NOTIFY_REDUNDANT_STATUS 0
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
301 struct ciss_notify_drive
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));
310 struct ciss_notify_locator
315 } __attribute__ ((packed));
317 struct ciss_notify_redundant_controller
320 } __attribute__ ((packed));
322 struct ciss_notify_logical_status
324 u_int16_t logical_drive;
325 u_int8_t previous_state;
327 u_int8_t spare_state;
328 } __attribute__ ((packed));
330 struct ciss_notify_rebuild_aborted
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));
339 struct ciss_notify_io_error
341 u_int16_t logical_drive;
343 u_int16_t block_count;
345 u_int8_t failure_bus;
346 u_int8_t failure_drive;
348 } __attribute__ ((packed));
350 struct ciss_notify_consistency_completed
352 u_int16_t logical_drive;
353 } __attribute__ ((packed));
357 u_int32_t timestamp; /* seconds since controller power-on */
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;
377 u_int16_t pre_power_up_time;
378 union ciss_device_address device;
379 /* XXX pads to 512 bytes */
380 } __attribute__ ((packed));
383 * CISS config table, which describes the controller's
384 * supported interface(s) and capabilities.
386 * This is mapped directly via PCI.
388 struct ciss_config_table
390 char signature[4]; /* "CISS" */
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;
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];
416 } __attribute__ ((packed));
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.
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
430 #define CISS_ARRAY_CONTROLLER_READ 0x26
431 #define CISS_ARRAY_CONTROLLER_WRITE 0x27
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
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.
453 #define CISS_BIG_MAP_ID(sc, bus, target) \
455 ((sc)->ciss_id->drives_per_scsi_bus * (bus)) | \
458 #define CISS_BIG_MAP_BUS(sc, id) \
459 (((id) & 0x80) ? (((id) & ~0x80) / (sc)->ciss_id->drives_per_scsi_bus) : -1)
461 #define CISS_BIG_MAP_TARGET(sc, id) \
462 (((id) & 0x80) ? (((id) & ~0x80) % (sc)->ciss_id->drives_per_scsi_bus) : -1)
464 #define CISS_BIG_MAP_ENTRIES 128 /* number of entries in a BIG_MAP */
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.
474 struct ciss_bmic_cdb {
479 u_int8_t bmic_opcode;
480 u_int16_t size; /* big-endian */
482 } __attribute__ ((packed));
485 * BMIC command command/return structures.
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
499 #if 0 /* only for identify logical drive extended (0x18) */
500 u_int32_t logical_drive_identifier;
501 char logical_drive_label[64];
503 } __attribute__ ((packed));
505 /* CISS_BMIC_ID_LSTATUS */
506 struct ciss_bmic_id_lstatus {
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;
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;
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;
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));
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;
558 u_int32_t deprecated_drive_present_map;
559 u_int32_t deprecated_external_drive_present_map;
562 u_int32_t deprecated_non_disk_map;
564 char marketting_revision;
566 u_int8_t more_than_seven_supported:1;
568 u_int8_t big_map_supported:1; /* must be set! */
570 u_int8_t scsi_bus_count;
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));
579 /* CISS_BMIC_ID_PDRIVE */
580 struct ciss_bmic_id_pdrive {
583 u_int16_t block_size;
584 u_int32_t total_blocks;
585 u_int32_t reserved_blocks;
589 u_int8_t inquiry_bits;
591 u_int8_t drive_present:1;
594 u_int8_t synchronous:1;
596 u_int8_t wide_downgraded_to_narrow: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;
604 u_int8_t configured:1;
605 u_int8_t configured_spare:1;
606 u_int8_t cache_saved_enabled:1;
609 u_int8_t cache_currently_enabled:1;
610 u_int8_t cache_safe:1;
615 } __attribute__ ((packed));
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
626 } __attribute__ ((packed));
628 /* CISS_BMIC_FLUSH_CACHE */
629 struct ciss_bmic_flush_cache {
631 #define CISS_BMIC_FLUSH_AND_ENABLE 0
632 #define CISS_BMIC_FLUSH_AND_DISABLE 1
634 } __attribute__ ((packed));
638 * CISS "simple" transport layer.
640 * Note that there are two slightly different versions of this interface
641 * with different interrupt mask bits. There's nothing like consistency...
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 */
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 */
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 */
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)
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 */
662 * Register access primitives.
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)
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)
673 * XXX documentation conflicts with the Linux driver as to whether setting or clearing
674 * bits masks interrupts
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)
683 #define CISS_TL_SIMPLE_OPQ_INTERRUPT(sc) \
684 (CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_ISR) & (sc)->ciss_interrupt_mask)