Use the new xpt_rescan function to truly now have dynamic
attachment of new devices that arrive (and we notice them via async Fibre Channel events). We've always had the right thing (of sorts) happen when devices go away- this is the corollary function that makes multipath failover actually work. MFC after: 2 weeks
This commit is contained in:
parent
9e6461a2d8
commit
ffcf6651a0
@ -2129,21 +2129,44 @@ isp_watchdog(void *arg)
|
||||
|
||||
|
||||
#if __FreeBSD_version >= 500000
|
||||
#define isp_make_here(isp, tgt) isp_announce(isp, tgt, AC_FOUND_DEVICE)
|
||||
#define isp_make_gone(isp, tgt) isp_announce(isp, tgt, AC_LOST_DEVICE)
|
||||
|
||||
/*
|
||||
* Support function for Announcement
|
||||
* Support functions for Found/Lost
|
||||
*/
|
||||
static void
|
||||
isp_announce(ispsoftc_t *isp, int tgt, int action)
|
||||
isp_make_here(ispsoftc_t *isp, int tgt)
|
||||
{
|
||||
struct cam_path *tmppath;
|
||||
union ccb *ccb;
|
||||
ISPLOCK_2_CAMLOCK(mpt);
|
||||
/*
|
||||
* Allocate a CCB, create a wildcard path for this bus,
|
||||
* and schedule a rescan.
|
||||
*/
|
||||
ccb = xpt_alloc_ccb_nowait();
|
||||
if (ccb == NULL) {
|
||||
isp_prt(isp, ISP_LOGWARN, "unable to alloc CCB for rescan");
|
||||
CAMLOCK_2_ISPLOCK(mpt);
|
||||
return;
|
||||
}
|
||||
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
|
||||
cam_sim_path(isp->isp_sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
|
||||
CAMLOCK_2_ISPLOCK(mpt);
|
||||
isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
|
||||
xpt_free_ccb(ccb);
|
||||
return;
|
||||
}
|
||||
xpt_rescan(ccb);
|
||||
CAMLOCK_2_ISPLOCK(mpt);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_make_gone(ispsoftc_t *isp, int tgt)
|
||||
{
|
||||
struct cam_path *tp;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
if (xpt_create_path(&tmppath, NULL, cam_sim_path(isp->isp_sim), tgt,
|
||||
if (xpt_create_path(&tp, NULL, cam_sim_path(isp->isp_sim), tgt,
|
||||
CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
|
||||
xpt_async(action, tmppath, NULL);
|
||||
xpt_free_path(tmppath);
|
||||
xpt_async(AC_LOST_DEVICE, tp, NULL);
|
||||
xpt_free_path(tp);
|
||||
}
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
}
|
||||
@ -3651,9 +3674,9 @@ isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
|
||||
}
|
||||
if (isp->isp_osinfo.mboxcmd_done == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"%s Mailbox Command (0x%x) Timeout",
|
||||
"%s Mailbox Command (0x%x) Timeout (%uus)",
|
||||
isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled",
|
||||
isp->isp_lastmbxcmd);
|
||||
isp->isp_lastmbxcmd, usecs);
|
||||
mbp->param[0] = MBOX_TIMEOUT;
|
||||
isp->isp_osinfo.mboxcmd_done = 1;
|
||||
}
|
||||
|
@ -2083,13 +2083,44 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req,
|
||||
break;
|
||||
|
||||
case MPI_EVENT_RESCAN:
|
||||
{
|
||||
union ccb *ccb;
|
||||
uint32_t pathid;
|
||||
/*
|
||||
* In general this means a device has been added to the loop.
|
||||
*/
|
||||
mpt_prt(mpt, "Rescan Port: %d\n", (data0 >> 8) & 0xff);
|
||||
/* xpt_async(AC_FOUND_DEVICE, path, NULL); */
|
||||
break;
|
||||
if (mpt->ready == 0) {
|
||||
break;
|
||||
}
|
||||
if (mpt->phydisk_sim) {
|
||||
pathid = cam_sim_path(mpt->phydisk_sim);;
|
||||
} else {
|
||||
pathid = cam_sim_path(mpt->sim);
|
||||
}
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
/*
|
||||
* Allocate a CCB, create a wildcard path for this bus,
|
||||
* and schedule a rescan.
|
||||
*/
|
||||
ccb = xpt_alloc_ccb_nowait();
|
||||
if (ccb == NULL) {
|
||||
mpt_prt(mpt, "unable to alloc CCB for rescan\n");
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
break;
|
||||
}
|
||||
|
||||
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid,
|
||||
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
mpt_prt(mpt, "unable to create path for rescan\n");
|
||||
xpt_free_ccb(ccb);
|
||||
break;
|
||||
}
|
||||
xpt_rescan(ccb);
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
break;
|
||||
}
|
||||
case MPI_EVENT_LINK_STATUS_CHANGE:
|
||||
mpt_prt(mpt, "Port %d: LinkState: %s\n",
|
||||
(data1 >> 8) & 0xff,
|
||||
@ -2909,6 +2940,13 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
|
||||
break;
|
||||
}
|
||||
#ifdef MPT_TEST_MULTIPATH
|
||||
if (mpt->failure_id == ccb->ccb_h.target_id) {
|
||||
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
|
||||
mpt_set_ccb_status(ccb, CAM_SEL_TIMEOUT);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
ccb->csio.scsi_status = SCSI_STATUS_OK;
|
||||
mpt_start(sim, ccb);
|
||||
return;
|
||||
|
@ -101,6 +101,8 @@
|
||||
#include <cam/cam_ccb.h>
|
||||
#include <cam/cam_sim.h>
|
||||
#include <cam/cam_xpt.h>
|
||||
#include <cam/cam_periph.h>
|
||||
#include <cam/cam_xpt_periph.h>
|
||||
#include <cam/cam_xpt_sim.h>
|
||||
#include <cam/cam_debug.h>
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
|
Loading…
Reference in New Issue
Block a user