diff options
author | mjacob <mjacob@FreeBSD.org> | 2007-02-23 05:51:57 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2007-02-23 05:51:57 +0000 |
commit | 915edfc6181812aef4328b273b73f567dc354014 (patch) | |
tree | 313531e53c900a9911440fd2d06b2fad48fb6a55 /sys/dev | |
parent | 5688edd0032e2541fedeaa58a3f918aa0af73835 (diff) | |
download | FreeBSD-src-915edfc6181812aef4328b273b73f567dc354014.zip FreeBSD-src-915edfc6181812aef4328b273b73f567dc354014.tar.gz |
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
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/isp/isp_freebsd.c | 45 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_cam.c | 42 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_cam.h | 2 |
3 files changed, 76 insertions, 13 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 124a6ee..dc4e5b8 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -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; } diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index 1b4a374..ee2da65 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -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; diff --git a/sys/dev/mpt/mpt_cam.h b/sys/dev/mpt/mpt_cam.h index 0bb6eb2..65e272e 100644 --- a/sys/dev/mpt/mpt_cam.h +++ b/sys/dev/mpt/mpt_cam.h @@ -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> |