xref: /freebsd/sys/dev/mlx/mlxreg.h (revision 807a5caa14df5ff04b331e24b45893f6a2f6bc1b)
1 /*-
2  * Copyright (c) 1999 Michael Smith
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	$FreeBSD$
27  */
28 
29 #define MLX_BLKSIZE	512		/* fixed feature */
30 
31 /*
32  * Selected command codes.
33  */
34 #define MLX_CMD_ENQUIRY_OLD	0x05
35 #define MLX_CMD_ENQUIRY		0x53
36 #define MLX_CMD_ENQUIRY2	0x1c
37 #define MLX_CMD_ENQSYSDRIVE	0x19
38 #define MLX_CMD_READSG		0xb6
39 #define MLX_CMD_WRITESG		0xb7
40 #define MLX_CMD_READSG_OLD	0x82
41 #define MLX_CMD_WRITESG_OLD	0x83
42 #define MLX_CMD_FLUSH		0x0a
43 #define MLX_CMD_LOGOP		0x72
44 #define MLX_CMD_REBUILDASYNC	0x16
45 #define MLX_CMD_CHECKASYNC	0x1e
46 #define MLX_CMD_REBUILDSTAT	0x0c
47 #define MLX_CMD_STOPCHANNEL	0x13
48 #define MLX_CMD_STARTCHANNEL	0x12
49 #define MLX_CMD_READ_CONFIG	0x4e
50 #define MLX_CMD_DIRECT_CDB	0x04
51 
52 #ifdef _KERNEL
53 
54 #define MLX_CFG_BASE0   0x10		/* first region */
55 #define MLX_CFG_BASE1   0x14		/* second region (type 3 only) */
56 
57 /*
58  * Status values.
59  */
60 #define MLX_STATUS_OK		0x0000
61 #define MLX_STATUS_RDWROFFLINE	0x0002	/* read/write claims drive is offline */
62 #define MLX_STATUS_WEDGED	0xdead	/* controller not listening */
63 #define MLX_STATUS_LOST		0xbeef	/* never came back */
64 #define MLX_STATUS_BUSY		0xffff	/* command is in controller */
65 
66 /*
67  * Accessor defines for the V3 interface.
68  */
69 #define MLX_V3_MAILBOX		0x00
70 #define	MLX_V3_STATUS_IDENT	0x0d
71 #define MLX_V3_STATUS		0x0e
72 #define MLX_V3_IDBR		0x40
73 #define MLX_V3_ODBR		0x41
74 #define MLX_V3_IER		0x43
75 #define MLX_V3_FWERROR		0x3f
76 #define MLX_V3_FWERROR_PARAM1	0x00
77 #define MLX_V3_FWERROR_PARAM2	0x01
78 
79 #define MLX_V3_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_MAILBOX + idx, val)
80 #define MLX_V3_GET_STATUS_IDENT(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_STATUS_IDENT)
81 #define MLX_V3_GET_STATUS(sc)		 bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_STATUS)
82 #define MLX_V3_GET_IDBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IDBR)
83 #define MLX_V3_PUT_IDBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IDBR, val)
84 #define MLX_V3_GET_ODBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_ODBR)
85 #define MLX_V3_PUT_ODBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_ODBR, val)
86 #define MLX_V3_PUT_IER(sc, val)		 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IER, val)
87 #define MLX_V3_GET_FWERROR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR)
88 #define MLX_V3_PUT_FWERROR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR, val)
89 #define MLX_V3_GET_FWERROR_PARAM1(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR_PARAM1)
90 #define MLX_V3_GET_FWERROR_PARAM2(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR_PARAM2)
91 
92 #define MLX_V3_IDB_FULL		(1<<0)		/* mailbox is full */
93 #define MLX_V3_IDB_INIT_BUSY	(1<<1)		/* initialisation in progress */
94 
95 #define MLX_V3_IDB_SACK		(1<<1)		/* acknowledge status read */
96 
97 #define MLX_V3_ODB_SAVAIL	(1<<0)		/* status is available */
98 
99 #define MLX_V3_FWERROR_PEND	(1<<2)		/* firmware error pending */
100 
101 /*
102  * Accessor defines for the V4 interface.
103  */
104 #define MLX_V4_MAILBOX		0x1000
105 #define MLX_V4_MAILBOX_LENGTH		16
106 #define MLX_V4_STATUS_IDENT	0x1018
107 #define MLX_V4_STATUS		0x101a
108 #define MLX_V4_IDBR		0x0020
109 #define MLX_V4_ODBR		0x002c
110 #define MLX_V4_IER		0x0034
111 #define MLX_V4_FWERROR		0x103f
112 #define MLX_V4_FWERROR_PARAM1	0x1000
113 #define MLX_V4_FWERROR_PARAM2	0x1001
114 
115 /* use longword access? */
116 #define MLX_V4_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_MAILBOX + idx, val)
117 #define MLX_V4_GET_STATUS_IDENT(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_STATUS_IDENT)
118 #define MLX_V4_GET_STATUS(sc)		 bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_STATUS)
119 #define MLX_V4_GET_IDBR(sc)		 bus_space_read_4 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IDBR)
120 #define MLX_V4_PUT_IDBR(sc, val)	 bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IDBR, val)
121 #define MLX_V4_GET_ODBR(sc)		 bus_space_read_4 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_ODBR)
122 #define MLX_V4_PUT_ODBR(sc, val)	 bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_ODBR, val)
123 #define MLX_V4_PUT_IER(sc, val)		 bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IER, val)
124 #define MLX_V4_GET_FWERROR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR)
125 #define MLX_V4_PUT_FWERROR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR, val)
126 #define MLX_V4_GET_FWERROR_PARAM1(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR_PARAM1)
127 #define MLX_V4_GET_FWERROR_PARAM2(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR_PARAM2)
128 
129 #define MLX_V4_IDB_FULL		(1<<0)		/* mailbox is full */
130 #define MLX_V4_IDB_INIT_BUSY	(1<<1)		/* initialisation in progress */
131 
132 #define MLX_V4_IDB_HWMBOX_CMD	(1<<0)		/* posted hardware mailbox command */
133 #define MLX_V4_IDB_SACK		(1<<1)		/* acknowledge status read */
134 #define MLX_V4_IDB_MEMMBOX_CMD	(1<<4)		/* posted memory mailbox command */
135 
136 #define MLX_V4_ODB_HWSAVAIL	(1<<0)		/* status is available for hardware mailbox */
137 #define MLX_V4_ODB_MEMSAVAIL	(1<<1)		/* status is available for memory mailbox */
138 
139 #define MLX_V4_ODB_HWMBOX_ACK	(1<<0)		/* ack status read from hardware mailbox */
140 #define MLX_V4_ODB_MEMMBOX_ACK	(1<<1)		/* ack status read from memory mailbox */
141 
142 #define MLX_V4_IER_MASK		0xfb		/* message unit interrupt mask */
143 #define MLX_V4_IER_DISINT	(1<<2)		/* interrupt disable bit */
144 
145 #define MLX_V4_FWERROR_PEND	(1<<2)		/* firmware error pending */
146 
147 /*
148  * Accessor defines for the V5 interface
149  */
150 #define MLX_V5_MAILBOX		0x50
151 #define MLX_V5_MAILBOX_LENGTH		16
152 #define MLX_V5_STATUS_IDENT	0x5d
153 #define MLX_V5_STATUS		0x5e
154 #define MLX_V5_IDBR		0x60
155 #define MLX_V5_ODBR		0x61
156 #define MLX_V5_IER		0x34
157 #define MLX_V5_FWERROR		0x63
158 #define MLX_V5_FWERROR_PARAM1	0x50
159 #define MLX_V5_FWERROR_PARAM2	0x51
160 
161 #define MLX_V5_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_MAILBOX + idx, val)
162 #define MLX_V5_GET_STATUS_IDENT(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_STATUS_IDENT)
163 #define MLX_V5_GET_STATUS(sc)		 bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_STATUS)
164 #define MLX_V5_GET_IDBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IDBR)
165 #define MLX_V5_PUT_IDBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IDBR, val)
166 #define MLX_V5_GET_ODBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_ODBR)
167 #define MLX_V5_PUT_ODBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_ODBR, val)
168 #define MLX_V5_PUT_IER(sc, val)		 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IER, val)
169 #define MLX_V5_GET_FWERROR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR)
170 #define MLX_V5_PUT_FWERROR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR, val)
171 #define MLX_V5_GET_FWERROR_PARAM1(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR_PARAM1)
172 #define MLX_V5_GET_FWERROR_PARAM2(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR_PARAM2)
173 
174 #define MLX_V5_IDB_EMPTY	(1<<0)		/* mailbox is empty */
175 #define MLX_V5_IDB_INIT_DONE	(1<<1)		/* initialisation has completed */
176 
177 #define MLX_V5_IDB_HWMBOX_CMD	(1<<0)		/* posted hardware mailbox command */
178 #define MLX_V5_IDB_SACK		(1<<1)		/* acknowledge status read */
179 #define MLX_V5_IDB_RESET	(1<<3)		/* reset request */
180 #define MLX_V5_IDB_MEMMBOX_CMD	(1<<4)		/* posted memory mailbox command */
181 
182 #define MLX_V5_ODB_HWSAVAIL	(1<<0)		/* status is available for hardware mailbox */
183 #define MLX_V5_ODB_MEMSAVAIL	(1<<1)		/* status is available for memory mailbox */
184 
185 #define MLX_V5_ODB_HWMBOX_ACK	(1<<0)		/* ack status read from hardware mailbox */
186 #define MLX_V5_ODB_MEMMBOX_ACK	(1<<1)		/* ack status read from memory mailbox */
187 
188 #define MLX_V5_IER_DISINT	(1<<2)		/* interrupt disable bit */
189 
190 #define MLX_V5_FWERROR_PEND	(1<<2)		/* firmware error pending */
191 
192 #endif /* _KERNEL */
193 
194 /*
195  * Scatter-gather list format, type 1, kind 00.
196  */
197 struct mlx_sgentry
198 {
199     u_int32_t	sg_addr;
200     u_int32_t	sg_count;
201 } __attribute__ ((packed));
202 
203 /*
204  * Command result buffers, as placed in system memory by the controller.
205  */
206 
207 struct mlx_enquiry_old	/* MLX_CMD_ENQUIRY_OLD */
208 {
209     u_int8_t		me_num_sys_drvs;
210     u_int8_t		res1[3];
211     u_int32_t		me_drvsize[8];
212     u_int16_t		me_flash_age;
213     u_int8_t		me_status_flags;
214     u_int8_t		me_free_state_change_count;
215     u_int8_t		me_fwminor;
216     u_int8_t		me_fwmajor;
217     u_int8_t		me_rebuild_flag;
218     u_int8_t		me_max_commands;
219     u_int8_t		me_offline_sd_count;
220     u_int8_t		res3;
221     u_int8_t		me_critical_sd_count;
222     u_int8_t		res4[3];
223     u_int8_t		me_dead_count;
224     u_int8_t		res5;
225     u_int8_t		me_rebuild_count;
226     u_int8_t		me_misc_flags;
227     struct
228     {
229 	u_int8_t	dd_targ;
230 	u_int8_t	dd_chan;
231     } __attribute__ ((packed)) me_dead[20];
232 } __attribute__ ((packed));
233 
234 struct mlx_enquiry	/* MLX_CMD_ENQUIRY */
235 {
236     u_int8_t		me_num_sys_drvs;
237     u_int8_t		res1[3];
238     u_int32_t		me_drvsize[32];
239     u_int16_t		me_flash_age;
240     u_int8_t		me_status_flags;
241 #define MLX_ENQ_SFLAG_DEFWRERR	(1<<0)	/* deferred write error indicator */
242 #define MLX_ENQ_SFLAG_BATTLOW	(1<<1)	/* battery low */
243     u_int8_t		res2;
244     u_int8_t		me_fwminor;
245     u_int8_t		me_fwmajor;
246     u_int8_t		me_rebuild_flag;
247     u_int8_t		me_max_commands;
248     u_int8_t		me_offline_sd_count;
249     u_int8_t		res3;
250     u_int16_t		me_event_log_seq_num;
251     u_int8_t		me_critical_sd_count;
252     u_int8_t		res4[3];
253     u_int8_t		me_dead_count;
254     u_int8_t		res5;
255     u_int8_t		me_rebuild_count;
256     u_int8_t		me_misc_flags;
257 #define MLX_ENQ_MISC_BBU	(1<<3)	/* battery backup present */
258     struct
259     {
260 	u_int8_t	dd_targ;
261 	u_int8_t	dd_chan;
262     } __attribute__ ((packed)) me_dead[20];
263 } __attribute__ ((packed));
264 
265 struct mlx_enquiry2	/* MLX_CMD_ENQUIRY2 */
266 {
267     u_int32_t		me_hardware_id;
268     u_int32_t		me_firmware_id;
269     u_int32_t		res1;
270     u_int8_t		me_configured_channels;
271     u_int8_t		me_actual_channels;
272     u_int8_t		me_max_targets;
273     u_int8_t		me_max_tags;
274     u_int8_t		me_max_sys_drives;
275     u_int8_t		me_max_arms;
276     u_int8_t		me_max_spans;
277     u_int8_t		res2;
278     u_int32_t		res3;
279     u_int32_t		me_mem_size;
280     u_int32_t		me_cache_size;
281     u_int32_t		me_flash_size;
282     u_int32_t		me_nvram_size;
283     u_int16_t		me_mem_type;
284     u_int16_t		me_clock_speed;
285     u_int16_t		me_mem_speed;
286     u_int16_t		me_hardware_speed;
287     u_int8_t		res4[12];
288     u_int16_t		me_max_commands;
289     u_int16_t		me_max_sg;
290     u_int16_t		me_max_dp;
291     u_int16_t		me_max_iod;
292     u_int16_t		me_max_comb;
293     u_int8_t		me_latency;
294     u_int8_t		res5;
295     u_int8_t		me_scsi_timeout;
296     u_int8_t		res6;
297     u_int16_t		me_min_freelines;
298     u_int8_t		res7[8];
299     u_int8_t		me_rate_const;
300     u_int8_t		res8[11];
301     u_int16_t		me_physblk;
302     u_int16_t		me_logblk;
303     u_int16_t		me_maxblk;
304     u_int16_t		me_blocking_factor;
305     u_int16_t		me_cacheline;
306     u_int8_t		me_scsi_cap;
307     u_int8_t		res9[5];
308     u_int16_t		me_firmware_build;
309     u_int8_t		me_fault_mgmt_type;
310     u_int8_t		res10;
311     u_int32_t		me_firmware_features;
312     u_int8_t		res11[8];
313 } __attribute__ ((packed));
314 
315 struct mlx_enq_sys_drive /* MLX_CMD_ENQSYSDRIVE returns an array of 32 of these */
316 {
317     u_int32_t		sd_size;
318     u_int8_t		sd_state;
319     u_int8_t		sd_raidlevel;
320     u_int16_t		res1;
321 } __attribute__ ((packed));
322 
323 struct mlx_eventlog_entry	/* MLX_CMD_LOGOP/MLX_LOGOP_GET */
324 {
325     u_int8_t		el_type;
326     u_int8_t		el_length;
327     u_char		el_target:5;
328     u_char		el_channel:3;
329     u_char		el_lun:6;
330     u_char		res1:2;
331     u_int16_t		el_seqno;
332     u_char		el_errorcode:7;
333     u_char		el_valid:1;
334     u_int8_t		el_segment;
335     u_char		el_sensekey:4;
336     u_char		res2:1;
337     u_char		el_ILI:1;
338     u_char		el_EOM:1;
339     u_char		el_filemark:1;
340     u_int8_t		el_information[4];
341     u_int8_t		el_addsense;
342     u_int8_t		el_csi[4];
343     u_int8_t		el_asc;
344     u_int8_t		el_asq;
345     u_int8_t		res3[12];
346 } __attribute__ ((packed));
347 
348 #define MLX_LOGOP_GET		0x00	/* operation codes for MLX_CMD_LOGOP */
349 #define MLX_LOGMSG_SENSE	0x00	/* log message contents codes */
350 
351 struct mlx_rebuild_stat	/* MLX_CMD_REBUILDSTAT */
352 {
353     u_int32_t	rb_drive;
354     u_int32_t	rb_size;
355     u_int32_t	rb_remaining;
356 } __attribute__ ((packed));
357 
358 struct mlx_config2
359 {
360     u_int16_t	cf_flags1;
361 #define MLX_CF2_ACTV_NEG	(1<<1)
362 #define MLX_CF2_NORSTRTRY	(1<<7)
363 #define MLX_CF2_STRGWRK		(1<<8)
364 #define MLX_CF2_HPSUPP		(1<<9)
365 #define MLX_CF2_NODISCN		(1<<10)
366 #define MLX_CF2_ARM    		(1<<13)
367 #define MLX_CF2_OFM		(1<<15)
368 #define MLX_CF2_AEMI (MLX_CF2_ARM | MLX_CF2_OFM)
369     u_int8_t	cf_oemid;
370     u_int8_t	cf_oem_model;
371     u_int8_t	cf_physical_sector;
372     u_int8_t	cf_logical_sector;
373     u_int8_t	cf_blockfactor;
374     u_int8_t	cf_flags2;
375 #define MLX_CF2_READAH		(1<<0)
376 #define MLX_CF2_BIOSDLY		(1<<1)
377 #define MLX_CF2_REASS1S		(1<<4)
378 #define MLX_CF2_FUAENABL	(1<<6)
379 #define MLX_CF2_R5ALLS		(1<<7)
380     u_int8_t	cf_rcrate;
381     u_int8_t	cf_res1;
382     u_int8_t	cf_blocks_per_cache_line;
383     u_int8_t	cf_blocks_per_stripe;
384     u_int8_t	cf_scsi_param_0;
385     u_int8_t	cf_scsi_param_1;
386     u_int8_t	cf_scsi_param_2;
387     u_int8_t	cf_scsi_param_3;
388     u_int8_t	cf_scsi_param_4;
389     u_int8_t	cf_scsi_param_5;
390     u_int8_t	cf_scsi_initiator_id;
391     u_int8_t	cf_res2;
392     u_int8_t	cf_startup_mode;
393     u_int8_t	cf_simultaneous_spinup_devices;
394     u_int8_t	cf_delay_between_spinups;
395     u_int8_t	cf_res3;
396     u_int16_t	cf_checksum;
397 } __attribute__ ((packed));
398 
399 struct mlx_sys_drv_span
400 {
401     u_int32_t	sp_start_lba;
402     u_int32_t	sp_nblks;
403     u_int8_t	sp_arm[8];
404 } __attribute__ ((packed));
405 
406 struct mlx_sys_drv
407 {
408     u_int8_t	sd_status;
409     u_int8_t	sd_ext_status;
410     u_int8_t	sd_mod1;
411     u_int8_t	sd_mod2;
412     u_int8_t	sd_raidlevel;
413 #define MLX_SYS_DRV_WRITEBACK	(1<<7)
414 #define MLX_SYS_DRV_RAID0	0
415 #define MLX_SYS_DRV_RAID1	1
416 #define MLX_SYS_DRV_RAID3	3
417 #define MLX_SYS_DRV_RAID5	5
418 #define MLX_SYS_DRV_RAID6	6
419 #define MLX_SYS_DRV_JBOD	7
420     u_int8_t	sd_valid_arms;
421     u_int8_t	sd_valid_spans;
422     u_int8_t	sd_init_state;
423 #define MLX_SYS_DRV_INITTED	0x81;
424     struct mlx_sys_drv_span sd_span[4];
425 } __attribute__ ((packed));
426 
427 struct mlx_phys_drv
428 {
429     u_int8_t	pd_flags1;
430 #define	MLX_PHYS_DRV_PRESENT	(1<<0)
431     u_int8_t	pd_flags2;
432 #define MLX_PHYS_DRV_OTHER	0x00
433 #define MLX_PHYS_DRV_DISK	0x01
434 #define MLX_PHYS_DRV_SEQUENTIAL	0x02
435 #define MLX_PHYS_DRV_CDROM	0x03
436 #define MLX_PHYS_DRV_FAST20	(1<<3)
437 #define MLX_PHYS_DRV_SYNC	(1<<4)
438 #define MLX_PHYS_DRV_FAST	(1<<5)
439 #define MLX_PHYS_DRV_WIDE	(1<<6)
440 #define MLX_PHYS_DRV_TAG	(1<<7)
441     u_int8_t	pd_status;
442 #define MLX_PHYS_DRV_DEAD	0x00
443 #define MLX_PHYS_DRV_WRONLY	0x02
444 #define MLX_PHYS_DRV_ONLINE	0x03
445 #define MLX_PHYS_DRV_STANDBY	0x10
446     u_int8_t	pd_res1;
447     u_int8_t	pd_period;
448     u_int8_t	pd_offset;
449     u_int32_t	pd_config_size;
450 } __attribute__ ((packed));
451 
452 struct mlx_core_cfg
453 {
454     u_int8_t	cc_num_sys_drives;
455     u_int8_t	cc_res1[3];
456     struct mlx_sys_drv	cc_sys_drives[32];
457     struct mlx_phys_drv cc_phys_drives[5 * 16];
458 } __attribute__ ((packed));
459 
460 struct mlx_dcdb
461 {
462     u_int8_t	dcdb_target:4;
463     u_int8_t	dcdb_channel:4;
464     u_int8_t	dcdb_flags;
465 #define MLX_DCDB_NO_DATA	0x00
466 #define MLX_DCDB_DATA_IN	0x01
467 #define MLX_DCDB_DATA_OUT	0x02
468 #define MLX_DCDB_EARLY_STATUS		(1<<2)
469 #define MLX_DCDB_TIMEOUT_10S	0x10
470 #define MLX_DCDB_TIMEOUT_60S	0x20
471 #define MLX_DCDB_TIMEOUT_20M	0x30
472 #define MLX_DCDB_TIMEOUT_24H	0x40
473 #define MLX_DCDB_NO_AUTO_SENSE	(1<<6)
474 #define MLX_DCDB_DISCONNECT	(1<<7)
475     u_int16_t	dcdb_datasize;
476     u_int32_t	dcdb_physaddr;
477     u_int8_t	dcdb_cdb_length:4;
478     u_int8_t	dcdb_datasize_high:4;
479     u_int8_t	dcdb_sense_length;
480     u_int8_t	dcdb_cdb[12];
481     u_int8_t	dcdb_sense[64];
482     u_int8_t	dcdb_status;
483     u_int8_t	res1;
484 } __attribute__ ((packed));
485 
486 #ifdef _KERNEL
487 /*
488  * Inlines to build various command structures
489  */
490 static __inline void
491 mlx_make_type1(struct mlx_command *mc,
492 	       u_int8_t code,
493 	       u_int16_t f1,
494 	       u_int32_t f2,
495 	       u_int8_t f3,
496 	       u_int32_t f4,
497 	       u_int8_t f5)
498 {
499     mc->mc_mailbox[0x0] = code;
500     mc->mc_mailbox[0x2] = f1 & 0xff;
501     mc->mc_mailbox[0x3] = (((f2 >> 24) & 0x3) << 6) | ((f1 >> 8) & 0x3f);
502     mc->mc_mailbox[0x4] = f2 & 0xff;
503     mc->mc_mailbox[0x5] = (f2 >> 8) & 0xff;
504     mc->mc_mailbox[0x6] = (f2 >> 16) & 0xff;
505     mc->mc_mailbox[0x7] = f3;
506     mc->mc_mailbox[0x8] = f4 & 0xff;
507     mc->mc_mailbox[0x9] = (f4 >> 8) & 0xff;
508     mc->mc_mailbox[0xa] = (f4 >> 16) & 0xff;
509     mc->mc_mailbox[0xb] = (f4 >> 24) & 0xff;
510     mc->mc_mailbox[0xc] = f5;
511 }
512 
513 static __inline void
514 mlx_make_type2(struct mlx_command *mc,
515 	       u_int8_t code,
516 	       u_int8_t f1,
517 	       u_int8_t f2,
518 	       u_int8_t f3,
519 	       u_int8_t f4,
520 	       u_int8_t f5,
521 	       u_int8_t f6,
522 	       u_int32_t f7,
523 	       u_int8_t f8)
524 {
525     mc->mc_mailbox[0x0] = code;
526     mc->mc_mailbox[0x2] = f1;
527     mc->mc_mailbox[0x3] = f2;
528     mc->mc_mailbox[0x4] = f3;
529     mc->mc_mailbox[0x5] = f4;
530     mc->mc_mailbox[0x6] = f5;
531     mc->mc_mailbox[0x7] = f6;
532     mc->mc_mailbox[0x8] = f7 & 0xff;
533     mc->mc_mailbox[0x9] = (f7 >> 8) & 0xff;
534     mc->mc_mailbox[0xa] = (f7 >> 16) & 0xff;
535     mc->mc_mailbox[0xb] = (f7 >> 24) & 0xff;
536     mc->mc_mailbox[0xc] = f8;
537 }
538 
539 static __inline void
540 mlx_make_type3(struct mlx_command *mc,
541 	       u_int8_t code,
542 	       u_int8_t f1,
543 	       u_int8_t f2,
544 	       u_int16_t f3,
545 	       u_int8_t f4,
546 	       u_int8_t f5,
547 	       u_int32_t f6,
548 	       u_int8_t f7)
549 {
550     mc->mc_mailbox[0x0] = code;
551     mc->mc_mailbox[0x2] = f1;
552     mc->mc_mailbox[0x3] = f2;
553     mc->mc_mailbox[0x4] = f3 & 0xff;
554     mc->mc_mailbox[0x5] = (f3 >> 8) & 0xff;
555     mc->mc_mailbox[0x6] = f4;
556     mc->mc_mailbox[0x7] = f5;
557     mc->mc_mailbox[0x8] = f6 & 0xff;
558     mc->mc_mailbox[0x9] = (f6 >> 8) & 0xff;
559     mc->mc_mailbox[0xa] = (f6 >> 16) & 0xff;
560     mc->mc_mailbox[0xb] = (f6 >> 24) & 0xff;
561     mc->mc_mailbox[0xc] = f7;
562 }
563 
564 static __inline void
565 mlx_make_type4(struct mlx_command *mc,
566 	       u_int8_t code,
567 	       u_int16_t f1,
568 	       u_int32_t f2,
569 	       u_int32_t f3,
570 	       u_int8_t f4)
571 {
572     mc->mc_mailbox[0x0] = code;
573     mc->mc_mailbox[0x2] = f1 & 0xff;
574     mc->mc_mailbox[0x3] = (f1 >> 8) & 0xff;
575     mc->mc_mailbox[0x4] = f2 & 0xff;
576     mc->mc_mailbox[0x5] = (f2 >> 8) & 0xff;
577     mc->mc_mailbox[0x6] = (f2 >> 16) & 0xff;
578     mc->mc_mailbox[0x7] = (f2 >> 24) & 0xff;
579     mc->mc_mailbox[0x8] = f3 & 0xff;
580     mc->mc_mailbox[0x9] = (f3 >> 8) & 0xff;
581     mc->mc_mailbox[0xa] = (f3 >> 16) & 0xff;
582     mc->mc_mailbox[0xb] = (f3 >> 24) & 0xff;
583     mc->mc_mailbox[0xc] = f4;
584 }
585 
586 static __inline void
587 mlx_make_type5(struct mlx_command *mc,
588 	       u_int8_t code,
589 	       u_int8_t f1,
590 	       u_int8_t f2,
591 	       u_int32_t f3,
592 	       u_int32_t f4,
593 	       u_int8_t f5)
594 {
595     mc->mc_mailbox[0x0] = code;
596     mc->mc_mailbox[0x2] = f1;
597     mc->mc_mailbox[0x3] = f2;
598     mc->mc_mailbox[0x4] = f3 & 0xff;
599     mc->mc_mailbox[0x5] = (f3 >> 8) & 0xff;
600     mc->mc_mailbox[0x6] = (f3 >> 16) & 0xff;
601     mc->mc_mailbox[0x7] = (f3 >> 24) & 0xff;
602     mc->mc_mailbox[0x8] = f4 & 0xff;
603     mc->mc_mailbox[0x9] = (f4 >> 8) & 0xff;
604     mc->mc_mailbox[0xa] = (f4 >> 16) & 0xff;
605     mc->mc_mailbox[0xb] = (f4 >> 24) & 0xff;
606     mc->mc_mailbox[0xc] = f5;
607 }
608 
609 #endif /* _KERNEL */
610