aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mpt
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2011-07-29 18:38:31 +0000
committerMarius Strobl <marius@FreeBSD.org>2011-07-29 18:38:31 +0000
commitec3e6e77a14adfe0003269d39caa4cf1e221d3e5 (patch)
tree833b3a25c644ec5b4b7abae3ffe673a949cd23da /sys/dev/mpt
parent87e255ac52df209599578d5af2fb6843afa62a1e (diff)
downloadsrc-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.c68
-rw-r--r--sys/dev/mpt/mpt_raid.c19
-rw-r--r--sys/dev/mpt/mpt_raid.h1
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