1 /*        $NetBSD: mlyreg.h,v 1.9 2024/02/10 09:21:53 andvar Exp $    */
2 
3 /*-
4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Andrew Doran, Thor Lancelot Simon, and Eric Haszlakiewicz.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*-
33  * Copyright (c) 2000 Michael Smith
34  * Copyright (c) 2000 BSDi
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
50  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56  * SUCH DAMAGE.
57  *
58  * from FreeBSD: mlyreg.h,v 1.1 2000/08/23 03:22:39 msmith Exp
59  */
60 
61 /*
62  * Section numbers in this document refer to the Mylex "Firmware Software Interface"
63  * document ('FSI'), revision 0.11 04/11/00 unless otherwise qualified.
64  *
65  * Reference is made to the Mylex "Programming Guide for 6.x Controllers" document
66  * ('PG6'), document #771242 revision 0.02, 04/11/00
67  *
68  * Note that fields marked N/A are not supported by the PCI controllers, but are
69  * defined here to hold place in datastructures that are shared with the SCSI
70  * controllers.  Items not relevant to PCI controllers are not described here.
71  *
72  * Ordering of items in this file is a little odd due to the constraints of
73  * nested declarations.
74  */
75 
76 #ifndef _PCI_MLYREG_H_
77 #define   _PCI_MLYREG_H_
78 
79 /*
80  * 2.1 (Scatter Gather List Format)
81  */
82 struct mly_sg_entry {
83           u_int64_t physaddr;
84           u_int64_t length;
85 } __packed;
86 
87 /*
88  * 5.2 System Device Access
89  *
90  * This is corroborated by the layout of the MDACIOCTL_GETCONTROLLERINFO data
91  * in 21.8
92  */
93 #define   MLY_MAX_CHANNELS    6
94 #define   MLY_MAX_TARGETS               16
95 #define   MLY_MAX_LUNS                  1
96 
97 /*
98  * 8.1 Different Device States
99  */
100 #define   MLY_DEVICE_STATE_OFFLINE      0x08      /* DEAD/OFFLINE */
101 #define   MLY_DEVICE_STATE_UNCONFIGURED 0x00
102 #define   MLY_DEVICE_STATE_ONLINE                 0x01
103 #define   MLY_DEVICE_STATE_CRITICAL     0x09
104 #define   MLY_DEVICE_STATE_WRITEONLY    0x03
105 #define   MLY_DEVICE_STATE_STANDBY      0x21
106 #define   MLY_DEVICE_STATE_MISSING      0x04      /* or-ed with (ONLINE or WRITEONLY or STANDBY) */
107 
108 /*
109  * 8.2 Device Type Field definitions
110  */
111 #define   MLY_DEVICE_TYPE_RAID0                   0x0       /* RAID 0 */
112 #define   MLY_DEVICE_TYPE_RAID1                   0x1       /* RAID 1 */
113 #define   MLY_DEVICE_TYPE_RAID3                   0x3       /* RAID 3 right asymmetric parity */
114 #define   MLY_DEVICE_TYPE_RAID5                   0x5       /* RAID 5 right asymmetric parity */
115 #define   MLY_DEVICE_TYPE_RAID6                   0x6       /* RAID 6 (Mylex RAID 6) */
116 #define   MLY_DEVICE_TYPE_RAID7                   0x7       /* RAID 7 (JBOD) */
117 #define   MLY_DEVICE_TYPE_NEWSPAN                 0x8       /* New Mylex SPAN */
118 #define   MLY_DEVICE_TYPE_RAID3F                  0x9       /* RAID 3 fixed parity */
119 #define   MLY_DEVICE_TYPE_RAID3L                  0xb       /* RAID 3 left symmetric parity */
120 #define   MLY_DEVICE_TYPE_SPAN                    0xc       /* current spanning implementation */
121 #define   MLY_DEVICE_TYPE_RAID5L                  0xd       /* RAID 5 left symmetric parity */
122 #define   MLY_DEVICE_TYPE_RAIDE                   0xe       /* RAID E (concatenation) */
123 #define   MLY_DEVICE_TYPE_PHYSICAL      0xf       /* physical device */
124 
125 /*
126  * 8.3 Stripe Size
127  */
128 #define   MLY_STRIPE_ZERO               0x0       /* no stripe (RAID 1, RAID 7, etc) */
129 #define   MLY_STRIPE_512b               0x1
130 #define   MLY_STRIPE_1k                 0x2
131 #define   MLY_STRIPE_2k                 0x3
132 #define   MLY_STRIPE_4k                 0x4
133 #define   MLY_STRIPE_8k                 0x5
134 #define   MLY_STRIPE_16k                0x6
135 #define   MLY_STRIPE_32k                0x7
136 #define   MLY_STRIPE_64k                0x8
137 #define   MLY_STRIPE_128k               0x9
138 #define   MLY_STRIPE_256k               0xa
139 #define   MLY_STRIPE_512k               0xb
140 #define   MLY_STRIPE_1m                 0xc
141 
142 /*
143  * 8.4 Cacheline Size
144  */
145 #define   MLY_CACHELINE_ZERO  0x0       /* caching cannot be enabled */
146 #define   MLY_CACHELINE_512b  0x1
147 #define   MLY_CACHELINE_1k    0x2
148 #define   MLY_CACHELINE_2k    0x3
149 #define   MLY_CACHELINE_4k    0x4
150 #define   MLY_CACHELINE_8k    0x5
151 #define   MLY_CACHELINE_16k   0x6
152 #define   MLY_CACHELINE_32k   0x7
153 #define   MLY_CACHELINE_64k   0x8
154 
155 /*
156  * 8.5 Read/Write control
157  */
158 #define   MLY_RWCtl_INITTED   (1<<7)    /* if set, the logical device is initialised */
159                               /* write control */
160 #define   MLY_RWCtl_WCD                 (0)       /* write cache disabled */
161 #define   MLY_RWCtl_WDISABLE  (1<<3)    /* writing disabled */
162 #define   MLY_RWCtl_WCE                 (2<<3)    /* write cache enabled */
163 #define   MLY_RWCtl_IWCE                (3<<3)    /* intelligent write cache enabled */
164                               /* read control */
165 #define   MLY_RWCtl_RCD                 (0)       /* read cache is disabled */
166 #define   MLY_RWCtl_RCE                 (1)       /* read cache enabled */
167 #define   MLY_RWCtl_RAHEAD    (2)       /* readahead enabled */
168 #define   MLY_RWCtl_IRAHEAD   (3)       /* intelligent readahead enabled */
169 
170 /*
171  * 9.0 LUN Map Format
172  */
173 struct mly_lun_map {
174           u_int8_t  res1:4;
175           u_int8_t  host_port_mapped:1; /* this system drive visibile to host on this controller/port combination */
176           u_int8_t  tid_valid:1;                  /* target ID valid */
177           u_int8_t  hid_valid:1;                  /* host ID valid */
178           u_int8_t  lun_valid:1;                  /* LUN valid */
179           u_int8_t  res2;
180           u_int8_t  lun;                          /* LUN */
181           u_int8_t  tid;                          /* TID */
182           u_int8_t  hid[32];            /* HID (one bit for each host) */
183 } __packed;
184 
185 /*
186  * 10.1 Controller Parameters
187  */
188 struct mly_param_controller {
189           u_int8_t  rdahen:1;                               /* N/A */
190           u_int8_t  bilodly:1;                                        /* N/A */
191           u_int8_t            fua_disable:1;
192           u_int8_t  reass1s:1;                                        /* N/A */
193           u_int8_t  truvrfy:1;                                        /* N/A */
194           u_int8_t  dwtvrfy:1;                                        /* N/A */
195           u_int8_t  background_initialisation:1;
196           u_int8_t  clustering:1;                                     /* N/A */
197 
198           u_int8_t  bios_disable:1;
199           u_int8_t            boot_from_cdrom:1;
200           u_int8_t  drive_coercion:1;
201           u_int8_t  write_same_disable:1;
202           u_int8_t  hba_mode:1;                                       /* N/A */
203           u_int8_t  bios_geometry:2;
204 #define   MLY_BIOSGEOM_2G     0x0
205 #define   MLY_BIOSGEOM_8G     0x1
206           u_int8_t  res1:1;                                           /* N/A */
207 
208           u_int8_t  res2[2];                                /* N/A */
209 
210           u_int8_t  v_dec:1;
211           u_int8_t  safte:1;                                /* N/A */
212           u_int8_t  ses:1;                                            /* N/A */
213           u_int8_t  res3:2;                                           /* N/A */
214           u_int8_t  v_arm:1;
215           u_int8_t  v_ofm:1;
216           u_int8_t  res4:1;                                           /* N/A */
217 
218           u_int8_t  rebuild_check_rate;
219           u_int8_t  cache_line_size;                        /* see 8.4 */
220           u_int8_t  oem_code;
221 #define   MLY_OEM_MYLEX       0x00
222 #define   MLY_OEM_IBM         0x08
223 #define   MLY_OEM_HP          0x0a
224 #define   MLY_OEM_DEC         0x0c
225 #define   MLY_OEM_SIEMENS     0x10
226 #define   MLY_OEM_INTEL       0x12
227           u_int8_t  spinup_mode;
228 #define   MLY_SPIN_AUTO                 0
229 #define   MLY_SPIN_PWRSPIN    1
230 #define   MLY_SPIN_WSSUSPIN   2
231           u_int8_t  spinup_devices;
232           u_int8_t  spinup_interval;
233           u_int8_t  spinup_wait_time;
234 
235           u_int8_t  res5:3;                                           /* N/A */
236           u_int8_t  vutursns:1;                                       /* N/A */
237           u_int8_t  dccfil:1;                               /* N/A */
238           u_int8_t  nopause:1;                                        /* N/A */
239           u_int8_t  disqfull:1;                                       /* N/A */
240           u_int8_t  disbusy:1;                                        /* N/A */
241 
242           u_int8_t  res6:2;                                           /* N/A */
243           u_int8_t  failover_node_name;                     /* N/A */
244           u_int8_t  res7:1;                                           /* N/A */
245           u_int8_t  ftopo:3;                                /* N/A */
246           u_int8_t  disable_ups:1;                                    /* N/A */
247 
248           u_int8_t  res8:1;                                           /* N/A */
249           u_int8_t  propagate_reset:1;                      /* N/A */
250           u_int8_t  nonstd_mp_reset:1;                      /* N/A */
251           u_int8_t  res9:5;                                           /* N/A */
252 
253           u_int8_t  res10;                                            /* N/A */
254           u_int8_t  serial_port_baud_rate;                            /* N/A */
255           u_int8_t  serial_port_control;                              /* N/A */
256           u_int8_t  change_stripe_ok_developer_flag_only;   /* N/A */
257 
258           u_int8_t  small_large_host_transfers:2;           /* N/A */
259           u_int8_t  frame_control:2;                        /* N/A */
260           u_int8_t  pci_latency_control:2;                            /* N/A */
261           u_int8_t  treat_lip_as_reset:1;                             /* N/A */
262           u_int8_t  res11:1;                                /* N/A */
263 
264           u_int8_t  ms_autorest:1;                                    /* N/A */
265           u_int8_t  res12:7;                                /* N/A */
266 
267           u_int8_t  ms_aa_fsim:1;                                     /* N/A */
268           u_int8_t  ms_aa_ccach:1;                                    /* N/A */
269           u_int8_t  ms_aa_fault_signals:1;                            /* N/A */
270           u_int8_t  ms_aa_c4_faults:1;                      /* N/A */
271           u_int8_t  ms_aa_host_reset_delay_mask:4;                    /* N/A */
272 
273           u_int8_t  ms_flg_simplex_no_rstcom:1;             /* N/A */
274           u_int8_t  res13:7;                                /* N/A */
275 
276           u_int8_t  res14;                                            /* N/A */
277           u_int8_t  hardloopid[2][2];                       /* N/A */
278           u_int8_t  ctrlname[2][16+1];                      /* N/A */
279           u_int8_t  initiator_id;
280           u_int8_t  startup_option;
281 #define   MLY_STARTUP_IF_NO_CHANGE      0x0
282 #define   MLY_STARTUP_IF_NO_LUN_CHANGE  0x1
283 #define   MLY_STARTUP_IF_NO_LUN_OFFLINE 0x2
284 #define   MLY_STARTUP_IF_LUN0_NO_CHANGE 0x3
285 #define   MLY_STARTUP_IF_LUN0_NOT_OFFLINE         0x4
286 #define   MLY_STARTUP_ALWAYS            0x5
287 
288           u_int8_t  res15[62];
289 } __packed;
290 
291 /*
292  * 10.2 Physical Device Parameters
293  */
294 struct mly_param_physical_device {
295           u_int16_t tags;
296           u_int16_t speed;
297           u_int8_t  width;
298           u_int8_t  combing:1;
299           u_int8_t  res1:7;
300           u_int8_t  res2[3];
301 } __packed;
302 
303 /*
304  * 10.3 Logical Device Parameters
305  */
306 struct mly_param_logical_device {
307           u_int8_t  type;                         /* see 8.2 */
308           u_int8_t  state;                        /* see 8.1 */
309           u_int16_t raid_device;
310           u_int8_t  res1;
311           u_int8_t  bios_geometry;                /* BIOS control word? */
312           u_int8_t  stripe_size;                  /* see 8.3 */
313           u_int8_t  read_write_control; /* see 8.5 */
314           u_int8_t  res2[8];
315 } __packed;
316 
317 /*
318  * 12.3 Health Status Buffer
319  *
320  * Pad to 128 bytes.
321  */
322 struct mly_health_status {
323           u_int32_t uptime_us;                                        /* N/A */
324           u_int32_t uptime_ms;                                        /* N/A */
325           u_int32_t realtime;                               /* N/A */
326           u_int32_t res1;                                             /* N/A */
327           u_int32_t change_counter;
328           u_int32_t res2;                                             /* N/A */
329           u_int32_t debug_message_index;                              /* N/A */
330           u_int32_t bios_message_index;                     /* N/A */
331           u_int32_t trace_page;                                       /* N/A */
332           u_int32_t profiler_page;                                    /* N/A */
333           u_int32_t next_event;
334           u_int8_t  res3[4 + 16 + 64];                      /* N/A */
335 } __packed;
336 
337 /*
338  * 14.2 Timeout Bit Format
339  */
340 #define   MLY_TIMEOUT_SECONDS 0x00
341 #define   MLY_TIMEOUT_MINUTES 0x40
342 #define   MLY_TIMEOUT_HOURS   0x80
343 
344 /*
345  * 14.3 Operation Device
346  */
347 #define   MLY_OPDEVICE_PHYSICAL_DEVICE            0x0
348 #define   MLY_OPDEVICE_RAID_DEVICE                0x1
349 #define   MLY_OPDEVICE_PHYSICAL_CHANNEL           0x2
350 #define   MLY_OPDEVICE_RAID_CHANNEL               0x3
351 #define   MLY_OPDEVICE_PHYSICAL_CONTROLLER        0x4
352 #define   MLY_OPDEVICE_RAID_CONTROLLER            0x5
353 #define   MLY_OPDEVICE_CONFIGURATION_GROUP        0x10
354 
355 /*
356  * 14.4 Status Bit Format
357  *
358  * AKA Status Mailbox Format
359  *
360  * XXX format conflict between FSI and PG6 over the ordering of the
361  * status and sense length fields.
362  */
363 struct mly_status {
364           u_int16_t command_id;
365           u_int8_t  status;
366           u_int8_t  sense_length;
367           int32_t             residue;
368 } __packed;
369 
370 /*
371  * 14.5 Command Control Bit (CCB) format
372  *
373  * This byte is unfortunately named.
374  */
375 #define   MLY_CMDCTL_FORCE_UNIT_ACCESS  0x01
376 #define   MLY_CMDCTL_DISABLE_PAGE_OUT   0x02
377 #define   MLY_CMDCTL_EXTENDED_SG_TABLE  0x08
378 #define   MLY_CMDCTL_DATA_DIRECTION     0x10
379 #define   MLY_CMDCTL_NO_AUTO_SENSE      0x40
380 #define   MLY_CMDCTL_DISABLE_DISCONNECT 0x80
381 
382 /*
383  * 15.0 Commands
384  *
385  * We use the command names as given by Mylex
386  */
387 #define   MDACMD_MEMCOPY                0x1       /* memory to memory copy */
388 #define   MDACMD_SCSIPT                 0x2       /* SCSI passthrough (small command) */
389 #define   MDACMD_SCSILCPT               0x3       /* SCSI passthrough (large command) */
390 #define   MDACMD_SCSI                   0x4       /* SCSI command for logical/physical device (small command) */
391 #define   MDACMD_SCSILC                 0x5       /* SCSI command for logical/physical device (large command) */
392 #define   MDACMD_IOCTL                  0x20      /* Management command */
393 #define   MDACMD_IOCTLCHECK   0x23      /* Validate management command (not implemented) */
394 
395 /*
396  * 16.0 IOCTL command
397  *
398  * We use the IOCTL names as given by Mylex
399  * Note that only ioctls supported by the PCI controller family are listed
400  */
401 #define   MDACIOCTL_GETCONTROLLERINFO             0x1
402 #define   MDACIOCTL_GETLOGDEVINFOVALID            0x3
403 #define   MDACIOCTL_GETPHYSDEVINFOVALID           0x5
404 #define   MDACIOCTL_GETCONTROLLERSTATISTICS       0xb
405 #define   MDACIOCTL_GETLOGDEVSTATISTICS           0xd
406 #define   MDACIOCTL_GETPHYSDEVSTATISTICS                    0xf
407 #define   MDACIOCTL_GETHEALTHSTATUS               0x11
408 #define   MDACIOCTL_GETEVENT                      0x15
409 /* flash update */
410 #define   MDACIOCTL_STOREIMAGE                              0x2c
411 #define   MDACIOCTL_READIMAGE                     0x2d
412 #define   MDACIOCTL_FLASHIMAGES                             0x2e
413 /* battery backup unit */
414 #define   MDACIOCTL_GET_SUBSYSTEM_DATA            0x70
415 #define   MDACIOCTL_SET_SUBSYSTEM_DATA            0x71
416 /* non-data commands */
417 #define   MDACIOCTL_STARTDISOCVERY                0x81
418 #define   MDACIOCTL_SETRAIDDEVSTATE               0x82
419 #define   MDACIOCTL_INITPHYSDEVSTART              0x84
420 #define   MDACIOCTL_INITPHYSDEVSTOP               0x85
421 #define   MDACIOCTL_INITRAIDDEVSTART              0x86
422 #define   MDACIOCTL_INITRAIDDEVSTOP               0x87
423 #define   MDACIOCTL_REBUILDRAIDDEVSTART           0x88
424 #define   MDACIOCTL_REBUILDRAIDDEVSTOP            0x89
425 #define   MDACIOCTL_MAKECONSISTENTDATASTART       0x8a
426 #define   MDACIOCTL_MAKECONSISTENTDATASTOP        0x8b
427 #define   MDACIOCTL_CONSISTENCYCHECKSTART                   0x8c
428 #define   MDACIOCTL_CONSISTENCYCHECKSTOP                    0x8d
429 #define   MDACIOCTL_SETMEMORYMAILBOX              0x8e
430 #define   MDACIOCTL_RESETDEVICE                             0x90
431 #define   MDACIOCTL_FLUSHDEVICEDATA               0x91
432 #define   MDACIOCTL_PAUSEDEVICE                             0x92
433 #define   MDACIOCTL_UNPAUSEDEVICE                           0x93
434 #define   MDACIOCTL_LOCATEDEVICE                            0x94
435 #define   MDACIOCTL_SETMASTERSLAVEMODE            0x95
436 #define   MDACIOCTL_SETREALTIMECLOCK              0xac
437 /* RAID configuration */
438 #define   MDACIOCTL_CREATENEWCONF                           0xc0
439 #define   MDACIOCTL_DELETERAIDDEV                           0xc1
440 #define   MDACIOCTL_REPLACEINTERNALDEV            0xc2
441 #define   MDACIOCTL_RENAMERAIDDEV                           0xc3
442 #define   MDACIOCTL_ADDNEWCONF                              0xc4
443 #define   MDACIOCTL_XLATEPHYSDEVTORAIDDEV                   0xc5
444 #define   MDACIOCTL_MORE                                    0xc6
445 #define   MDACIOCTL_SETPHYSDEVPARAMETER           0xc8
446 #define   MDACIOCTL_GETPHYSDEVPARAMETER           0xc9
447 #define   MDACIOCTL_CLEARCONF                     0xca
448 #define   MDACIOCTL_GETDEVCONFINFO                0xcb
449 #define   MDACIOCTL_GETGROUPCONFINFO              0xcc
450 #define   MDACIOCTL_GETFREESPACELIST              0xcd
451 #define   MDACIOCTL_GETLOGDEVPARAMETER            0xce
452 #define   MDACIOCTL_SETLOGDEVPARAMETER            0xcf
453 #define   MDACIOCTL_GETCONTROLLERPARAMETER        0xd0
454 #define   MDACIOCTL_SETCONTRLLERPARAMETER                   0xd1
455 #define   MDACIOCTL_CLEARCONFSUSPMODE             0xd2
456 #define   MDACIOCTL_GETBDT_FOR_SYSDRIVE           0xe0
457 
458 /*
459  * 17.1.4 Data Transfer Memory Address Without SG List
460  */
461 struct mly_short_transfer {
462           struct mly_sg_entry sg[2];
463 } __packed;
464 
465 /*
466  * 17.1.5 Data Transfer Memory Address With SG List
467  *
468  * Note that only the first s/g table is currently used.
469  */
470 struct mly_sg_transfer {
471           u_int16_t entries[3];
472           u_int16_t res1;
473           u_int64_t table_physaddr[3];
474 } __packed;
475 
476 /*
477  * 17.1.3 Data Transfer Memory Address Format
478  */
479 union mly_cmd_transfer {
480           struct mly_short_transfer     direct;
481           struct mly_sg_transfer        indirect;
482 };
483 
484 /*
485  * 21.1  MDACIOCTL_SETREALTIMECLOCK
486  * 21.7  MDACIOCTL_GETHEALTHSTATUS
487  * 21.8  MDACIOCTL_GETCONTROLLERINFO
488  * 21.9  MDACIOCTL_GETLOGDEVINFOVALID
489  * 21.10 MDACIOCTL_GETPHYSDEVINFOVALID
490  * 21.11 MDACIOCTL_GETPHYSDEVSTATISTICS
491  * 21.12 MDACIOCTL_GETLOGDEVSTATISTICS
492  * 21.13 MDACIOCTL_GETCONTROLLERSTATISTICS
493  * 21.27 MDACIOCTL_GETBDT_FOR_SYSDRIVE
494  * 23.4  MDACIOCTL_CREATENEWCONF
495  * 23.5  MDACIOCTL_ADDNEWCONF
496  * 23.8  MDACIOCTL_GETDEVCONFINFO
497  * 23.9  MDACIOCTL_GETFREESPACELIST
498  * 24.1  MDACIOCTL_MORE
499  * 25.1  MDACIOCTL_GETPHYSDEVPARAMETER
500  * 25.2  MDACIOCTL_SETPHYSDEVPARAMETER
501  * 25.3  MDACIOCTL_GETLOGDEVPARAMETER
502  * 25.4  MDACIOCTL_SETLOGDEVPARAMETER
503  * 25.5  MDACIOCTL_GETCONTROLLERPARAMETER
504  * 25.6  MDACIOCTL_SETCONTROLLERPARAMETER
505  *
506  * These commands just transfer data
507  */
508 struct mly_ioctl_param_data {
509           u_int8_t  param[10];
510           union mly_cmd_transfer        transfer;
511 } __packed;
512 
513 /*
514  * 21.2 MDACIOCTL_SETMEMORYMAILBOX
515  */
516 struct mly_ioctl_param_setmemorymailbox {
517           u_int8_t  health_buffer_size;
518           u_int8_t  res1;
519           u_int64_t health_buffer_physaddr;
520           u_int64_t command_mailbox_physaddr;
521           u_int64_t status_mailbox_physaddr;
522           u_int64_t res2[2];
523 } __packed;
524 
525 /*
526  * 21.8.2 MDACIOCTL_GETCONTROLLERINFO: Data Format
527  */
528 struct mly_ioctl_getcontrollerinfo {
529           u_int8_t  res1;                                             /* N/A */
530           u_int8_t  interface_type;
531           u_int8_t  controller_type;
532           u_int8_t  res2;                                             /* N/A */
533           u_int16_t interface_speed;
534           u_int8_t  interface_width;
535           u_int8_t  res3[9];                                /* N/A */
536           char                interface_name[16];
537           char                controller_name[16];
538           u_int8_t  res4[16];                               /* N/A */
539           /* firmware release information */
540           u_int8_t  fw_major;
541           u_int8_t  fw_minor;
542           u_int8_t  fw_turn;
543           u_int8_t  fw_build;
544           u_int8_t  fw_day;
545           u_int8_t  fw_month;
546           u_int8_t  fw_century;
547           u_int8_t  fw_year;
548           /* hardware release information */
549           u_int8_t  hw_revision;                                      /* N/A */
550           u_int8_t  res5[3];                                /* N/A */
551           u_int8_t  hw_release_day;                                   /* N/A */
552           u_int8_t  hw_release_month;                       /* N/A */
553           u_int8_t  hw_release_century;                     /* N/A */
554           u_int8_t  hw_release_year;                        /* N/A */
555           /* hardware manufacturing information */
556           u_int8_t  batch_number;                                     /* N/A */
557           u_int8_t  res6;                                             /* N/A */
558           u_int8_t  plant_number;
559           u_int8_t  res7;
560           u_int8_t  hw_manuf_day;
561           u_int8_t  hw_manuf_month;
562           u_int8_t  hw_manuf_century;
563           u_int8_t  hw_manuf_year;
564           u_int8_t  max_pdd_per_xldd;
565           u_int8_t  max_ildd_per_xldd;
566           u_int16_t nvram_size;
567           u_int8_t  max_number_of_xld;                      /* N/A */
568           u_int8_t  res8[3];                                /* N/A */
569           /* unique information per controller */
570           char                serial_number[16];
571           u_int8_t  res9[16];                               /* N/A */
572           /* vendor information */
573           u_int8_t  res10[3];                               /* N/A */
574           u_int8_t  oem_information;
575           char                vendor_name[16];                        /* N/A */
576           /* other physical/controller/operation information */
577           u_int8_t  bbu_present:1;
578           u_int8_t  active_clustering:1;
579           u_int8_t  res11:6;                                /* N/A */
580           u_int8_t  res12[3];                               /* N/A */
581           /* physical device scan information */
582           u_int8_t  physical_scan_active:1;
583           u_int8_t  res13:7;                                /* N/A */
584           u_int8_t  physical_scan_channel;
585           u_int8_t  physical_scan_target;
586           u_int8_t  physical_scan_lun;
587           /* maximum command data transfer size */
588           u_int16_t maximum_block_count;
589           u_int16_t maximum_sg_entries;
590           /* logical/physical device counts */
591           u_int16_t logical_devices_present;
592           u_int16_t logical_devices_critical;
593           u_int16_t logical_devices_offline;
594           u_int16_t physical_devices_present;
595           u_int16_t physical_disks_present;
596           u_int16_t physical_disks_critical;                /* N/A */
597           u_int16_t physical_disks_offline;
598           u_int16_t maximum_parallel_commands;
599           /* channel and target ID information */
600           u_int8_t  physical_channels_present;
601           u_int8_t  virtual_channels_present;
602           u_int8_t  physical_channels_possible;
603           u_int8_t  virtual_channels_possible;
604           u_int8_t  maximum_targets_possible[16];           /* N/A (6 and up) */
605           u_int8_t  res14[12];                                        /* N/A */
606           /* memory/cache information */
607           u_int16_t memory_size;
608           u_int16_t cache_size;
609           u_int32_t valid_cache_size;                       /* N/A */
610           u_int32_t dirty_cache_size;                       /* N/A */
611           u_int16_t memory_speed;
612           u_int8_t  memory_width;
613           u_int8_t  memory_type:5;
614           u_int8_t  res15:1;                                /* N/A */
615           u_int8_t  memory_parity:1;
616           u_int8_t  memory_ecc:1;
617           char                memory_information[16];                           /* N/A */
618           /* execution memory information */
619           u_int16_t exmemory_size;
620           u_int16_t l2cache_size;                                     /* N/A */
621           u_int8_t  res16[8];                               /* N/A */
622           u_int16_t exmemory_speed;
623           u_int8_t  exmemory_width;
624           u_int8_t  exmemory_type:5;
625           u_int8_t  res17:1;                                /* N/A */
626           u_int8_t  exmemory_parity:1;
627           u_int8_t  exmemory_ecc:1;
628           char                exmemory_name[16];                      /* N/A */
629           /* CPU information */
630           struct {
631                     u_int16_t speed;
632                     u_int8_t  type;
633                     u_int8_t  number;
634                     u_int8_t  res1[12];                     /* N/A */
635                     char                name[16];                     /* N/A */
636           } cpu[2] __packed;
637           /* debugging/profiling/command time tracing information */
638           u_int16_t profiling_page;                                   /* N/A */
639           u_int16_t profiling_programs;                     /* N/A */
640           u_int16_t time_trace_page;                        /* N/A */
641           u_int16_t time_trace_programs;                              /* N/A */
642           u_int8_t  res18[8];                               /* N/A */
643           /* error counters on physical devices */
644           u_int16_t physical_device_bus_resets;             /* N/A */
645           u_int16_t physical_device_parity_errors;                    /* N/A */
646           u_int16_t physical_device_soft_errors;            /* N/A */
647           u_int16_t physical_device_commands_failed;        /* N/A */
648           u_int16_t physical_device_miscellaneous_errors;   /* N/A */
649           u_int16_t physical_device_command_timeouts;       /* N/A */
650           u_int16_t physical_device_selection_timeouts;     /* N/A */
651           u_int16_t physical_device_retries;                /* N/A */
652           u_int16_t physical_device_aborts;                           /* N/A */
653           u_int16_t physical_device_host_command_aborts;    /* N/A */
654           u_int16_t physical_device_PFAs_detected;                    /* N/A */
655           u_int16_t physical_device_host_commands_failed;   /* N/A */
656           u_int8_t  res19[8];                               /* N/A */
657           /* error counters on logical devices */
658           u_int16_t logical_device_soft_errors;             /* N/A */
659           u_int16_t logical_device_commands_failed;                   /* N/A */
660           u_int16_t logical_device_host_command_aborts;     /* N/A */
661           u_int16_t res20;                                            /* N/A */
662           /* error counters on controller */
663           u_int16_t controller_parity_ecc_errors;
664           u_int16_t controller_host_command_aborts;                   /* N/A */
665           u_int8_t  res21[4];                               /* N/A */
666           /* long duration activity information */
667           u_int16_t background_inits_active;
668           u_int16_t logical_inits_active;
669           u_int16_t physical_inits_active;
670           u_int16_t consistency_checks_active;
671           u_int16_t rebuilds_active;
672           u_int16_t MORE_active;
673           u_int16_t patrol_active;                                    /* N/A */
674           u_int8_t  long_operation_status;                            /* N/A */
675           u_int8_t  res22;                                            /* N/A */
676           /* flash ROM information */
677           u_int8_t  flash_type;                                       /* N/A */
678           u_int8_t  res23;                                            /* N/A */
679           u_int16_t flash_size;
680           u_int32_t flash_maximum_age;
681           u_int32_t flash_age;
682           u_int8_t  res24[4];                               /* N/A */
683           char                flash_name[16];                                   /* N/A */
684           /* firmware runtime information */
685           u_int8_t  rebuild_rate;
686           u_int8_t  background_init_rate;
687           u_int8_t  init_rate;
688           u_int8_t  consistency_check_rate;
689           u_int8_t  res25[4];                               /* N/A */
690           u_int32_t maximum_dp;
691           u_int32_t free_dp;
692           u_int32_t maximum_iop;
693           u_int32_t free_iop;
694           u_int16_t maximum_comb_length;
695           u_int16_t maximum_configuration_groups;
696           u_int8_t  installation_abort:1;
697           u_int8_t  maintenance:1;
698           u_int8_t  res26:6;                                /* N/A */
699           u_int8_t  res27[3];                               /* N/A */
700           u_int8_t  res28[32 + 512];                        /* N/A */
701 } __packed;
702 
703 /*
704  * 21.9.2 MDACIOCTL_GETLOGDEVINFOVALID
705  */
706 struct mly_ioctl_getlogdevinfovalid {
707           u_int8_t  res1;                                             /* N/A */
708           u_int8_t  channel;
709           u_int8_t  target;
710           u_int8_t  lun;
711           u_int8_t  state;                                            /* see 8.1 */
712           u_int8_t  raid_level;                                       /* see 8.2 */
713           u_int8_t  stripe_size;                                      /* see 8.3 */
714           u_int8_t  cache_line_size;                        /* see 8.4 */
715           u_int8_t  read_write_control;                     /* see 8.5 */
716           u_int8_t  consistency_check:1;
717           u_int8_t  rebuild:1;
718           u_int8_t  make_consistent:1;
719           u_int8_t  initialisation:1;
720           u_int8_t  migration:1;
721           u_int8_t  patrol:1;
722           u_int8_t  res2:2;                                           /* N/A */
723           u_int8_t  ar5_limit;
724           u_int8_t  ar5_algo;
725           u_int16_t logical_device_number;
726           u_int16_t bios_control;
727           /* error counters */
728           u_int16_t soft_errors;                                      /* N/A */
729           u_int16_t commands_failed;                        /* N/A */
730           u_int16_t host_command_aborts;                              /* N/A */
731           u_int16_t deferred_write_errors;                            /* N/A */
732           u_int8_t  res3[8];                                /* N/A */
733           /* device size information */
734           u_int8_t  res4[2];                                /* N/A */
735           u_int16_t device_block_size;
736           u_int32_t original_device_size;                             /* N/A */
737           u_int32_t device_size;                  /* XXX "blocks or MB" Huh? */
738           u_int8_t  res5[4];                                /* N/A */
739           char                device_name[32];                        /* N/A */
740           u_int8_t  inquiry[36];
741           u_int8_t  res6[12];                               /* N/A */
742           u_int64_t last_read_block;                        /* N/A */
743           u_int64_t last_written_block;                     /* N/A */
744           u_int64_t consistency_check_block;
745           u_int64_t rebuild_block;
746           u_int64_t make_consistent_block;
747           u_int64_t initialisation_block;
748           u_int64_t migration_block;
749           u_int64_t patrol_block;                                     /* N/A */
750           u_int8_t  res7[64];                               /* N/A */
751 } __packed;
752 
753 /*
754  * 21.10.2 MDACIOCTL_GETPHYSDEVINFOVALID: Data Format
755  */
756 struct mly_ioctl_getphysdevinfovalid {
757           u_int8_t  res1;
758           u_int8_t  channel;
759           u_int8_t  target;
760           u_int8_t  lun;
761           u_int8_t  raid_ft:1;                              /* configuration status */
762           u_int8_t  res2:1;                                           /* N/A */
763           u_int8_t  local:1;
764           u_int8_t  res3:5;
765           u_int8_t  host_dead:1;                            /* multiple host/controller status *//* N/A */
766           u_int8_t  host_connection_dead:1;                           /* N/A */
767           u_int8_t  res4:6;                                           /* N/A */
768           u_int8_t  state;                                  /* see 8.1 */
769           u_int8_t  width;
770           u_int16_t speed;
771           /* multiported physical device information */
772           u_int8_t  ports_available;                        /* N/A */
773           u_int8_t  ports_inuse;                                      /* N/A */
774           u_int8_t  res5[4];
775           u_int8_t  ether_address[16];                      /* N/A */
776           u_int16_t command_tags;
777           u_int8_t  consistency_check:1;                              /* N/A */
778           u_int8_t  rebuild:1;                                        /* N/A */
779           u_int8_t  make_consistent:1;                      /* N/A */
780           u_int8_t  initialisation:1;
781           u_int8_t  migration:1;                                      /* N/A */
782           u_int8_t  patrol:1;                               /* N/A */
783           u_int8_t  res6:2;
784           u_int8_t  long_operation_status;                            /* N/A */
785           u_int8_t  parity_errors;
786           u_int8_t  soft_errors;
787           u_int8_t  hard_errors;
788           u_int8_t  miscellaneous_errors;
789           u_int8_t  command_timeouts;                       /* N/A */
790           u_int8_t  retries;                                /* N/A */
791           u_int8_t  aborts;                                           /* N/A */
792           u_int8_t  PFAs_detected;                                    /* N/A */
793           u_int8_t  res7[6];
794           u_int16_t block_size;
795           u_int32_t original_device_size;                   /* XXX "blocks or MB" Huh? */
796           u_int32_t device_size;                            /* XXX "blocks or MB" Huh? */
797           u_int8_t  res8[4];
798           char                name[16];                               /* N/A */
799           u_int8_t  res9[16 + 32];
800           u_int8_t  inquiry[36];
801           u_int8_t  res10[12 + 16];
802           u_int64_t last_read_block;                        /* N/A */
803           u_int64_t last_written_block;                     /* N/A */
804           u_int64_t consistency_check_block;                /* N/A */
805           u_int64_t rebuild_block;                                    /* N/A */
806           u_int64_t make_consistent_block;                            /* N/A */
807           u_int64_t initialisation_block;                             /* N/A */
808           u_int64_t migration_block;                        /* N/A */
809           u_int64_t patrol_block;                                     /* N/A */
810           u_int8_t  res11[256];
811 } __packed;
812 
813 union mly_devinfo {
814           struct mly_ioctl_getlogdevinfovalid     logdev;
815           struct mly_ioctl_getphysdevinfovalid    physdev;
816 };
817 
818 /*
819  * 21.11.2 MDACIOCTL_GETPHYSDEVSTATISTICS: Data Format
820  * 21.12.2 MDACIOCTL_GETLOGDEVSTATISTICS: Data Format
821  */
822 struct mly_ioctl_getdevstatistics {
823           u_int32_t uptime_ms;                              /* getphysedevstatistics only */
824           u_int8_t  res1[5];                                /* N/A */
825           u_int8_t  channel;
826           u_int8_t  target;
827           u_int8_t  lun;
828           u_int16_t raid_device;                            /* getlogdevstatistics only */
829           u_int8_t  res2[2];                                /* N/A */
830           /* total read/write performance including cache data */
831           u_int32_t total_reads;
832           u_int32_t total_writes;
833           u_int32_t total_read_size;
834           u_int32_t total_write_size;
835           /* cache read/write performance */
836           u_int32_t cache_reads;                                      /* N/A */
837           u_int32_t cache_writes;                                     /* N/A */
838           u_int32_t cache_read_size;                        /* N/A */
839           u_int32_t cache_write_size;                       /* N/A */
840           /* commands active/wait information */
841           u_int32_t command_waits_done;                     /* N/A */
842           u_int16_t active_commands;                        /* N/A */
843           u_int16_t waiting_commands;                       /* N/A */
844           u_int8_t  res3[8];                                /* N/A */
845 } __packed;
846 
847 /*
848  * 21.13.2 MDACIOCTL_GETCONTROLLERSTATISTICS: Data Format
849  */
850 struct mly_ioctl_getcontrollerstatistics {
851           u_int32_t uptime_ms;                                        /* N/A */
852           u_int8_t  res1[12];                               /* N/A */
853           /* target physical device performance data information */
854           u_int32_t target_physical_device_interrupts;      /* N/A */
855           u_int32_t target_physical_device_stray_interrupts;/* N/A */
856           u_int8_t  res2[8];                                /* N/A */
857           u_int32_t target_physical_device_reads;           /* N/A */
858           u_int32_t target_physical_device_writes;                    /* N/A */
859           u_int32_t target_physical_device_read_size;       /* N/A */
860           u_int32_t target_physical_device_write_size;      /* N/A */
861           /* host system performance data information */
862           u_int32_t host_system_interrupts;                           /* N/A */
863           u_int32_t host_system_stray_interrupts;           /* N/A */
864           u_int32_t host_system_sent_interrupts;            /* N/A */
865           u_int8_t  res3[4];                                /* N/A */
866           u_int32_t physical_device_reads;                            /* N/A */
867           u_int32_t physical_device_writes;                           /* N/A */
868           u_int32_t physical_device_read_size;              /* N/A */
869           u_int32_t physical_device_write_size;             /* N/A */
870           u_int32_t physical_device_cache_reads;            /* N/A */
871           u_int32_t physical_device_cache_writes;           /* N/A */
872           u_int32_t physical_device_cache_read_size;        /* N/A */
873           u_int32_t physical_device_cache_write_size;       /* N/A */
874           u_int32_t logical_device_reads;                             /* N/A */
875           u_int32_t logical_device_writes;                            /* N/A */
876           u_int32_t logical_device_read_size;               /* N/A */
877           u_int32_t logical_device_write_size;              /* N/A */
878           u_int32_t logical_device_cache_reads;             /* N/A */
879           u_int32_t logical_device_cache_writes;            /* N/A */
880           u_int32_t logical_device_cache_read_size;                   /* N/A */
881           u_int32_t logical_device_cache_write_size;        /* N/A */
882           u_int16_t target_physical_device_commands_active; /* N/A */
883           u_int16_t target_physical_device_commands_waiting;/* N/A */
884           u_int16_t host_system_commands_active;            /* N/A */
885           u_int16_t host_system_commands_waiting;           /* N/A */
886           u_int8_t  res4[48 + 64];                                    /* N/A */
887 } __packed;
888 
889 /*
890  * 21.2 MDACIOCTL_SETRAIDDEVSTATE
891  */
892 struct mly_ioctl_param_setraiddevstate {
893           u_int8_t  state;
894 } __packed;
895 
896 /*
897  * 21.27.2 MDACIOCTL_GETBDT_FOR_SYSDRIVE: Data Format
898  */
899 #define   MLY_MAX_BDT_ENTRIES 1022
900 struct mly_ioctl_getbdt_for_sysdrive {
901           u_int32_t num_of_bdt_entries;
902           u_int32_t bad_data_block_address[MLY_MAX_BDT_ENTRIES];
903 } __packed;
904 
905 /*
906  * 22.1 Physical Device Definition (PDD)
907  */
908 struct mly_pdd {
909           u_int8_t  type;                                   /* see 8.2 */
910           u_int8_t  state;                                  /* see 8.1 */
911           u_int16_t raid_device;
912           u_int32_t device_size;                            /* XXX "block or MB" Huh? */
913           u_int8_t  controller;
914           u_int8_t  channel;
915           u_int8_t  target;
916           u_int8_t  lun;
917           u_int32_t start_address;
918 } __packed;
919 
920 /*
921  * 22.2 RAID Device Use Definition (UDD)
922  */
923 struct mly_udd {
924           u_int8_t  res1;
925           u_int8_t  state;                                  /* see 8.1 */
926           u_int16_t raid_device;
927           u_int32_t start_address;
928 } __packed;
929 
930 /*
931  * RAID Device Definition (LDD)
932  */
933 struct mly_ldd {
934           u_int8_t  type;                                   /* see 8.2 */
935           u_int8_t  state;                                  /* see 8.1 */
936           u_int16_t raid_device;
937           u_int32_t device_size;                            /* XXX "block or MB" Huh? */
938           u_int8_t  devices_used_count;
939           u_int8_t  stripe_size;                            /* see 8.3 */
940           u_int8_t  cache_line_size;              /* see 8.4 */
941           u_int8_t  read_write_control;           /* see 8.5 */
942           u_int32_t devices_used_size;            /* XXX "block or MB" Huh? */
943           u_int16_t devices_used[32];             /* XXX actual size of this field unknown! */
944 } __packed;
945 
946 /*
947  * Define a datastructure giving the smallest allocation that will hold
948  * a PDD, UDD or LDD for MDACIOCTL_GETDEVCONFINFO.
949  */
950 struct mly_devconf_hdr {
951           u_int8_t  type;                                   /* see 8.2 */
952           u_int8_t  state;                                  /* see 8.1 */
953           u_int16_t raid_device;
954 };
955 
956 union mly_ioctl_devconfinfo {
957           struct mly_pdd                pdd;
958           struct mly_udd                udd;
959           struct mly_ldd                ldd;
960           struct mly_devconf_hdr        hdr;
961 };
962 
963 /*
964  * 22.3 MDACIOCTL_RENAMERAIDDEV
965  *
966  * XXX this command is listed as transferring data, but does not define the data.
967  */
968 struct mly_ioctl_param_renameraiddev {
969           u_int8_t  new_raid_device;
970 } __packed;
971 
972 /*
973  * 23.6.2 MDACIOCTL_XLATEPHYSDEVTORAIDDEV
974  *
975  * XXX documentation suggests this format will change
976  */
977 struct mly_ioctl_param_xlatephysdevtoraiddev {
978           u_int16_t raid_device;
979           u_int8_t  res1[2];
980           u_int8_t  controller;
981           u_int8_t  channel;
982           u_int8_t  target;
983           u_int8_t  lun;
984 } __packed;
985 
986 /*
987  * 23.7 MDACIOCTL_GETGROUPCONFINFO
988  */
989 struct mly_ioctl_param_getgroupconfinfo {
990           u_int16_t                     group;
991           u_int8_t                      res1[8];
992           union mly_cmd_transfer        transfer;
993 } __packed;
994 
995 /*
996  * 23.9.2 MDACIOCTL_GETFREESPACELIST: Data Format
997  *
998  * The controller will populate as much of this structure as is provided,
999  * or as is required to fully list the free space available.
1000  */
1001 struct mly_ioctl_getfreespacelist_entry {
1002           u_int16_t raid_device;
1003           u_int8_t  res1[6];
1004           u_int32_t address;            /* XXX "blocks or MB" Huh? */
1005           u_int32_t size;                         /* XXX "blocks or MB" Huh? */
1006 } __packed;
1007 
1008 struct mly_ioctl_getfrespacelist {
1009           u_int16_t returned_entries;
1010           u_int16_t total_entries;
1011           u_int8_t  res1[12];
1012           struct mly_ioctl_getfreespacelist_entry space[];  /* expand to suit */
1013 } __packed;
1014 
1015 /*
1016  * 27.1 MDACIOCTL_GETSUBSYSTEMDATA
1017  * 27.2 MDACIOCTL_SETSUBSYSTEMDATA
1018  *
1019  * PCI controller only supports a limited subset of the possible operations.
1020  *
1021  * XXX where does the status end up? (the command transfers no data)
1022  */
1023 struct mly_ioctl_param_subsystemdata {
1024           u_int8_t  operation:4;
1025 #define   MLY_BBU_GETSTATUS   0x00
1026 #define   MLY_BBU_SET_THRESHOLD         0x00      /* minutes in param[0,1] */
1027           u_int8_t  subsystem:4;
1028 #define   MLY_SUBSYSTEM_BBU   0x01
1029           u_int     parameter[3];                 /* only for SETSUBSYSTEMDATA */
1030 } __packed;
1031 
1032 struct mly_ioctl_getsubsystemdata_bbustatus {
1033           u_int16_t current_power;
1034           u_int16_t maximum_power;
1035           u_int16_t power_threshold;
1036           u_int8_t  charge_level;
1037           u_int8_t  hardware_version;
1038           u_int8_t  battery_type;
1039 #define   MLY_BBU_TYPE_UNKNOWN          0x00
1040 #define   MLY_BBU_TYPE_NICAD  0x01
1041 #define   MLY_BBU_TYPE_MISSING          0xfe
1042           u_int8_t  res1;
1043           u_int8_t  operation_status;
1044 #define   MLY_BBU_STATUS_NO_SYNC                  0x01
1045 #define   MLY_BBU_STATUS_OUT_OF_SYNC    0x02
1046 #define   MLY_BBU_STATUS_FIRST_WARNING  0x04
1047 #define   MLY_BBU_STATUS_SECOND_WARNING 0x08
1048 #define   MLY_BBU_STATUS_RECONDITIONING 0x10
1049 #define   MLY_BBU_STATUS_DISCHARGING    0x20
1050 #define   MLY_BBU_STATUS_FASTCHARGING   0x40
1051           u_int8_t  res2;
1052 } __packed;
1053 
1054 /*
1055  * 28.9  MDACIOCTL_RESETDEVICE
1056  * 28.10 MDACIOCTL_FLUSHDEVICEDATA
1057  * 28.11 MDACIOCTL_PAUSEDEVICE
1058  * 28.12 MDACIOCTL_UNPAUSEDEVICE
1059  */
1060 struct mly_ioctl_param_deviceoperation {
1061           u_int8_t  operation_device;             /* see 14.3 */
1062 } __packed;
1063 
1064 /*
1065  * 31.1 Event Data Format
1066  */
1067 struct mly_event {
1068           u_int32_t sequence_number;
1069           u_int32_t timestamp;
1070           u_int32_t code;
1071           u_int8_t  controller;
1072           u_int8_t  channel;
1073           u_int8_t  target;                                 /* also enclosure */
1074           u_int8_t  lun;                                    /* also enclosure unit */
1075           u_int8_t            res1[4];
1076           u_int32_t param;
1077           u_int8_t  sense[40];
1078 } __packed;
1079 
1080 /*
1081  * 31.2 MDACIOCTL_GETEVENT
1082  */
1083 struct mly_ioctl_param_getevent {
1084           u_int16_t           sequence_number_low;
1085           u_int8_t            res1[8];
1086           union mly_cmd_transfer        transfer;
1087 } __packed;
1088 
1089 union mly_ioctl_param {
1090           struct mly_ioctl_param_data                       data;
1091           struct mly_ioctl_param_setmemorymailbox           setmemorymailbox;
1092           struct mly_ioctl_param_setraiddevstate            setraiddevstate;
1093           struct mly_ioctl_param_renameraiddev              renameraiddev;
1094           struct mly_ioctl_param_xlatephysdevtoraiddev      xlatephysdevtoraiddev;
1095           struct mly_ioctl_param_getgroupconfinfo           getgroupconfinfo;
1096           struct mly_ioctl_param_subsystemdata              subsystemdata;
1097           struct mly_ioctl_param_deviceoperation            deviceoperation;
1098           struct mly_ioctl_param_getevent                             getevent;
1099 };
1100 
1101 /*
1102  * 19 SCSI Command Format
1103  */
1104 #define   MLY_PHYADDR(c, b, t, l)       \
1105           ((l) | ((t) << 8) | ((b) << 16) | ((c) << 19))
1106 #define   MLY_LOGADDR(c, u)   \
1107           ((u) | ((c) << 19))
1108 
1109 #define   MLY_LOGADDR_DEV(a)            (a & 0xffff)
1110 #define   MLY_LOGADDR_CTLR(a)           (a >> 19)
1111 
1112 #define   MLY_PHYADDR_LUN(a)            (a & 0xff)
1113 #define   MLY_PHYADDR_TARGET(a)                   ((a >> 8) & 0xff)
1114 #define   MLY_PHYADDR_CHANNEL(a)                  ((a >> 16) & 0x07)
1115 #define   MLY_PHYADDR_CTLR(a)           ((a >> 19) & 0x1f)
1116 
1117 /*
1118  * struct mly_cmd_address_physical {
1119  *        u_int8_t                      lun;
1120  *        u_int8_t                      target;
1121  *        u_int8_t                      channel:3;
1122  *        u_int8_t                      controller:5;
1123  * } __packed;
1124  *
1125  * struct mly_cmd_address_logical {
1126  *        u_int16_t                     logdev;
1127  *        u_int8_t                      res1:3;
1128  *        u_int8_t                      controller:5;
1129  * } __packed;
1130  */
1131 
1132 struct mly_cmd_generic {
1133           u_int16_t                     command_id;
1134           u_int8_t                      opcode;
1135           u_int8_t                      command_control;
1136           u_int32_t                     data_size;
1137           u_int64_t                     sense_buffer_address;
1138           u_int8_t                      addr[3];
1139           u_int8_t                      timeout;
1140           u_int8_t                      maximum_sense_size;
1141           u_int8_t                      res1[11];
1142           union mly_cmd_transfer        transfer;
1143 } __packed;
1144 
1145 
1146 /*
1147  * 19.1 MDACMD_SCSI & MDACMD_SCSIPT
1148  */
1149 #define   MLY_CMD_SCSI_SMALL_CDB        10
1150 struct mly_cmd_scsi_small {
1151           u_int16_t                     command_id;
1152           u_int8_t                      opcode;
1153           u_int8_t                      command_control;
1154           u_int32_t                     data_size;
1155           u_int64_t                     sense_buffer_address;
1156           u_int8_t                      addr[3];
1157           u_int8_t                      timeout;
1158           u_int8_t                      maximum_sense_size;
1159           u_int8_t                      cdb_length;
1160           u_int8_t                      cdb[MLY_CMD_SCSI_SMALL_CDB];
1161           union mly_cmd_transfer        transfer;
1162 } __packed;
1163 
1164 /*
1165  * 19.2 MDACMD_SCSILC & MDACMD_SCSILCPT
1166  */
1167 struct mly_cmd_scsi_large {
1168           u_int16_t                     command_id;
1169           u_int8_t                      opcode;
1170           u_int8_t                      command_control;
1171           u_int32_t                     data_size;
1172           u_int64_t                     sense_buffer_address;
1173           u_int8_t                      addr[3];
1174           u_int8_t                      timeout;
1175           u_int8_t                      maximum_sense_size;
1176           u_int8_t                      cdb_length;
1177           u_int16_t                     res1;
1178           u_int64_t                     cdb_physaddr;
1179           union mly_cmd_transfer        transfer;
1180 } __packed;
1181 
1182 /*
1183  * 20.1 IOCTL Command Format: Internal Bus
1184  */
1185 struct mly_cmd_ioctl {
1186           u_int16_t                     command_id;
1187           u_int8_t                      opcode;
1188           u_int8_t                      command_control;
1189           u_int32_t                     data_size;
1190           u_int64_t                     sense_buffer_address;
1191           u_int8_t                      addr[3];
1192           u_int8_t                      timeout;
1193           u_int8_t                      maximum_sense_size;
1194           u_int8_t                      sub_ioctl;
1195           union mly_ioctl_param                   param;
1196 } __packed;
1197 
1198 /*
1199  * PG6: 8.2.2
1200  */
1201 struct mly_cmd_mmbox {
1202           u_int32_t                     flag;
1203           u_int8_t                      data[60];
1204 } __packed;
1205 
1206 union mly_cmd_packet {
1207           struct mly_cmd_generic                  generic;
1208           struct mly_cmd_scsi_small     scsi_small;
1209           struct mly_cmd_scsi_large     scsi_large;
1210           struct mly_cmd_ioctl                    ioctl;
1211           struct mly_cmd_mmbox                    mmbox;
1212 };
1213 
1214 /*
1215  * PG6: 5.3
1216  */
1217 #define   MLY_I960RX_COMMAND_MAILBOX    0x10
1218 #define   MLY_I960RX_STATUS_MAILBOX     0x18
1219 #define   MLY_I960RX_IDBR                         0x20
1220 #define   MLY_I960RX_ODBR                         0x2c
1221 #define   MLY_I960RX_ERROR_STATUS                 0x2e
1222 #define   MLY_I960RX_INTERRUPT_STATUS   0x30
1223 #define   MLY_I960RX_INTERRUPT_MASK     0x34
1224 
1225 #define   MLY_STRONGARM_COMMAND_MAILBOX 0x50
1226 #define   MLY_STRONGARM_STATUS_MAILBOX  0x58
1227 #define   MLY_STRONGARM_IDBR            0x60
1228 #define   MLY_STRONGARM_ODBR            0x61
1229 #define   MLY_STRONGARM_ERROR_STATUS    0x63
1230 #define   MLY_STRONGARM_INTERRUPT_STATUS          0x30
1231 #define   MLY_STRONGARM_INTERRUPT_MASK  0x34
1232 
1233 /*
1234  * PG6: 5.4.3 Doorbell 0
1235  */
1236 #define   MLY_HM_CMDSENT                          (1<<0)
1237 #define   MLY_HM_STSACK                           (1<<1)
1238 #define   MLY_SOFT_RST                            (1<<3)
1239 #define   MLY_AM_CMDSENT                          (1<<4)
1240 
1241 /*
1242  * PG6: 5.4.4 Doorbell 1
1243  *
1244  * Note that the documentation claims that these bits are set when the
1245  * status queue(s) are empty, whereas the Linux driver and experience
1246  * suggest they are set when there is status available.
1247  */
1248 #define   MLY_HM_STSREADY                         (1<<0)
1249 #define   MLY_AM_STSREADY                         (1<<1)
1250 
1251 /*
1252  * PG6: 5.4.6 Doorbell 3
1253  */
1254 #define   MLY_MSG_EMPTY                           (1<<3)
1255 #define   MLY_MSG_SPINUP                          0x08
1256 #define   MLY_MSG_RACE_RECOVERY_FAIL    0x60
1257 #define   MLY_MSG_RACE_IN_PROGRESS      0x70
1258 #define   MLY_MSG_RACE_ON_CRITICAL      0xb0
1259 #define   MLY_MSG_PARITY_ERROR                    0xf0
1260 
1261 /*
1262  * PG6: 5.4.8 Outbound Interrupt Mask
1263  */
1264 #define   MLY_INTERRUPT_MASK_DISABLE    0xff
1265 #define   MLY_INTERRUPT_MASK_ENABLE     (0xff & ~(1<<2))
1266 
1267 /*
1268  * PG6: 8.2 Advanced Mailbox Scheme
1269  *
1270  * Note that this must be allocated on a 4k boundary, and all internal
1271  * fields must also reside on a 4k boundary.
1272  * We could dynamically size this structure, but the extra effort
1273  * is probably unjustified.  Note that these buffers do not need to be
1274  * adjacent - we just group them to simplify allocation of the bus-visible
1275  * buffer.
1276  *
1277  * XXX Note that for some reason, if MLY_MMBOX_COMMANDS is > 64, the controller
1278  * fails to respond to the command at (MLY_MMBOX_COMMANDS - 64).  It's not
1279  * wrapping to 0 at this point (determined by experimentation).  This is not
1280  * consistent with the Linux driver's implementation.
1281  * Whilst it's handy to have lots of room for status returns in case we end up
1282  * being slow getting back to completed commands, it seems unlikely that we
1283  * would get 64 commands ahead of the controller on the submissions side, so
1284  * the current workaround is to simply limit the command ring to 64 entries.
1285  */
1286 union mly_status_packet {
1287            struct mly_status            status;
1288            struct {
1289                      u_int32_t                    flag;
1290                      u_int8_t           data[4];
1291            } __packed mmbox;
1292 };
1293 union mly_health_region {
1294           struct mly_health_status      status;
1295           u_int8_t                      pad[1024];
1296 };
1297 
1298 #define   MLY_MMBOX_COMMANDS            64
1299 #define   MLY_MMBOX_STATUS              512
1300 struct mly_mmbox {
1301           union mly_cmd_packet          mmm_command[MLY_MMBOX_COMMANDS];
1302           union mly_status_packet       mmm_status[MLY_MMBOX_STATUS];
1303           union mly_health_region       mmm_health;
1304 } __packed;
1305 
1306 #endif    /* !defined _PCI_MLYREG_H_ */
1307