DF-4214 / fix.diff
--- a/sys/dev/disk/mpt/mpt_raid.c +++ b/sys/dev/disk/mpt/mpt_raid.c @@ -133,6 +133,12 @@ static void mpt_schedule_raid_refresh(struct mpt_softc *mpt); static uint32_t raid_handler_id = MPT_HANDLER_ID_NONE; +/* + * mpt_reply_handlers[] is global and mpt_register_handler() is idempotent + * across controllers (it returns the existing slot), so the handler may + * only be deregistered when the LAST mpt_raid personality detaches. + */ +static u_int raid_handler_refs; static const char * mpt_vol_type(struct mpt_raid_volume *vol) @@ -291,6 +297,7 @@ handler.reply_handler = mpt_raid_reply_handler; error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler, &raid_handler_id); + raid_handler_refs++; if (error != 0) { mpt_prt(mpt, "Unable to register RAID haandler!\n"); goto cleanup; @@ -336,8 +343,9 @@ MPT_LOCK(mpt); mpt_terminate_raid_thread(mpt); handler.reply_handler = mpt_raid_reply_handler; - mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler, - raid_handler_id); + if (raid_handler_refs > 0 && --raid_handler_refs == 0) + mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler, + raid_handler_id); xpt_setup_ccb(&csa->ccb_h, mpt->path, /*priority*/5); csa->ccb_h.func_code = XPT_SASYNC_CB; csa->event_enable = 0; |