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