Author: marius
Date: Fri Jul 29 18:38:31 2011
New Revision: 224494
URL: http://svn.freebsd.org/changeset/base/224494

Log:
  - 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

Modified:
  head/sys/dev/mpt/mpt_cam.c
  head/sys/dev/mpt/mpt_raid.c
  head/sys/dev/mpt/mpt_raid.h

Modified: head/sys/dev/mpt/mpt_cam.c
==============================================================================
--- head/sys/dev/mpt/mpt_cam.c  Fri Jul 29 18:35:10 2011        (r224493)
+++ head/sys/dev/mpt/mpt_cam.c  Fri Jul 29 18:38:31 2011        (r224494)
@@ -2538,7 +2538,8 @@ mpt_cam_event(struct mpt_softc *mpt, 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, 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:

Modified: head/sys/dev/mpt/mpt_raid.c
==============================================================================
--- head/sys/dev/mpt/mpt_raid.c Fri Jul 29 18:35:10 2011        (r224493)
+++ head/sys/dev/mpt/mpt_raid.c Fri Jul 29 18:38:31 2011        (r224494)
@@ -812,6 +812,25 @@ mpt_map_physdisk(struct mpt_softc *mpt, 
 
 /* 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;

Modified: head/sys/dev/mpt/mpt_raid.h
==============================================================================
--- head/sys/dev/mpt/mpt_raid.h Fri Jul 29 18:35:10 2011        (r224493)
+++ head/sys/dev/mpt/mpt_raid.h Fri Jul 29 18:38:31 2011        (r224494)
@@ -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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to