summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2017-02-07 05:08:54 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2017-02-07 05:08:54 +0000
commitb9a9caf6e4cd32a9a3caad012f363a84eff1fa29 (patch)
tree7c0a1dd27b1537818675af5d39e500a41332c601 /sys/dev
parent8be06fdd1bdcd454806923515778a6f765750ec3 (diff)
handle physical disk state changes.
more specificially we probe the disk if it goes from UNCONFIGURED_GOOD to a SYSTEM disk, and detach it if goes from being a SYSTEM disk to anything else. this semantic comes from the lsi^Wavago code in the illumos mr_sas driver. seems to work fine. i think this covers all the ways a passthru disk can transition on these boards.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/mfii.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/sys/dev/pci/mfii.c b/sys/dev/pci/mfii.c
index 52a022885d0..f7346e82c9d 100644
--- a/sys/dev/pci/mfii.c
+++ b/sys/dev/pci/mfii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfii.c,v 1.39 2017/02/07 04:43:59 dlg Exp $ */
+/* $OpenBSD: mfii.c,v 1.40 2017/02/07 05:08:53 dlg Exp $ */
/*
* Copyright (c) 2012 David Gwynne <dlg@openbsd.org>
@@ -379,6 +379,8 @@ void mfii_aen_pd_insert(struct mfii_softc *,
const struct mfi_evtarg_pd_address *);
void mfii_aen_pd_remove(struct mfii_softc *,
const struct mfi_evtarg_pd_address *);
+void mfii_aen_pd_state_change(struct mfii_softc *,
+ const struct mfi_evtarg_pd_state *);
/*
* mfii boards support asynchronous (and non-polled) completion of
@@ -940,6 +942,14 @@ mfii_aen(void *arg)
mfii_aen_pd_remove(sc, &med->args.pd_address);
break;
+
+ case MFI_EVT_PD_STATE_CHANGE:
+ if (med->med_arg_type != MFI_EVT_ARGS_PD_STATE)
+ break;
+
+ mfii_aen_pd_state_change(sc, &med->args.pd_state);
+ break;
+
default:
break;
}
@@ -990,6 +1000,30 @@ mfii_aen_pd_remove(struct mfii_softc *sc,
}
void
+mfii_aen_pd_state_change(struct mfii_softc *sc,
+ const struct mfi_evtarg_pd_state *state)
+{
+ uint16_t target = lemtoh16(&state->pd.mep_device_id);
+
+ if (state->prev_state == htole32(MFI_PD_SYSTEM) &&
+ state->new_state != htole32(MFI_PD_SYSTEM)) {
+ /* it's been pulled or configured for raid */
+
+ scsi_activate(sc->sc_pd->pd_scsibus, target, -1,
+ DVACT_DEACTIVATE);
+ /* outstanding commands will simply complete or get aborted */
+ scsi_detach_target(sc->sc_pd->pd_scsibus, target,
+ DETACH_FORCE);
+
+ } else if (state->prev_state == htole32(MFI_PD_UNCONFIG_GOOD) &&
+ state->new_state == htole32(MFI_PD_SYSTEM)) {
+ /* the firmware is handing the disk over */
+
+ scsi_probe_target(sc->sc_pd->pd_scsibus, target);
+ }
+}
+
+void
mfii_aen_unregister(struct mfii_softc *sc)
{
/* XXX */