On Tue, Oct 25, 2016 at 05:29:55PM +0900, YASUOKA Masahiko wrote: > Hi, > > I'm working on making mfii(4) bio(4) capable. > > If you have a machine which has mfii(4), I'd like you to test the diff > following. (It might be risky for production machines for this > moment.) > > After the diff applied, bioctl(8) against the disk (eg. sd0) starts > working and also "sysctl hw.sensors.mfii0" will appear. > > Especially if you can configure a hotspare, testing it is very > helpful for me since I can't use a hotspare on my test machine.
> + > +int > +mfii_ioctl_alarm(struct mfii_softc *sc, struct bioc_alarm *ba) > +{ > + struct mfii_ccb *ccb; > + u_char spkr; > + int rv, cmd, flags = 0; > + > + if (!ISSET(letoh32(sc->sc_info.mci_hw_present), MFI_INFO_HW_ALARM)) > + return (ENXIO); > + > + switch (ba->ba_status) { > + case BIOC_SADISABLE: > + cmd = MR_DCMD_SPEAKER_DISABLE; > + break; > + case BIOC_SAENABLE: > + cmd = MR_DCMD_SPEAKER_ENABLE; > + break; > + case BIOC_SASILENCE: > + cmd = MR_DCMD_SPEAKER_SILENCE; > + break; > + case BIOC_GASTATUS: > + cmd = MR_DCMD_SPEAKER_GET; > + flags = SCSI_DATA_IN; > + break; > + case BIOC_SATEST: > + cmd = MR_DCMD_SPEAKER_TEST; > + break; > + default: > + return (EINVAL); > + } > + > + ccb = scsi_io_get(&sc->sc_iopool, 0); > + rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_SET_STATE, NULL, > + &spkr, sizeof(spkr), flags | SCSI_NOSLEEP); Should this be cmd rather than MR_DCMD_PD_SET_STATE? The cmd values from the switch statement are not used. > + scsi_io_put(&sc->sc_iopool, ccb); > + if (rv != 0) > + return (rv); > + > + ba->ba_status = (ba->ba_status == BIOC_GASTATUS)? spkr : 0; > + > + return (rv); > +} > + > +int > +mfii_ioctl_blink(struct mfii_softc *sc, struct bioc_blink *bb) > +{ > + struct mfi_pd_list *list = NULL; > + struct mfii_ccb *ccb; > + uint8_t mbox[MFI_MBOX_SIZE]; > + int rv, i, cmd; > + > + list = malloc(sizeof(*list), M_TEMP, M_WAITOK | M_ZERO); > + > + ccb = scsi_io_get(&sc->sc_iopool, 0); > + rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_GET_LIST, NULL, > + list, sizeof(*list), SCSI_DATA_IN | SCSI_NOSLEEP); > + scsi_io_put(&sc->sc_iopool, ccb); > + if (rv != 0) > + goto done; > + > + for (i = 0; i < letoh16(list->mpl_no_pd); i++) > + if (list->mpl_address[i].mpa_enc_index == bb->bb_channel && > + list->mpl_address[i].mpa_enc_slot == bb->bb_target) > + break; > + if (i >= letoh16(list->mpl_no_pd)) { > + rv = EINVAL; > + goto done; > + } > + > + memset(mbox, 0, sizeof(mbox)); > + *((uint16_t *)&mbox[0]) = list->mpl_address[i].mpa_pd_id; > + > + switch (bb->bb_status) { > + case BIOC_SBUNBLINK: > + cmd = MR_DCMD_PD_UNBLINK; > + break; > + case BIOC_SBBLINK: > + case BIOC_SBALARM: > + cmd = MR_DCMD_PD_BLINK; > + break; > + default: > + rv = EINVAL; > + goto done; > + } > + > + ccb = scsi_io_get(&sc->sc_iopool, 0); > + rv = mfii_mgmt(sc, ccb, cmd, NULL, NULL, 0, SCSI_NOSLEEP); > + scsi_io_put(&sc->sc_iopool, ccb); > + > + done: > + free(list, M_TEMP, sizeof(*list)); > + > + return (ENOTTY); > +} Shouldn't this be return (rv) to return the EINVAL values? With rv set to 0 before the 'done' to return 0 when there is no error?