1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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