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