diff options
author | Marius Strobl <marius@FreeBSD.org> | 2011-07-29 18:38:31 +0000 |
---|---|---|
committer | Marius Strobl <marius@FreeBSD.org> | 2011-07-29 18:38:31 +0000 |
commit | ec3e6e77a14adfe0003269d39caa4cf1e221d3e5 (patch) | |
tree | 833b3a25c644ec5b4b7abae3ffe673a949cd23da /sys/dev/mpt | |
parent | 87e255ac52df209599578d5af2fb6843afa62a1e (diff) | |
download | src-ec3e6e77a14adfe0003269d39caa4cf1e221d3e5.tar.gz src-ec3e6e77a14adfe0003269d39caa4cf1e221d3e5.zip |
- Send the RELSIM_ADJUST_OPENINGS in response to a MPI_EVENT_QUEUE_FULL using
the right SIM in case the HBA is RAID-capable but the target in question is
not a hot spare or member of a RAID volume.
- Report the loss and addition of SAS and SATA targets detected via PHY link
status changes and signalled by MPI_EVENT_SAS_DEVICE_STATUS_CHANGE to cam(4)
as lost devices and trigger rescans as appropriate. Without this it can take
quite some time until a lost device actually is no longer tried to be used,
if it ever stops. [1]
- Handle MPI_EVENT_IR2, MPI_EVENT_LOG_ENTRY_ADDED, MPI_EVENT_SAS_DISCOVERY
and MPI_EVENT_SAS_PHY_LINK_STATUS silently as these serve no additional
purpose beyond adding cryptic entries to logs.
Thanks to Hans-Joerg Sirtl for providing one of the HBAs these changes were
developed with and RIP to the mainboard that didn't survive testing them.
PR: 157534 [1]
Approved by: re (kib)
MFC after: 2 weeks
Notes
Notes:
svn path=/head/; revision=224494
Diffstat (limited to 'sys/dev/mpt')
-rw-r--r-- | sys/dev/mpt/mpt_cam.c | 68 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_raid.c | 19 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_raid.h | 1 |
3 files changed, 86 insertions, 2 deletions
diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index f54ed7f24c3c..10856721ef8c 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -2538,7 +2538,8 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, pqf->CurrentDepth = le16toh(pqf->CurrentDepth); mpt_prt(mpt, "QUEUE FULL EVENT: Bus 0x%02x Target 0x%02x Depth " "%d\n", pqf->Bus, pqf->TargetID, pqf->CurrentDepth); - if (mpt->phydisk_sim) { + if (mpt->phydisk_sim && mpt_is_raid_member(mpt, + pqf->TargetID) != 0) { sim = mpt->phydisk_sim; } else { sim = mpt->sim; @@ -2570,9 +2571,72 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, mpt_prt(mpt, "IR resync update %d completed\n", (data0 >> 16) & 0xff); break; + case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: + { + union ccb *ccb; + struct cam_sim *sim; + struct cam_path *tmppath; + PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE psdsc; + + psdsc = (PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE)msg->Data; + if (mpt->phydisk_sim && mpt_is_raid_member(mpt, + psdsc->TargetID) != 0) + sim = mpt->phydisk_sim; + else + sim = mpt->sim; + switch(psdsc->ReasonCode) { + case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: + MPTLOCK_2_CAMLOCK(mpt); + 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, + cam_sim_path(sim), psdsc->TargetID, + 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_SAS_DEV_STAT_RC_NOT_RESPONDING: + MPTLOCK_2_CAMLOCK(mpt); + if (xpt_create_path(&tmppath, NULL, cam_sim_path(sim), + psdsc->TargetID, CAM_LUN_WILDCARD) != + CAM_REQ_CMP) { + mpt_prt(mpt, + "unable to create path for async event"); + CAMLOCK_2_MPTLOCK(mpt); + break; + } + xpt_async(AC_LOST_DEVICE, tmppath, NULL); + xpt_free_path(tmppath); + CAMLOCK_2_MPTLOCK(mpt); + break; + case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: + break; + default: + mpt_lprt(mpt, MPT_PRT_WARN, + "SAS device status change: Bus: 0x%02x TargetID: " + "0x%02x ReasonCode: 0x%02x\n", psdsc->TargetID, + psdsc->Bus, psdsc->ReasonCode); + break; + } + break; + } case MPI_EVENT_EVENT_CHANGE: case MPI_EVENT_INTEGRATED_RAID: - case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: + case MPI_EVENT_IR2: + case MPI_EVENT_LOG_ENTRY_ADDED: + case MPI_EVENT_SAS_DISCOVERY: + case MPI_EVENT_SAS_PHY_LINK_STATUS: case MPI_EVENT_SAS_SES: break; default: diff --git a/sys/dev/mpt/mpt_raid.c b/sys/dev/mpt/mpt_raid.c index 07eadfb34d39..8000a0103ed1 100644 --- a/sys/dev/mpt/mpt_raid.c +++ b/sys/dev/mpt/mpt_raid.c @@ -812,6 +812,25 @@ mpt_map_physdisk(struct mpt_softc *mpt, union ccb *ccb, target_id_t *tgt) /* XXX Ignores that there may be multiple busses/IOCs involved. */ int +mpt_is_raid_member(struct mpt_softc *mpt, target_id_t tgt) +{ + struct mpt_raid_disk *mpt_disk; + int i; + + if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) + return (0); + for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) { + mpt_disk = &mpt->raid_disks[i]; + if ((mpt_disk->flags & MPT_RDF_ACTIVE) != 0 && + mpt_disk->config_page.PhysDiskID == tgt) + return (1); + } + return (0); + +} + +/* XXX Ignores that there may be multiple busses/IOCs involved. */ +int mpt_is_raid_volume(struct mpt_softc *mpt, target_id_t tgt) { CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol; diff --git a/sys/dev/mpt/mpt_raid.h b/sys/dev/mpt/mpt_raid.h index 05d2be119acc..2047707b155c 100644 --- a/sys/dev/mpt/mpt_raid.h +++ b/sys/dev/mpt/mpt_raid.h @@ -54,6 +54,7 @@ typedef enum { } mpt_raid_mwce_t; cam_status mpt_map_physdisk(struct mpt_softc *, union ccb *, target_id_t *); +int mpt_is_raid_member(struct mpt_softc *, target_id_t); int mpt_is_raid_volume(struct mpt_softc *, target_id_t); #if 0 cam_status |