I'm using NEC Express5800 with its optional RAID contoller, but I
could not set the drive state into rebuild or offline by bioctl(8).
Tsubai found mfi(4) needs to be fixed to operate the firmware
interface properly.
I'd like to commit below diff from him.
test? ok?
Fix mfi ioctl to set drive state properly.
diff from Tsubai Masanari
Index: sys/dev/ic/mfi.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/dev/ic/mfi.c,v
retrieving revision 1.157
diff -u -p -r1.157 mfi.c
--- sys/dev/ic/mfi.c 14 Sep 2014 14:17:24 -0000 1.157
+++ sys/dev/ic/mfi.c 29 Nov 2014 02:01:18 -0000
@@ -1900,6 +1900,7 @@ int
mfi_ioctl_setstate(struct mfi_softc *sc, struct bioc_setstate *bs)
{
struct mfi_pd_list *pd;
+ struct mfi_pd_details *info;
int i, found, rv = EINVAL;
uint8_t mbox[MFI_MBOX_SIZE];
@@ -1907,6 +1908,7 @@ mfi_ioctl_setstate(struct mfi_softc *sc,
bs->bs_status);
pd = malloc(sizeof(*pd), M_DEVBUF, M_WAITOK);
+ info = malloc(sizeof *info, M_DEVBUF, M_WAITOK);
if (mfi_mgmt(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN,
sizeof(*pd), pd, NULL))
@@ -1925,23 +1927,30 @@ mfi_ioctl_setstate(struct mfi_softc *sc,
memset(mbox, 0, sizeof mbox);
*((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id;
+ if (mfi_mgmt(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN,
+ sizeof *info, info, mbox))
+ goto done;
+
+ *((uint16_t *)&mbox[0]) = pd->mpl_address[i].mpa_pd_id;
+ *((uint16_t *)&mbox[2]) = info->mpd_pd.mfp_seq;
switch (bs->bs_status) {
case BIOC_SSONLINE:
- mbox[2] = MFI_PD_ONLINE;
+ mbox[4] = MFI_PD_ONLINE;
break;
case BIOC_SSOFFLINE:
- mbox[2] = MFI_PD_OFFLINE;
+ mbox[4] = MFI_PD_OFFLINE;
break;
case BIOC_SSHOTSPARE:
- mbox[2] = MFI_PD_HOTSPARE;
+ mbox[4] = MFI_PD_HOTSPARE;
break;
-/*
+
case BIOC_SSREBUILD:
+ mbox[4] = MFI_PD_REBUILD;
break;
-*/
+
default:
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_setstate invalid "
"opcode %x\n", DEVNAME(sc), bs->bs_status);
@@ -1955,6 +1964,7 @@ mfi_ioctl_setstate(struct mfi_softc *sc,
rv = 0;
done:
free(pd, M_DEVBUF, 0);
+ free(info, M_DEVBUF, 0);
return (rv);
}