1 /* $NetBSD: mfii.c,v 1.28 2022/09/29 10:27:02 bouyer Exp $ */ 2 /* $OpenBSD: mfii.c,v 1.58 2018/08/14 05:22:21 jmatthew Exp $ */ 3 4 /* 5 * Copyright (c) 2018 Manuel Bouyer <Manuel.Bouyer@lip6.fr> 6 * Copyright (c) 2012 David Gwynne <dlg@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/cdefs.h> 22 __KERNEL_RCSID(0, "$NetBSD: mfii.c,v 1.28 2022/09/29 10:27:02 bouyer Exp $"); 23 24 #include "bio.h" 25 26 #include <sys/atomic.h> 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/buf.h> 30 #include <sys/ioctl.h> 31 #include <sys/device.h> 32 #include <sys/kernel.h> 33 #include <sys/proc.h> 34 #include <sys/cpu.h> 35 #include <sys/conf.h> 36 #include <sys/kauth.h> 37 #include <sys/workqueue.h> 38 #include <sys/malloc.h> 39 40 #include <uvm/uvm_param.h> 41 42 #include <dev/pci/pcidevs.h> 43 #include <dev/pci/pcivar.h> 44 45 #include <sys/bus.h> 46 47 #include <dev/sysmon/sysmonvar.h> 48 #include <sys/envsys.h> 49 50 #include <dev/scsipi/scsipi_all.h> 51 #include <dev/scsipi/scsi_all.h> 52 #include <dev/scsipi/scsi_spc.h> 53 #include <dev/scsipi/scsipi_disk.h> 54 #include <dev/scsipi/scsi_disk.h> 55 #include <dev/scsipi/scsiconf.h> 56 57 #if NBIO > 0 58 #include <dev/biovar.h> 59 #endif /* NBIO > 0 */ 60 61 #include <dev/ic/mfireg.h> 62 #include <dev/pci/mpiireg.h> 63 64 #define MFII_BAR 0x14 65 #define MFII_BAR_35 0x10 66 #define MFII_PCI_MEMSIZE 0x2000 /* 8k */ 67 68 #define MFII_OSTS_INTR_VALID 0x00000009 69 #define MFII_RPI 0x6c /* reply post host index */ 70 #define MFII_OSP2 0xb4 /* outbound scratch pad 2 */ 71 #define MFII_OSP3 0xb8 /* outbound scratch pad 3 */ 72 73 #define MFII_REQ_TYPE_SCSI MPII_REQ_DESCR_SCSI_IO 74 #define MFII_REQ_TYPE_LDIO (0x7 << 1) 75 #define MFII_REQ_TYPE_MFA (0x1 << 1) 76 #define MFII_REQ_TYPE_NO_LOCK (0x2 << 1) 77 #define MFII_REQ_TYPE_HI_PRI (0x6 << 1) 78 79 #define MFII_REQ_MFA(_a) htole64((_a) | MFII_REQ_TYPE_MFA) 80 81 #define MFII_FUNCTION_PASSTHRU_IO (0xf0) 82 #define MFII_FUNCTION_LDIO_REQUEST (0xf1) 83 84 #define MFII_MAX_CHAIN_UNIT 0x00400000 85 #define MFII_MAX_CHAIN_MASK 0x000003E0 86 #define MFII_MAX_CHAIN_SHIFT 5 87 88 #define MFII_256K_IO 128 89 #define MFII_1MB_IO (MFII_256K_IO * 4) 90 91 #define MFII_CHAIN_FRAME_MIN 1024 92 93 struct mfii_request_descr { 94 u_int8_t flags; 95 u_int8_t msix_index; 96 u_int16_t smid; 97 98 u_int16_t lmid; 99 u_int16_t dev_handle; 100 } __packed; 101 102 #define MFII_RAID_CTX_IO_TYPE_SYSPD (0x1 << 4) 103 #define MFII_RAID_CTX_TYPE_CUDA (0x2 << 4) 104 105 struct mfii_raid_context { 106 u_int8_t type_nseg; 107 u_int8_t _reserved1; 108 u_int16_t timeout_value; 109 110 u_int16_t reg_lock_flags; 111 #define MFII_RAID_CTX_RL_FLAGS_SEQNO_EN (0x08) 112 #define MFII_RAID_CTX_RL_FLAGS_CPU0 (0x00) 113 #define MFII_RAID_CTX_RL_FLAGS_CPU1 (0x10) 114 #define MFII_RAID_CTX_RL_FLAGS_CUDA (0x80) 115 116 #define MFII_RAID_CTX_ROUTING_FLAGS_SQN (1 << 4) 117 #define MFII_RAID_CTX_ROUTING_FLAGS_CPU0 0 118 u_int16_t virtual_disk_target_id; 119 120 u_int64_t reg_lock_row_lba; 121 122 u_int32_t reg_lock_length; 123 124 u_int16_t next_lm_id; 125 u_int8_t ex_status; 126 u_int8_t status; 127 128 u_int8_t raid_flags; 129 u_int8_t num_sge; 130 u_int16_t config_seq_num; 131 132 u_int8_t span_arm; 133 u_int8_t _reserved3[3]; 134 } __packed; 135 136 struct mfii_sge { 137 u_int64_t sg_addr; 138 u_int32_t sg_len; 139 u_int16_t _reserved; 140 u_int8_t sg_next_chain_offset; 141 u_int8_t sg_flags; 142 } __packed; 143 144 #define MFII_SGE_ADDR_MASK (0x03) 145 #define MFII_SGE_ADDR_SYSTEM (0x00) 146 #define MFII_SGE_ADDR_IOCDDR (0x01) 147 #define MFII_SGE_ADDR_IOCPLB (0x02) 148 #define MFII_SGE_ADDR_IOCPLBNTA (0x03) 149 #define MFII_SGE_END_OF_LIST (0x40) 150 #define MFII_SGE_CHAIN_ELEMENT (0x80) 151 152 #define MFII_REQUEST_SIZE 256 153 154 #define MR_DCMD_LD_MAP_GET_INFO 0x0300e101 155 156 #define MFII_MAX_ROW 32 157 #define MFII_MAX_ARRAY 128 158 159 struct mfii_array_map { 160 uint16_t mam_pd[MFII_MAX_ROW]; 161 } __packed; 162 163 struct mfii_dev_handle { 164 uint16_t mdh_cur_handle; 165 uint8_t mdh_valid; 166 uint8_t mdh_reserved; 167 uint16_t mdh_handle[2]; 168 } __packed; 169 170 struct mfii_ld_map { 171 uint32_t mlm_total_size; 172 uint32_t mlm_reserved1[5]; 173 uint32_t mlm_num_lds; 174 uint32_t mlm_reserved2; 175 uint8_t mlm_tgtid_to_ld[2 * MFI_MAX_LD]; 176 uint8_t mlm_pd_timeout; 177 uint8_t mlm_reserved3[7]; 178 struct mfii_array_map mlm_am[MFII_MAX_ARRAY]; 179 struct mfii_dev_handle mlm_dev_handle[MFI_MAX_PD]; 180 } __packed; 181 182 struct mfii_task_mgmt { 183 union { 184 uint8_t request[128]; 185 struct mpii_msg_scsi_task_request 186 mpii_request; 187 } __packed __aligned(8); 188 189 union { 190 uint8_t reply[128]; 191 uint32_t flags; 192 #define MFII_TASK_MGMT_FLAGS_LD (1 << 0) 193 #define MFII_TASK_MGMT_FLAGS_PD (1 << 1) 194 struct mpii_msg_scsi_task_reply 195 mpii_reply; 196 } __packed __aligned(8); 197 } __packed __aligned(8); 198 199 /* We currently don't know the full details of the following struct */ 200 struct mfii_foreign_scan_cfg { 201 char data[24]; 202 } __packed; 203 204 struct mfii_foreign_scan_info { 205 uint32_t count; /* Number of foreign configs found */ 206 struct mfii_foreign_scan_cfg cfgs[8]; 207 } __packed; 208 209 #define MFII_MAX_LD_EXT 256 210 211 struct mfii_ld_list_ext { 212 uint32_t mll_no_ld; 213 uint32_t mll_res; 214 struct { 215 struct mfi_ld mll_ld; 216 uint8_t mll_state; /* states are the same as MFI_ */ 217 uint8_t mll_res2; 218 uint8_t mll_res3; 219 uint8_t mll_res4; 220 uint64_t mll_size; 221 } mll_list[MFII_MAX_LD_EXT]; 222 } __packed; 223 224 struct mfii_dmamem { 225 bus_dmamap_t mdm_map; 226 bus_dma_segment_t mdm_seg; 227 size_t mdm_size; 228 void * mdm_kva; 229 }; 230 #define MFII_DMA_MAP(_mdm) ((_mdm)->mdm_map) 231 #define MFII_DMA_LEN(_mdm) ((_mdm)->mdm_size) 232 #define MFII_DMA_DVA(_mdm) ((u_int64_t)(_mdm)->mdm_map->dm_segs[0].ds_addr) 233 #define MFII_DMA_KVA(_mdm) ((void *)(_mdm)->mdm_kva) 234 235 struct mfii_softc; 236 237 typedef enum mfii_direction { 238 MFII_DATA_NONE = 0, 239 MFII_DATA_IN, 240 MFII_DATA_OUT 241 } mfii_direction_t; 242 243 struct mfii_ccb { 244 struct mfii_softc *ccb_sc; 245 void *ccb_request; 246 u_int64_t ccb_request_dva; 247 bus_addr_t ccb_request_offset; 248 249 void *ccb_mfi; 250 u_int64_t ccb_mfi_dva; 251 bus_addr_t ccb_mfi_offset; 252 253 struct mfi_sense *ccb_sense; 254 u_int64_t ccb_sense_dva; 255 bus_addr_t ccb_sense_offset; 256 257 struct mfii_sge *ccb_sgl; 258 u_int64_t ccb_sgl_dva; 259 bus_addr_t ccb_sgl_offset; 260 u_int ccb_sgl_len; 261 262 struct mfii_request_descr ccb_req; 263 264 bus_dmamap_t ccb_dmamap64; 265 bus_dmamap_t ccb_dmamap32; 266 bool ccb_dma64; 267 268 /* data for sgl */ 269 void *ccb_data; 270 size_t ccb_len; 271 272 mfii_direction_t ccb_direction; 273 274 void *ccb_cookie; 275 kmutex_t ccb_mtx; 276 kcondvar_t ccb_cv; 277 void (*ccb_done)(struct mfii_softc *, 278 struct mfii_ccb *); 279 280 u_int32_t ccb_flags; 281 #define MFI_CCB_F_ERR (1<<0) 282 u_int ccb_smid; 283 SIMPLEQ_ENTRY(mfii_ccb) ccb_link; 284 }; 285 SIMPLEQ_HEAD(mfii_ccb_list, mfii_ccb); 286 287 struct mfii_iop { 288 int bar; 289 int num_sge_loc; 290 #define MFII_IOP_NUM_SGE_LOC_ORIG 0 291 #define MFII_IOP_NUM_SGE_LOC_35 1 292 u_int16_t ldio_ctx_reg_lock_flags; 293 u_int8_t ldio_req_type; 294 u_int8_t ldio_ctx_type_nseg; 295 u_int8_t sge_flag_chain; 296 u_int8_t sge_flag_eol; 297 u_int8_t iop_flag; 298 #define MFII_IOP_QUIRK_REGREAD 0x01 299 #define MFII_IOP_HAS_32BITDESC_BIT 0x02 300 }; 301 302 struct mfii_softc { 303 device_t sc_dev; 304 struct scsipi_channel sc_chan; 305 struct scsipi_adapter sc_adapt; 306 307 const struct mfii_iop *sc_iop; 308 u_int sc_iop_flag; 309 #define MFII_IOP_DESC_32BIT 0x01 310 311 pci_chipset_tag_t sc_pc; 312 pcitag_t sc_tag; 313 314 bus_space_tag_t sc_iot; 315 bus_space_handle_t sc_ioh; 316 bus_size_t sc_ios; 317 bus_dma_tag_t sc_dmat; 318 bus_dma_tag_t sc_dmat64; 319 bool sc_64bit_dma; 320 321 void *sc_ih; 322 323 kmutex_t sc_ccb_mtx; 324 kmutex_t sc_post_mtx; 325 326 u_int sc_max_fw_cmds; 327 u_int sc_max_cmds; 328 u_int sc_max_sgl; 329 330 u_int sc_reply_postq_depth; 331 u_int sc_reply_postq_index; 332 kmutex_t sc_reply_postq_mtx; 333 struct mfii_dmamem *sc_reply_postq; 334 335 struct mfii_dmamem *sc_requests; 336 struct mfii_dmamem *sc_mfi; 337 struct mfii_dmamem *sc_sense; 338 struct mfii_dmamem *sc_sgl; 339 340 struct mfii_ccb *sc_ccb; 341 struct mfii_ccb_list sc_ccb_freeq; 342 343 struct mfii_ccb *sc_aen_ccb; 344 struct workqueue *sc_aen_wq; 345 struct work sc_aen_work; 346 347 kmutex_t sc_abort_mtx; 348 struct mfii_ccb_list sc_abort_list; 349 struct workqueue *sc_abort_wq; 350 struct work sc_abort_work; 351 352 /* save some useful information for logical drives that is missing 353 * in sc_ld_list 354 */ 355 struct { 356 bool ld_present; 357 char ld_dev[16]; /* device name sd? */ 358 int ld_target_id; 359 } sc_ld[MFII_MAX_LD_EXT]; 360 int sc_target_lds[MFII_MAX_LD_EXT]; 361 bool sc_max256vd; 362 363 /* bio */ 364 struct mfi_conf *sc_cfg; 365 struct mfi_ctrl_info sc_info; 366 struct mfii_ld_list_ext sc_ld_list; 367 struct mfi_ld_details *sc_ld_details; /* array to all logical disks */ 368 int sc_no_pd; /* used physical disks */ 369 int sc_ld_sz; /* sizeof sc_ld_details */ 370 371 /* mgmt lock */ 372 kmutex_t sc_lock; 373 bool sc_running; 374 375 /* sensors */ 376 struct sysmon_envsys *sc_sme; 377 envsys_data_t *sc_sensors; 378 bool sc_bbuok; 379 380 device_t sc_child; 381 }; 382 383 // #define MFII_DEBUG 384 #ifdef MFII_DEBUG 385 #define DPRINTF(x...) do { if (mfii_debug) printf(x); } while(0) 386 #define DNPRINTF(n,x...) do { if (mfii_debug & n) printf(x); } while(0) 387 #define MFII_D_CMD 0x0001 388 #define MFII_D_INTR 0x0002 389 #define MFII_D_MISC 0x0004 390 #define MFII_D_DMA 0x0008 391 #define MFII_D_IOCTL 0x0010 392 #define MFII_D_RW 0x0020 393 #define MFII_D_MEM 0x0040 394 #define MFII_D_CCB 0x0080 395 uint32_t mfii_debug = 0 396 /* | MFII_D_CMD */ 397 /* | MFII_D_INTR */ 398 | MFII_D_MISC 399 /* | MFII_D_DMA */ 400 /* | MFII_D_IOCTL */ 401 /* | MFII_D_RW */ 402 /* | MFII_D_MEM */ 403 /* | MFII_D_CCB */ 404 ; 405 #else 406 #define DPRINTF(x...) 407 #define DNPRINTF(n,x...) 408 #endif 409 410 static int mfii_match(device_t, cfdata_t, void *); 411 static void mfii_attach(device_t, device_t, void *); 412 static int mfii_detach(device_t, int); 413 static int mfii_rescan(device_t, const char *, const int *); 414 static void mfii_childdetached(device_t, device_t); 415 static bool mfii_suspend(device_t, const pmf_qual_t *); 416 static bool mfii_resume(device_t, const pmf_qual_t *); 417 static bool mfii_shutdown(device_t, int); 418 419 420 CFATTACH_DECL3_NEW(mfii, sizeof(struct mfii_softc), 421 mfii_match, mfii_attach, mfii_detach, NULL, mfii_rescan, 422 mfii_childdetached, DVF_DETACH_SHUTDOWN); 423 424 static void mfii_scsipi_request(struct scsipi_channel *, 425 scsipi_adapter_req_t, void *); 426 static void mfii_scsi_cmd_done(struct mfii_softc *, struct mfii_ccb *); 427 428 #define DEVNAME(_sc) (device_xname((_sc)->sc_dev)) 429 430 static u_int32_t mfii_read(struct mfii_softc *, bus_size_t); 431 static void mfii_write(struct mfii_softc *, bus_size_t, u_int32_t); 432 433 static struct mfii_dmamem * mfii_dmamem_alloc(struct mfii_softc *, size_t); 434 static void mfii_dmamem_free(struct mfii_softc *, 435 struct mfii_dmamem *); 436 437 static struct mfii_ccb * mfii_get_ccb(struct mfii_softc *); 438 static void mfii_put_ccb(struct mfii_softc *, struct mfii_ccb *); 439 static int mfii_init_ccb(struct mfii_softc *); 440 static void mfii_scrub_ccb(struct mfii_ccb *); 441 442 static int mfii_transition_firmware(struct mfii_softc *); 443 static int mfii_initialise_firmware(struct mfii_softc *); 444 static int mfii_get_info(struct mfii_softc *); 445 446 static void mfii_start(struct mfii_softc *, struct mfii_ccb *); 447 static void mfii_start64(struct mfii_softc *, struct mfii_ccb *); 448 static void mfii_start_common(struct mfii_softc *, 449 struct mfii_ccb *, bool); 450 static void mfii_done(struct mfii_softc *, struct mfii_ccb *); 451 static int mfii_poll(struct mfii_softc *, struct mfii_ccb *); 452 static void mfii_poll_done(struct mfii_softc *, struct mfii_ccb *); 453 static int mfii_exec(struct mfii_softc *, struct mfii_ccb *); 454 static void mfii_exec_done(struct mfii_softc *, struct mfii_ccb *); 455 static int mfii_my_intr(struct mfii_softc *); 456 static int mfii_intr(void *); 457 static void mfii_postq(struct mfii_softc *); 458 459 static int mfii_load_ccb(struct mfii_softc *, struct mfii_ccb *, 460 void *, int); 461 static int mfii_load_mfa(struct mfii_softc *, struct mfii_ccb *, 462 void *, int); 463 464 static int mfii_mfa_poll(struct mfii_softc *, struct mfii_ccb *); 465 466 static int mfii_mgmt(struct mfii_softc *, uint32_t, 467 const union mfi_mbox *, void *, size_t, 468 mfii_direction_t, bool); 469 static int mfii_do_mgmt(struct mfii_softc *, struct mfii_ccb *, 470 uint32_t, const union mfi_mbox *, void *, size_t, 471 mfii_direction_t, bool); 472 static void mfii_empty_done(struct mfii_softc *, struct mfii_ccb *); 473 474 static int mfii_scsi_cmd_io(struct mfii_softc *, 475 struct mfii_ccb *, struct scsipi_xfer *); 476 static int mfii_scsi_cmd_cdb(struct mfii_softc *, 477 struct mfii_ccb *, struct scsipi_xfer *); 478 static void mfii_scsi_cmd_tmo(void *); 479 480 static void mfii_abort_task(struct work *, void *); 481 static void mfii_abort(struct mfii_softc *, struct mfii_ccb *, 482 uint16_t, uint16_t, uint8_t, uint32_t); 483 static void mfii_scsi_cmd_abort_done(struct mfii_softc *, 484 struct mfii_ccb *); 485 486 static int mfii_aen_register(struct mfii_softc *); 487 static void mfii_aen_start(struct mfii_softc *, struct mfii_ccb *, 488 struct mfii_dmamem *, uint32_t); 489 static void mfii_aen_done(struct mfii_softc *, struct mfii_ccb *); 490 static void mfii_aen(struct work *, void *); 491 static void mfii_aen_unregister(struct mfii_softc *); 492 493 static void mfii_aen_pd_insert(struct mfii_softc *, 494 const struct mfi_evtarg_pd_address *); 495 static void mfii_aen_pd_remove(struct mfii_softc *, 496 const struct mfi_evtarg_pd_address *); 497 static void mfii_aen_pd_state_change(struct mfii_softc *, 498 const struct mfi_evtarg_pd_state *); 499 static void mfii_aen_ld_update(struct mfii_softc *); 500 501 #if NBIO > 0 502 static int mfii_ioctl(device_t, u_long, void *); 503 static int mfii_ioctl_inq(struct mfii_softc *, struct bioc_inq *); 504 static int mfii_ioctl_vol(struct mfii_softc *, struct bioc_vol *); 505 static int mfii_ioctl_disk(struct mfii_softc *, struct bioc_disk *); 506 static int mfii_ioctl_alarm(struct mfii_softc *, struct bioc_alarm *); 507 static int mfii_ioctl_blink(struct mfii_softc *sc, struct bioc_blink *); 508 static int mfii_ioctl_setstate(struct mfii_softc *, 509 struct bioc_setstate *); 510 static int mfii_bio_hs(struct mfii_softc *, int, int, void *); 511 static int mfii_bio_getitall(struct mfii_softc *); 512 #endif /* NBIO > 0 */ 513 514 #if 0 515 static const char *mfi_bbu_indicators[] = { 516 "pack missing", 517 "voltage low", 518 "temp high", 519 "charge active", 520 "discharge active", 521 "learn cycle req'd", 522 "learn cycle active", 523 "learn cycle failed", 524 "learn cycle timeout", 525 "I2C errors", 526 "replace pack", 527 "low capacity", 528 "periodic learn req'd" 529 }; 530 #endif 531 532 static void mfii_init_ld_sensor(struct mfii_softc *, envsys_data_t *, int); 533 static void mfii_refresh_ld_sensor(struct mfii_softc *, envsys_data_t *); 534 static void mfii_attach_sensor(struct mfii_softc *, envsys_data_t *); 535 static int mfii_create_sensors(struct mfii_softc *); 536 static int mfii_destroy_sensors(struct mfii_softc *); 537 static void mfii_refresh_sensor(struct sysmon_envsys *, envsys_data_t *); 538 static void mfii_bbu(struct mfii_softc *, envsys_data_t *); 539 540 /* 541 * mfii boards support asynchronous (and non-polled) completion of 542 * dcmds by proxying them through a passthru mpii command that points 543 * at a dcmd frame. since the passthru command is submitted like 544 * the scsi commands using an SMID in the request descriptor, 545 * ccb_request memory * must contain the passthru command because 546 * that is what the SMID refers to. this means ccb_request cannot 547 * contain the dcmd. rather than allocating separate dma memory to 548 * hold the dcmd, we reuse the sense memory buffer for it. 549 */ 550 551 static void mfii_dcmd_start(struct mfii_softc *, struct mfii_ccb *); 552 553 static inline void 554 mfii_dcmd_scrub(struct mfii_ccb *ccb) 555 { 556 memset(ccb->ccb_sense, 0, sizeof(*ccb->ccb_sense)); 557 } 558 559 static inline struct mfi_dcmd_frame * 560 mfii_dcmd_frame(struct mfii_ccb *ccb) 561 { 562 CTASSERT(sizeof(struct mfi_dcmd_frame) <= sizeof(*ccb->ccb_sense)); 563 return ((struct mfi_dcmd_frame *)ccb->ccb_sense); 564 } 565 566 static inline void 567 mfii_dcmd_sync(struct mfii_softc *sc, struct mfii_ccb *ccb, int flags) 568 { 569 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_sense), 570 ccb->ccb_sense_offset, sizeof(*ccb->ccb_sense), flags); 571 } 572 573 #define mfii_fw_state(_sc) mfii_read((_sc), MFI_OSP) 574 575 static const struct mfii_iop mfii_iop_thunderbolt = { 576 MFII_BAR, 577 MFII_IOP_NUM_SGE_LOC_ORIG, 578 0, 579 MFII_REQ_TYPE_LDIO, 580 0, 581 MFII_SGE_CHAIN_ELEMENT | MFII_SGE_ADDR_IOCPLBNTA, 582 0, 583 0 584 }; 585 586 /* 587 * a lot of these values depend on us not implementing fastpath yet. 588 */ 589 static const struct mfii_iop mfii_iop_25 = { 590 MFII_BAR, 591 MFII_IOP_NUM_SGE_LOC_ORIG, 592 MFII_RAID_CTX_RL_FLAGS_CPU0, /* | MFII_RAID_CTX_RL_FLAGS_SEQNO_EN */ 593 MFII_REQ_TYPE_NO_LOCK, 594 MFII_RAID_CTX_TYPE_CUDA | 0x1, 595 MFII_SGE_CHAIN_ELEMENT, 596 MFII_SGE_END_OF_LIST, 597 0 598 }; 599 600 static const struct mfii_iop mfii_iop_35 = { 601 MFII_BAR_35, 602 MFII_IOP_NUM_SGE_LOC_35, 603 MFII_RAID_CTX_ROUTING_FLAGS_CPU0, /* | MFII_RAID_CTX_ROUTING_FLAGS_SQN */ 604 MFII_REQ_TYPE_NO_LOCK, 605 MFII_RAID_CTX_TYPE_CUDA | 0x1, 606 MFII_SGE_CHAIN_ELEMENT, 607 MFII_SGE_END_OF_LIST, 608 0 609 }; 610 611 static const struct mfii_iop mfii_iop_aero = { 612 MFII_BAR_35, 613 MFII_IOP_NUM_SGE_LOC_35, 614 MFII_RAID_CTX_ROUTING_FLAGS_CPU0, /* | MFII_RAID_CTX_ROUTING_FLAGS_SQN */ 615 MFII_REQ_TYPE_NO_LOCK, 616 MFII_RAID_CTX_TYPE_CUDA | 0x1, 617 MFII_SGE_CHAIN_ELEMENT, 618 MFII_SGE_END_OF_LIST, 619 MFII_IOP_QUIRK_REGREAD | MFII_IOP_HAS_32BITDESC_BIT 620 }; 621 622 struct mfii_device { 623 pcireg_t mpd_vendor; 624 pcireg_t mpd_product; 625 const struct mfii_iop *mpd_iop; 626 }; 627 628 static const struct mfii_device mfii_devices[] = { 629 /* Fusion */ 630 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_2208, 631 &mfii_iop_thunderbolt }, 632 /* Fury */ 633 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3008, 634 &mfii_iop_25 }, 635 /* Invader */ 636 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3108, 637 &mfii_iop_25 }, 638 /* Intruder */ 639 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3316, 640 &mfii_iop_25 }, 641 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3324, 642 &mfii_iop_25 }, 643 /* Cutlass */ 644 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_32XX_1, 645 &mfii_iop_25 }, 646 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_32XX_2, 647 &mfii_iop_25 }, 648 /* Crusader */ 649 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3404, 650 &mfii_iop_35 }, 651 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3416, 652 &mfii_iop_35 }, 653 /* Ventura */ 654 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3504, 655 &mfii_iop_35 }, 656 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3516, 657 &mfii_iop_35 }, 658 /* Tomcat */ 659 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3408, 660 &mfii_iop_35 }, 661 /* Harpoon */ 662 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_3508, 663 &mfii_iop_35 }, 664 /* Aero */ 665 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_39XX_2, 666 &mfii_iop_aero }, 667 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_39XX_3, 668 &mfii_iop_aero }, 669 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_38XX_2, 670 &mfii_iop_aero }, 671 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_38XX_3, 672 &mfii_iop_aero } 673 }; 674 675 static const struct mfii_iop *mfii_find_iop(struct pci_attach_args *); 676 677 static const struct mfii_iop * 678 mfii_find_iop(struct pci_attach_args *pa) 679 { 680 const struct mfii_device *mpd; 681 int i; 682 683 for (i = 0; i < __arraycount(mfii_devices); i++) { 684 mpd = &mfii_devices[i]; 685 686 if (mpd->mpd_vendor == PCI_VENDOR(pa->pa_id) && 687 mpd->mpd_product == PCI_PRODUCT(pa->pa_id)) 688 return (mpd->mpd_iop); 689 } 690 691 return (NULL); 692 } 693 694 static int 695 mfii_match(device_t parent, cfdata_t match, void *aux) 696 { 697 return ((mfii_find_iop(aux) != NULL) ? 2 : 0); 698 } 699 700 static void 701 mfii_attach(device_t parent, device_t self, void *aux) 702 { 703 struct mfii_softc *sc = device_private(self); 704 struct pci_attach_args *pa = aux; 705 pcireg_t memtype; 706 pci_intr_handle_t *ihp; 707 char intrbuf[PCI_INTRSTR_LEN]; 708 const char *intrstr; 709 u_int32_t status, scpad2, scpad3; 710 int chain_frame_sz, nsge_in_io, nsge_in_chain, i; 711 struct scsipi_adapter *adapt = &sc->sc_adapt; 712 struct scsipi_channel *chan = &sc->sc_chan; 713 union mfi_mbox mbox; 714 715 /* init sc */ 716 sc->sc_dev = self; 717 sc->sc_iop = mfii_find_iop(aux); 718 sc->sc_dmat = pa->pa_dmat; 719 if (pci_dma64_available(pa)) { 720 sc->sc_dmat64 = pa->pa_dmat64; 721 sc->sc_64bit_dma = 1; 722 } else { 723 sc->sc_dmat64 = pa->pa_dmat; 724 sc->sc_64bit_dma = 0; 725 } 726 SIMPLEQ_INIT(&sc->sc_ccb_freeq); 727 mutex_init(&sc->sc_ccb_mtx, MUTEX_DEFAULT, IPL_BIO); 728 mutex_init(&sc->sc_post_mtx, MUTEX_DEFAULT, IPL_BIO); 729 mutex_init(&sc->sc_reply_postq_mtx, MUTEX_DEFAULT, IPL_BIO); 730 731 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 732 733 sc->sc_aen_ccb = NULL; 734 snprintf(intrbuf, sizeof(intrbuf) - 1, "%saen", device_xname(self)); 735 workqueue_create(&sc->sc_aen_wq, intrbuf, mfii_aen, sc, 736 PRI_BIO, IPL_BIO, WQ_MPSAFE); 737 738 snprintf(intrbuf, sizeof(intrbuf) - 1, "%sabrt", device_xname(self)); 739 workqueue_create(&sc->sc_abort_wq, intrbuf, mfii_abort_task, 740 sc, PRI_BIO, IPL_BIO, WQ_MPSAFE); 741 742 mutex_init(&sc->sc_abort_mtx, MUTEX_DEFAULT, IPL_BIO); 743 SIMPLEQ_INIT(&sc->sc_abort_list); 744 745 /* wire up the bus shizz */ 746 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, sc->sc_iop->bar); 747 memtype |= PCI_MAPREG_MEM_TYPE_32BIT; 748 if (pci_mapreg_map(pa, sc->sc_iop->bar, memtype, 0, 749 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) { 750 aprint_error(": unable to map registers\n"); 751 return; 752 } 753 754 /* disable interrupts */ 755 mfii_write(sc, MFI_OMSK, 0xffffffff); 756 757 if (pci_intr_alloc(pa, &ihp, NULL, 0)) { 758 aprint_error(": unable to map interrupt\n"); 759 goto pci_unmap; 760 } 761 intrstr = pci_intr_string(pa->pa_pc, ihp[0], intrbuf, sizeof(intrbuf)); 762 pci_intr_setattr(pa->pa_pc, &ihp[0], PCI_INTR_MPSAFE, true); 763 764 /* lets get started */ 765 if (mfii_transition_firmware(sc)) 766 goto pci_unmap; 767 sc->sc_running = true; 768 769 /* determine max_cmds (refer to the Linux megaraid_sas driver) */ 770 scpad3 = mfii_read(sc, MFII_OSP3); 771 status = mfii_fw_state(sc); 772 sc->sc_max_fw_cmds = scpad3 & MFI_STATE_MAXCMD_MASK; 773 if (sc->sc_max_fw_cmds == 0) 774 sc->sc_max_fw_cmds = status & MFI_STATE_MAXCMD_MASK; 775 /* 776 * reduce max_cmds by 1 to ensure that the reply queue depth does not 777 * exceed FW supplied max_fw_cmds. 778 */ 779 sc->sc_max_cmds = uimin(sc->sc_max_fw_cmds, 1024) - 1; 780 781 /* determine max_sgl (refer to the Linux megaraid_sas driver) */ 782 scpad2 = mfii_read(sc, MFII_OSP2); 783 chain_frame_sz = 784 ((scpad2 & MFII_MAX_CHAIN_MASK) >> MFII_MAX_CHAIN_SHIFT) * 785 ((scpad2 & MFII_MAX_CHAIN_UNIT) ? MFII_1MB_IO : MFII_256K_IO); 786 if (chain_frame_sz < MFII_CHAIN_FRAME_MIN) 787 chain_frame_sz = MFII_CHAIN_FRAME_MIN; 788 789 nsge_in_io = (MFII_REQUEST_SIZE - 790 sizeof(struct mpii_msg_scsi_io) - 791 sizeof(struct mfii_raid_context)) / sizeof(struct mfii_sge); 792 nsge_in_chain = chain_frame_sz / sizeof(struct mfii_sge); 793 794 /* round down to nearest power of two */ 795 sc->sc_max_sgl = 1; 796 while ((sc->sc_max_sgl << 1) <= (nsge_in_io + nsge_in_chain)) 797 sc->sc_max_sgl <<= 1; 798 799 /* Check for atomic(32bit) descriptor */ 800 if (((sc->sc_iop->iop_flag & MFII_IOP_HAS_32BITDESC_BIT) != 0) && 801 ((scpad2 & MFI_STATE_ATOMIC_DESCRIPTOR) != 0)) 802 sc->sc_iop_flag |= MFII_IOP_DESC_32BIT; 803 804 DNPRINTF(MFII_D_MISC, "%s: OSP 0x%08x, OSP2 0x%08x, OSP3 0x%08x\n", 805 DEVNAME(sc), status, scpad2, scpad3); 806 DNPRINTF(MFII_D_MISC, "%s: max_fw_cmds %d, max_cmds %d\n", 807 DEVNAME(sc), sc->sc_max_fw_cmds, sc->sc_max_cmds); 808 DNPRINTF(MFII_D_MISC, "%s: nsge_in_io %d, nsge_in_chain %d, " 809 "max_sgl %d\n", DEVNAME(sc), nsge_in_io, nsge_in_chain, 810 sc->sc_max_sgl); 811 812 /* sense memory */ 813 CTASSERT(sizeof(struct mfi_sense) == MFI_SENSE_SIZE); 814 sc->sc_sense = mfii_dmamem_alloc(sc, sc->sc_max_cmds * MFI_SENSE_SIZE); 815 if (sc->sc_sense == NULL) { 816 aprint_error(": unable to allocate sense memory\n"); 817 goto pci_unmap; 818 } 819 820 /* reply post queue */ 821 sc->sc_reply_postq_depth = roundup(sc->sc_max_fw_cmds, 16); 822 823 sc->sc_reply_postq = mfii_dmamem_alloc(sc, 824 sc->sc_reply_postq_depth * sizeof(struct mpii_reply_descr)); 825 if (sc->sc_reply_postq == NULL) 826 goto free_sense; 827 828 memset(MFII_DMA_KVA(sc->sc_reply_postq), 0xff, 829 MFII_DMA_LEN(sc->sc_reply_postq)); 830 831 /* MPII request frame array */ 832 sc->sc_requests = mfii_dmamem_alloc(sc, 833 MFII_REQUEST_SIZE * (sc->sc_max_cmds + 1)); 834 if (sc->sc_requests == NULL) 835 goto free_reply_postq; 836 837 /* MFI command frame array */ 838 sc->sc_mfi = mfii_dmamem_alloc(sc, sc->sc_max_cmds * MFI_FRAME_SIZE); 839 if (sc->sc_mfi == NULL) 840 goto free_requests; 841 842 /* MPII SGL array */ 843 sc->sc_sgl = mfii_dmamem_alloc(sc, sc->sc_max_cmds * 844 sizeof(struct mfii_sge) * sc->sc_max_sgl); 845 if (sc->sc_sgl == NULL) 846 goto free_mfi; 847 848 if (mfii_init_ccb(sc) != 0) { 849 aprint_error(": could not init ccb list\n"); 850 goto free_sgl; 851 } 852 853 /* kickstart firmware with all addresses and pointers */ 854 if (mfii_initialise_firmware(sc) != 0) { 855 aprint_error(": could not initialize firmware\n"); 856 goto free_sgl; 857 } 858 859 mutex_enter(&sc->sc_lock); 860 if (mfii_get_info(sc) != 0) { 861 mutex_exit(&sc->sc_lock); 862 aprint_error(": could not retrieve controller information\n"); 863 goto free_sgl; 864 } 865 mutex_exit(&sc->sc_lock); 866 867 aprint_normal(": \"%s\", firmware %s", 868 sc->sc_info.mci_product_name, sc->sc_info.mci_package_version); 869 if (le16toh(sc->sc_info.mci_memory_size) > 0) { 870 aprint_normal(", %uMB cache", 871 le16toh(sc->sc_info.mci_memory_size)); 872 } 873 aprint_normal("\n"); 874 aprint_naive("\n"); 875 876 sc->sc_ih = pci_intr_establish_xname(sc->sc_pc, ihp[0], IPL_BIO, 877 mfii_intr, sc, DEVNAME(sc)); 878 if (sc->sc_ih == NULL) { 879 aprint_error_dev(self, "can't establish interrupt"); 880 if (intrstr) 881 aprint_error(" at %s", intrstr); 882 aprint_error("\n"); 883 goto free_sgl; 884 } 885 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 886 887 for (i = 0; i < sc->sc_info.mci_lds_present; i++) 888 sc->sc_ld[i].ld_present = 1; 889 890 sc->sc_max256vd = 891 (sc->sc_info.mci_adapter_ops3 & MFI_INFO_AOPS3_SUPP_MAX_EXT_LDS) ? 892 true : false; 893 894 if (sc->sc_max256vd) 895 aprint_verbose_dev(self, "Max 256 VD support\n"); 896 897 memset(adapt, 0, sizeof(*adapt)); 898 adapt->adapt_dev = sc->sc_dev; 899 adapt->adapt_nchannels = 1; 900 /* keep a few commands for management */ 901 if (sc->sc_max_cmds > 4) 902 adapt->adapt_openings = sc->sc_max_cmds - 4; 903 else 904 adapt->adapt_openings = sc->sc_max_cmds; 905 adapt->adapt_max_periph = adapt->adapt_openings; 906 adapt->adapt_request = mfii_scsipi_request; 907 adapt->adapt_minphys = minphys; 908 adapt->adapt_flags = SCSIPI_ADAPT_MPSAFE; 909 910 memset(chan, 0, sizeof(*chan)); 911 chan->chan_adapter = adapt; 912 chan->chan_bustype = &scsi_sas_bustype; 913 chan->chan_channel = 0; 914 chan->chan_flags = 0; 915 chan->chan_nluns = 8; 916 chan->chan_ntargets = sc->sc_info.mci_max_lds; 917 chan->chan_id = sc->sc_info.mci_max_lds; 918 919 mfii_rescan(sc->sc_dev, NULL, NULL); 920 921 if (mfii_aen_register(sc) != 0) { 922 /* error printed by mfii_aen_register */ 923 goto intr_disestablish; 924 } 925 926 memset(&mbox, 0, sizeof(mbox)); 927 if (sc->sc_max256vd) 928 mbox.b[0] = 1; 929 mutex_enter(&sc->sc_lock); 930 if (mfii_mgmt(sc, MR_DCMD_LD_GET_LIST, &mbox, &sc->sc_ld_list, 931 sizeof(sc->sc_ld_list), MFII_DATA_IN, true) != 0) { 932 mutex_exit(&sc->sc_lock); 933 aprint_error_dev(self, 934 "getting list of logical disks failed\n"); 935 goto intr_disestablish; 936 } 937 mutex_exit(&sc->sc_lock); 938 memset(sc->sc_target_lds, -1, sizeof(sc->sc_target_lds)); 939 for (i = 0; i < sc->sc_ld_list.mll_no_ld; i++) { 940 int target = sc->sc_ld_list.mll_list[i].mll_ld.mld_target; 941 sc->sc_target_lds[target] = i; 942 sc->sc_ld[i].ld_target_id = target; 943 } 944 945 /* enable interrupts */ 946 mfii_write(sc, MFI_OSTS, 0xffffffff); 947 mfii_write(sc, MFI_OMSK, ~MFII_OSTS_INTR_VALID); 948 949 #if NBIO > 0 950 if (bio_register(sc->sc_dev, mfii_ioctl) != 0) 951 panic("%s: controller registration failed", DEVNAME(sc)); 952 #endif /* NBIO > 0 */ 953 954 if (mfii_create_sensors(sc) != 0) 955 aprint_error_dev(self, "unable to create sensors\n"); 956 957 if (!pmf_device_register1(sc->sc_dev, mfii_suspend, mfii_resume, 958 mfii_shutdown)) 959 aprint_error_dev(self, "couldn't establish power handler\n"); 960 return; 961 intr_disestablish: 962 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 963 free_sgl: 964 mfii_dmamem_free(sc, sc->sc_sgl); 965 free_mfi: 966 mfii_dmamem_free(sc, sc->sc_mfi); 967 free_requests: 968 mfii_dmamem_free(sc, sc->sc_requests); 969 free_reply_postq: 970 mfii_dmamem_free(sc, sc->sc_reply_postq); 971 free_sense: 972 mfii_dmamem_free(sc, sc->sc_sense); 973 pci_unmap: 974 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 975 } 976 977 #if 0 978 struct srp_gc mfii_dev_handles_gc = 979 SRP_GC_INITIALIZER(mfii_dev_handles_dtor, NULL); 980 981 static inline uint16_t 982 mfii_dev_handle(struct mfii_softc *sc, uint16_t target) 983 { 984 struct srp_ref sr; 985 uint16_t *map, handle; 986 987 map = srp_enter(&sr, &sc->sc_pd->pd_dev_handles); 988 handle = map[target]; 989 srp_leave(&sr); 990 991 return (handle); 992 } 993 994 static int 995 mfii_dev_handles_update(struct mfii_softc *sc) 996 { 997 struct mfii_ld_map *lm; 998 uint16_t *dev_handles = NULL; 999 int i; 1000 int rv = 0; 1001 1002 lm = malloc(sizeof(*lm), M_TEMP, M_WAITOK|M_ZERO); 1003 1004 rv = mfii_mgmt(sc, MR_DCMD_LD_MAP_GET_INFO, NULL, lm, sizeof(*lm), 1005 MFII_DATA_IN, false); 1006 1007 if (rv != 0) { 1008 rv = EIO; 1009 goto free_lm; 1010 } 1011 1012 dev_handles = mallocarray(MFI_MAX_PD, sizeof(*dev_handles), 1013 M_DEVBUF, M_WAITOK); 1014 1015 for (i = 0; i < MFI_MAX_PD; i++) 1016 dev_handles[i] = lm->mlm_dev_handle[i].mdh_cur_handle; 1017 1018 /* commit the updated info */ 1019 sc->sc_pd->pd_timeout = lm->mlm_pd_timeout; 1020 srp_update_locked(&mfii_dev_handles_gc, 1021 &sc->sc_pd->pd_dev_handles, dev_handles); 1022 1023 free_lm: 1024 free(lm, M_TEMP, sizeof(*lm)); 1025 1026 return (rv); 1027 } 1028 1029 static void 1030 mfii_dev_handles_dtor(void *null, void *v) 1031 { 1032 uint16_t *dev_handles = v; 1033 1034 free(dev_handles, M_DEVBUF, sizeof(*dev_handles) * MFI_MAX_PD); 1035 } 1036 #endif /* 0 */ 1037 1038 static int 1039 mfii_detach(device_t self, int flags) 1040 { 1041 struct mfii_softc *sc = device_private(self); 1042 int error; 1043 1044 if (sc->sc_ih == NULL) 1045 return (0); 1046 1047 if ((error = config_detach_children(sc->sc_dev, flags)) != 0) 1048 return error; 1049 1050 mfii_destroy_sensors(sc); 1051 #if NBIO > 0 1052 bio_unregister(sc->sc_dev); 1053 #endif 1054 mfii_shutdown(sc->sc_dev, 0); 1055 mfii_write(sc, MFI_OMSK, 0xffffffff); 1056 1057 mfii_aen_unregister(sc); 1058 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 1059 mfii_dmamem_free(sc, sc->sc_sgl); 1060 mfii_dmamem_free(sc, sc->sc_mfi); 1061 mfii_dmamem_free(sc, sc->sc_requests); 1062 mfii_dmamem_free(sc, sc->sc_reply_postq); 1063 mfii_dmamem_free(sc, sc->sc_sense); 1064 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 1065 1066 return (0); 1067 } 1068 1069 static int 1070 mfii_rescan(device_t self, const char *ifattr, const int *locators) 1071 { 1072 struct mfii_softc *sc = device_private(self); 1073 1074 if (sc->sc_child != NULL) 1075 return 0; 1076 1077 sc->sc_child = config_found(self, &sc->sc_chan, scsiprint, 1078 CFARGS_NONE); 1079 return 0; 1080 } 1081 1082 static void 1083 mfii_childdetached(device_t self, device_t child) 1084 { 1085 struct mfii_softc *sc = device_private(self); 1086 1087 KASSERT(self == sc->sc_dev); 1088 KASSERT(child == sc->sc_child); 1089 1090 if (child == sc->sc_child) 1091 sc->sc_child = NULL; 1092 } 1093 1094 static bool 1095 mfii_suspend(device_t dev, const pmf_qual_t *q) 1096 { 1097 /* XXX to be implemented */ 1098 return false; 1099 } 1100 1101 static bool 1102 mfii_resume(device_t dev, const pmf_qual_t *q) 1103 { 1104 /* XXX to be implemented */ 1105 return false; 1106 } 1107 1108 static bool 1109 mfii_shutdown(device_t dev, int how) 1110 { 1111 struct mfii_softc *sc = device_private(dev); 1112 struct mfii_ccb *ccb; 1113 union mfi_mbox mbox; 1114 bool rv = true; 1115 1116 memset(&mbox, 0, sizeof(mbox)); 1117 1118 mutex_enter(&sc->sc_lock); 1119 DNPRINTF(MFII_D_MISC, "%s: mfii_shutdown\n", DEVNAME(sc)); 1120 ccb = mfii_get_ccb(sc); 1121 if (ccb == NULL) 1122 return false; 1123 mutex_enter(&sc->sc_ccb_mtx); 1124 if (sc->sc_running) { 1125 sc->sc_running = 0; /* prevent new commands */ 1126 mutex_exit(&sc->sc_ccb_mtx); 1127 #if 0 /* XXX why does this hang ? */ 1128 mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 1129 mfii_scrub_ccb(ccb); 1130 if (mfii_do_mgmt(sc, ccb, MR_DCMD_CTRL_CACHE_FLUSH, &mbox, 1131 NULL, 0, MFII_DATA_NONE, true)) { 1132 aprint_error_dev(dev, 1133 "shutdown: cache flush failed\n"); 1134 rv = false; 1135 goto fail; 1136 } 1137 printf("ok1\n"); 1138 #endif 1139 mbox.b[0] = 0; 1140 mfii_scrub_ccb(ccb); 1141 if (mfii_do_mgmt(sc, ccb, MR_DCMD_CTRL_SHUTDOWN, &mbox, 1142 NULL, 0, MFII_DATA_NONE, true)) { 1143 aprint_error_dev(dev, "shutdown: " 1144 "firmware shutdown failed\n"); 1145 rv = false; 1146 goto fail; 1147 } 1148 } else { 1149 mutex_exit(&sc->sc_ccb_mtx); 1150 } 1151 fail: 1152 mfii_put_ccb(sc, ccb); 1153 mutex_exit(&sc->sc_lock); 1154 return rv; 1155 } 1156 1157 /* Register read function without retry */ 1158 static inline u_int32_t 1159 mfii_read_wor(struct mfii_softc *sc, bus_size_t r) 1160 { 1161 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1162 BUS_SPACE_BARRIER_READ); 1163 return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, r)); 1164 } 1165 1166 static u_int32_t 1167 mfii_read(struct mfii_softc *sc, bus_size_t r) 1168 { 1169 uint32_t rv; 1170 int i = 0; 1171 1172 if ((sc->sc_iop->iop_flag & MFII_IOP_QUIRK_REGREAD) != 0) { 1173 do { 1174 rv = mfii_read_wor(sc, r); 1175 i++; 1176 } while ((rv == 0) && (i < 3)); 1177 } else 1178 rv = mfii_read_wor(sc, r); 1179 1180 return rv; 1181 } 1182 1183 static void 1184 mfii_write(struct mfii_softc *sc, bus_size_t r, u_int32_t v) 1185 { 1186 bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v); 1187 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1188 BUS_SPACE_BARRIER_WRITE); 1189 } 1190 1191 static struct mfii_dmamem * 1192 mfii_dmamem_alloc(struct mfii_softc *sc, size_t size) 1193 { 1194 struct mfii_dmamem *m; 1195 int nsegs; 1196 1197 m = malloc(sizeof(*m), M_DEVBUF, M_WAITOK | M_ZERO); 1198 m->mdm_size = size; 1199 1200 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 1201 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &m->mdm_map) != 0) 1202 goto mdmfree; 1203 1204 if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &m->mdm_seg, 1, 1205 &nsegs, BUS_DMA_NOWAIT) != 0) 1206 goto destroy; 1207 1208 if (bus_dmamem_map(sc->sc_dmat, &m->mdm_seg, nsegs, size, &m->mdm_kva, 1209 BUS_DMA_NOWAIT) != 0) 1210 goto free; 1211 1212 if (bus_dmamap_load(sc->sc_dmat, m->mdm_map, m->mdm_kva, size, NULL, 1213 BUS_DMA_NOWAIT) != 0) 1214 goto unmap; 1215 1216 memset(m->mdm_kva, 0, size); 1217 return (m); 1218 1219 unmap: 1220 bus_dmamem_unmap(sc->sc_dmat, m->mdm_kva, m->mdm_size); 1221 free: 1222 bus_dmamem_free(sc->sc_dmat, &m->mdm_seg, 1); 1223 destroy: 1224 bus_dmamap_destroy(sc->sc_dmat, m->mdm_map); 1225 mdmfree: 1226 free(m, M_DEVBUF); 1227 1228 return (NULL); 1229 } 1230 1231 static void 1232 mfii_dmamem_free(struct mfii_softc *sc, struct mfii_dmamem *m) 1233 { 1234 bus_dmamap_unload(sc->sc_dmat, m->mdm_map); 1235 bus_dmamem_unmap(sc->sc_dmat, m->mdm_kva, m->mdm_size); 1236 bus_dmamem_free(sc->sc_dmat, &m->mdm_seg, 1); 1237 bus_dmamap_destroy(sc->sc_dmat, m->mdm_map); 1238 free(m, M_DEVBUF); 1239 } 1240 1241 static void 1242 mfii_dcmd_start(struct mfii_softc *sc, struct mfii_ccb *ccb) 1243 { 1244 struct mpii_msg_scsi_io *io = ccb->ccb_request; 1245 struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1); 1246 struct mfii_sge *sge = (struct mfii_sge *)(ctx + 1); 1247 1248 io->function = MFII_FUNCTION_PASSTHRU_IO; 1249 io->sgl_offset0 = (uint32_t *)sge - (uint32_t *)io; 1250 io->chain_offset = io->sgl_offset0 / 4; 1251 1252 sge->sg_addr = htole64(ccb->ccb_sense_dva); 1253 sge->sg_len = htole32(sizeof(*ccb->ccb_sense)); 1254 sge->sg_flags = MFII_SGE_CHAIN_ELEMENT | MFII_SGE_ADDR_IOCPLBNTA; 1255 1256 ccb->ccb_req.flags = MFII_REQ_TYPE_SCSI; 1257 ccb->ccb_req.smid = le16toh(ccb->ccb_smid); 1258 1259 mfii_start(sc, ccb); 1260 } 1261 1262 static int 1263 mfii_aen_register(struct mfii_softc *sc) 1264 { 1265 struct mfi_evt_log_info mel; 1266 struct mfii_ccb *ccb; 1267 struct mfii_dmamem *mdm; 1268 int rv; 1269 1270 ccb = mfii_get_ccb(sc); 1271 if (ccb == NULL) { 1272 printf("%s: unable to allocate ccb for aen\n", DEVNAME(sc)); 1273 return (ENOMEM); 1274 } 1275 1276 memset(&mel, 0, sizeof(mel)); 1277 mfii_scrub_ccb(ccb); 1278 1279 rv = mfii_do_mgmt(sc, ccb, MR_DCMD_CTRL_EVENT_GET_INFO, NULL, 1280 &mel, sizeof(mel), MFII_DATA_IN, true); 1281 if (rv != 0) { 1282 mfii_put_ccb(sc, ccb); 1283 aprint_error_dev(sc->sc_dev, "unable to get event info\n"); 1284 return (EIO); 1285 } 1286 1287 mdm = mfii_dmamem_alloc(sc, sizeof(struct mfi_evt_detail)); 1288 if (mdm == NULL) { 1289 mfii_put_ccb(sc, ccb); 1290 aprint_error_dev(sc->sc_dev, 1291 "unable to allocate event data\n"); 1292 return (ENOMEM); 1293 } 1294 1295 /* replay all the events from boot */ 1296 mfii_aen_start(sc, ccb, mdm, le32toh(mel.mel_boot_seq_num)); 1297 1298 return (0); 1299 } 1300 1301 static void 1302 mfii_aen_start(struct mfii_softc *sc, struct mfii_ccb *ccb, 1303 struct mfii_dmamem *mdm, uint32_t seq) 1304 { 1305 struct mfi_dcmd_frame *dcmd = mfii_dcmd_frame(ccb); 1306 struct mfi_frame_header *hdr = &dcmd->mdf_header; 1307 union mfi_sgl *sgl = &dcmd->mdf_sgl; 1308 union mfi_evt_class_locale mec; 1309 1310 mfii_scrub_ccb(ccb); 1311 mfii_dcmd_scrub(ccb); 1312 memset(MFII_DMA_KVA(mdm), 0, MFII_DMA_LEN(mdm)); 1313 1314 ccb->ccb_cookie = mdm; 1315 ccb->ccb_done = mfii_aen_done; 1316 sc->sc_aen_ccb = ccb; 1317 1318 mec.mec_members.class = MFI_EVT_CLASS_DEBUG; 1319 mec.mec_members.reserved = 0; 1320 mec.mec_members.locale = htole16(MFI_EVT_LOCALE_ALL); 1321 1322 hdr->mfh_cmd = MFI_CMD_DCMD; 1323 hdr->mfh_sg_count = 1; 1324 hdr->mfh_flags = htole16(MFI_FRAME_DIR_READ | MFI_FRAME_SGL64); 1325 hdr->mfh_data_len = htole32(MFII_DMA_LEN(mdm)); 1326 dcmd->mdf_opcode = htole32(MR_DCMD_CTRL_EVENT_WAIT); 1327 dcmd->mdf_mbox.w[0] = htole32(seq); 1328 dcmd->mdf_mbox.w[1] = htole32(mec.mec_word); 1329 sgl->sg64[0].addr = htole64(MFII_DMA_DVA(mdm)); 1330 sgl->sg64[0].len = htole32(MFII_DMA_LEN(mdm)); 1331 1332 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(mdm), 1333 0, MFII_DMA_LEN(mdm), BUS_DMASYNC_PREREAD); 1334 1335 mfii_dcmd_sync(sc, ccb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1336 mfii_dcmd_start(sc, ccb); 1337 } 1338 1339 static void 1340 mfii_aen_done(struct mfii_softc *sc, struct mfii_ccb *ccb) 1341 { 1342 KASSERT(sc->sc_aen_ccb == ccb); 1343 1344 /* 1345 * defer to a thread with KERNEL_LOCK so we can run autoconf 1346 * We shouldn't have more than one AEN command pending at a time, 1347 * so no need to lock 1348 */ 1349 if (sc->sc_running) 1350 workqueue_enqueue(sc->sc_aen_wq, &sc->sc_aen_work, NULL); 1351 } 1352 1353 static void 1354 mfii_aen(struct work *wk, void *arg) 1355 { 1356 struct mfii_softc *sc = arg; 1357 struct mfii_ccb *ccb = sc->sc_aen_ccb; 1358 struct mfii_dmamem *mdm = ccb->ccb_cookie; 1359 const struct mfi_evt_detail *med = MFII_DMA_KVA(mdm); 1360 1361 mfii_dcmd_sync(sc, ccb, 1362 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1363 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(mdm), 1364 0, MFII_DMA_LEN(mdm), BUS_DMASYNC_POSTREAD); 1365 1366 DNPRINTF(MFII_D_MISC, "%s: %u %08x %02x %s\n", DEVNAME(sc), 1367 le32toh(med->med_seq_num), le32toh(med->med_code), 1368 med->med_arg_type, med->med_description); 1369 1370 switch (le32toh(med->med_code)) { 1371 case MR_EVT_PD_INSERTED_EXT: 1372 if (med->med_arg_type != MR_EVT_ARGS_PD_ADDRESS) 1373 break; 1374 1375 mfii_aen_pd_insert(sc, &med->args.pd_address); 1376 break; 1377 case MR_EVT_PD_REMOVED_EXT: 1378 if (med->med_arg_type != MR_EVT_ARGS_PD_ADDRESS) 1379 break; 1380 1381 mfii_aen_pd_remove(sc, &med->args.pd_address); 1382 break; 1383 1384 case MR_EVT_PD_STATE_CHANGE: 1385 if (med->med_arg_type != MR_EVT_ARGS_PD_STATE) 1386 break; 1387 1388 mfii_aen_pd_state_change(sc, &med->args.pd_state); 1389 break; 1390 1391 case MR_EVT_LD_CREATED: 1392 case MR_EVT_LD_DELETED: 1393 mfii_aen_ld_update(sc); 1394 break; 1395 1396 default: 1397 break; 1398 } 1399 1400 mfii_aen_start(sc, ccb, mdm, le32toh(med->med_seq_num) + 1); 1401 } 1402 1403 static void 1404 mfii_aen_pd_insert(struct mfii_softc *sc, 1405 const struct mfi_evtarg_pd_address *pd) 1406 { 1407 printf("%s: physical disk inserted id %d enclosure %d\n", DEVNAME(sc), 1408 le16toh(pd->device_id), le16toh(pd->encl_id)); 1409 } 1410 1411 static void 1412 mfii_aen_pd_remove(struct mfii_softc *sc, 1413 const struct mfi_evtarg_pd_address *pd) 1414 { 1415 printf("%s: physical disk removed id %d enclosure %d\n", DEVNAME(sc), 1416 le16toh(pd->device_id), le16toh(pd->encl_id)); 1417 } 1418 1419 static void 1420 mfii_aen_pd_state_change(struct mfii_softc *sc, 1421 const struct mfi_evtarg_pd_state *state) 1422 { 1423 return; 1424 } 1425 1426 static void 1427 mfii_aen_ld_update(struct mfii_softc *sc) 1428 { 1429 union mfi_mbox mbox; 1430 int i, target, old, nld; 1431 int newlds[MFII_MAX_LD_EXT]; 1432 1433 memset(&mbox, 0, sizeof(mbox)); 1434 if (sc->sc_max256vd) 1435 mbox.b[0] = 1; 1436 mutex_enter(&sc->sc_lock); 1437 if (mfii_mgmt(sc, MR_DCMD_LD_GET_LIST, &mbox, &sc->sc_ld_list, 1438 sizeof(sc->sc_ld_list), MFII_DATA_IN, false) != 0) { 1439 mutex_exit(&sc->sc_lock); 1440 DNPRINTF(MFII_D_MISC, 1441 "%s: getting list of logical disks failed\n", DEVNAME(sc)); 1442 return; 1443 } 1444 mutex_exit(&sc->sc_lock); 1445 1446 memset(newlds, -1, sizeof(newlds)); 1447 1448 for (i = 0; i < sc->sc_ld_list.mll_no_ld; i++) { 1449 target = sc->sc_ld_list.mll_list[i].mll_ld.mld_target; 1450 DNPRINTF(MFII_D_MISC, "%s: target %d: state %d\n", 1451 DEVNAME(sc), target, sc->sc_ld_list.mll_list[i].mll_state); 1452 newlds[target] = i; 1453 sc->sc_ld[i].ld_target_id = target; 1454 } 1455 1456 for (i = 0; i < MFII_MAX_LD_EXT; i++) { 1457 old = sc->sc_target_lds[i]; 1458 nld = newlds[i]; 1459 1460 if (old == -1 && nld != -1) { 1461 printf("%s: logical drive %d added (target %d)\n", 1462 DEVNAME(sc), i, nld); 1463 1464 // XXX scsi_probe_target(sc->sc_scsibus, i); 1465 1466 mfii_init_ld_sensor(sc, &sc->sc_sensors[i], i); 1467 mfii_attach_sensor(sc, &sc->sc_sensors[i]); 1468 } else if (nld == -1 && old != -1) { 1469 printf("%s: logical drive %d removed (target %d)\n", 1470 DEVNAME(sc), i, old); 1471 1472 scsipi_target_detach(&sc->sc_chan, i, 0, DETACH_FORCE); 1473 sysmon_envsys_sensor_detach(sc->sc_sme, 1474 &sc->sc_sensors[i]); 1475 } 1476 } 1477 1478 memcpy(sc->sc_target_lds, newlds, sizeof(sc->sc_target_lds)); 1479 } 1480 1481 static void 1482 mfii_aen_unregister(struct mfii_softc *sc) 1483 { 1484 /* XXX */ 1485 } 1486 1487 static int 1488 mfii_transition_firmware(struct mfii_softc *sc) 1489 { 1490 int32_t fw_state, cur_state; 1491 int max_wait, i; 1492 1493 fw_state = mfii_fw_state(sc) & MFI_STATE_MASK; 1494 1495 while (fw_state != MFI_STATE_READY) { 1496 cur_state = fw_state; 1497 switch (fw_state) { 1498 case MFI_STATE_FAULT: 1499 printf("%s: firmware fault\n", DEVNAME(sc)); 1500 return (1); 1501 case MFI_STATE_WAIT_HANDSHAKE: 1502 mfii_write(sc, MFI_SKINNY_IDB, 1503 MFI_INIT_CLEAR_HANDSHAKE); 1504 max_wait = 2; 1505 break; 1506 case MFI_STATE_OPERATIONAL: 1507 mfii_write(sc, MFI_SKINNY_IDB, MFI_INIT_READY); 1508 max_wait = 10; 1509 break; 1510 case MFI_STATE_UNDEFINED: 1511 case MFI_STATE_BB_INIT: 1512 max_wait = 2; 1513 break; 1514 case MFI_STATE_FW_INIT: 1515 case MFI_STATE_DEVICE_SCAN: 1516 case MFI_STATE_FLUSH_CACHE: 1517 max_wait = 20; 1518 break; 1519 default: 1520 printf("%s: unknown firmware state %d\n", 1521 DEVNAME(sc), fw_state); 1522 return (1); 1523 } 1524 for (i = 0; i < (max_wait * 10); i++) { 1525 fw_state = mfii_fw_state(sc) & MFI_STATE_MASK; 1526 if (fw_state == cur_state) 1527 DELAY(100000); 1528 else 1529 break; 1530 } 1531 if (fw_state == cur_state) { 1532 printf("%s: firmware stuck in state %#x\n", 1533 DEVNAME(sc), fw_state); 1534 return (1); 1535 } 1536 } 1537 1538 return (0); 1539 } 1540 1541 static int 1542 mfii_get_info(struct mfii_softc *sc) 1543 { 1544 int i, rv; 1545 1546 rv = mfii_mgmt(sc, MR_DCMD_CTRL_GET_INFO, NULL, &sc->sc_info, 1547 sizeof(sc->sc_info), MFII_DATA_IN, true); 1548 1549 if (rv != 0) 1550 return (rv); 1551 1552 for (i = 0; i < sc->sc_info.mci_image_component_count; i++) { 1553 DPRINTF("%s: active FW %s Version %s date %s time %s\n", 1554 DEVNAME(sc), 1555 sc->sc_info.mci_image_component[i].mic_name, 1556 sc->sc_info.mci_image_component[i].mic_version, 1557 sc->sc_info.mci_image_component[i].mic_build_date, 1558 sc->sc_info.mci_image_component[i].mic_build_time); 1559 } 1560 1561 for (i = 0; i < sc->sc_info.mci_pending_image_component_count; i++) { 1562 DPRINTF("%s: pending FW %s Version %s date %s time %s\n", 1563 DEVNAME(sc), 1564 sc->sc_info.mci_pending_image_component[i].mic_name, 1565 sc->sc_info.mci_pending_image_component[i].mic_version, 1566 sc->sc_info.mci_pending_image_component[i].mic_build_date, 1567 sc->sc_info.mci_pending_image_component[i].mic_build_time); 1568 } 1569 1570 DPRINTF("%s: max_arms %d max_spans %d max_arrs %d max_lds %d name %s\n", 1571 DEVNAME(sc), 1572 sc->sc_info.mci_max_arms, 1573 sc->sc_info.mci_max_spans, 1574 sc->sc_info.mci_max_arrays, 1575 sc->sc_info.mci_max_lds, 1576 sc->sc_info.mci_product_name); 1577 1578 DPRINTF("%s: serial %s present %#x fw time %d max_cmds %d max_sg %d\n", 1579 DEVNAME(sc), 1580 sc->sc_info.mci_serial_number, 1581 sc->sc_info.mci_hw_present, 1582 sc->sc_info.mci_current_fw_time, 1583 sc->sc_info.mci_max_cmds, 1584 sc->sc_info.mci_max_sg_elements); 1585 1586 DPRINTF("%s: max_rq %d lds_pres %d lds_deg %d lds_off %d pd_pres %d\n", 1587 DEVNAME(sc), 1588 sc->sc_info.mci_max_request_size, 1589 sc->sc_info.mci_lds_present, 1590 sc->sc_info.mci_lds_degraded, 1591 sc->sc_info.mci_lds_offline, 1592 sc->sc_info.mci_pd_present); 1593 1594 DPRINTF("%s: pd_dsk_prs %d pd_dsk_pred_fail %d pd_dsk_fail %d\n", 1595 DEVNAME(sc), 1596 sc->sc_info.mci_pd_disks_present, 1597 sc->sc_info.mci_pd_disks_pred_failure, 1598 sc->sc_info.mci_pd_disks_failed); 1599 1600 DPRINTF("%s: nvram %d mem %d flash %d\n", 1601 DEVNAME(sc), 1602 sc->sc_info.mci_nvram_size, 1603 sc->sc_info.mci_memory_size, 1604 sc->sc_info.mci_flash_size); 1605 1606 DPRINTF("%s: ram_cor %d ram_uncor %d clus_all %d clus_act %d\n", 1607 DEVNAME(sc), 1608 sc->sc_info.mci_ram_correctable_errors, 1609 sc->sc_info.mci_ram_uncorrectable_errors, 1610 sc->sc_info.mci_cluster_allowed, 1611 sc->sc_info.mci_cluster_active); 1612 1613 DPRINTF("%s: max_strps_io %d raid_lvl %#x adapt_ops %#x ld_ops %#x\n", 1614 DEVNAME(sc), 1615 sc->sc_info.mci_max_strips_per_io, 1616 sc->sc_info.mci_raid_levels, 1617 sc->sc_info.mci_adapter_ops, 1618 sc->sc_info.mci_ld_ops); 1619 1620 DPRINTF("%s: strp_sz_min %d strp_sz_max %d pd_ops %#x pd_mix %#x\n", 1621 DEVNAME(sc), 1622 sc->sc_info.mci_stripe_sz_ops.min, 1623 sc->sc_info.mci_stripe_sz_ops.max, 1624 sc->sc_info.mci_pd_ops, 1625 sc->sc_info.mci_pd_mix_support); 1626 1627 DPRINTF("%s: ecc_bucket %d pckg_prop %s\n", 1628 DEVNAME(sc), 1629 sc->sc_info.mci_ecc_bucket_count, 1630 sc->sc_info.mci_package_version); 1631 1632 DPRINTF("%s: sq_nm %d prd_fail_poll %d intr_thrtl %d intr_thrtl_to %d\n", 1633 DEVNAME(sc), 1634 sc->sc_info.mci_properties.mcp_seq_num, 1635 sc->sc_info.mci_properties.mcp_pred_fail_poll_interval, 1636 sc->sc_info.mci_properties.mcp_intr_throttle_cnt, 1637 sc->sc_info.mci_properties.mcp_intr_throttle_timeout); 1638 1639 DPRINTF("%s: rbld_rate %d patr_rd_rate %d bgi_rate %d cc_rate %d\n", 1640 DEVNAME(sc), 1641 sc->sc_info.mci_properties.mcp_rebuild_rate, 1642 sc->sc_info.mci_properties.mcp_patrol_read_rate, 1643 sc->sc_info.mci_properties.mcp_bgi_rate, 1644 sc->sc_info.mci_properties.mcp_cc_rate); 1645 1646 DPRINTF("%s: rc_rate %d ch_flsh %d spin_cnt %d spin_dly %d clus_en %d\n", 1647 DEVNAME(sc), 1648 sc->sc_info.mci_properties.mcp_recon_rate, 1649 sc->sc_info.mci_properties.mcp_cache_flush_interval, 1650 sc->sc_info.mci_properties.mcp_spinup_drv_cnt, 1651 sc->sc_info.mci_properties.mcp_spinup_delay, 1652 sc->sc_info.mci_properties.mcp_cluster_enable); 1653 1654 DPRINTF("%s: coerc %d alarm %d dis_auto_rbld %d dis_bat_wrn %d ecc %d\n", 1655 DEVNAME(sc), 1656 sc->sc_info.mci_properties.mcp_coercion_mode, 1657 sc->sc_info.mci_properties.mcp_alarm_enable, 1658 sc->sc_info.mci_properties.mcp_disable_auto_rebuild, 1659 sc->sc_info.mci_properties.mcp_disable_battery_warn, 1660 sc->sc_info.mci_properties.mcp_ecc_bucket_size); 1661 1662 DPRINTF("%s: ecc_leak %d rest_hs %d exp_encl_dev %d\n", 1663 DEVNAME(sc), 1664 sc->sc_info.mci_properties.mcp_ecc_bucket_leak_rate, 1665 sc->sc_info.mci_properties.mcp_restore_hotspare_on_insertion, 1666 sc->sc_info.mci_properties.mcp_expose_encl_devices); 1667 1668 DPRINTF("%s: vendor %#x device %#x subvendor %#x subdevice %#x\n", 1669 DEVNAME(sc), 1670 sc->sc_info.mci_pci.mip_vendor, 1671 sc->sc_info.mci_pci.mip_device, 1672 sc->sc_info.mci_pci.mip_subvendor, 1673 sc->sc_info.mci_pci.mip_subdevice); 1674 1675 DPRINTF("%s: type %#x port_count %d port_addr ", 1676 DEVNAME(sc), 1677 sc->sc_info.mci_host.mih_type, 1678 sc->sc_info.mci_host.mih_port_count); 1679 1680 for (i = 0; i < 8; i++) 1681 DPRINTF("%.0" PRIx64 " ", 1682 sc->sc_info.mci_host.mih_port_addr[i]); 1683 DPRINTF("\n"); 1684 1685 DPRINTF("%s: type %.x port_count %d port_addr ", 1686 DEVNAME(sc), 1687 sc->sc_info.mci_device.mid_type, 1688 sc->sc_info.mci_device.mid_port_count); 1689 1690 for (i = 0; i < 8; i++) 1691 DPRINTF("%.0" PRIx64 " ", 1692 sc->sc_info.mci_device.mid_port_addr[i]); 1693 DPRINTF("\n"); 1694 1695 return (0); 1696 } 1697 1698 static int 1699 mfii_mfa_poll(struct mfii_softc *sc, struct mfii_ccb *ccb) 1700 { 1701 struct mfi_frame_header *hdr = ccb->ccb_request; 1702 u_int64_t r; 1703 int to = 0, rv = 0; 1704 1705 #ifdef DIAGNOSTIC 1706 if (ccb->ccb_cookie != NULL || ccb->ccb_done != NULL) 1707 panic("mfii_mfa_poll called with cookie or done set"); 1708 #endif 1709 1710 hdr->mfh_context = ccb->ccb_smid; 1711 hdr->mfh_cmd_status = MFI_STAT_INVALID_STATUS; 1712 hdr->mfh_flags |= htole16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE); 1713 1714 r = MFII_REQ_MFA(ccb->ccb_request_dva); 1715 memcpy(&ccb->ccb_req, &r, sizeof(ccb->ccb_req)); 1716 1717 /* 1718 * Even if the Aero card supports 32bit descriptor, 64bit descriptor 1719 * access is required for MFI_CMD_INIT. 1720 * Currently, mfii_mfa_poll() is called for MFI_CMD_INIT only. 1721 */ 1722 mfii_start64(sc, ccb); 1723 1724 for (;;) { 1725 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_requests), 1726 ccb->ccb_request_offset, MFII_REQUEST_SIZE, 1727 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1728 1729 if (hdr->mfh_cmd_status != MFI_STAT_INVALID_STATUS) 1730 break; 1731 1732 if (to++ > 5000) { /* XXX 5 seconds busywait sucks */ 1733 printf("%s: timeout on ccb %d\n", DEVNAME(sc), 1734 ccb->ccb_smid); 1735 ccb->ccb_flags |= MFI_CCB_F_ERR; 1736 rv = 1; 1737 break; 1738 } 1739 1740 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_requests), 1741 ccb->ccb_request_offset, MFII_REQUEST_SIZE, 1742 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1743 1744 delay(1000); 1745 } 1746 1747 if (ccb->ccb_len > 0) { 1748 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap32, 1749 0, ccb->ccb_dmamap32->dm_mapsize, 1750 (ccb->ccb_direction == MFII_DATA_IN) ? 1751 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1752 1753 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap32); 1754 } 1755 1756 return (rv); 1757 } 1758 1759 static int 1760 mfii_poll(struct mfii_softc *sc, struct mfii_ccb *ccb) 1761 { 1762 void (*done)(struct mfii_softc *, struct mfii_ccb *); 1763 void *cookie; 1764 int rv = 1; 1765 1766 done = ccb->ccb_done; 1767 cookie = ccb->ccb_cookie; 1768 1769 ccb->ccb_done = mfii_poll_done; 1770 ccb->ccb_cookie = &rv; 1771 1772 mfii_start(sc, ccb); 1773 1774 do { 1775 delay(10); 1776 mfii_postq(sc); 1777 } while (rv == 1); 1778 1779 ccb->ccb_cookie = cookie; 1780 done(sc, ccb); 1781 1782 return (0); 1783 } 1784 1785 static void 1786 mfii_poll_done(struct mfii_softc *sc, struct mfii_ccb *ccb) 1787 { 1788 int *rv = ccb->ccb_cookie; 1789 1790 *rv = 0; 1791 } 1792 1793 static int 1794 mfii_exec(struct mfii_softc *sc, struct mfii_ccb *ccb) 1795 { 1796 #ifdef DIAGNOSTIC 1797 if (ccb->ccb_cookie != NULL || ccb->ccb_done != NULL) 1798 panic("mfii_exec called with cookie or done set"); 1799 #endif 1800 1801 ccb->ccb_cookie = ccb; 1802 ccb->ccb_done = mfii_exec_done; 1803 1804 mfii_start(sc, ccb); 1805 1806 mutex_enter(&ccb->ccb_mtx); 1807 while (ccb->ccb_cookie != NULL) 1808 cv_wait(&ccb->ccb_cv, &ccb->ccb_mtx); 1809 mutex_exit(&ccb->ccb_mtx); 1810 1811 return (0); 1812 } 1813 1814 static void 1815 mfii_exec_done(struct mfii_softc *sc, struct mfii_ccb *ccb) 1816 { 1817 mutex_enter(&ccb->ccb_mtx); 1818 ccb->ccb_cookie = NULL; 1819 cv_signal(&ccb->ccb_cv); 1820 mutex_exit(&ccb->ccb_mtx); 1821 } 1822 1823 static int 1824 mfii_mgmt(struct mfii_softc *sc, uint32_t opc, const union mfi_mbox *mbox, 1825 void *buf, size_t len, mfii_direction_t dir, bool poll) 1826 { 1827 struct mfii_ccb *ccb; 1828 int rv; 1829 1830 KASSERT(mutex_owned(&sc->sc_lock)); 1831 if (!sc->sc_running) 1832 return EAGAIN; 1833 1834 ccb = mfii_get_ccb(sc); 1835 if (ccb == NULL) 1836 return (ENOMEM); 1837 1838 mfii_scrub_ccb(ccb); 1839 rv = mfii_do_mgmt(sc, ccb, opc, mbox, buf, len, dir, poll); 1840 mfii_put_ccb(sc, ccb); 1841 1842 return (rv); 1843 } 1844 1845 static int 1846 mfii_do_mgmt(struct mfii_softc *sc, struct mfii_ccb *ccb, uint32_t opc, 1847 const union mfi_mbox *mbox, void *buf, size_t len, mfii_direction_t dir, 1848 bool poll) 1849 { 1850 struct mpii_msg_scsi_io *io = ccb->ccb_request; 1851 struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1); 1852 struct mfii_sge *sge = (struct mfii_sge *)(ctx + 1); 1853 struct mfi_dcmd_frame *dcmd = ccb->ccb_mfi; 1854 struct mfi_frame_header *hdr = &dcmd->mdf_header; 1855 int rv = EIO; 1856 1857 if (cold) 1858 poll = true; 1859 1860 ccb->ccb_data = buf; 1861 ccb->ccb_len = len; 1862 ccb->ccb_direction = dir; 1863 switch (dir) { 1864 case MFII_DATA_IN: 1865 hdr->mfh_flags = htole16(MFI_FRAME_DIR_READ); 1866 break; 1867 case MFII_DATA_OUT: 1868 hdr->mfh_flags = htole16(MFI_FRAME_DIR_WRITE); 1869 break; 1870 case MFII_DATA_NONE: 1871 hdr->mfh_flags = htole16(MFI_FRAME_DIR_NONE); 1872 break; 1873 } 1874 1875 if (mfii_load_mfa(sc, ccb, &dcmd->mdf_sgl, poll) != 0) { 1876 rv = ENOMEM; 1877 goto done; 1878 } 1879 1880 hdr->mfh_cmd = MFI_CMD_DCMD; 1881 hdr->mfh_context = ccb->ccb_smid; 1882 hdr->mfh_data_len = htole32(len); 1883 hdr->mfh_sg_count = ccb->ccb_dmamap32->dm_nsegs; 1884 KASSERT(!ccb->ccb_dma64); 1885 1886 dcmd->mdf_opcode = opc; 1887 /* handle special opcodes */ 1888 if (mbox != NULL) 1889 memcpy(&dcmd->mdf_mbox, mbox, sizeof(dcmd->mdf_mbox)); 1890 1891 io->function = MFII_FUNCTION_PASSTHRU_IO; 1892 io->sgl_offset0 = ((u_int8_t *)sge - (u_int8_t *)io) / 4; 1893 io->chain_offset = ((u_int8_t *)sge - (u_int8_t *)io) / 16; 1894 1895 sge->sg_addr = htole64(ccb->ccb_mfi_dva); 1896 sge->sg_len = htole32(MFI_FRAME_SIZE); 1897 sge->sg_flags = MFII_SGE_CHAIN_ELEMENT | MFII_SGE_ADDR_IOCPLBNTA; 1898 1899 ccb->ccb_req.flags = MFII_REQ_TYPE_SCSI; 1900 ccb->ccb_req.smid = le16toh(ccb->ccb_smid); 1901 1902 if (poll) { 1903 ccb->ccb_done = mfii_empty_done; 1904 mfii_poll(sc, ccb); 1905 } else 1906 mfii_exec(sc, ccb); 1907 1908 if (hdr->mfh_cmd_status == MFI_STAT_OK) { 1909 rv = 0; 1910 } 1911 1912 done: 1913 return (rv); 1914 } 1915 1916 static void 1917 mfii_empty_done(struct mfii_softc *sc, struct mfii_ccb *ccb) 1918 { 1919 return; 1920 } 1921 1922 static int 1923 mfii_load_mfa(struct mfii_softc *sc, struct mfii_ccb *ccb, 1924 void *sglp, int nosleep) 1925 { 1926 union mfi_sgl *sgl = sglp; 1927 bus_dmamap_t dmap = ccb->ccb_dmamap32; 1928 int error; 1929 int i; 1930 1931 KASSERT(!ccb->ccb_dma64); 1932 if (ccb->ccb_len == 0) 1933 return (0); 1934 1935 error = bus_dmamap_load(sc->sc_dmat, dmap, 1936 ccb->ccb_data, ccb->ccb_len, NULL, 1937 nosleep ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); 1938 if (error) { 1939 printf("%s: error %d loading dmamap\n", DEVNAME(sc), error); 1940 return (1); 1941 } 1942 1943 for (i = 0; i < dmap->dm_nsegs; i++) { 1944 sgl->sg32[i].addr = htole32(dmap->dm_segs[i].ds_addr); 1945 sgl->sg32[i].len = htole32(dmap->dm_segs[i].ds_len); 1946 } 1947 1948 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 1949 ccb->ccb_direction == MFII_DATA_OUT ? 1950 BUS_DMASYNC_PREWRITE : BUS_DMASYNC_PREREAD); 1951 1952 return (0); 1953 } 1954 1955 static void 1956 mfii_start(struct mfii_softc *sc, struct mfii_ccb *ccb) 1957 { 1958 1959 mfii_start_common(sc, ccb, 1960 ((sc->sc_iop_flag & MFII_IOP_DESC_32BIT) != 0) ? true : false); 1961 } 1962 1963 static void 1964 mfii_start64(struct mfii_softc *sc, struct mfii_ccb *ccb) 1965 { 1966 1967 mfii_start_common(sc, ccb, false); 1968 } 1969 1970 static void 1971 mfii_start_common(struct mfii_softc *sc, struct mfii_ccb *ccb, bool do32) 1972 { 1973 uint32_t *r = (uint32_t *)&ccb->ccb_req; 1974 1975 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_requests), 1976 ccb->ccb_request_offset, MFII_REQUEST_SIZE, 1977 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1978 1979 if (do32) 1980 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MFI_ISQP, r[0]); 1981 else { 1982 #if defined(__LP64__) 1983 uint64_t buf; 1984 1985 buf = ((uint64_t)r[1] << 32) | r[0]; 1986 bus_space_write_8(sc->sc_iot, sc->sc_ioh, MFI_IQPL, buf); 1987 #else 1988 mutex_enter(&sc->sc_post_mtx); 1989 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MFI_IQPL, r[0]); 1990 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MFI_IQPH, r[1]); 1991 bus_space_barrier(sc->sc_iot, sc->sc_ioh, 1992 MFI_IQPL, 8, BUS_SPACE_BARRIER_WRITE); 1993 mutex_exit(&sc->sc_post_mtx); 1994 #endif 1995 } 1996 } 1997 1998 static void 1999 mfii_done(struct mfii_softc *sc, struct mfii_ccb *ccb) 2000 { 2001 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_requests), 2002 ccb->ccb_request_offset, MFII_REQUEST_SIZE, 2003 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2004 2005 if (ccb->ccb_sgl_len > 0) { 2006 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_sgl), 2007 ccb->ccb_sgl_offset, ccb->ccb_sgl_len, 2008 BUS_DMASYNC_POSTWRITE); 2009 } 2010 2011 if (ccb->ccb_dma64) { 2012 KASSERT(ccb->ccb_len > 0); 2013 bus_dmamap_sync(sc->sc_dmat64, ccb->ccb_dmamap64, 2014 0, ccb->ccb_dmamap64->dm_mapsize, 2015 (ccb->ccb_direction == MFII_DATA_IN) ? 2016 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 2017 2018 bus_dmamap_unload(sc->sc_dmat64, ccb->ccb_dmamap64); 2019 } else if (ccb->ccb_len > 0) { 2020 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap32, 2021 0, ccb->ccb_dmamap32->dm_mapsize, 2022 (ccb->ccb_direction == MFII_DATA_IN) ? 2023 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 2024 2025 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap32); 2026 } 2027 2028 ccb->ccb_done(sc, ccb); 2029 } 2030 2031 static int 2032 mfii_initialise_firmware(struct mfii_softc *sc) 2033 { 2034 struct mpii_msg_iocinit_request *iiq; 2035 struct mfii_dmamem *m; 2036 struct mfii_ccb *ccb; 2037 struct mfi_init_frame *init; 2038 int rv; 2039 2040 m = mfii_dmamem_alloc(sc, sizeof(*iiq)); 2041 if (m == NULL) 2042 return (1); 2043 2044 iiq = MFII_DMA_KVA(m); 2045 memset(iiq, 0, sizeof(*iiq)); 2046 2047 iiq->function = MPII_FUNCTION_IOC_INIT; 2048 iiq->whoinit = MPII_WHOINIT_HOST_DRIVER; 2049 2050 iiq->msg_version_maj = 0x02; 2051 iiq->msg_version_min = 0x00; 2052 iiq->hdr_version_unit = 0x10; 2053 iiq->hdr_version_dev = 0x0; 2054 2055 iiq->system_request_frame_size = htole16(MFII_REQUEST_SIZE / 4); 2056 2057 iiq->reply_descriptor_post_queue_depth = 2058 htole16(sc->sc_reply_postq_depth); 2059 iiq->reply_free_queue_depth = htole16(0); 2060 2061 iiq->sense_buffer_address_high = htole32( 2062 MFII_DMA_DVA(sc->sc_sense) >> 32); 2063 2064 iiq->reply_descriptor_post_queue_address_lo = 2065 htole32(MFII_DMA_DVA(sc->sc_reply_postq)); 2066 iiq->reply_descriptor_post_queue_address_hi = 2067 htole32(MFII_DMA_DVA(sc->sc_reply_postq) >> 32); 2068 2069 iiq->system_request_frame_base_address_lo = 2070 htole32(MFII_DMA_DVA(sc->sc_requests)); 2071 iiq->system_request_frame_base_address_hi = 2072 htole32(MFII_DMA_DVA(sc->sc_requests) >> 32); 2073 2074 iiq->timestamp = htole64(time_uptime); 2075 2076 ccb = mfii_get_ccb(sc); 2077 if (ccb == NULL) { 2078 /* shouldn't ever run out of ccbs during attach */ 2079 return (1); 2080 } 2081 mfii_scrub_ccb(ccb); 2082 init = ccb->ccb_request; 2083 2084 init->mif_header.mfh_cmd = MFI_CMD_INIT; 2085 init->mif_header.mfh_data_len = htole32(sizeof(*iiq)); 2086 init->mif_qinfo_new_addr_lo = htole32(MFII_DMA_DVA(m)); 2087 init->mif_qinfo_new_addr_hi = htole32((uint64_t)MFII_DMA_DVA(m) >> 32); 2088 2089 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_reply_postq), 2090 0, MFII_DMA_LEN(sc->sc_reply_postq), 2091 BUS_DMASYNC_PREREAD); 2092 2093 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(m), 2094 0, sizeof(*iiq), BUS_DMASYNC_PREREAD); 2095 2096 rv = mfii_mfa_poll(sc, ccb); 2097 2098 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(m), 2099 0, sizeof(*iiq), BUS_DMASYNC_POSTREAD); 2100 2101 mfii_put_ccb(sc, ccb); 2102 mfii_dmamem_free(sc, m); 2103 2104 return (rv); 2105 } 2106 2107 static int 2108 mfii_my_intr(struct mfii_softc *sc) 2109 { 2110 u_int32_t status; 2111 2112 status = mfii_read(sc, MFI_OSTS); 2113 2114 DNPRINTF(MFII_D_INTR, "%s: intr status 0x%x\n", DEVNAME(sc), status); 2115 if (ISSET(status, 0x1)) { 2116 mfii_write(sc, MFI_OSTS, status); 2117 return (1); 2118 } 2119 2120 return (ISSET(status, MFII_OSTS_INTR_VALID) ? 1 : 0); 2121 } 2122 2123 static int 2124 mfii_intr(void *arg) 2125 { 2126 struct mfii_softc *sc = arg; 2127 2128 if (!mfii_my_intr(sc)) 2129 return (0); 2130 2131 mfii_postq(sc); 2132 2133 return (1); 2134 } 2135 2136 static void 2137 mfii_postq(struct mfii_softc *sc) 2138 { 2139 struct mfii_ccb_list ccbs = SIMPLEQ_HEAD_INITIALIZER(ccbs); 2140 struct mpii_reply_descr *postq = MFII_DMA_KVA(sc->sc_reply_postq); 2141 struct mpii_reply_descr *rdp; 2142 struct mfii_ccb *ccb; 2143 int rpi = 0; 2144 2145 mutex_enter(&sc->sc_reply_postq_mtx); 2146 2147 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_reply_postq), 2148 0, MFII_DMA_LEN(sc->sc_reply_postq), 2149 BUS_DMASYNC_POSTREAD); 2150 2151 for (;;) { 2152 rdp = &postq[sc->sc_reply_postq_index]; 2153 DNPRINTF(MFII_D_INTR, 2154 "%s: mfii_postq index %d flags 0x%x data 0x%x\n", 2155 DEVNAME(sc), sc->sc_reply_postq_index, rdp->reply_flags, 2156 rdp->data == 0xffffffff); 2157 if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) == 2158 MPII_REPLY_DESCR_UNUSED) 2159 break; 2160 if (rdp->data == 0xffffffff) { 2161 /* 2162 * ioc is still writing to the reply post queue 2163 * race condition - bail! 2164 */ 2165 break; 2166 } 2167 2168 ccb = &sc->sc_ccb[le16toh(rdp->smid) - 1]; 2169 SIMPLEQ_INSERT_TAIL(&ccbs, ccb, ccb_link); 2170 memset(rdp, 0xff, sizeof(*rdp)); 2171 2172 sc->sc_reply_postq_index++; 2173 sc->sc_reply_postq_index %= sc->sc_reply_postq_depth; 2174 rpi = 1; 2175 } 2176 2177 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_reply_postq), 2178 0, MFII_DMA_LEN(sc->sc_reply_postq), 2179 BUS_DMASYNC_PREREAD); 2180 2181 if (rpi) 2182 mfii_write(sc, MFII_RPI, sc->sc_reply_postq_index); 2183 2184 mutex_exit(&sc->sc_reply_postq_mtx); 2185 2186 while ((ccb = SIMPLEQ_FIRST(&ccbs)) != NULL) { 2187 SIMPLEQ_REMOVE_HEAD(&ccbs, ccb_link); 2188 mfii_done(sc, ccb); 2189 } 2190 } 2191 2192 static void 2193 mfii_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 2194 void *arg) 2195 { 2196 struct scsipi_periph *periph; 2197 struct scsipi_xfer *xs; 2198 struct scsipi_adapter *adapt = chan->chan_adapter; 2199 struct mfii_softc *sc = device_private(adapt->adapt_dev); 2200 struct mfii_ccb *ccb; 2201 int timeout; 2202 int target; 2203 2204 switch (req) { 2205 case ADAPTER_REQ_GROW_RESOURCES: 2206 /* Not supported. */ 2207 return; 2208 case ADAPTER_REQ_SET_XFER_MODE: 2209 { 2210 struct scsipi_xfer_mode *xm = arg; 2211 xm->xm_mode = PERIPH_CAP_TQING; 2212 xm->xm_period = 0; 2213 xm->xm_offset = 0; 2214 scsipi_async_event(&sc->sc_chan, ASYNC_EVENT_XFER_MODE, xm); 2215 return; 2216 } 2217 case ADAPTER_REQ_RUN_XFER: 2218 break; 2219 } 2220 2221 xs = arg; 2222 periph = xs->xs_periph; 2223 target = periph->periph_target; 2224 2225 if (target >= MFII_MAX_LD_EXT || !sc->sc_ld[target].ld_present || 2226 periph->periph_lun != 0) { 2227 xs->error = XS_SELTIMEOUT; 2228 scsipi_done(xs); 2229 return; 2230 } 2231 2232 if ((xs->cmd->opcode == SCSI_SYNCHRONIZE_CACHE_10 || 2233 xs->cmd->opcode == SCSI_SYNCHRONIZE_CACHE_16) && sc->sc_bbuok) { 2234 /* the cache is stable storage, don't flush */ 2235 xs->error = XS_NOERROR; 2236 xs->status = SCSI_OK; 2237 xs->resid = 0; 2238 scsipi_done(xs); 2239 return; 2240 } 2241 2242 ccb = mfii_get_ccb(sc); 2243 if (ccb == NULL) { 2244 xs->error = XS_RESOURCE_SHORTAGE; 2245 scsipi_done(xs); 2246 return; 2247 } 2248 mfii_scrub_ccb(ccb); 2249 ccb->ccb_cookie = xs; 2250 ccb->ccb_done = mfii_scsi_cmd_done; 2251 ccb->ccb_data = xs->data; 2252 ccb->ccb_len = xs->datalen; 2253 2254 timeout = mstohz(xs->timeout); 2255 if (timeout == 0) 2256 timeout = 1; 2257 callout_reset(&xs->xs_callout, timeout, mfii_scsi_cmd_tmo, ccb); 2258 2259 switch (xs->cmd->opcode) { 2260 case SCSI_READ_6_COMMAND: 2261 case READ_10: 2262 case READ_12: 2263 case READ_16: 2264 case SCSI_WRITE_6_COMMAND: 2265 case WRITE_10: 2266 case WRITE_12: 2267 case WRITE_16: 2268 if (mfii_scsi_cmd_io(sc, ccb, xs) != 0) 2269 goto stuffup; 2270 break; 2271 2272 default: 2273 if (mfii_scsi_cmd_cdb(sc, ccb, xs) != 0) 2274 goto stuffup; 2275 break; 2276 } 2277 2278 xs->error = XS_NOERROR; 2279 xs->resid = 0; 2280 2281 DNPRINTF(MFII_D_CMD, "%s: start io %d cmd %d\n", DEVNAME(sc), target, 2282 xs->cmd->opcode); 2283 2284 if (xs->xs_control & XS_CTL_POLL) { 2285 if (mfii_poll(sc, ccb) != 0) 2286 goto stuffup; 2287 return; 2288 } 2289 2290 mfii_start(sc, ccb); 2291 2292 return; 2293 2294 stuffup: 2295 xs->error = XS_DRIVER_STUFFUP; 2296 scsipi_done(xs); 2297 mfii_put_ccb(sc, ccb); 2298 } 2299 2300 static void 2301 mfii_scsi_cmd_done(struct mfii_softc *sc, struct mfii_ccb *ccb) 2302 { 2303 struct scsipi_xfer *xs = ccb->ccb_cookie; 2304 struct mpii_msg_scsi_io *io = ccb->ccb_request; 2305 struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1); 2306 2307 if (callout_stop(&xs->xs_callout) != 0) 2308 return; 2309 2310 switch (ctx->status) { 2311 case MFI_STAT_OK: 2312 break; 2313 2314 case MFI_STAT_SCSI_DONE_WITH_ERROR: 2315 xs->error = XS_SENSE; 2316 memset(&xs->sense, 0, sizeof(xs->sense)); 2317 memcpy(&xs->sense, ccb->ccb_sense, sizeof(xs->sense)); 2318 break; 2319 2320 case MFI_STAT_LD_OFFLINE: 2321 case MFI_STAT_DEVICE_NOT_FOUND: 2322 xs->error = XS_SELTIMEOUT; 2323 break; 2324 2325 default: 2326 xs->error = XS_DRIVER_STUFFUP; 2327 break; 2328 } 2329 2330 scsipi_done(xs); 2331 mfii_put_ccb(sc, ccb); 2332 } 2333 2334 static int 2335 mfii_scsi_cmd_io(struct mfii_softc *sc, struct mfii_ccb *ccb, 2336 struct scsipi_xfer *xs) 2337 { 2338 struct scsipi_periph *periph = xs->xs_periph; 2339 struct mpii_msg_scsi_io *io = ccb->ccb_request; 2340 struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1); 2341 int segs, target; 2342 2343 target = sc->sc_ld[periph->periph_target].ld_target_id; 2344 io->dev_handle = htole16(target); 2345 io->function = MFII_FUNCTION_LDIO_REQUEST; 2346 io->sense_buffer_low_address = htole32(ccb->ccb_sense_dva); 2347 io->sgl_flags = htole16(0x02); /* XXX */ 2348 io->sense_buffer_length = sizeof(xs->sense); 2349 io->sgl_offset0 = (sizeof(*io) + sizeof(*ctx)) / 4; 2350 io->data_length = htole32(xs->datalen); 2351 io->io_flags = htole16(xs->cmdlen); 2352 switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { 2353 case XS_CTL_DATA_IN: 2354 ccb->ccb_direction = MFII_DATA_IN; 2355 io->direction = MPII_SCSIIO_DIR_READ; 2356 break; 2357 case XS_CTL_DATA_OUT: 2358 ccb->ccb_direction = MFII_DATA_OUT; 2359 io->direction = MPII_SCSIIO_DIR_WRITE; 2360 break; 2361 default: 2362 ccb->ccb_direction = MFII_DATA_NONE; 2363 io->direction = MPII_SCSIIO_DIR_NONE; 2364 break; 2365 } 2366 memcpy(io->cdb, xs->cmd, xs->cmdlen); 2367 2368 ctx->type_nseg = sc->sc_iop->ldio_ctx_type_nseg; 2369 ctx->timeout_value = htole16(0x14); /* XXX */ 2370 ctx->reg_lock_flags = htole16(sc->sc_iop->ldio_ctx_reg_lock_flags); 2371 ctx->virtual_disk_target_id = htole16(target); 2372 2373 if (mfii_load_ccb(sc, ccb, ctx + 1, 2374 ISSET(xs->xs_control, XS_CTL_NOSLEEP)) != 0) 2375 return (1); 2376 2377 KASSERT(ccb->ccb_len == 0 || ccb->ccb_dma64); 2378 segs = (ccb->ccb_len == 0) ? 0 : ccb->ccb_dmamap64->dm_nsegs; 2379 switch (sc->sc_iop->num_sge_loc) { 2380 case MFII_IOP_NUM_SGE_LOC_ORIG: 2381 ctx->num_sge = segs; 2382 break; 2383 case MFII_IOP_NUM_SGE_LOC_35: 2384 /* 12 bit field, but we're only using the lower 8 */ 2385 ctx->span_arm = segs; 2386 break; 2387 } 2388 2389 ccb->ccb_req.flags = sc->sc_iop->ldio_req_type; 2390 ccb->ccb_req.smid = le16toh(ccb->ccb_smid); 2391 2392 return (0); 2393 } 2394 2395 static int 2396 mfii_scsi_cmd_cdb(struct mfii_softc *sc, struct mfii_ccb *ccb, 2397 struct scsipi_xfer *xs) 2398 { 2399 struct scsipi_periph *periph = xs->xs_periph; 2400 struct mpii_msg_scsi_io *io = ccb->ccb_request; 2401 struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1); 2402 int target; 2403 2404 target = sc->sc_ld[periph->periph_target].ld_target_id; 2405 io->dev_handle = htole16(target); 2406 io->function = MFII_FUNCTION_LDIO_REQUEST; 2407 io->sense_buffer_low_address = htole32(ccb->ccb_sense_dva); 2408 io->sgl_flags = htole16(0x02); /* XXX */ 2409 io->sense_buffer_length = sizeof(xs->sense); 2410 io->sgl_offset0 = (sizeof(*io) + sizeof(*ctx)) / 4; 2411 io->data_length = htole32(xs->datalen); 2412 io->io_flags = htole16(xs->cmdlen); 2413 io->lun[0] = htobe16(periph->periph_lun); 2414 switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { 2415 case XS_CTL_DATA_IN: 2416 ccb->ccb_direction = MFII_DATA_IN; 2417 io->direction = MPII_SCSIIO_DIR_READ; 2418 break; 2419 case XS_CTL_DATA_OUT: 2420 ccb->ccb_direction = MFII_DATA_OUT; 2421 io->direction = MPII_SCSIIO_DIR_WRITE; 2422 break; 2423 default: 2424 ccb->ccb_direction = MFII_DATA_NONE; 2425 io->direction = MPII_SCSIIO_DIR_NONE; 2426 break; 2427 } 2428 memcpy(io->cdb, xs->cmd, xs->cmdlen); 2429 2430 ctx->virtual_disk_target_id = htole16(target); 2431 2432 if (mfii_load_ccb(sc, ccb, ctx + 1, 2433 ISSET(xs->xs_control, XS_CTL_NOSLEEP)) != 0) 2434 return (1); 2435 2436 ctx->num_sge = (ccb->ccb_len == 0) ? 0 : ccb->ccb_dmamap64->dm_nsegs; 2437 KASSERT(ccb->ccb_len == 0 || ccb->ccb_dma64); 2438 2439 ccb->ccb_req.flags = MFII_REQ_TYPE_SCSI; 2440 ccb->ccb_req.smid = le16toh(ccb->ccb_smid); 2441 2442 return (0); 2443 } 2444 2445 #if 0 2446 void 2447 mfii_pd_scsi_cmd(struct scsipi_xfer *xs) 2448 { 2449 struct scsi_link *link = xs->sc_link; 2450 struct mfii_softc *sc = link->adapter_softc; 2451 struct mfii_ccb *ccb = xs->io; 2452 2453 mfii_scrub_ccb(ccb); 2454 ccb->ccb_cookie = xs; 2455 ccb->ccb_done = mfii_scsi_cmd_done; 2456 ccb->ccb_data = xs->data; 2457 ccb->ccb_len = xs->datalen; 2458 2459 // XXX timeout_set(&xs->stimeout, mfii_scsi_cmd_tmo, xs); 2460 2461 xs->error = mfii_pd_scsi_cmd_cdb(sc, xs); 2462 if (xs->error != XS_NOERROR) 2463 goto done; 2464 2465 xs->resid = 0; 2466 2467 if (ISSET(xs->xs_control, XS_CTL_POLL)) { 2468 if (mfii_poll(sc, ccb) != 0) 2469 goto stuffup; 2470 return; 2471 } 2472 2473 // XXX timeout_add_msec(&xs->stimeout, xs->timeout); 2474 mfii_start(sc, ccb); 2475 2476 return; 2477 2478 stuffup: 2479 xs->error = XS_DRIVER_STUFFUP; 2480 done: 2481 scsi_done(xs); 2482 } 2483 2484 int 2485 mfii_pd_scsi_probe(struct scsi_link *link) 2486 { 2487 struct mfii_softc *sc = link->adapter_softc; 2488 struct mfi_pd_details mpd; 2489 union mfi_mbox mbox; 2490 int rv; 2491 2492 if (link->lun > 0) 2493 return (0); 2494 2495 memset(&mbox, 0, sizeof(mbox)); 2496 mbox.s[0] = htole16(link->target); 2497 2498 rv = mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, &mpd, sizeof(mpd), 2499 MFII_DATA_IN, true); 2500 if (rv != 0) 2501 return (EIO); 2502 2503 if (mpd.mpd_fw_state != htole16(MFI_PD_SYSTEM)) 2504 return (ENXIO); 2505 2506 return (0); 2507 } 2508 2509 int 2510 mfii_pd_scsi_cmd_cdb(struct mfii_softc *sc, struct mfii_ccb *ccb, 2511 struct scsipi_xfer *xs) 2512 { 2513 struct scsi_link *link = xs->sc_link; 2514 struct mpii_msg_scsi_io *io = ccb->ccb_request; 2515 struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1); 2516 uint16_t dev_handle; 2517 2518 dev_handle = mfii_dev_handle(sc, link->target); 2519 if (dev_handle == htole16(0xffff)) 2520 return (XS_SELTIMEOUT); 2521 2522 io->dev_handle = dev_handle; 2523 io->function = 0; 2524 io->sense_buffer_low_address = htole32(ccb->ccb_sense_dva); 2525 io->sgl_flags = htole16(0x02); /* XXX */ 2526 io->sense_buffer_length = sizeof(xs->sense); 2527 io->sgl_offset0 = (sizeof(*io) + sizeof(*ctx)) / 4; 2528 io->data_length = htole32(xs->datalen); 2529 io->io_flags = htole16(xs->cmdlen); 2530 io->lun[0] = htobe16(link->lun); 2531 switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { 2532 case XS_CTL_DATA_IN: 2533 ccb->ccb_direction = MFII_DATA_IN; 2534 io->direction = MPII_SCSIIO_DIR_READ; 2535 break; 2536 case XS_CTL_DATA_OUT: 2537 ccb->ccb_direction = MFII_DATA_OUT; 2538 io->direction = MPII_SCSIIO_DIR_WRITE; 2539 break; 2540 default: 2541 ccb->ccb_direction = MFII_DATA_NONE; 2542 io->direction = MPII_SCSIIO_DIR_NONE; 2543 break; 2544 } 2545 memcpy(io->cdb, xs->cmd, xs->cmdlen); 2546 2547 ctx->virtual_disk_target_id = htole16(link->target); 2548 ctx->raid_flags = MFII_RAID_CTX_IO_TYPE_SYSPD; 2549 ctx->timeout_value = sc->sc_pd->pd_timeout; 2550 2551 if (mfii_load_ccb(sc, ccb, ctx + 1, 2552 ISSET(xs->xs_control, XS_CTL_NOSLEEP)) != 0) 2553 return (XS_DRIVER_STUFFUP); 2554 2555 ctx->num_sge = (ccb->ccb_len == 0) ? 0 : ccb->ccb_dmamap64->dm_nsegs; 2556 KASSERT(ccb->ccb_dma64); 2557 2558 ccb->ccb_req.flags = MFII_REQ_TYPE_HI_PRI; 2559 ccb->ccb_req.smid = le16toh(ccb->ccb_smid); 2560 ccb->ccb_req.dev_handle = dev_handle; 2561 2562 return (XS_NOERROR); 2563 } 2564 #endif 2565 2566 static int 2567 mfii_load_ccb(struct mfii_softc *sc, struct mfii_ccb *ccb, void *sglp, 2568 int nosleep) 2569 { 2570 struct mpii_msg_request *req = ccb->ccb_request; 2571 struct mfii_sge *sge = NULL, *nsge = sglp; 2572 struct mfii_sge *ce = NULL; 2573 bus_dmamap_t dmap = ccb->ccb_dmamap64; 2574 u_int space; 2575 int i; 2576 2577 int error; 2578 2579 if (ccb->ccb_len == 0) 2580 return (0); 2581 2582 ccb->ccb_dma64 = true; 2583 error = bus_dmamap_load(sc->sc_dmat64, dmap, 2584 ccb->ccb_data, ccb->ccb_len, NULL, 2585 nosleep ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); 2586 if (error) { 2587 printf("%s: error %d loading dmamap\n", DEVNAME(sc), error); 2588 return (1); 2589 } 2590 2591 space = (MFII_REQUEST_SIZE - ((u_int8_t *)nsge - (u_int8_t *)req)) / 2592 sizeof(*nsge); 2593 if (dmap->dm_nsegs > space) { 2594 space--; 2595 2596 ccb->ccb_sgl_len = (dmap->dm_nsegs - space) * sizeof(*nsge); 2597 memset(ccb->ccb_sgl, 0, ccb->ccb_sgl_len); 2598 2599 ce = nsge + space; 2600 ce->sg_addr = htole64(ccb->ccb_sgl_dva); 2601 ce->sg_len = htole32(ccb->ccb_sgl_len); 2602 ce->sg_flags = sc->sc_iop->sge_flag_chain; 2603 2604 req->chain_offset = ((u_int8_t *)ce - (u_int8_t *)req) / 16; 2605 } 2606 2607 for (i = 0; i < dmap->dm_nsegs; i++) { 2608 if (nsge == ce) 2609 nsge = ccb->ccb_sgl; 2610 2611 sge = nsge; 2612 2613 sge->sg_addr = htole64(dmap->dm_segs[i].ds_addr); 2614 sge->sg_len = htole32(dmap->dm_segs[i].ds_len); 2615 sge->sg_flags = MFII_SGE_ADDR_SYSTEM; 2616 2617 nsge = sge + 1; 2618 } 2619 sge->sg_flags |= sc->sc_iop->sge_flag_eol; 2620 2621 bus_dmamap_sync(sc->sc_dmat64, dmap, 0, dmap->dm_mapsize, 2622 ccb->ccb_direction == MFII_DATA_OUT ? 2623 BUS_DMASYNC_PREWRITE : BUS_DMASYNC_PREREAD); 2624 2625 if (ccb->ccb_sgl_len > 0) { 2626 bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_sgl), 2627 ccb->ccb_sgl_offset, ccb->ccb_sgl_len, 2628 BUS_DMASYNC_PREWRITE); 2629 } 2630 2631 return (0); 2632 } 2633 2634 static void 2635 mfii_scsi_cmd_tmo(void *p) 2636 { 2637 struct mfii_ccb *ccb = p; 2638 struct mfii_softc *sc = ccb->ccb_sc; 2639 bool start_abort; 2640 2641 printf("%s: cmd timeout ccb %p\n", DEVNAME(sc), p); 2642 2643 mutex_enter(&sc->sc_abort_mtx); 2644 start_abort = (SIMPLEQ_FIRST(&sc->sc_abort_list) == 0); 2645 SIMPLEQ_INSERT_TAIL(&sc->sc_abort_list, ccb, ccb_link); 2646 if (start_abort) 2647 workqueue_enqueue(sc->sc_abort_wq, &sc->sc_abort_work, NULL); 2648 mutex_exit(&sc->sc_abort_mtx); 2649 } 2650 2651 static void 2652 mfii_abort_task(struct work *wk, void *scp) 2653 { 2654 struct mfii_softc *sc = scp; 2655 struct mfii_ccb *list; 2656 2657 mutex_enter(&sc->sc_abort_mtx); 2658 list = SIMPLEQ_FIRST(&sc->sc_abort_list); 2659 SIMPLEQ_INIT(&sc->sc_abort_list); 2660 mutex_exit(&sc->sc_abort_mtx); 2661 2662 while (list != NULL) { 2663 struct mfii_ccb *ccb = list; 2664 struct scsipi_xfer *xs = ccb->ccb_cookie; 2665 struct scsipi_periph *periph = xs->xs_periph; 2666 struct mfii_ccb *accb; 2667 2668 list = SIMPLEQ_NEXT(ccb, ccb_link); 2669 2670 if (!sc->sc_ld[periph->periph_target].ld_present) { 2671 /* device is gone */ 2672 xs->error = XS_SELTIMEOUT; 2673 scsipi_done(xs); 2674 mfii_put_ccb(sc, ccb); 2675 continue; 2676 } 2677 2678 accb = mfii_get_ccb(sc); 2679 mfii_scrub_ccb(accb); 2680 mfii_abort(sc, accb, periph->periph_target, ccb->ccb_smid, 2681 MPII_SCSI_TASK_ABORT_TASK, 2682 htole32(MFII_TASK_MGMT_FLAGS_PD)); 2683 2684 accb->ccb_cookie = ccb; 2685 accb->ccb_done = mfii_scsi_cmd_abort_done; 2686 2687 mfii_start(sc, accb); 2688 } 2689 } 2690 2691 static void 2692 mfii_abort(struct mfii_softc *sc, struct mfii_ccb *accb, uint16_t dev_handle, 2693 uint16_t smid, uint8_t type, uint32_t flags) 2694 { 2695 struct mfii_task_mgmt *msg; 2696 struct mpii_msg_scsi_task_request *req; 2697 2698 msg = accb->ccb_request; 2699 req = &msg->mpii_request; 2700 req->dev_handle = dev_handle; 2701 req->function = MPII_FUNCTION_SCSI_TASK_MGMT; 2702 req->task_type = type; 2703 req->task_mid = htole16( smid); 2704 msg->flags = flags; 2705 2706 accb->ccb_req.flags = MFII_REQ_TYPE_HI_PRI; 2707 accb->ccb_req.smid = le16toh(accb->ccb_smid); 2708 } 2709 2710 static void 2711 mfii_scsi_cmd_abort_done(struct mfii_softc *sc, struct mfii_ccb *accb) 2712 { 2713 struct mfii_ccb *ccb = accb->ccb_cookie; 2714 struct scsipi_xfer *xs = ccb->ccb_cookie; 2715 2716 /* XXX check accb completion? */ 2717 2718 mfii_put_ccb(sc, accb); 2719 printf("%s: cmd aborted ccb %p\n", DEVNAME(sc), ccb); 2720 2721 xs->error = XS_TIMEOUT; 2722 scsipi_done(xs); 2723 mfii_put_ccb(sc, ccb); 2724 } 2725 2726 static struct mfii_ccb * 2727 mfii_get_ccb(struct mfii_softc *sc) 2728 { 2729 struct mfii_ccb *ccb; 2730 2731 mutex_enter(&sc->sc_ccb_mtx); 2732 if (!sc->sc_running) { 2733 ccb = NULL; 2734 } else { 2735 ccb = SIMPLEQ_FIRST(&sc->sc_ccb_freeq); 2736 if (ccb != NULL) 2737 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_freeq, ccb_link); 2738 } 2739 mutex_exit(&sc->sc_ccb_mtx); 2740 return (ccb); 2741 } 2742 2743 static void 2744 mfii_scrub_ccb(struct mfii_ccb *ccb) 2745 { 2746 ccb->ccb_cookie = NULL; 2747 ccb->ccb_done = NULL; 2748 ccb->ccb_flags = 0; 2749 ccb->ccb_data = NULL; 2750 ccb->ccb_direction = MFII_DATA_NONE; 2751 ccb->ccb_dma64 = false; 2752 ccb->ccb_len = 0; 2753 ccb->ccb_sgl_len = 0; 2754 memset(&ccb->ccb_req, 0, sizeof(ccb->ccb_req)); 2755 memset(ccb->ccb_request, 0, MFII_REQUEST_SIZE); 2756 memset(ccb->ccb_mfi, 0, MFI_FRAME_SIZE); 2757 } 2758 2759 static void 2760 mfii_put_ccb(struct mfii_softc *sc, struct mfii_ccb *ccb) 2761 { 2762 mutex_enter(&sc->sc_ccb_mtx); 2763 SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_freeq, ccb, ccb_link); 2764 mutex_exit(&sc->sc_ccb_mtx); 2765 } 2766 2767 static int 2768 mfii_init_ccb(struct mfii_softc *sc) 2769 { 2770 struct mfii_ccb *ccb; 2771 u_int8_t *request = MFII_DMA_KVA(sc->sc_requests); 2772 u_int8_t *mfi = MFII_DMA_KVA(sc->sc_mfi); 2773 u_int8_t *sense = MFII_DMA_KVA(sc->sc_sense); 2774 u_int8_t *sgl = MFII_DMA_KVA(sc->sc_sgl); 2775 u_int i; 2776 int error; 2777 2778 sc->sc_ccb = malloc(sc->sc_max_cmds * sizeof(struct mfii_ccb), 2779 M_DEVBUF, M_WAITOK|M_ZERO); 2780 2781 for (i = 0; i < sc->sc_max_cmds; i++) { 2782 ccb = &sc->sc_ccb[i]; 2783 ccb->ccb_sc = sc; 2784 2785 /* create a dma map for transfer */ 2786 error = bus_dmamap_create(sc->sc_dmat, 2787 MAXPHYS, sc->sc_max_sgl, MAXPHYS, 0, 2788 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap32); 2789 if (error) { 2790 printf("%s: cannot create ccb dmamap32 (%d)\n", 2791 DEVNAME(sc), error); 2792 goto destroy; 2793 } 2794 error = bus_dmamap_create(sc->sc_dmat64, 2795 MAXPHYS, sc->sc_max_sgl, MAXPHYS, 0, 2796 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap64); 2797 if (error) { 2798 printf("%s: cannot create ccb dmamap64 (%d)\n", 2799 DEVNAME(sc), error); 2800 goto destroy32; 2801 } 2802 2803 /* select i + 1'th request. 0 is reserved for events */ 2804 ccb->ccb_smid = i + 1; 2805 ccb->ccb_request_offset = MFII_REQUEST_SIZE * (i + 1); 2806 ccb->ccb_request = request + ccb->ccb_request_offset; 2807 ccb->ccb_request_dva = MFII_DMA_DVA(sc->sc_requests) + 2808 ccb->ccb_request_offset; 2809 2810 /* select i'th MFI command frame */ 2811 ccb->ccb_mfi_offset = MFI_FRAME_SIZE * i; 2812 ccb->ccb_mfi = mfi + ccb->ccb_mfi_offset; 2813 ccb->ccb_mfi_dva = MFII_DMA_DVA(sc->sc_mfi) + 2814 ccb->ccb_mfi_offset; 2815 2816 /* select i'th sense */ 2817 ccb->ccb_sense_offset = MFI_SENSE_SIZE * i; 2818 ccb->ccb_sense = (struct mfi_sense *)(sense + 2819 ccb->ccb_sense_offset); 2820 ccb->ccb_sense_dva = MFII_DMA_DVA(sc->sc_sense) + 2821 ccb->ccb_sense_offset; 2822 2823 /* select i'th sgl */ 2824 ccb->ccb_sgl_offset = sizeof(struct mfii_sge) * 2825 sc->sc_max_sgl * i; 2826 ccb->ccb_sgl = (struct mfii_sge *)(sgl + ccb->ccb_sgl_offset); 2827 ccb->ccb_sgl_dva = MFII_DMA_DVA(sc->sc_sgl) + 2828 ccb->ccb_sgl_offset; 2829 2830 mutex_init(&ccb->ccb_mtx, MUTEX_DEFAULT, IPL_BIO); 2831 cv_init(&ccb->ccb_cv, "mfiiexec"); 2832 2833 /* add ccb to queue */ 2834 mfii_put_ccb(sc, ccb); 2835 } 2836 2837 return (0); 2838 2839 destroy32: 2840 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap32); 2841 destroy: 2842 /* free dma maps and ccb memory */ 2843 while ((ccb = mfii_get_ccb(sc)) != NULL) { 2844 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap32); 2845 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap64); 2846 } 2847 2848 free(sc->sc_ccb, M_DEVBUF); 2849 2850 return (1); 2851 } 2852 2853 #if NBIO > 0 2854 static int 2855 mfii_ioctl(device_t dev, u_long cmd, void *addr) 2856 { 2857 struct mfii_softc *sc = device_private(dev); 2858 int error = 0; 2859 2860 DNPRINTF(MFII_D_IOCTL, "%s: mfii_ioctl ", DEVNAME(sc)); 2861 2862 mutex_enter(&sc->sc_lock); 2863 2864 switch (cmd) { 2865 case BIOCINQ: 2866 DNPRINTF(MFII_D_IOCTL, "inq\n"); 2867 error = mfii_ioctl_inq(sc, (struct bioc_inq *)addr); 2868 break; 2869 2870 case BIOCVOL: 2871 DNPRINTF(MFII_D_IOCTL, "vol\n"); 2872 error = mfii_ioctl_vol(sc, (struct bioc_vol *)addr); 2873 break; 2874 2875 case BIOCDISK: 2876 DNPRINTF(MFII_D_IOCTL, "disk\n"); 2877 error = mfii_ioctl_disk(sc, (struct bioc_disk *)addr); 2878 break; 2879 2880 case BIOCALARM: 2881 DNPRINTF(MFII_D_IOCTL, "alarm\n"); 2882 error = mfii_ioctl_alarm(sc, (struct bioc_alarm *)addr); 2883 break; 2884 2885 case BIOCBLINK: 2886 DNPRINTF(MFII_D_IOCTL, "blink\n"); 2887 error = mfii_ioctl_blink(sc, (struct bioc_blink *)addr); 2888 break; 2889 2890 case BIOCSETSTATE: 2891 DNPRINTF(MFII_D_IOCTL, "setstate\n"); 2892 error = mfii_ioctl_setstate(sc, (struct bioc_setstate *)addr); 2893 break; 2894 2895 #if 0 2896 case BIOCPATROL: 2897 DNPRINTF(MFII_D_IOCTL, "patrol\n"); 2898 error = mfii_ioctl_patrol(sc, (struct bioc_patrol *)addr); 2899 break; 2900 #endif 2901 2902 default: 2903 DNPRINTF(MFII_D_IOCTL, " invalid ioctl\n"); 2904 error = ENOTTY; 2905 } 2906 2907 mutex_exit(&sc->sc_lock); 2908 2909 return (error); 2910 } 2911 2912 static int 2913 mfii_bio_getitall(struct mfii_softc *sc) 2914 { 2915 int i, d, rv = EINVAL; 2916 size_t size; 2917 union mfi_mbox mbox; 2918 struct mfi_conf *cfg = NULL; 2919 struct mfi_ld_details *ld_det = NULL; 2920 2921 /* get info */ 2922 if (mfii_get_info(sc)) { 2923 DNPRINTF(MFII_D_IOCTL, "%s: mfii_get_info failed\n", 2924 DEVNAME(sc)); 2925 goto done; 2926 } 2927 2928 /* send single element command to retrieve size for full structure */ 2929 cfg = malloc(sizeof *cfg, M_DEVBUF, M_NOWAIT | M_ZERO); 2930 if (cfg == NULL) 2931 goto done; 2932 if (mfii_mgmt(sc, MR_DCMD_CONF_GET, NULL, cfg, sizeof(*cfg), 2933 MFII_DATA_IN, false)) { 2934 free(cfg, M_DEVBUF); 2935 goto done; 2936 } 2937 2938 size = cfg->mfc_size; 2939 free(cfg, M_DEVBUF); 2940 2941 /* memory for read config */ 2942 cfg = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); 2943 if (cfg == NULL) 2944 goto done; 2945 if (mfii_mgmt(sc, MR_DCMD_CONF_GET, NULL, cfg, size, 2946 MFII_DATA_IN, false)) { 2947 free(cfg, M_DEVBUF); 2948 goto done; 2949 } 2950 2951 /* replace current pointer with new one */ 2952 if (sc->sc_cfg) 2953 free(sc->sc_cfg, M_DEVBUF); 2954 sc->sc_cfg = cfg; 2955 2956 /* get all ld info */ 2957 memset(&mbox, 0, sizeof(mbox)); 2958 if (sc->sc_max256vd) 2959 mbox.b[0] = 1; 2960 if (mfii_mgmt(sc, MR_DCMD_LD_GET_LIST, &mbox, &sc->sc_ld_list, 2961 sizeof(sc->sc_ld_list), MFII_DATA_IN, false)) 2962 goto done; 2963 2964 /* get memory for all ld structures */ 2965 size = cfg->mfc_no_ld * sizeof(struct mfi_ld_details); 2966 if (sc->sc_ld_sz != size) { 2967 if (sc->sc_ld_details) 2968 free(sc->sc_ld_details, M_DEVBUF); 2969 2970 ld_det = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); 2971 if (ld_det == NULL) 2972 goto done; 2973 sc->sc_ld_sz = size; 2974 sc->sc_ld_details = ld_det; 2975 } 2976 2977 /* find used physical disks */ 2978 size = sizeof(struct mfi_ld_details); 2979 for (i = 0, d = 0; i < cfg->mfc_no_ld; i++) { 2980 memset(&mbox, 0, sizeof(mbox)); 2981 mbox.b[0] = sc->sc_ld_list.mll_list[i].mll_ld.mld_target; 2982 if (mfii_mgmt(sc, MR_DCMD_LD_GET_INFO, &mbox, 2983 &sc->sc_ld_details[i], size, MFII_DATA_IN, false)) 2984 goto done; 2985 2986 d += sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_no_drv_per_span * 2987 sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_span_depth; 2988 } 2989 sc->sc_no_pd = d; 2990 2991 rv = 0; 2992 done: 2993 return (rv); 2994 } 2995 2996 static int 2997 mfii_ioctl_inq(struct mfii_softc *sc, struct bioc_inq *bi) 2998 { 2999 int rv = EINVAL; 3000 struct mfi_conf *cfg = NULL; 3001 3002 DNPRINTF(MFII_D_IOCTL, "%s: mfii_ioctl_inq\n", DEVNAME(sc)); 3003 3004 if (mfii_bio_getitall(sc)) { 3005 DNPRINTF(MFII_D_IOCTL, "%s: mfii_bio_getitall failed\n", 3006 DEVNAME(sc)); 3007 goto done; 3008 } 3009 3010 /* count unused disks as volumes */ 3011 if (sc->sc_cfg == NULL) 3012 goto done; 3013 cfg = sc->sc_cfg; 3014 3015 bi->bi_nodisk = sc->sc_info.mci_pd_disks_present; 3016 bi->bi_novol = cfg->mfc_no_ld + cfg->mfc_no_hs; 3017 #if notyet 3018 bi->bi_novol = cfg->mfc_no_ld + cfg->mfc_no_hs + 3019 (bi->bi_nodisk - sc->sc_no_pd); 3020 #endif 3021 /* tell bio who we are */ 3022 strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev)); 3023 3024 rv = 0; 3025 done: 3026 return (rv); 3027 } 3028 3029 static int 3030 mfii_ioctl_vol(struct mfii_softc *sc, struct bioc_vol *bv) 3031 { 3032 int i, per, rv = EINVAL; 3033 3034 DNPRINTF(MFII_D_IOCTL, "%s: mfii_ioctl_vol %#x\n", 3035 DEVNAME(sc), bv->bv_volid); 3036 3037 /* we really could skip and expect that inq took care of it */ 3038 if (mfii_bio_getitall(sc)) { 3039 DNPRINTF(MFII_D_IOCTL, "%s: mfii_bio_getitall failed\n", 3040 DEVNAME(sc)); 3041 goto done; 3042 } 3043 3044 if (bv->bv_volid >= sc->sc_ld_list.mll_no_ld) { 3045 /* go do hotspares & unused disks */ 3046 rv = mfii_bio_hs(sc, bv->bv_volid, MFI_MGMT_VD, bv); 3047 goto done; 3048 } 3049 3050 i = bv->bv_volid; 3051 strlcpy(bv->bv_dev, sc->sc_ld_details[i].mld_cfg.mlc_prop.mlp_name, 3052 sizeof(bv->bv_dev)); 3053 3054 switch (sc->sc_ld_list.mll_list[i].mll_state) { 3055 case MFI_LD_OFFLINE: 3056 bv->bv_status = BIOC_SVOFFLINE; 3057 break; 3058 3059 case MFI_LD_PART_DEGRADED: 3060 case MFI_LD_DEGRADED: 3061 bv->bv_status = BIOC_SVDEGRADED; 3062 break; 3063 3064 case MFI_LD_ONLINE: 3065 bv->bv_status = BIOC_SVONLINE; 3066 break; 3067 3068 default: 3069 bv->bv_status = BIOC_SVINVALID; 3070 DNPRINTF(MFII_D_IOCTL, "%s: invalid logical disk state %#x\n", 3071 DEVNAME(sc), 3072 sc->sc_ld_list.mll_list[i].mll_state); 3073 } 3074 3075 /* additional status can modify MFI status */ 3076 switch (sc->sc_ld_details[i].mld_progress.mlp_in_prog) { 3077 case MFI_LD_PROG_CC: 3078 bv->bv_status = BIOC_SVSCRUB; 3079 per = (int)sc->sc_ld_details[i].mld_progress.mlp_cc.mp_progress; 3080 bv->bv_percent = (per * 100) / 0xffff; 3081 bv->bv_seconds = 3082 sc->sc_ld_details[i].mld_progress.mlp_cc.mp_elapsed_seconds; 3083 break; 3084 3085 case MFI_LD_PROG_BGI: 3086 bv->bv_status = BIOC_SVSCRUB; 3087 per = (int)sc->sc_ld_details[i].mld_progress.mlp_bgi.mp_progress; 3088 bv->bv_percent = (per * 100) / 0xffff; 3089 bv->bv_seconds = 3090 sc->sc_ld_details[i].mld_progress.mlp_bgi.mp_elapsed_seconds; 3091 break; 3092 3093 case MFI_LD_PROG_FGI: 3094 case MFI_LD_PROG_RECONSTRUCT: 3095 /* nothing yet */ 3096 break; 3097 } 3098 3099 #if 0 3100 if (sc->sc_ld_details[i].mld_cfg.mlc_prop.mlp_cur_cache_policy & 0x01) 3101 bv->bv_cache = BIOC_CVWRITEBACK; 3102 else 3103 bv->bv_cache = BIOC_CVWRITETHROUGH; 3104 #endif 3105 3106 /* 3107 * The RAID levels are determined per the SNIA DDF spec, this is only 3108 * a subset that is valid for the MFI controller. 3109 */ 3110 bv->bv_level = sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_pri_raid; 3111 if (sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_span_depth > 1) 3112 bv->bv_level *= 10; 3113 3114 bv->bv_nodisk = 3115 sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_no_drv_per_span * 3116 sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_span_depth; 3117 3118 bv->bv_size = sc->sc_ld_details[i].mld_size * 512; /* bytes per block */ 3119 bv->bv_stripe_size = 3120 (512 << sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_stripe_size) 3121 / 1024; /* in KB */ 3122 3123 rv = 0; 3124 done: 3125 return (rv); 3126 } 3127 3128 static int 3129 mfii_ioctl_disk(struct mfii_softc *sc, struct bioc_disk *bd) 3130 { 3131 struct mfi_conf *cfg; 3132 struct mfi_array *ar; 3133 struct mfi_ld_cfg *ld; 3134 struct mfi_pd_details *pd; 3135 struct mfi_pd_list *pl; 3136 struct scsipi_inquiry_data *inqbuf; 3137 char vend[8+16+4+1], *vendp; 3138 int i, rv = EINVAL; 3139 int arr, vol, disk, span; 3140 union mfi_mbox mbox; 3141 3142 DNPRINTF(MFII_D_IOCTL, "%s: mfii_ioctl_disk %#x\n", 3143 DEVNAME(sc), bd->bd_diskid); 3144 3145 /* we really could skip and expect that inq took care of it */ 3146 if (mfii_bio_getitall(sc)) { 3147 DNPRINTF(MFII_D_IOCTL, "%s: mfii_bio_getitall failed\n", 3148 DEVNAME(sc)); 3149 return (rv); 3150 } 3151 cfg = sc->sc_cfg; 3152 3153 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); 3154 pl = malloc(sizeof *pl, M_DEVBUF, M_WAITOK); 3155 3156 ar = cfg->mfc_array; 3157 vol = bd->bd_volid; 3158 if (vol >= cfg->mfc_no_ld) { 3159 /* do hotspares */ 3160 rv = mfii_bio_hs(sc, bd->bd_volid, MFI_MGMT_SD, bd); 3161 goto freeme; 3162 } 3163 3164 /* calculate offset to ld structure */ 3165 ld = (struct mfi_ld_cfg *)( 3166 ((uint8_t *)cfg) + offsetof(struct mfi_conf, mfc_array) + 3167 cfg->mfc_array_size * cfg->mfc_no_array); 3168 3169 /* use span 0 only when raid group is not spanned */ 3170 if (ld[vol].mlc_parm.mpa_span_depth > 1) 3171 span = bd->bd_diskid / ld[vol].mlc_parm.mpa_no_drv_per_span; 3172 else 3173 span = 0; 3174 arr = ld[vol].mlc_span[span].mls_index; 3175 3176 /* offset disk into pd list */ 3177 disk = bd->bd_diskid % ld[vol].mlc_parm.mpa_no_drv_per_span; 3178 3179 if (ar[arr].pd[disk].mar_pd.mfp_id == 0xffffU) { 3180 /* disk is missing but succeed command */ 3181 bd->bd_status = BIOC_SDFAILED; 3182 rv = 0; 3183 3184 /* try to find an unused disk for the target to rebuild */ 3185 if (mfii_mgmt(sc, MR_DCMD_PD_GET_LIST, NULL, pl, sizeof(*pl), 3186 MFII_DATA_IN, false)) 3187 goto freeme; 3188 3189 for (i = 0; i < pl->mpl_no_pd; i++) { 3190 if (pl->mpl_address[i].mpa_scsi_type != 0) 3191 continue; 3192 3193 memset(&mbox, 0, sizeof(mbox)); 3194 mbox.s[0] = pl->mpl_address[i].mpa_pd_id; 3195 if (mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, 3196 pd, sizeof(*pd), MFII_DATA_IN, false)) 3197 continue; 3198 3199 if (pd->mpd_fw_state == MFI_PD_UNCONFIG_GOOD || 3200 pd->mpd_fw_state == MFI_PD_UNCONFIG_BAD) 3201 break; 3202 } 3203 3204 if (i == pl->mpl_no_pd) 3205 goto freeme; 3206 } else { 3207 memset(&mbox, 0, sizeof(mbox)); 3208 mbox.s[0] = ar[arr].pd[disk].mar_pd.mfp_id; 3209 if (mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, pd, sizeof(*pd), 3210 MFII_DATA_IN, false)) { 3211 bd->bd_status = BIOC_SDINVALID; 3212 goto freeme; 3213 } 3214 } 3215 3216 /* get the remaining fields */ 3217 bd->bd_channel = pd->mpd_enc_idx; 3218 bd->bd_target = pd->mpd_enc_slot; 3219 3220 /* get status */ 3221 switch (pd->mpd_fw_state){ 3222 case MFI_PD_UNCONFIG_GOOD: 3223 case MFI_PD_UNCONFIG_BAD: 3224 bd->bd_status = BIOC_SDUNUSED; 3225 break; 3226 3227 case MFI_PD_HOTSPARE: /* XXX dedicated hotspare part of array? */ 3228 bd->bd_status = BIOC_SDHOTSPARE; 3229 break; 3230 3231 case MFI_PD_OFFLINE: 3232 bd->bd_status = BIOC_SDOFFLINE; 3233 break; 3234 3235 case MFI_PD_FAILED: 3236 bd->bd_status = BIOC_SDFAILED; 3237 break; 3238 3239 case MFI_PD_REBUILD: 3240 bd->bd_status = BIOC_SDREBUILD; 3241 break; 3242 3243 case MFI_PD_ONLINE: 3244 bd->bd_status = BIOC_SDONLINE; 3245 break; 3246 3247 case MFI_PD_COPYBACK: 3248 case MFI_PD_SYSTEM: 3249 default: 3250 bd->bd_status = BIOC_SDINVALID; 3251 break; 3252 } 3253 3254 bd->bd_size = pd->mpd_size * 512; /* bytes per block */ 3255 3256 inqbuf = (struct scsipi_inquiry_data *)&pd->mpd_inq_data; 3257 vendp = inqbuf->vendor; 3258 memcpy(vend, vendp, sizeof vend - 1); 3259 vend[sizeof vend - 1] = '\0'; 3260 strlcpy(bd->bd_vendor, vend, sizeof(bd->bd_vendor)); 3261 3262 /* XXX find a way to retrieve serial nr from drive */ 3263 /* XXX find a way to get bd_procdev */ 3264 3265 #if 0 3266 mfp = &pd->mpd_progress; 3267 if (mfp->mfp_in_prog & MFI_PD_PROG_PR) { 3268 mp = &mfp->mfp_patrol_read; 3269 bd->bd_patrol.bdp_percent = (mp->mp_progress * 100) / 0xffff; 3270 bd->bd_patrol.bdp_seconds = mp->mp_elapsed_seconds; 3271 } 3272 #endif 3273 3274 rv = 0; 3275 freeme: 3276 free(pd, M_DEVBUF); 3277 free(pl, M_DEVBUF); 3278 3279 return (rv); 3280 } 3281 3282 static int 3283 mfii_ioctl_alarm(struct mfii_softc *sc, struct bioc_alarm *ba) 3284 { 3285 uint32_t opc; 3286 int rv = 0; 3287 int8_t ret; 3288 mfii_direction_t dir = MFII_DATA_NONE; 3289 3290 switch (ba->ba_opcode) { 3291 case BIOC_SADISABLE: 3292 opc = MR_DCMD_SPEAKER_DISABLE; 3293 break; 3294 3295 case BIOC_SAENABLE: 3296 opc = MR_DCMD_SPEAKER_ENABLE; 3297 break; 3298 3299 case BIOC_SASILENCE: 3300 opc = MR_DCMD_SPEAKER_SILENCE; 3301 break; 3302 3303 case BIOC_GASTATUS: 3304 opc = MR_DCMD_SPEAKER_GET; 3305 dir = MFII_DATA_IN; 3306 break; 3307 3308 case BIOC_SATEST: 3309 opc = MR_DCMD_SPEAKER_TEST; 3310 break; 3311 3312 default: 3313 DNPRINTF(MFII_D_IOCTL, 3314 "%s: mfii_ioctl_alarm biocalarm invalid opcode %x\n", 3315 DEVNAME(sc), ba->ba_opcode); 3316 return (EINVAL); 3317 } 3318 3319 if (mfii_mgmt(sc, opc, NULL, &ret, sizeof(ret), dir, false)) 3320 rv = EINVAL; 3321 else 3322 if (ba->ba_opcode == BIOC_GASTATUS) 3323 ba->ba_status = ret; 3324 else 3325 ba->ba_status = 0; 3326 3327 return (rv); 3328 } 3329 3330 static int 3331 mfii_ioctl_blink(struct mfii_softc *sc, struct bioc_blink *bb) 3332 { 3333 int i, found, rv = EINVAL; 3334 union mfi_mbox mbox; 3335 uint32_t cmd; 3336 struct mfi_pd_list *pd; 3337 3338 DNPRINTF(MFII_D_IOCTL, "%s: mfii_ioctl_blink %x\n", DEVNAME(sc), 3339 bb->bb_status); 3340 3341 /* channel 0 means not in an enclosure so can't be blinked */ 3342 if (bb->bb_channel == 0) 3343 return (EINVAL); 3344 3345 pd = malloc(sizeof(*pd), M_DEVBUF, M_WAITOK); 3346 3347 if (mfii_mgmt(sc, MR_DCMD_PD_GET_LIST, NULL, pd, sizeof(*pd), 3348 MFII_DATA_IN, false)) 3349 goto done; 3350 3351 for (i = 0, found = 0; i < pd->mpl_no_pd; i++) 3352 if (bb->bb_channel == pd->mpl_address[i].mpa_enc_index && 3353 bb->bb_target == pd->mpl_address[i].mpa_enc_slot) { 3354 found = 1; 3355 break; 3356 } 3357 3358 if (!found) 3359 goto done; 3360 3361 memset(&mbox, 0, sizeof(mbox)); 3362 mbox.s[0] = pd->mpl_address[i].mpa_pd_id; 3363 3364 switch (bb->bb_status) { 3365 case BIOC_SBUNBLINK: 3366 cmd = MR_DCMD_PD_UNBLINK; 3367 break; 3368 3369 case BIOC_SBBLINK: 3370 cmd = MR_DCMD_PD_BLINK; 3371 break; 3372 3373 case BIOC_SBALARM: 3374 default: 3375 DNPRINTF(MFII_D_IOCTL, 3376 "%s: mfii_ioctl_blink biocblink invalid opcode %x\n", 3377 DEVNAME(sc), bb->bb_status); 3378 goto done; 3379 } 3380 3381 3382 if (mfii_mgmt(sc, cmd, &mbox, NULL, 0, MFII_DATA_NONE, false)) 3383 goto done; 3384 3385 rv = 0; 3386 done: 3387 free(pd, M_DEVBUF); 3388 return (rv); 3389 } 3390 3391 static int 3392 mfii_makegood(struct mfii_softc *sc, uint16_t pd_id) 3393 { 3394 struct mfii_foreign_scan_info *fsi; 3395 struct mfi_pd_details *pd; 3396 union mfi_mbox mbox; 3397 int rv; 3398 3399 fsi = malloc(sizeof *fsi, M_DEVBUF, M_WAITOK); 3400 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); 3401 3402 memset(&mbox, 0, sizeof mbox); 3403 mbox.s[0] = pd_id; 3404 rv = mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, pd, sizeof(*pd), 3405 MFII_DATA_IN, false); 3406 if (rv != 0) 3407 goto done; 3408 3409 if (pd->mpd_fw_state == MFI_PD_UNCONFIG_BAD) { 3410 mbox.s[0] = pd_id; 3411 mbox.s[1] = pd->mpd_pd.mfp_seq; 3412 mbox.b[4] = MFI_PD_UNCONFIG_GOOD; 3413 rv = mfii_mgmt(sc, MR_DCMD_PD_SET_STATE, &mbox, NULL, 0, 3414 MFII_DATA_NONE, false); 3415 if (rv != 0) 3416 goto done; 3417 } 3418 3419 memset(&mbox, 0, sizeof mbox); 3420 mbox.s[0] = pd_id; 3421 rv = mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, pd, sizeof(*pd), 3422 MFII_DATA_IN, false); 3423 if (rv != 0) 3424 goto done; 3425 3426 if (pd->mpd_ddf_state & MFI_DDF_FOREIGN) { 3427 rv = mfii_mgmt(sc, MR_DCMD_CFG_FOREIGN_SCAN, NULL, 3428 fsi, sizeof(*fsi), MFII_DATA_IN, false); 3429 if (rv != 0) 3430 goto done; 3431 3432 if (fsi->count > 0) { 3433 rv = mfii_mgmt(sc, MR_DCMD_CFG_FOREIGN_CLEAR, NULL, 3434 NULL, 0, MFII_DATA_NONE, false); 3435 if (rv != 0) 3436 goto done; 3437 } 3438 } 3439 3440 memset(&mbox, 0, sizeof mbox); 3441 mbox.s[0] = pd_id; 3442 rv = mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, pd, sizeof(*pd), 3443 MFII_DATA_IN, false); 3444 if (rv != 0) 3445 goto done; 3446 3447 if (pd->mpd_fw_state != MFI_PD_UNCONFIG_GOOD || 3448 pd->mpd_ddf_state & MFI_DDF_FOREIGN) 3449 rv = ENXIO; 3450 3451 done: 3452 free(fsi, M_DEVBUF); 3453 free(pd, M_DEVBUF); 3454 3455 return (rv); 3456 } 3457 3458 static int 3459 mfii_makespare(struct mfii_softc *sc, uint16_t pd_id) 3460 { 3461 struct mfi_hotspare *hs; 3462 struct mfi_pd_details *pd; 3463 union mfi_mbox mbox; 3464 size_t size; 3465 int rv = EINVAL; 3466 3467 /* we really could skip and expect that inq took care of it */ 3468 if (mfii_bio_getitall(sc)) { 3469 DNPRINTF(MFII_D_IOCTL, "%s: mfii_bio_getitall failed\n", 3470 DEVNAME(sc)); 3471 return (rv); 3472 } 3473 size = sizeof *hs + sizeof(uint16_t) * sc->sc_cfg->mfc_no_array; 3474 3475 hs = malloc(size, M_DEVBUF, M_WAITOK); 3476 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); 3477 3478 memset(&mbox, 0, sizeof mbox); 3479 mbox.s[0] = pd_id; 3480 rv = mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, pd, sizeof(*pd), 3481 MFII_DATA_IN, false); 3482 if (rv != 0) 3483 goto done; 3484 3485 memset(hs, 0, size); 3486 hs->mhs_pd.mfp_id = pd->mpd_pd.mfp_id; 3487 hs->mhs_pd.mfp_seq = pd->mpd_pd.mfp_seq; 3488 rv = mfii_mgmt(sc, MR_DCMD_CFG_MAKE_SPARE, NULL, hs, size, 3489 MFII_DATA_OUT, false); 3490 3491 done: 3492 free(hs, M_DEVBUF); 3493 free(pd, M_DEVBUF); 3494 3495 return (rv); 3496 } 3497 3498 static int 3499 mfii_ioctl_setstate(struct mfii_softc *sc, struct bioc_setstate *bs) 3500 { 3501 struct mfi_pd_details *pd; 3502 struct mfi_pd_list *pl; 3503 int i, found, rv = EINVAL; 3504 union mfi_mbox mbox; 3505 3506 DNPRINTF(MFII_D_IOCTL, "%s: mfii_ioctl_setstate %x\n", DEVNAME(sc), 3507 bs->bs_status); 3508 3509 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); 3510 pl = malloc(sizeof *pl, M_DEVBUF, M_WAITOK); 3511 3512 if (mfii_mgmt(sc, MR_DCMD_PD_GET_LIST, NULL, pl, sizeof(*pl), 3513 MFII_DATA_IN, false)) 3514 goto done; 3515 3516 for (i = 0, found = 0; i < pl->mpl_no_pd; i++) 3517 if (bs->bs_channel == pl->mpl_address[i].mpa_enc_index && 3518 bs->bs_target == pl->mpl_address[i].mpa_enc_slot) { 3519 found = 1; 3520 break; 3521 } 3522 3523 if (!found) 3524 goto done; 3525 3526 memset(&mbox, 0, sizeof(mbox)); 3527 mbox.s[0] = pl->mpl_address[i].mpa_pd_id; 3528 3529 if (mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, pd, sizeof(*pd), 3530 MFII_DATA_IN, false)) 3531 goto done; 3532 3533 mbox.s[0] = pl->mpl_address[i].mpa_pd_id; 3534 mbox.s[1] = pd->mpd_pd.mfp_seq; 3535 3536 switch (bs->bs_status) { 3537 case BIOC_SSONLINE: 3538 mbox.b[4] = MFI_PD_ONLINE; 3539 break; 3540 3541 case BIOC_SSOFFLINE: 3542 mbox.b[4] = MFI_PD_OFFLINE; 3543 break; 3544 3545 case BIOC_SSHOTSPARE: 3546 mbox.b[4] = MFI_PD_HOTSPARE; 3547 break; 3548 3549 case BIOC_SSREBUILD: 3550 if (pd->mpd_fw_state != MFI_PD_OFFLINE) { 3551 if ((rv = mfii_makegood(sc, 3552 pl->mpl_address[i].mpa_pd_id))) 3553 goto done; 3554 3555 if ((rv = mfii_makespare(sc, 3556 pl->mpl_address[i].mpa_pd_id))) 3557 goto done; 3558 3559 memset(&mbox, 0, sizeof(mbox)); 3560 mbox.s[0] = pl->mpl_address[i].mpa_pd_id; 3561 rv = mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, 3562 pd, sizeof(*pd), MFII_DATA_IN, false); 3563 if (rv != 0) 3564 goto done; 3565 3566 /* rebuilding might be started by mfii_makespare() */ 3567 if (pd->mpd_fw_state == MFI_PD_REBUILD) { 3568 rv = 0; 3569 goto done; 3570 } 3571 3572 mbox.s[0] = pl->mpl_address[i].mpa_pd_id; 3573 mbox.s[1] = pd->mpd_pd.mfp_seq; 3574 } 3575 mbox.b[4] = MFI_PD_REBUILD; 3576 break; 3577 3578 default: 3579 DNPRINTF(MFII_D_IOCTL, "%s: mfii_ioctl_setstate invalid " 3580 "opcode %x\n", DEVNAME(sc), bs->bs_status); 3581 goto done; 3582 } 3583 3584 3585 rv = mfii_mgmt(sc, MR_DCMD_PD_SET_STATE, &mbox, NULL, 0, 3586 MFII_DATA_NONE, false); 3587 done: 3588 free(pd, M_DEVBUF); 3589 free(pl, M_DEVBUF); 3590 return (rv); 3591 } 3592 3593 #if 0 3594 int 3595 mfii_ioctl_patrol(struct mfii_softc *sc, struct bioc_patrol *bp) 3596 { 3597 uint32_t opc; 3598 int rv = 0; 3599 struct mfi_pr_properties prop; 3600 struct mfi_pr_status status; 3601 uint32_t time, exec_freq; 3602 3603 switch (bp->bp_opcode) { 3604 case BIOC_SPSTOP: 3605 case BIOC_SPSTART: 3606 if (bp->bp_opcode == BIOC_SPSTART) 3607 opc = MR_DCMD_PR_START; 3608 else 3609 opc = MR_DCMD_PR_STOP; 3610 if (mfii_mgmt(sc, opc, NULL, NULL, 0, MFII_DATA_IN, false)) 3611 return (EINVAL); 3612 break; 3613 3614 case BIOC_SPMANUAL: 3615 case BIOC_SPDISABLE: 3616 case BIOC_SPAUTO: 3617 /* Get device's time. */ 3618 opc = MR_DCMD_TIME_SECS_GET; 3619 if (mfii_mgmt(sc, opc, NULL, &time, sizeof(time), 3620 MFII_DATA_IN, false)) 3621 return (EINVAL); 3622 3623 opc = MR_DCMD_PR_GET_PROPERTIES; 3624 if (mfii_mgmt(sc, opc, NULL, &prop, sizeof(prop), 3625 MFII_DATA_IN, false)) 3626 return (EINVAL); 3627 3628 switch (bp->bp_opcode) { 3629 case BIOC_SPMANUAL: 3630 prop.op_mode = MFI_PR_OPMODE_MANUAL; 3631 break; 3632 case BIOC_SPDISABLE: 3633 prop.op_mode = MFI_PR_OPMODE_DISABLED; 3634 break; 3635 case BIOC_SPAUTO: 3636 if (bp->bp_autoival != 0) { 3637 if (bp->bp_autoival == -1) 3638 /* continuously */ 3639 exec_freq = 0xffffffffU; 3640 else if (bp->bp_autoival > 0) 3641 exec_freq = bp->bp_autoival; 3642 else 3643 return (EINVAL); 3644 prop.exec_freq = exec_freq; 3645 } 3646 if (bp->bp_autonext != 0) { 3647 if (bp->bp_autonext < 0) 3648 return (EINVAL); 3649 else 3650 prop.next_exec = 3651 time + bp->bp_autonext; 3652 } 3653 prop.op_mode = MFI_PR_OPMODE_AUTO; 3654 break; 3655 } 3656 3657 opc = MR_DCMD_PR_SET_PROPERTIES; 3658 if (mfii_mgmt(sc, opc, NULL, &prop, sizeof(prop), 3659 MFII_DATA_OUT, false)) 3660 return (EINVAL); 3661 3662 break; 3663 3664 case BIOC_GPSTATUS: 3665 opc = MR_DCMD_PR_GET_PROPERTIES; 3666 if (mfii_mgmt(sc, opc, NULL, &prop, sizeof(prop), 3667 MFII_DATA_IN, false)) 3668 return (EINVAL); 3669 3670 opc = MR_DCMD_PR_GET_STATUS; 3671 if (mfii_mgmt(sc, opc, NULL, &status, sizeof(status), 3672 MFII_DATA_IN, false)) 3673 return (EINVAL); 3674 3675 /* Get device's time. */ 3676 opc = MR_DCMD_TIME_SECS_GET; 3677 if (mfii_mgmt(sc, opc, NULL, &time, sizeof(time), 3678 MFII_DATA_IN, false)) 3679 return (EINVAL); 3680 3681 switch (prop.op_mode) { 3682 case MFI_PR_OPMODE_AUTO: 3683 bp->bp_mode = BIOC_SPMAUTO; 3684 bp->bp_autoival = prop.exec_freq; 3685 bp->bp_autonext = prop.next_exec; 3686 bp->bp_autonow = time; 3687 break; 3688 case MFI_PR_OPMODE_MANUAL: 3689 bp->bp_mode = BIOC_SPMMANUAL; 3690 break; 3691 case MFI_PR_OPMODE_DISABLED: 3692 bp->bp_mode = BIOC_SPMDISABLED; 3693 break; 3694 default: 3695 printf("%s: unknown patrol mode %d\n", 3696 DEVNAME(sc), prop.op_mode); 3697 break; 3698 } 3699 3700 switch (status.state) { 3701 case MFI_PR_STATE_STOPPED: 3702 bp->bp_status = BIOC_SPSSTOPPED; 3703 break; 3704 case MFI_PR_STATE_READY: 3705 bp->bp_status = BIOC_SPSREADY; 3706 break; 3707 case MFI_PR_STATE_ACTIVE: 3708 bp->bp_status = BIOC_SPSACTIVE; 3709 break; 3710 case MFI_PR_STATE_ABORTED: 3711 bp->bp_status = BIOC_SPSABORTED; 3712 break; 3713 default: 3714 printf("%s: unknown patrol state %d\n", 3715 DEVNAME(sc), status.state); 3716 break; 3717 } 3718 3719 break; 3720 3721 default: 3722 DNPRINTF(MFII_D_IOCTL, 3723 "%s: mfii_ioctl_patrol biocpatrol invalid opcode %x\n", 3724 DEVNAME(sc), bp->bp_opcode); 3725 return (EINVAL); 3726 } 3727 3728 return (rv); 3729 } 3730 #endif 3731 3732 static int 3733 mfii_bio_hs(struct mfii_softc *sc, int volid, int type, void *bio_hs) 3734 { 3735 struct mfi_conf *cfg; 3736 struct mfi_hotspare *hs; 3737 struct mfi_pd_details *pd; 3738 struct bioc_disk *sdhs; 3739 struct bioc_vol *vdhs; 3740 struct scsipi_inquiry_data *inqbuf; 3741 char vend[8+16+4+1], *vendp; 3742 int i, rv = EINVAL; 3743 uint32_t size; 3744 union mfi_mbox mbox; 3745 3746 DNPRINTF(MFII_D_IOCTL, "%s: mfii_vol_hs %d\n", DEVNAME(sc), volid); 3747 3748 if (!bio_hs) 3749 return (EINVAL); 3750 3751 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); 3752 3753 /* send single element command to retrieve size for full structure */ 3754 cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); 3755 if (mfii_mgmt(sc, MR_DCMD_CONF_GET, NULL, cfg, sizeof(*cfg), 3756 MFII_DATA_IN, false)) 3757 goto freeme; 3758 3759 size = cfg->mfc_size; 3760 free(cfg, M_DEVBUF); 3761 3762 /* memory for read config */ 3763 cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); 3764 if (mfii_mgmt(sc, MR_DCMD_CONF_GET, NULL, cfg, size, 3765 MFII_DATA_IN, false)) 3766 goto freeme; 3767 3768 /* calculate offset to hs structure */ 3769 hs = (struct mfi_hotspare *)( 3770 ((uint8_t *)cfg) + offsetof(struct mfi_conf, mfc_array) + 3771 cfg->mfc_array_size * cfg->mfc_no_array + 3772 cfg->mfc_ld_size * cfg->mfc_no_ld); 3773 3774 if (volid < cfg->mfc_no_ld) 3775 goto freeme; /* not a hotspare */ 3776 3777 if (volid > (cfg->mfc_no_ld + cfg->mfc_no_hs)) 3778 goto freeme; /* not a hotspare */ 3779 3780 /* offset into hotspare structure */ 3781 i = volid - cfg->mfc_no_ld; 3782 3783 DNPRINTF(MFII_D_IOCTL, 3784 "%s: mfii_vol_hs i %d volid %d no_ld %d no_hs %d " 3785 "hs %p cfg %p id %02x\n", DEVNAME(sc), i, volid, cfg->mfc_no_ld, 3786 cfg->mfc_no_hs, hs, cfg, hs[i].mhs_pd.mfp_id); 3787 3788 /* get pd fields */ 3789 memset(&mbox, 0, sizeof(mbox)); 3790 mbox.s[0] = hs[i].mhs_pd.mfp_id; 3791 if (mfii_mgmt(sc, MR_DCMD_PD_GET_INFO, &mbox, pd, sizeof(*pd), 3792 MFII_DATA_IN, false)) { 3793 DNPRINTF(MFII_D_IOCTL, "%s: mfii_vol_hs illegal PD\n", 3794 DEVNAME(sc)); 3795 goto freeme; 3796 } 3797 3798 switch (type) { 3799 case MFI_MGMT_VD: 3800 vdhs = bio_hs; 3801 vdhs->bv_status = BIOC_SVONLINE; 3802 vdhs->bv_size = pd->mpd_size / 2 * 1024; /* XXX why? */ 3803 vdhs->bv_level = -1; /* hotspare */ 3804 vdhs->bv_nodisk = 1; 3805 break; 3806 3807 case MFI_MGMT_SD: 3808 sdhs = bio_hs; 3809 sdhs->bd_status = BIOC_SDHOTSPARE; 3810 sdhs->bd_size = pd->mpd_size / 2 * 1024; /* XXX why? */ 3811 sdhs->bd_channel = pd->mpd_enc_idx; 3812 sdhs->bd_target = pd->mpd_enc_slot; 3813 inqbuf = (struct scsipi_inquiry_data *)&pd->mpd_inq_data; 3814 vendp = inqbuf->vendor; 3815 memcpy(vend, vendp, sizeof vend - 1); 3816 vend[sizeof vend - 1] = '\0'; 3817 strlcpy(sdhs->bd_vendor, vend, sizeof(sdhs->bd_vendor)); 3818 break; 3819 3820 default: 3821 goto freeme; 3822 } 3823 3824 DNPRINTF(MFII_D_IOCTL, "%s: mfii_vol_hs 6\n", DEVNAME(sc)); 3825 rv = 0; 3826 freeme: 3827 free(pd, M_DEVBUF); 3828 free(cfg, M_DEVBUF); 3829 3830 return (rv); 3831 } 3832 3833 #endif /* NBIO > 0 */ 3834 3835 #define MFI_BBU_SENSORS 4 3836 3837 static void 3838 mfii_bbu(struct mfii_softc *sc, envsys_data_t *edata) 3839 { 3840 struct mfi_bbu_status bbu; 3841 u_int32_t status; 3842 u_int32_t mask; 3843 u_int32_t soh_bad; 3844 int rv; 3845 3846 mutex_enter(&sc->sc_lock); 3847 rv = mfii_mgmt(sc, MR_DCMD_BBU_GET_STATUS, NULL, &bbu, 3848 sizeof(bbu), MFII_DATA_IN, false); 3849 mutex_exit(&sc->sc_lock); 3850 if (rv != 0) { 3851 edata->state = ENVSYS_SINVALID; 3852 edata->value_cur = 0; 3853 return; 3854 } 3855 3856 switch (bbu.battery_type) { 3857 case MFI_BBU_TYPE_IBBU: 3858 case MFI_BBU_TYPE_IBBU09: 3859 case MFI_BBU_TYPE_CVPM02: 3860 mask = MFI_BBU_STATE_BAD_IBBU; 3861 soh_bad = 0; 3862 break; 3863 case MFI_BBU_TYPE_BBU: 3864 mask = MFI_BBU_STATE_BAD_BBU; 3865 soh_bad = (bbu.detail.bbu.is_SOH_good == 0); 3866 break; 3867 3868 case MFI_BBU_TYPE_NONE: 3869 default: 3870 edata->state = ENVSYS_SCRITICAL; 3871 edata->value_cur = 0; 3872 return; 3873 } 3874 3875 status = le32toh(bbu.fw_status) & mask; 3876 switch (edata->sensor) { 3877 case 0: 3878 edata->value_cur = (status || soh_bad) ? 0 : 1; 3879 edata->state = 3880 edata->value_cur ? ENVSYS_SVALID : ENVSYS_SCRITICAL; 3881 return; 3882 case 1: 3883 edata->value_cur = le16toh(bbu.voltage) * 1000; 3884 edata->state = ENVSYS_SVALID; 3885 return; 3886 case 2: 3887 edata->value_cur = (int16_t)le16toh(bbu.current) * 1000; 3888 edata->state = ENVSYS_SVALID; 3889 return; 3890 case 3: 3891 edata->value_cur = 3892 le16toh(bbu.temperature) * 1000000 + 273150000; 3893 edata->state = ENVSYS_SVALID; 3894 return; 3895 } 3896 } 3897 3898 static void 3899 mfii_refresh_ld_sensor(struct mfii_softc *sc, envsys_data_t *edata) 3900 { 3901 struct bioc_vol bv; 3902 int error; 3903 3904 memset(&bv, 0, sizeof(bv)); 3905 bv.bv_volid = edata->sensor - MFI_BBU_SENSORS; 3906 mutex_enter(&sc->sc_lock); 3907 error = mfii_ioctl_vol(sc, &bv); 3908 mutex_exit(&sc->sc_lock); 3909 if (error) 3910 bv.bv_status = BIOC_SVINVALID; 3911 bio_vol_to_envsys(edata, &bv); 3912 } 3913 3914 static void 3915 mfii_init_ld_sensor(struct mfii_softc *sc, envsys_data_t *sensor, int i) 3916 { 3917 sensor->units = ENVSYS_DRIVE; 3918 sensor->state = ENVSYS_SINVALID; 3919 sensor->value_cur = ENVSYS_DRIVE_EMPTY; 3920 /* Enable monitoring for drive state changes */ 3921 sensor->flags |= ENVSYS_FMONSTCHANGED; 3922 snprintf(sensor->desc, sizeof(sensor->desc), "%s:%d", DEVNAME(sc), i); 3923 } 3924 3925 static void 3926 mfii_attach_sensor(struct mfii_softc *sc, envsys_data_t *s) 3927 { 3928 if (sysmon_envsys_sensor_attach(sc->sc_sme, s)) 3929 aprint_error_dev(sc->sc_dev, 3930 "failed to attach sensor %s\n", s->desc); 3931 } 3932 3933 static int 3934 mfii_create_sensors(struct mfii_softc *sc) 3935 { 3936 int i, rv; 3937 const int nsensors = MFI_BBU_SENSORS + MFII_MAX_LD_EXT; 3938 3939 sc->sc_sme = sysmon_envsys_create(); 3940 sc->sc_sensors = malloc(sizeof(envsys_data_t) * nsensors, 3941 M_DEVBUF, M_WAITOK | M_ZERO); 3942 3943 /* BBU */ 3944 sc->sc_sensors[0].units = ENVSYS_INDICATOR; 3945 sc->sc_sensors[0].state = ENVSYS_SINVALID; 3946 sc->sc_sensors[0].value_cur = 0; 3947 sc->sc_sensors[1].units = ENVSYS_SVOLTS_DC; 3948 sc->sc_sensors[1].state = ENVSYS_SINVALID; 3949 sc->sc_sensors[1].value_cur = 0; 3950 sc->sc_sensors[2].units = ENVSYS_SAMPS; 3951 sc->sc_sensors[2].state = ENVSYS_SINVALID; 3952 sc->sc_sensors[2].value_cur = 0; 3953 sc->sc_sensors[3].units = ENVSYS_STEMP; 3954 sc->sc_sensors[3].state = ENVSYS_SINVALID; 3955 sc->sc_sensors[3].value_cur = 0; 3956 3957 if (ISSET(le32toh(sc->sc_info.mci_hw_present), MFI_INFO_HW_BBU)) { 3958 sc->sc_bbuok = true; 3959 sc->sc_sensors[0].flags |= ENVSYS_FMONCRITICAL; 3960 snprintf(sc->sc_sensors[0].desc, sizeof(sc->sc_sensors[0].desc), 3961 "%s BBU state", DEVNAME(sc)); 3962 snprintf(sc->sc_sensors[1].desc, sizeof(sc->sc_sensors[1].desc), 3963 "%s BBU voltage", DEVNAME(sc)); 3964 snprintf(sc->sc_sensors[2].desc, sizeof(sc->sc_sensors[2].desc), 3965 "%s BBU current", DEVNAME(sc)); 3966 snprintf(sc->sc_sensors[3].desc, sizeof(sc->sc_sensors[3].desc), 3967 "%s BBU temperature", DEVNAME(sc)); 3968 for (i = 0; i < MFI_BBU_SENSORS; i++) { 3969 mfii_attach_sensor(sc, &sc->sc_sensors[i]); 3970 } 3971 } 3972 3973 for (i = 0; i < sc->sc_ld_list.mll_no_ld; i++) { 3974 mfii_init_ld_sensor(sc, &sc->sc_sensors[i + MFI_BBU_SENSORS], i); 3975 mfii_attach_sensor(sc, &sc->sc_sensors[i + MFI_BBU_SENSORS]); 3976 } 3977 3978 sc->sc_sme->sme_name = DEVNAME(sc); 3979 sc->sc_sme->sme_cookie = sc; 3980 sc->sc_sme->sme_refresh = mfii_refresh_sensor; 3981 rv = sysmon_envsys_register(sc->sc_sme); 3982 if (rv) { 3983 aprint_error_dev(sc->sc_dev, 3984 "unable to register with sysmon (rv = %d)\n", rv); 3985 sysmon_envsys_destroy(sc->sc_sme); 3986 sc->sc_sme = NULL; 3987 } 3988 return rv; 3989 3990 } 3991 3992 static int 3993 mfii_destroy_sensors(struct mfii_softc *sc) 3994 { 3995 if (sc->sc_sme == NULL) 3996 return 0; 3997 sysmon_envsys_unregister(sc->sc_sme); 3998 sc->sc_sme = NULL; 3999 free(sc->sc_sensors, M_DEVBUF); 4000 return 0; 4001 } 4002 4003 static void 4004 mfii_refresh_sensor(struct sysmon_envsys *sme, envsys_data_t *edata) 4005 { 4006 struct mfii_softc *sc = sme->sme_cookie; 4007 4008 if (edata->sensor >= MFI_BBU_SENSORS + MFII_MAX_LD_EXT) 4009 return; 4010 4011 if (edata->sensor < MFI_BBU_SENSORS) { 4012 if (sc->sc_bbuok) 4013 mfii_bbu(sc, edata); 4014 } else { 4015 mfii_refresh_ld_sensor(sc, edata); 4016 } 4017 } 4018