2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2000 BSDi
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * Section numbers in this document refer to the Mylex "Firmware Software Interface"
32 * document ('FSI'), revision 0.11 04/11/00 unless otherwise qualified.
34 * Reference is made to the Mylex "Programming Guide for 6.x Controllers" document
35 * ('PG6'), document #771242 revision 0.02, 04/11/00
37 * Note that fields marked N/A are not supported by the PCI controllers, but are
38 * defined here to hold place in datastructures that are shared with the SCSI
39 * controllers. Items not relevant to PCI controllers are not described here.
41 * Ordering of items in this file is a little odd due to the constraints of
42 * nested declarations.
46 * 2.1 (Scatter Gather List Format)
51 } __attribute__ ((packed));
54 * 5.2 System Device Access
56 * This is corroborated by the layout of the MDACIOCTL_GETCONTROLLERINFO data
59 #define MLY_MAX_CHANNELS 6
60 #define MLY_MAX_TARGETS 16
61 #define MLY_MAX_LUNS 1
64 * 8.1 Different Device States
66 #define MLY_DEVICE_STATE_OFFLINE 0x08 /* DEAD/OFFLINE */
67 #define MLY_DEVICE_STATE_UNCONFIGURED 0x00
68 #define MLY_DEVICE_STATE_ONLINE 0x01
69 #define MLY_DEVICE_STATE_CRITICAL 0x09
70 #define MLY_DEVICE_STATE_WRITEONLY 0x03
71 #define MLY_DEVICE_STATE_STANDBY 0x21
72 #define MLY_DEVICE_STATE_MISSING 0x04 /* or-ed with (ONLINE or WRITEONLY or STANDBY) */
75 * 8.2 Device Type Field definitions
77 #define MLY_DEVICE_TYPE_RAID0 0x0 /* RAID 0 */
78 #define MLY_DEVICE_TYPE_RAID1 0x1 /* RAID 1 */
79 #define MLY_DEVICE_TYPE_RAID3 0x3 /* RAID 3 right asymmetric parity */
80 #define MLY_DEVICE_TYPE_RAID5 0x5 /* RAID 5 right asymmetric parity */
81 #define MLY_DEVICE_TYPE_RAID6 0x6 /* RAID 6 (Mylex RAID 6) */
82 #define MLY_DEVICE_TYPE_RAID7 0x7 /* RAID 7 (JBOD) */
83 #define MLY_DEVICE_TYPE_NEWSPAN 0x8 /* New Mylex SPAN */
84 #define MLY_DEVICE_TYPE_RAID3F 0x9 /* RAID 3 fixed parity */
85 #define MLY_DEVICE_TYPE_RAID3L 0xb /* RAID 3 left symmetric parity */
86 #define MLY_DEVICE_TYPE_SPAN 0xc /* current spanning implementation */
87 #define MLY_DEVICE_TYPE_RAID5L 0xd /* RAID 5 left symmetric parity */
88 #define MLY_DEVICE_TYPE_RAIDE 0xe /* RAID E (concatenation) */
89 #define MLY_DEVICE_TYPE_PHYSICAL 0xf /* physical device */
94 #define MLY_STRIPE_ZERO 0x0 /* no stripe (RAID 1, RAID 7, etc) */
95 #define MLY_STRIPE_512b 0x1
96 #define MLY_STRIPE_1k 0x2
97 #define MLY_STRIPE_2k 0x3
98 #define MLY_STRIPE_4k 0x4
99 #define MLY_STRIPE_8k 0x5
100 #define MLY_STRIPE_16k 0x6
101 #define MLY_STRIPE_32k 0x7
102 #define MLY_STRIPE_64k 0x8
103 #define MLY_STRIPE_128k 0x9
104 #define MLY_STRIPE_256k 0xa
105 #define MLY_STRIPE_512k 0xb
106 #define MLY_STRIPE_1m 0xc
111 #define MLY_CACHELINE_ZERO 0x0 /* caching cannot be enabled */
112 #define MLY_CACHELINE_512b 0x1
113 #define MLY_CACHELINE_1k 0x2
114 #define MLY_CACHELINE_2k 0x3
115 #define MLY_CACHELINE_4k 0x4
116 #define MLY_CACHELINE_8k 0x5
117 #define MLY_CACHELINE_16k 0x6
118 #define MLY_CACHELINE_32k 0x7
119 #define MLY_CACHELINE_64k 0x8
122 * 8.5 Read/Write control
124 #define MLY_RWCtl_INITTED (1<<7) /* if set, the logical device is initialised */
126 #define MLY_RWCtl_WCD (0) /* write cache disabled */
127 #define MLY_RWCtl_WDISABLE (1<<3) /* writing disabled */
128 #define MLY_RWCtl_WCE (2<<3) /* write cache enabled */
129 #define MLY_RWCtl_IWCE (3<<3) /* intelligent write cache enabled */
131 #define MLY_RWCtl_RCD (0) /* read cache is disabled */
132 #define MLY_RWCtl_RCE (1) /* read cache enabled */
133 #define MLY_RWCtl_RAHEAD (2) /* readahead enabled */
134 #define MLY_RWCtl_IRAHEAD (3) /* intelligent readahead enabled */
141 u_int8_t host_port_mapped:1; /* this system drive visibile to host on this controller/port combination */
142 u_int8_t tid_valid:1; /* target ID valid */
143 u_int8_t hid_valid:1; /* host ID valid */
144 u_int8_t lun_valid:1; /* LUN valid */
146 u_int8_t lun; /* LUN */
147 u_int8_t tid; /* TID */
148 u_int8_t hid[32]; /* HID (one bit for each host) */
149 } __attribute__ ((packed));
152 * 10.1 Controller Parameters
154 struct mly_param_controller {
155 u_int8_t rdahen:1; /* N/A */
156 u_int8_t bilodly:1; /* N/A */
157 u_int8_t fua_disable:1;
158 u_int8_t reass1s:1; /* N/A */
159 u_int8_t truvrfy:1; /* N/A */
160 u_int8_t dwtvrfy:1; /* N/A */
161 u_int8_t background_initialisation:1;
162 u_int8_t clustering:1; /* N/A */
164 u_int8_t bios_disable:1;
165 u_int8_t boot_from_cdrom:1;
166 u_int8_t drive_coercion:1;
167 u_int8_t write_same_disable:1;
168 u_int8_t hba_mode:1; /* N/A */
169 u_int8_t bios_geometry:2;
170 #define MLY_BIOSGEOM_2G 0x0
171 #define MLY_BIOSGEOM_8G 0x1
172 u_int8_t res1:1; /* N/A */
174 u_int8_t res2[2]; /* N/A */
177 u_int8_t safte:1; /* N/A */
178 u_int8_t ses:1; /* N/A */
179 u_int8_t res3:2; /* N/A */
182 u_int8_t res4:1; /* N/A */
184 u_int8_t rebuild_check_rate;
185 u_int8_t cache_line_size; /* see 8.4 */
187 #define MLY_OEM_MYLEX 0x00
188 #define MLY_OEM_IBM 0x08
189 #define MLY_OEM_HP 0x0a
190 #define MLY_OEM_DEC 0x0c
191 #define MLY_OEM_SIEMENS 0x10
192 #define MLY_OEM_INTEL 0x12
193 u_int8_t spinup_mode;
194 #define MLY_SPIN_AUTO 0
195 #define MLY_SPIN_PWRSPIN 1
196 #define MLY_SPIN_WSSUSPIN 2
197 u_int8_t spinup_devices;
198 u_int8_t spinup_interval;
199 u_int8_t spinup_wait_time;
201 u_int8_t res5:3; /* N/A */
202 u_int8_t vutursns:1; /* N/A */
203 u_int8_t dccfil:1; /* N/A */
204 u_int8_t nopause:1; /* N/A */
205 u_int8_t disqfull:1; /* N/A */
206 u_int8_t disbusy:1; /* N/A */
208 u_int8_t res6:2; /* N/A */
209 u_int8_t failover_node_name; /* N/A */
210 u_int8_t res7:1; /* N/A */
211 u_int8_t ftopo:3; /* N/A */
212 u_int8_t disable_ups:1; /* N/A */
214 u_int8_t res8:1; /* N/A */
215 u_int8_t propagate_reset:1; /* N/A */
216 u_int8_t nonstd_mp_reset:1; /* N/A */
217 u_int8_t res9:5; /* N/A */
219 u_int8_t res10; /* N/A */
220 u_int8_t serial_port_baud_rate; /* N/A */
221 u_int8_t serial_port_control; /* N/A */
222 u_int8_t change_stripe_ok_developer_flag_only; /* N/A */
224 u_int8_t small_large_host_transfers:2; /* N/A */
225 u_int8_t frame_control:2; /* N/A */
226 u_int8_t pci_latency_control:2; /* N/A */
227 u_int8_t treat_lip_as_reset:1; /* N/A */
228 u_int8_t res11:1; /* N/A */
230 u_int8_t ms_autorest:1; /* N/A */
231 u_int8_t res12:7; /* N/A */
233 u_int8_t ms_aa_fsim:1; /* N/A */
234 u_int8_t ms_aa_ccach:1; /* N/A */
235 u_int8_t ms_aa_fault_signals:1; /* N/A */
236 u_int8_t ms_aa_c4_faults:1; /* N/A */
237 u_int8_t ms_aa_host_reset_delay_mask:4; /* N/A */
239 u_int8_t ms_flg_simplex_no_rstcom:1; /* N/A */
240 u_int8_t res13:7; /* N/A */
242 u_int8_t res14; /* N/A */
243 u_int8_t hardloopid[2][2]; /* N/A */
244 u_int8_t ctrlname[2][16+1]; /* N/A */
245 u_int8_t initiator_id;
246 u_int8_t startup_option;
247 #define MLY_STARTUP_IF_NO_CHANGE 0x0
248 #define MLY_STARTUP_IF_NO_LUN_CHANGE 0x1
249 #define MLY_STARTUP_IF_NO_LUN_OFFLINE 0x2
250 #define MLY_STARTUP_IF_LUN0_NO_CHANGE 0x3
251 #define MLY_STARTUP_IF_LUN0_NOT_OFFLINE 0x4
252 #define MLY_STARTUP_ALWAYS 0x5
255 } __attribute__ ((packed));
258 * 10.2 Physical Device Parameters
260 struct mly_param_physical_device {
267 } __attribute__ ((packed));
270 * 10.3 Logical Device Parameters
272 struct mly_param_logical_device {
273 u_int8_t type; /* see 8.2 */
274 u_int8_t state; /* see 8.1 */
275 u_int16_t raid_device;
277 u_int8_t bios_geometry; /* BIOS control word? */
278 u_int8_t stripe_size; /* see 8.3 */
279 u_int8_t read_write_control; /* see 8.5 */
281 } __attribute__ ((packed));
284 * 12.3 Health Status Buffer
288 struct mly_health_status {
289 u_int32_t uptime_us; /* N/A */
290 u_int32_t uptime_ms; /* N/A */
291 u_int32_t realtime; /* N/A */
292 u_int32_t res1; /* N/A */
293 u_int32_t change_counter;
294 u_int32_t res2; /* N/A */
295 u_int32_t debug_message_index; /* N/A */
296 u_int32_t bios_message_index; /* N/A */
297 u_int32_t trace_page; /* N/A */
298 u_int32_t profiler_page; /* N/A */
299 u_int32_t next_event;
300 u_int8_t res3[4 + 16 + 64]; /* N/A */
301 } __attribute__ ((packed));
304 * 14.2 Timeout Bit Format
309 #define MLY_TIMEOUT_SECONDS 0x0
310 #define MLY_TIMEOUT_MINUTES 0x1
311 #define MLY_TIMEOUT_HOURS 0x2
312 } __attribute__ ((packed));
315 * 14.3 Operation Device
317 #define MLY_OPDEVICE_PHYSICAL_DEVICE 0x0
318 #define MLY_OPDEVICE_RAID_DEVICE 0x1
319 #define MLY_OPDEVICE_PHYSICAL_CHANNEL 0x2
320 #define MLY_OPDEVICE_RAID_CHANNEL 0x3
321 #define MLY_OPDEVICE_PHYSICAL_CONTROLLER 0x4
322 #define MLY_OPDEVICE_RAID_CONTROLLER 0x5
323 #define MLY_OPDEVICE_CONFIGURATION_GROUP 0x10
326 * 14.4 Status Bit Format
328 * AKA Status Mailbox Format
330 * XXX format conflict between FSI and PG6 over the ordering of the
331 * status and sense length fields.
334 u_int16_t command_id;
336 u_int8_t sense_length;
338 } __attribute__ ((packed));
341 * 14.5 Command Control Bit (CCB) format
343 * This byte is unfortunately named.
345 struct mly_command_control {
346 u_int8_t force_unit_access:1;
347 u_int8_t disable_page_out:1;
349 u_int8_t extended_sg_table:1;
350 u_int8_t data_direction:1;
351 #define MLY_CCB_WRITE 1
352 #define MLY_CCB_READ 0
354 u_int8_t no_auto_sense:1;
355 u_int8_t disable_disconnect:1;
356 } __attribute__ ((packed));
361 * We use the command names as given by Mylex
363 #define MDACMD_MEMCOPY 0x1 /* memory to memory copy */
364 #define MDACMD_SCSIPT 0x2 /* SCSI passthrough (small command) */
365 #define MDACMD_SCSILCPT 0x3 /* SCSI passthrough (large command) */
366 #define MDACMD_SCSI 0x4 /* SCSI command for logical/phyiscal device (small command) */
367 #define MDACMD_SCSILC 0x5 /* SCSI command for logical/phyiscal device (large command) */
368 #define MDACMD_IOCTL 0x20 /* Management command */
369 #define MDACMD_IOCTLCHECK 0x23 /* Validate management command (not implemented) */
374 * We use the IOCTL names as given by Mylex
375 * Note that only ioctls supported by the PCI controller family are listed
377 #define MDACIOCTL_GETCONTROLLERINFO 0x1
378 #define MDACIOCTL_GETLOGDEVINFOVALID 0x3
379 #define MDACIOCTL_GETPHYSDEVINFOVALID 0x5
380 #define MDACIOCTL_GETCONTROLLERSTATISTICS 0xb
381 #define MDACIOCTL_GETLOGDEVSTATISTICS 0xd
382 #define MDACIOCTL_GETPHYSDEVSTATISTICS 0xf
383 #define MDACIOCTL_GETHEALTHSTATUS 0x11
384 #define MDACIOCTL_GETEVENT 0x15
386 #define MDACIOCTL_STOREIMAGE 0x2c
387 #define MDACIOCTL_READIMAGE 0x2d
388 #define MDACIOCTL_FLASHIMAGES 0x2e
389 /* battery backup unit */
390 #define MDACIOCTL_GET_SUBSYSTEM_DATA 0x70
391 #define MDACIOCTL_SET_SUBSYSTEM_DATA 0x71
392 /* non-data commands */
393 #define MDACIOCTL_STARTDISOCVERY 0x81
394 #define MDACIOCTL_SETRAIDDEVSTATE 0x82
395 #define MDACIOCTL_INITPHYSDEVSTART 0x84
396 #define MDACIOCTL_INITPHYSDEVSTOP 0x85
397 #define MDACIOCTL_INITRAIDDEVSTART 0x86
398 #define MDACIOCTL_INITRAIDDEVSTOP 0x87
399 #define MDACIOCTL_REBUILDRAIDDEVSTART 0x88
400 #define MDACIOCTL_REBUILDRAIDDEVSTOP 0x89
401 #define MDACIOCTL_MAKECONSISTENTDATASTART 0x8a
402 #define MDACIOCTL_MAKECONSISTENTDATASTOP 0x8b
403 #define MDACIOCTL_CONSISTENCYCHECKSTART 0x8c
404 #define MDACIOCTL_CONSISTENCYCHECKSTOP 0x8d
405 #define MDACIOCTL_SETMEMORYMAILBOX 0x8e
406 #define MDACIOCTL_RESETDEVICE 0x90
407 #define MDACIOCTL_FLUSHDEVICEDATA 0x91
408 #define MDACIOCTL_PAUSEDEVICE 0x92
409 #define MDACIOCTL_UNPAUSEDEVICE 0x93
410 #define MDACIOCTL_LOCATEDEVICE 0x94
411 #define MDACIOCTL_SETMASTERSLAVEMODE 0x95
412 #define MDACIOCTL_SETREALTIMECLOCK 0xac
413 /* RAID configuration */
414 #define MDACIOCTL_CREATENEWCONF 0xc0
415 #define MDACIOCTL_DELETERAIDDEV 0xc1
416 #define MDACIOCTL_REPLACEINTERNALDEV 0xc2
417 #define MDACIOCTL_RENAMERAIDDEV 0xc3
418 #define MDACIOCTL_ADDNEWCONF 0xc4
419 #define MDACIOCTL_XLATEPHYSDEVTORAIDDEV 0xc5
420 #define MDACIOCTL_MORE 0xc6
421 #define MDACIOCTL_SETPHYSDEVPARAMETER 0xc8
422 #define MDACIOCTL_GETPHYSDEVPARAMETER 0xc9
423 #define MDACIOCTL_CLEARCONF 0xca
424 #define MDACIOCTL_GETDEVCONFINFO 0xcb
425 #define MDACIOCTL_GETGROUPCONFINFO 0xcc
426 #define MDACIOCTL_GETFREESPACELIST 0xcd
427 #define MDACIOCTL_GETLOGDEVPARAMETER 0xce
428 #define MDACIOCTL_SETLOGDEVPARAMETER 0xcf
429 #define MDACIOCTL_GETCONTROLLERPARAMETER 0xd0
430 #define MDACIOCTL_SETCONTRLLERPARAMETER 0xd1
431 #define MDACIOCTL_CLEARCONFSUSPMODE 0xd2
432 #define MDACIOCTL_GETBDT_FOR_SYSDRIVE 0xe0
435 * 17.1.4 Data Transfer Memory Address Without SG List
437 struct mly_short_transfer {
438 struct mly_sg_entry sg[2];
439 } __attribute__ ((packed));
442 * 17.1.5 Data Transfer Memory Address With SG List
444 * Note that only the first s/g table is currently used.
446 struct mly_sg_transfer {
447 u_int16_t entries[3];
449 u_int64_t table_physaddr[3];
450 } __attribute__ ((packed));
453 * 17.1.3 Data Transfer Memory Address Format
455 union mly_command_transfer {
456 struct mly_short_transfer direct;
457 struct mly_sg_transfer indirect;
461 * 21.1 MDACIOCTL_SETREALTIMECLOCK
462 * 21.7 MDACIOCTL_GETHEALTHSTATUS
463 * 21.8 MDACIOCTL_GETCONTROLLERINFO
464 * 21.9 MDACIOCTL_GETLOGDEVINFOVALID
465 * 21.10 MDACIOCTL_GETPHYSDEVINFOVALID
466 * 21.11 MDACIOCTL_GETPHYSDEVSTATISTICS
467 * 21.12 MDACIOCTL_GETLOGDEVSTATISTICS
468 * 21.13 MDACIOCTL_GETCONTROLLERSTATISTICS
469 * 21.27 MDACIOCTL_GETBDT_FOR_SYSDRIVE
470 * 23.4 MDACIOCTL_CREATENEWCONF
471 * 23.5 MDACIOCTL_ADDNEWCONF
472 * 23.8 MDACIOCTL_GETDEVCONFINFO
473 * 23.9 MDACIOCTL_GETFREESPACELIST
474 * 24.1 MDACIOCTL_MORE
475 * 25.1 MDACIOCTL_GETPHYSDEVPARAMETER
476 * 25.2 MDACIOCTL_SETPHYSDEVPARAMETER
477 * 25.3 MDACIOCTL_GETLOGDEVPARAMETER
478 * 25.4 MDACIOCTL_SETLOGDEVPARAMETER
479 * 25.5 MDACIOCTL_GETCONTROLLERPARAMETER
480 * 25.6 MDACIOCTL_SETCONTROLLERPARAMETER
482 * These commands just transfer data
484 struct mly_ioctl_param_data {
486 union mly_command_transfer transfer;
487 } __attribute__ ((packed));
490 * 21.2 MDACIOCTL_SETMEMORYMAILBOX
492 struct mly_ioctl_param_setmemorymailbox {
493 u_int8_t health_buffer_size;
495 u_int64_t health_buffer_physaddr;
496 u_int64_t command_mailbox_physaddr;
497 u_int64_t status_mailbox_physaddr;
499 } __attribute__ ((packed));
502 * 21.8.2 MDACIOCTL_GETCONTROLLERINFO: Data Format
504 struct mly_ioctl_getcontrollerinfo {
505 u_int8_t res1; /* N/A */
506 u_int8_t interface_type;
507 u_int8_t controller_type;
508 u_int8_t res2; /* N/A */
509 u_int16_t interface_speed;
510 u_int8_t interface_width;
511 u_int8_t res3[9]; /* N/A */
512 char interface_name[16];
513 char controller_name[16];
514 u_int8_t res4[16]; /* N/A */
515 /* firmware release information */
524 /* hardware release information */
525 u_int8_t hw_revision; /* N/A */
526 u_int8_t res5[3]; /* N/A */
527 u_int8_t hw_release_day; /* N/A */
528 u_int8_t hw_release_month; /* N/A */
529 u_int8_t hw_release_century; /* N/A */
530 u_int8_t hw_release_year; /* N/A */
531 /* hardware manufacturing information */
532 u_int8_t batch_number; /* N/A */
533 u_int8_t res6; /* N/A */
534 u_int8_t plant_number;
536 u_int8_t hw_manuf_day;
537 u_int8_t hw_manuf_month;
538 u_int8_t hw_manuf_century;
539 u_int8_t hw_manuf_year;
540 u_int8_t max_pdd_per_xldd;
541 u_int8_t max_ildd_per_xldd;
542 u_int16_t nvram_size;
543 u_int8_t max_number_of_xld; /* N/A */
544 u_int8_t res8[3]; /* N/A */
545 /* unique information per controller */
546 char serial_number[16];
547 u_int8_t res9[16]; /* N/A */
548 /* vendor information */
549 u_int8_t res10[3]; /* N/A */
550 u_int8_t oem_information;
551 char vendor_name[16]; /* N/A */
552 /* other physical/controller/operation information */
553 u_int8_t bbu_present:1;
554 u_int8_t active_clustering:1;
555 u_int8_t res11:6; /* N/A */
556 u_int8_t res12[3]; /* N/A */
557 /* physical device scan information */
558 u_int8_t physical_scan_active:1;
559 u_int8_t res13:7; /* N/A */
560 u_int8_t physical_scan_channel;
561 u_int8_t physical_scan_target;
562 u_int8_t physical_scan_lun;
563 /* maximum command data transfer size */
564 u_int16_t maximum_block_count;
565 u_int16_t maximum_sg_entries;
566 /* logical/physical device counts */
567 u_int16_t logical_devices_present;
568 u_int16_t logical_devices_critical;
569 u_int16_t logical_devices_offline;
570 u_int16_t physical_devices_present;
571 u_int16_t physical_disks_present;
572 u_int16_t physical_disks_critical; /* N/A */
573 u_int16_t physical_disks_offline;
574 u_int16_t maximum_parallel_commands;
575 /* channel and target ID information */
576 u_int8_t physical_channels_present;
577 u_int8_t virtual_channels_present;
578 u_int8_t physical_channels_possible;
579 u_int8_t virtual_channels_possible;
580 u_int8_t maximum_targets_possible[16]; /* N/A (6 and up) */
581 u_int8_t res14[12]; /* N/A */
582 /* memory/cache information */
583 u_int16_t memory_size;
584 u_int16_t cache_size;
585 u_int32_t valid_cache_size; /* N/A */
586 u_int32_t dirty_cache_size; /* N/A */
587 u_int16_t memory_speed;
588 u_int8_t memory_width;
589 u_int8_t memory_type:5;
590 u_int8_t res15:1; /* N/A */
591 u_int8_t memory_parity:1;
592 u_int8_t memory_ecc:1;
593 char memory_information[16]; /* N/A */
594 /* execution memory information */
595 u_int16_t exmemory_size;
596 u_int16_t l2cache_size; /* N/A */
597 u_int8_t res16[8]; /* N/A */
598 u_int16_t exmemory_speed;
599 u_int8_t exmemory_width;
600 u_int8_t exmemory_type:5;
601 u_int8_t res17:1; /* N/A */
602 u_int8_t exmemory_parity:1;
603 u_int8_t exmemory_ecc:1;
604 char exmemory_name[16]; /* N/A */
605 /* CPU information */
610 u_int8_t res1[12]; /* N/A */
611 char name[16]; /* N/A */
612 } cpu[2] __attribute__ ((packed));
613 /* debugging/profiling/command time tracing information */
614 u_int16_t profiling_page; /* N/A */
615 u_int16_t profiling_programs; /* N/A */
616 u_int16_t time_trace_page; /* N/A */
617 u_int16_t time_trace_programs; /* N/A */
618 u_int8_t res18[8]; /* N/A */
619 /* error counters on physical devices */
620 u_int16_t physical_device_bus_resets; /* N/A */
621 u_int16_t physical_device_parity_errors; /* N/A */
622 u_int16_t physical_device_soft_errors; /* N/A */
623 u_int16_t physical_device_commands_failed; /* N/A */
624 u_int16_t physical_device_miscellaneous_errors; /* N/A */
625 u_int16_t physical_device_command_timeouts; /* N/A */
626 u_int16_t physical_device_selection_timeouts; /* N/A */
627 u_int16_t physical_device_retries; /* N/A */
628 u_int16_t physical_device_aborts; /* N/A */
629 u_int16_t physical_device_host_command_aborts; /* N/A */
630 u_int16_t physical_device_PFAs_detected; /* N/A */
631 u_int16_t physical_device_host_commands_failed; /* N/A */
632 u_int8_t res19[8]; /* N/A */
633 /* error counters on logical devices */
634 u_int16_t logical_device_soft_errors; /* N/A */
635 u_int16_t logical_device_commands_failed; /* N/A */
636 u_int16_t logical_device_host_command_aborts; /* N/A */
637 u_int16_t res20; /* N/A */
638 /* error counters on controller */
639 u_int16_t controller_parity_ecc_errors;
640 u_int16_t controller_host_command_aborts; /* N/A */
641 u_int8_t res21[4]; /* N/A */
642 /* long duration activity information */
643 u_int16_t background_inits_active;
644 u_int16_t logical_inits_active;
645 u_int16_t physical_inits_active;
646 u_int16_t consistency_checks_active;
647 u_int16_t rebuilds_active;
648 u_int16_t MORE_active;
649 u_int16_t patrol_active; /* N/A */
650 u_int8_t long_operation_status; /* N/A */
651 u_int8_t res22; /* N/A */
652 /* flash ROM information */
653 u_int8_t flash_type; /* N/A */
654 u_int8_t res23; /* N/A */
655 u_int16_t flash_size;
656 u_int32_t flash_maximum_age;
658 u_int8_t res24[4]; /* N/A */
659 char flash_name[16]; /* N/A */
660 /* firmware runtime information */
661 u_int8_t rebuild_rate;
662 u_int8_t background_init_rate;
664 u_int8_t consistency_check_rate;
665 u_int8_t res25[4]; /* N/A */
666 u_int32_t maximum_dp;
668 u_int32_t maximum_iop;
670 u_int16_t maximum_comb_length;
671 u_int16_t maximum_configuration_groups;
672 u_int8_t installation_abort:1;
673 u_int8_t maintenance:1;
674 u_int8_t res26:6; /* N/A */
675 u_int8_t res27[3]; /* N/A */
676 u_int8_t res28[32 + 512]; /* N/A */
677 } __attribute__ ((packed));
680 * 21.9.2 MDACIOCTL_GETLOGDEVINFOVALID
682 struct mly_ioctl_getlogdevinfovalid {
683 u_int8_t res1; /* N/A */
687 u_int8_t state; /* see 8.1 */
688 u_int8_t raid_level; /* see 8.2 */
689 u_int8_t stripe_size; /* see 8.3 */
690 u_int8_t cache_line_size; /* see 8.4 */
691 u_int8_t read_write_control; /* see 8.5 */
692 u_int8_t consistency_check:1;
694 u_int8_t make_consistent:1;
695 u_int8_t initialisation:1;
696 u_int8_t migration:1;
698 u_int8_t res2:2; /* N/A */
701 u_int16_t logical_device_number;
702 u_int16_t bios_control;
704 u_int16_t soft_errors; /* N/A */
705 u_int16_t commands_failed; /* N/A */
706 u_int16_t host_command_aborts; /* N/A */
707 u_int16_t deferred_write_errors; /* N/A */
708 u_int8_t res3[8]; /* N/A */
709 /* device size information */
710 u_int8_t res4[2]; /* N/A */
711 u_int16_t device_block_size;
712 u_int32_t original_device_size; /* N/A */
713 u_int32_t device_size; /* XXX "blocks or MB" Huh? */
714 u_int8_t res5[4]; /* N/A */
715 char device_name[32]; /* N/A */
716 u_int8_t inquiry[36];
717 u_int8_t res6[12]; /* N/A */
718 u_int64_t last_read_block; /* N/A */
719 u_int64_t last_written_block; /* N/A */
720 u_int64_t consistency_check_block;
721 u_int64_t rebuild_block;
722 u_int64_t make_consistent_block;
723 u_int64_t initialisation_block;
724 u_int64_t migration_block;
725 u_int64_t patrol_block; /* N/A */
726 u_int8_t res7[64]; /* N/A */
727 } __attribute__ ((packed));
730 * 21.10.2 MDACIOCTL_GETPHYSDEVINFOVALID: Data Format
732 struct mly_ioctl_getphysdevinfovalid {
737 u_int8_t raid_ft:1; /* configuration status */
738 u_int8_t res2:1; /* N/A */
741 u_int8_t host_dead:1; /* multiple host/controller status *//* N/A */
742 u_int8_t host_connection_dead:1; /* N/A */
743 u_int8_t res4:6; /* N/A */
744 u_int8_t state; /* see 8.1 */
747 /* multiported physical device information */
748 u_int8_t ports_available; /* N/A */
749 u_int8_t ports_inuse; /* N/A */
751 u_int8_t ether_address[16]; /* N/A */
752 u_int16_t command_tags;
753 u_int8_t consistency_check:1; /* N/A */
754 u_int8_t rebuild:1; /* N/A */
755 u_int8_t make_consistent:1; /* N/A */
756 u_int8_t initialisation:1;
757 u_int8_t migration:1; /* N/A */
758 u_int8_t patrol:1; /* N/A */
760 u_int8_t long_operation_status; /* N/A */
761 u_int8_t parity_errors;
762 u_int8_t soft_errors;
763 u_int8_t hard_errors;
764 u_int8_t miscellaneous_errors;
765 u_int8_t command_timeouts; /* N/A */
766 u_int8_t retries; /* N/A */
767 u_int8_t aborts; /* N/A */
768 u_int8_t PFAs_detected; /* N/A */
770 u_int16_t block_size;
771 u_int32_t original_device_size; /* XXX "blocks or MB" Huh? */
772 u_int32_t device_size; /* XXX "blocks or MB" Huh? */
774 char name[16]; /* N/A */
775 u_int8_t res9[16 + 32];
776 u_int8_t inquiry[36];
777 u_int8_t res10[12 + 16];
778 u_int64_t last_read_block; /* N/A */
779 u_int64_t last_written_block; /* N/A */
780 u_int64_t consistency_check_block; /* N/A */
781 u_int64_t rebuild_block; /* N/A */
782 u_int64_t make_consistent_block; /* N/A */
783 u_int64_t initialisation_block; /* N/A */
784 u_int64_t migration_block; /* N/A */
785 u_int64_t patrol_block; /* N/A */
787 } __attribute__ ((packed));
790 struct mly_ioctl_getlogdevinfovalid logdev;
791 struct mly_ioctl_getphysdevinfovalid physdev;
795 * 21.11.2 MDACIOCTL_GETPHYSDEVSTATISTICS: Data Format
796 * 21.12.2 MDACIOCTL_GETLOGDEVSTATISTICS: Data Format
798 struct mly_ioctl_getdevstatistics {
799 u_int32_t uptime_ms; /* getphysedevstatistics only */
800 u_int8_t res1[5]; /* N/A */
804 u_int16_t raid_device; /* getlogdevstatistics only */
805 u_int8_t res2[2]; /* N/A */
806 /* total read/write performance including cache data */
807 u_int32_t total_reads;
808 u_int32_t total_writes;
809 u_int32_t total_read_size;
810 u_int32_t total_write_size;
811 /* cache read/write performance */
812 u_int32_t cache_reads; /* N/A */
813 u_int32_t cache_writes; /* N/A */
814 u_int32_t cache_read_size; /* N/A */
815 u_int32_t cache_write_size; /* N/A */
816 /* commands active/wait information */
817 u_int32_t command_waits_done; /* N/A */
818 u_int16_t active_commands; /* N/A */
819 u_int16_t waiting_commands; /* N/A */
820 u_int8_t res3[8]; /* N/A */
821 } __attribute__ ((packed));
824 * 21.13.2 MDACIOCTL_GETCONTROLLERSTATISTICS: Data Format
826 struct mly_ioctl_getcontrollerstatistics {
827 u_int32_t uptime_ms; /* N/A */
828 u_int8_t res1[12]; /* N/A */
829 /* target physical device performance data information */
830 u_int32_t target_physical_device_interrupts; /* N/A */
831 u_int32_t target_physical_device_stray_interrupts; /* N/A */
832 u_int8_t res2[8]; /* N/A */
833 u_int32_t target_physical_device_reads; /* N/A */
834 u_int32_t target_physical_device_writes; /* N/A */
835 u_int32_t target_physical_device_read_size; /* N/A */
836 u_int32_t target_physical_device_write_size; /* N/A */
837 /* host system performance data information */
838 u_int32_t host_system_interrupts; /* N/A */
839 u_int32_t host_system_stray_interrupts; /* N/A */
840 u_int32_t host_system_sent_interrupts; /* N/A */
841 u_int8_t res3[4]; /* N/A */
842 u_int32_t physical_device_reads; /* N/A */
843 u_int32_t physical_device_writes; /* N/A */
844 u_int32_t physical_device_read_size; /* N/A */
845 u_int32_t physical_device_write_size; /* N/A */
846 u_int32_t physical_device_cache_reads; /* N/A */
847 u_int32_t physical_device_cache_writes; /* N/A */
848 u_int32_t physical_device_cache_read_size; /* N/A */
849 u_int32_t physical_device_cache_write_size; /* N/A */
850 u_int32_t logical_device_reads; /* N/A */
851 u_int32_t logical_device_writes; /* N/A */
852 u_int32_t logical_device_read_size; /* N/A */
853 u_int32_t logical_device_write_size; /* N/A */
854 u_int32_t logical_device_cache_reads; /* N/A */
855 u_int32_t logical_device_cache_writes; /* N/A */
856 u_int32_t logical_device_cache_read_size; /* N/A */
857 u_int32_t logical_device_cache_write_size; /* N/A */
858 u_int16_t target_physical_device_commands_active; /* N/A */
859 u_int16_t target_physical_device_commands_waiting; /* N/A */
860 u_int16_t host_system_commands_active; /* N/A */
861 u_int16_t host_system_commands_waiting; /* N/A */
862 u_int8_t res4[48 + 64]; /* N/A */
863 } __attribute__ ((packed));
866 * 21.2 MDACIOCTL_SETRAIDDEVSTATE
868 struct mly_ioctl_param_setraiddevstate {
870 } __attribute__ ((packed));
873 * 21.27.2 MDACIOCTL_GETBDT_FOR_SYSDRIVE: Data Format
875 #define MLY_MAX_BDT_ENTRIES 1022
876 struct mly_ioctl_getbdt_for_sysdrive {
877 u_int32_t num_of_bdt_entries;
878 u_int32_t bad_data_block_address[MLY_MAX_BDT_ENTRIES];
879 } __attribute__ ((packed));
882 * 22.1 Physical Device Definition (PDD)
885 u_int8_t type; /* see 8.2 */
886 u_int8_t state; /* see 8.1 */
887 u_int16_t raid_device;
888 u_int32_t device_size; /* XXX "block or MB" Huh? */
893 u_int32_t start_address;
894 } __attribute__ ((packed));
897 * 22.2 RAID Device Use Definition (UDD)
901 u_int8_t state; /* see 8.1 */
902 u_int16_t raid_device;
903 u_int32_t start_address;
904 } __attribute__ ((packed));
907 * RAID Device Definition (LDD)
910 u_int8_t type; /* see 8.2 */
911 u_int8_t state; /* see 8.1 */
912 u_int16_t raid_device;
913 u_int32_t device_size; /* XXX "block or MB" Huh? */
914 u_int8_t devices_used_count;
915 u_int8_t stripe_size; /* see 8.3 */
916 u_int8_t cache_line_size; /* see 8.4 */
917 u_int8_t read_write_control; /* see 8.5 */
918 u_int32_t devices_used_size; /* XXX "block or MB" Huh? */
919 u_int16_t devices_used[32]; /* XXX actual size of this field unknown! */
920 } __attribute__ ((packed));
923 * Define a datastructure giving the smallest allocation that will hold
924 * a PDD, UDD or LDD for MDACIOCTL_GETDEVCONFINFO.
926 struct mly_devconf_hdr {
927 u_int8_t type; /* see 8.2 */
928 u_int8_t state; /* see 8.1 */
929 u_int16_t raid_device;
932 union mly_ioctl_devconfinfo {
936 struct mly_devconf_hdr hdr;
940 * 22.3 MDACIOCTL_RENAMERAIDDEV
942 * XXX this command is listed as transferring data, but does not define the data.
944 struct mly_ioctl_param_renameraiddev {
945 u_int8_t new_raid_device;
946 } __attribute__ ((packed));
949 * 23.6.2 MDACIOCTL_XLATEPHYSDEVTORAIDDEV
951 * XXX documentation suggests this format will change
953 struct mly_ioctl_param_xlatephysdevtoraiddev {
954 u_int16_t raid_device;
960 } __attribute__ ((packed));
963 * 23.7 MDACIOCTL_GETGROUPCONFINFO
965 struct mly_ioctl_param_getgroupconfinfo {
968 union mly_command_transfer transfer;
969 } __attribute__ ((packed));
972 * 23.9.2 MDACIOCTL_GETFREESPACELIST: Data Format
974 * The controller will populate as much of this structure as is provided,
975 * or as is required to fully list the free space available.
977 struct mly_ioctl_getfreespacelist_entry {
978 u_int16_t raid_device;
980 u_int32_t address; /* XXX "blocks or MB" Huh? */
981 u_int32_t size; /* XXX "blocks or MB" Huh? */
982 } __attribute__ ((packed));
984 struct mly_ioctl_getfrespacelist {
985 u_int16_t returned_entries;
986 u_int16_t total_entries;
988 struct mly_ioctl_getfreespacelist_entry space[0]; /* expand to suit */
989 } __attribute__ ((packed));
992 * 27.1 MDACIOCTL_GETSUBSYSTEMDATA
993 * 27.2 MDACIOCTL_SETSUBSYSTEMDATA
995 * PCI controller only supports a limited subset of the possible operations.
997 * XXX where does the status end up? (the command transfers no data)
999 struct mly_ioctl_param_subsystemdata {
1000 u_int8_t operation:4;
1001 #define MLY_BBU_GETSTATUS 0x00
1002 #define MLY_BBU_SET_THRESHOLD 0x00 /* minutes in param[0,1] */
1003 u_int8_t subsystem:4;
1004 #define MLY_SUBSYSTEM_BBU 0x01
1005 u_int parameter[3]; /* only for SETSUBSYSTEMDATA */
1006 } __attribute__ ((packed));
1008 struct mly_ioctl_getsubsystemdata_bbustatus {
1009 u_int16_t current_power;
1010 u_int16_t maximum_power;
1011 u_int16_t power_threshold;
1012 u_int8_t charge_level;
1013 u_int8_t hardware_version;
1014 u_int8_t battery_type;
1015 #define MLY_BBU_TYPE_UNKNOWN 0x00
1016 #define MLY_BBU_TYPE_NICAD 0x01
1017 #define MLY_BBU_TYPE_MISSING 0xfe
1019 u_int8_t operation_status;
1020 #define MLY_BBU_STATUS_NO_SYNC 0x01
1021 #define MLY_BBU_STATUS_OUT_OF_SYNC 0x02
1022 #define MLY_BBU_STATUS_FIRST_WARNING 0x04
1023 #define MLY_BBU_STATUS_SECOND_WARNING 0x08
1024 #define MLY_BBU_STATUS_RECONDITIONING 0x10
1025 #define MLY_BBU_STATUS_DISCHARGING 0x20
1026 #define MLY_BBU_STATUS_FASTCHARGING 0x40
1028 } __attribute__ ((packed));
1031 * 28.9 MDACIOCTL_RESETDEVICE
1032 * 28.10 MDACIOCTL_FLUSHDEVICEDATA
1033 * 28.11 MDACIOCTL_PAUSEDEVICE
1034 * 28.12 MDACIOCTL_UNPAUSEDEVICE
1036 struct mly_ioctl_param_deviceoperation {
1037 u_int8_t operation_device; /* see 14.3 */
1038 } __attribute__ ((packed));
1041 * 31.1 Event Data Format
1044 u_int32_t sequence_number;
1045 u_int32_t timestamp;
1047 u_int8_t controller;
1049 u_int8_t target; /* also enclosure */
1050 u_int8_t lun; /* also enclosure unit */
1054 } __attribute__ ((packed));
1057 * 31.2 MDACIOCTL_GETEVENT
1059 struct mly_ioctl_param_getevent {
1060 u_int16_t sequence_number_low;
1062 union mly_command_transfer transfer;
1063 } __attribute__ ((packed));
1065 union mly_ioctl_param {
1066 struct mly_ioctl_param_data data;
1067 struct mly_ioctl_param_setmemorymailbox setmemorymailbox;
1068 struct mly_ioctl_param_setraiddevstate setraiddevstate;
1069 struct mly_ioctl_param_renameraiddev renameraiddev;
1070 struct mly_ioctl_param_xlatephysdevtoraiddev xlatephysdevtoraiddev;
1071 struct mly_ioctl_param_getgroupconfinfo getgroupconfinfo;
1072 struct mly_ioctl_param_subsystemdata subsystemdata;
1073 struct mly_ioctl_param_deviceoperation deviceoperation;
1074 struct mly_ioctl_param_getevent getevent;
1078 * 19 SCSI Command Format
1080 struct mly_command_address_physical {
1084 u_int8_t controller:5;
1085 } __attribute__ ((packed));
1087 struct mly_command_address_logical {
1090 u_int8_t controller:5;
1091 } __attribute__ ((packed));
1093 union mly_command_address {
1094 struct mly_command_address_physical phys;
1095 struct mly_command_address_logical log;
1098 struct mly_command_generic {
1099 u_int16_t command_id;
1101 struct mly_command_control command_control;
1102 u_int32_t data_size;
1103 u_int64_t sense_buffer_address;
1104 union mly_command_address addr;
1105 struct mly_timeout timeout;
1106 u_int8_t maximum_sense_size;
1108 union mly_command_transfer transfer;
1109 } __attribute__ ((packed));
1113 * 19.1 MDACMD_SCSI & MDACMD_SCSIPT
1115 #define MLY_CMD_SCSI_SMALL_CDB 10
1116 struct mly_command_scsi_small {
1117 u_int16_t command_id;
1119 struct mly_command_control command_control;
1120 u_int32_t data_size;
1121 u_int64_t sense_buffer_address;
1122 union mly_command_address addr;
1123 struct mly_timeout timeout;
1124 u_int8_t maximum_sense_size;
1125 u_int8_t cdb_length;
1126 u_int8_t cdb[MLY_CMD_SCSI_SMALL_CDB];
1127 union mly_command_transfer transfer;
1128 } __attribute__ ((packed));
1131 * 19.2 MDACMD_SCSILC & MDACMD_SCSILCPT
1133 struct mly_command_scsi_large {
1134 u_int16_t command_id;
1136 struct mly_command_control command_control;
1137 u_int32_t data_size;
1138 u_int64_t sense_buffer_address;
1139 union mly_command_address addr;
1140 struct mly_timeout timeout;
1141 u_int8_t maximum_sense_size;
1142 u_int8_t cdb_length;
1144 u_int64_t cdb_physaddr;
1145 union mly_command_transfer transfer;
1146 } __attribute__ ((packed));
1149 * 20.1 IOCTL Command Format: Internal Bus
1151 struct mly_command_ioctl {
1152 u_int16_t command_id;
1154 struct mly_command_control command_control;
1155 u_int32_t data_size;
1156 u_int64_t sense_buffer_address;
1157 union mly_command_address addr;
1158 struct mly_timeout timeout;
1159 u_int8_t maximum_sense_size;
1161 union mly_ioctl_param param;
1162 } __attribute__ ((packed));
1167 struct mly_command_mmbox {
1170 } __attribute__ ((packed));
1172 union mly_command_packet {
1173 struct mly_command_generic generic;
1174 struct mly_command_scsi_small scsi_small;
1175 struct mly_command_scsi_large scsi_large;
1176 struct mly_command_ioctl ioctl;
1177 struct mly_command_mmbox mmbox;
1183 #define MLY_I960RX_COMMAND_MAILBOX 0x10
1184 #define MLY_I960RX_STATUS_MAILBOX 0x18
1185 #define MLY_I960RX_IDBR 0x20
1186 #define MLY_I960RX_ODBR 0x2c
1187 #define MLY_I960RX_ERROR_STATUS 0x2e
1188 #define MLY_I960RX_INTERRUPT_STATUS 0x30
1189 #define MLY_I960RX_INTERRUPT_MASK 0x34
1191 #define MLY_STRONGARM_COMMAND_MAILBOX 0x50
1192 #define MLY_STRONGARM_STATUS_MAILBOX 0x58
1193 #define MLY_STRONGARM_IDBR 0x60
1194 #define MLY_STRONGARM_ODBR 0x61
1195 #define MLY_STRONGARM_ERROR_STATUS 0x63
1196 #define MLY_STRONGARM_INTERRUPT_STATUS 0x30
1197 #define MLY_STRONGARM_INTERRUPT_MASK 0x34
1200 * PG6: 5.4.3 Doorbell 0
1202 #define MLY_HM_CMDSENT (1<<0)
1203 #define MLY_HM_STSACK (1<<1)
1204 #define MLY_SOFT_RST (1<<3)
1205 #define MLY_AM_CMDSENT (1<<4)
1208 * PG6: 5.4.4 Doorbell 1
1210 * Note that the documentation claims that these bits are set when the
1211 * status queue(s) are empty, wheras the Linux driver and experience
1212 * suggest they are set when there is status available.
1214 #define MLY_HM_STSREADY (1<<0)
1215 #define MLY_AM_STSREADY (1<<1)
1218 * PG6: 5.4.6 Doorbell 3
1220 #define MLY_MSG_EMPTY (1<<3)
1221 #define MLY_MSG_SPINUP 0x08
1222 #define MLY_MSG_RACE_RECOVERY_FAIL 0x60
1223 #define MLY_MSG_RACE_IN_PROGRESS 0x70
1224 #define MLY_MSG_RACE_ON_CRITICAL 0xb0
1225 #define MLY_MSG_PARITY_ERROR 0xf0
1228 * PG6: 5.4.8 Outbound Interrupt Mask
1230 #define MLY_INTERRUPT_MASK_DISABLE 0xff
1231 #define MLY_INTERRUPT_MASK_ENABLE (0xff & ~(1<<2))
1234 * PG6: 8.2 Advanced Mailbox Scheme
1236 * Note that this must be allocated on a 4k boundary, and all internal
1237 * fields must also reside on a 4k boundary.
1238 * We could dynamically size this structure, but the extra effort
1239 * is probably unjustified. Note that these buffers do not need to be
1240 * adjacent - we just group them to simplify allocation of the bus-visible
1243 * XXX Note that for some reason, if MLY_MMBOX_COMMANDS is > 64, the controller
1244 * fails to respond to the command at (MLY_MMBOX_COMMANDS - 64). It's not
1245 * wrapping to 0 at this point (determined by experimentation). This is not
1246 * consistent with the Linux driver's implementation.
1247 * Whilst it's handy to have lots of room for status returns in case we end up
1248 * being slow getting back to completed commands, it seems unlikely that we
1249 * would get 64 commands ahead of the controller on the submissions side, so
1250 * the current workaround is to simply limit the command ring to 64 entries.
1252 union mly_status_packet {
1253 struct mly_status status;
1257 } __attribute__ ((packed)) mmbox;
1259 union mly_health_region {
1260 struct mly_health_status status;
1264 #define MLY_MMBOX_COMMANDS 64
1265 #define MLY_MMBOX_STATUS 512
1267 union mly_command_packet mmm_command[MLY_MMBOX_COMMANDS];
1268 union mly_status_packet mmm_status[MLY_MMBOX_STATUS];
1269 union mly_health_region mmm_health;
1270 } __attribute__ ((packed));