--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c Thu Mar 25 20:25:11 2010 -0600
@@ -53,6 +53,7 @@
static void pmcs_clear_phys(pmcs_hw_t *, pmcs_phy_t *);
static int pmcs_configure_new_devices(pmcs_hw_t *, pmcs_phy_t *);
static void pmcs_begin_observations(pmcs_hw_t *);
+static void pmcs_flush_observations(pmcs_hw_t *);
static boolean_t pmcs_report_observations(pmcs_hw_t *);
static boolean_t pmcs_report_iport_observations(pmcs_hw_t *, pmcs_iport_t *,
pmcs_phy_t *);
@@ -2371,7 +2372,6 @@
{
pmcs_phy_t *pptr;
pmcs_phy_t *root_phy;
- int phymap_active;
DTRACE_PROBE2(pmcs__discover__entry, ulong_t, pwp->work_flags,
boolean_t, pwp->config_changed);
@@ -2391,7 +2391,6 @@
return;
}
- phymap_active = pwp->phymap_active;
mutex_exit(&pwp->lock);
/*
@@ -2406,14 +2405,6 @@
SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER);
return;
}
- if (pwp->num_iports != phymap_active) {
- rw_exit(&pwp->iports_lock);
- pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
- "%s: phymaps or iport maps not stable; retry discovery",
- __func__);
- SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER);
- return;
- }
rw_exit(&pwp->iports_lock);
mutex_enter(&pwp->config_lock);
@@ -2580,6 +2571,7 @@
restart:
/* Clean up and restart discovery */
pmcs_release_scratch(pwp);
+ pmcs_flush_observations(pwp);
mutex_enter(&pwp->config_lock);
pwp->configuring = 0;
RESTART_DISCOVERY_LOCKED(pwp);
@@ -2664,6 +2656,41 @@
}
/*
+ * Tell SCSA to flush the observations we've already sent (if any), as they
+ * are no longer valid.
+ */
+static void
+pmcs_flush_observations(pmcs_hw_t *pwp)
+{
+ pmcs_iport_t *iport;
+ scsi_hba_tgtmap_t *tgtmap;
+
+ rw_enter(&pwp->iports_lock, RW_READER);
+ for (iport = list_head(&pwp->iports); iport != NULL;
+ iport = list_next(&pwp->iports, iport)) {
+ /*
+ * Skip this iport if it has no PHYs up.
+ */
+ if (!sas_phymap_uahasphys(pwp->hss_phymap, iport->ua)) {
+ continue;
+ }
+
+ tgtmap = iport->iss_tgtmap;
+ ASSERT(tgtmap);
+ if (scsi_hba_tgtmap_set_flush(tgtmap) != DDI_SUCCESS) {
+ pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL,
+ "%s: Failed set_flush on tgtmap 0x%p", __func__,
+ (void *)tgtmap);
+ } else {
+ pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL,
+ "%s: set flush on tgtmap 0x%p", __func__,
+ (void *)tgtmap);
+ }
+ }
+ rw_exit(&pwp->iports_lock);
+}
+
+/*
* Report current observations to SCSA.
*/
static boolean_t
--- a/usr/src/uts/common/io/scsi/impl/scsi_hba.c Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/io/scsi/impl/scsi_hba.c Thu Mar 25 20:25:11 2010 -0600
@@ -5162,7 +5162,7 @@
* kernels.
*/
SCSI_HBA_LOG((_LOG(1), NULL, self,
- "no node_name for device @%s:\n compatible: %s",
+ "no node_name for device @%s:\n compatible: %s",
addr, *compat));
goto out;
}
@@ -8413,52 +8413,71 @@
return (empty);
}
-int
-scsi_hba_tgtmap_set_begin(scsi_hba_tgtmap_t *handle)
+static int
+scsi_tgtmap_begin_or_flush(scsi_hba_tgtmap_t *handle, boolean_t do_begin)
{
impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle;
dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip;
char *context;
- int rv = DDI_SUCCESS;
+ int rv = DAM_SUCCESS;
int i;
for (i = 0; i < SCSI_TGT_NTYPES; i++) {
- if (tgtmap->tgtmap_dam[i] == NULL)
+ if (tgtmap->tgtmap_dam[i] == NULL) {
continue;
+ }
context = damap_name(tgtmap->tgtmap_dam[i]);
-
- if (i == SCSI_TGT_SCSI_DEVICE) {
- /*
- * In scsi_device context, so we have the 'context'
- * string, diagnose the case where the tgtmap caller
- * is failing to make forward progress, i.e. the caller
- * is never completing an observation, and calling
- * scsi_hbg_tgtmap_set_end. If this occurs, the solaris
- * target/lun state may be out of sync with hardware.
- */
- if (tgtmap->tgtmap_reports++ >=
- scsi_hba_tgtmap_reports_max) {
- tgtmap->tgtmap_noisy++;
- if (tgtmap->tgtmap_noisy == 1)
- SCSI_HBA_LOG((_LOG(WARN), self, NULL,
- "%s: failing to complete a tgtmap "
- "observation", context));
+ if (do_begin == B_TRUE) {
+ if (i == SCSI_TGT_SCSI_DEVICE) {
+ /*
+ * In scsi_device context, so we have the
+ * 'context' string, diagnose the case where
+ * the tgtmap caller is failing to make
+ * forward progress, i.e. the caller is never
+ * completing an observation, and calling
+ * scsi_hbg_tgtmap_set_end. If this occurs,
+ * the solaris target/lun state may be out
+ * of sync with hardware.
+ */
+ if (tgtmap->tgtmap_reports++ >=
+ scsi_hba_tgtmap_reports_max) {
+ tgtmap->tgtmap_noisy++;
+ if (tgtmap->tgtmap_noisy == 1) {
+ SCSI_HBA_LOG((_LOG(WARN), self,
+ NULL, "%s: failing a tgtmap"
+ " observation", context));
+ }
+ }
}
- }
-
- if (damap_addrset_begin(
- tgtmap->tgtmap_dam[i]) != DAM_SUCCESS) {
+
+ rv = damap_addrset_begin(tgtmap->tgtmap_dam[i]);
+ } else {
+ rv = damap_addrset_flush(tgtmap->tgtmap_dam[i]);
+ }
+
+ if (rv != DAM_SUCCESS) {
SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s FAIL", context));
- rv = DDI_FAILURE;
- continue;
- }
-
- SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
- }
- return (rv);
-}
-
+ } else {
+ SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
+ }
+ }
+
+ return ((rv == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
+}
+
+
+int
+scsi_hba_tgtmap_set_begin(scsi_hba_tgtmap_t *handle)
+{
+ return (scsi_tgtmap_begin_or_flush(handle, B_TRUE));
+}
+
+int
+scsi_hba_tgtmap_set_flush(scsi_hba_tgtmap_t *handle)
+{
+ return (scsi_tgtmap_begin_or_flush(handle, B_FALSE));
+}
int
scsi_hba_tgtmap_set_add(scsi_hba_tgtmap_t *handle,
--- a/usr/src/uts/common/os/damap.c Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/os/damap.c Thu Mar 25 20:25:11 2010 -0600
@@ -434,6 +434,46 @@
return (DAM_SUCCESS);
}
+static int
+damap_addrset_flush_locked(damap_t *damapp)
+{
+ dam_t *mapp = (dam_t *)damapp;
+ int idx;
+
+ ASSERT(mapp);
+ ASSERT(mutex_owned(&mapp->dam_lock));
+ if (mapp->dam_rptmode != DAMAP_REPORT_FULLSET) {
+ return (DAM_EINVAL);
+ }
+
+ DTRACE_PROBE2(damap__addrset__flush__locked__enter, char *,
+ mapp->dam_name, dam_t *, mapp);
+ if (mapp->dam_flags & DAM_SETADD) {
+ DTRACE_PROBE2(damap__addrset__flush__locked__reset, char *,
+ mapp->dam_name, dam_t *, mapp);
+
+ /*
+ * cancel stabilization timeout
+ */
+ dam_sched_tmo(mapp, 0, NULL);
+ DAM_INCR_STAT(mapp, dam_jitter);
+
+ /*
+ * clear pending reports
+ */
+ for (idx = 1; idx < mapp->dam_high; idx++) {
+ if (DAM_IN_REPORT(mapp, idx)) {
+ dam_addr_report_release(mapp, idx);
+ }
+ }
+
+ bitset_zero(&mapp->dam_report_set);
+ mapp->dam_flags &= ~DAM_SETADD;
+ }
+
+ return (DAM_SUCCESS);
+}
+
/*
* Initiate full-set report
*
@@ -445,40 +485,58 @@
int
damap_addrset_begin(damap_t *damapp)
{
- dam_t *mapp = (dam_t *)damapp;
- int i;
+ dam_t *mapp = (dam_t *)damapp;
+ int rv;
- if (!mapp || (mapp->dam_rptmode != DAMAP_REPORT_FULLSET))
+ if (mapp == NULL) {
return (DAM_EINVAL);
+ }
DTRACE_PROBE2(damap__addrset__begin, char *, mapp->dam_name, dam_t *,
mapp);
+
mutex_enter(&mapp->dam_lock);
if (dam_map_alloc(mapp) != DAM_SUCCESS) {
mutex_exit(&mapp->dam_lock);
+
return (DAM_MAPFULL);
}
- if (mapp->dam_flags & DAM_SETADD) {
- DTRACE_PROBE2(damap__addrset__begin__reset, char *,
- mapp->dam_name, dam_t *, mapp);
- /*
- * cancel stabilization timeout
- */
- dam_sched_tmo(mapp, 0, NULL);
- DAM_INCR_STAT(mapp, dam_jitter);
+
+ rv = damap_addrset_flush_locked(damapp);
+ if (rv == DAM_SUCCESS) {
+ mapp->dam_flags |= DAM_SETADD;
+ }
+ mutex_exit(&mapp->dam_lock);
+
+ return (rv);
+}
- /*
- * clear pending reports
- */
- for (i = 1; i < mapp->dam_high; i++) {
- if (DAM_IN_REPORT(mapp, i))
- dam_addr_report_release(mapp, i);
- }
+/*
+ * Cancel full-set report
+ *
+ * damapp: address map
+ *
+ * Returns: DAM_SUCCESS
+ * DAM_EINVAL Invalid argument(s)
+ */
+int
+damap_addrset_flush(damap_t *damapp)
+{
+ int rv;
+ dam_t *mapp = (dam_t *)damapp;
+
+ if (mapp == NULL) {
+ return (DAM_EINVAL);
}
- bitset_zero(&mapp->dam_report_set);
- mapp->dam_flags |= DAM_SETADD;
+
+ DTRACE_PROBE2(damap__addrset__flush, char *, mapp->dam_name,
+ dam_t *, mapp);
+
+ mutex_enter(&mapp->dam_lock);
+ rv = damap_addrset_flush_locked(damapp);
mutex_exit(&mapp->dam_lock);
- return (DAM_SUCCESS);
+
+ return (rv);
}
/*
--- a/usr/src/uts/common/sys/damap.h Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/sys/damap.h Thu Mar 25 20:25:11 2010 -0600
@@ -152,6 +152,7 @@
int damap_addrset_add(damap_t *, char *, damap_id_t *,
nvlist_t *, void *);
int damap_addrset_end(damap_t *, int);
+int damap_addrset_flush(damap_t *);
int damap_addrset_reset(damap_t *, int);
damap_id_t damap_id_next(damap_t *, damap_id_list_t, damap_id_t);
char *damap_id2addr(damap_t *, damap_id_t);
--- a/usr/src/uts/common/sys/scsi/impl/transport.h Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/sys/scsi/impl/transport.h Thu Mar 25 20:25:11 2010 -0600
@@ -643,6 +643,8 @@
scsi_hba_tgtmap_t *tgtmap,
uint_t flags);
+int scsi_hba_tgtmap_set_flush(scsi_hba_tgtmap_t *tgtmap);
+
int scsi_hba_tgtmap_tgt_add(
scsi_hba_tgtmap_t *tgtmap,
scsi_tgtmap_tgt_type_t tgt_type,