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