--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c Mon Apr 05 15:52:44 2010 -0700
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c Mon Apr 05 18:56:56 2010 -0400
@@ -111,7 +111,7 @@
static int pmcs_quiesce(dev_info_t *dip);
static boolean_t pmcs_fabricate_wwid(pmcs_hw_t *);
-static void pmcs_create_phy_stats(pmcs_iport_t *);
+static void pmcs_create_all_phy_stats(pmcs_iport_t *);
int pmcs_update_phy_stats(kstat_t *, int);
static void pmcs_destroy_phy_stats(pmcs_iport_t *);
@@ -374,7 +374,7 @@
mutex_exit(&iport->lock);
/* Create kstats for each of the phys in this port */
- pmcs_create_phy_stats(iport);
+ pmcs_create_all_phy_stats(iport);
/*
* Insert this iport handle into our list and set
@@ -3008,15 +3008,78 @@
pwp->scratch_locked = 0;
}
-static void
-pmcs_create_phy_stats(pmcs_iport_t *iport)
+/* Called with iport_lock and phy lock held */
+void
+pmcs_create_one_phy_stats(pmcs_iport_t *iport, pmcs_phy_t *phyp)
{
sas_phy_stats_t *ps;
pmcs_hw_t *pwp;
- pmcs_phy_t *phyp;
int ndata;
char ks_name[KSTAT_STRLEN];
+ ASSERT(mutex_owned(&iport->lock));
+ pwp = iport->pwp;
+ ASSERT(pwp != NULL);
+ ASSERT(mutex_owned(&phyp->phy_lock));
+
+ if (phyp->phy_stats != NULL) {
+ /*
+ * Delete existing kstats with name containing
+ * old iport instance# and allow creation of
+ * new kstats with new iport instance# in the name.
+ */
+ kstat_delete(phyp->phy_stats);
+ }
+
+ ndata = (sizeof (sas_phy_stats_t)/sizeof (kstat_named_t));
+
+ (void) snprintf(ks_name, sizeof (ks_name),
+ "%s.%llx.%d.%d", ddi_driver_name(iport->dip),
+ (longlong_t)pwp->sas_wwns[0],
+ ddi_get_instance(iport->dip), phyp->phynum);
+
+ phyp->phy_stats = kstat_create("pmcs",
+ ddi_get_instance(iport->dip), ks_name, KSTAT_SAS_PHY_CLASS,
+ KSTAT_TYPE_NAMED, ndata, 0);
+
+ if (phyp->phy_stats == NULL) {
+ pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
+ "%s: Failed to create %s kstats for PHY(0x%p) at %s",
+ __func__, ks_name, (void *)phyp, phyp->path);
+ }
+
+ ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
+
+ kstat_named_init(&ps->seconds_since_last_reset,
+ "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->tx_frames,
+ "TxFrames", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->rx_frames,
+ "RxFrames", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->tx_words,
+ "TxWords", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->rx_words,
+ "RxWords", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->invalid_dword_count,
+ "InvalidDwordCount", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->running_disparity_error_count,
+ "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->loss_of_dword_sync_count,
+ "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&ps->phy_reset_problem_count,
+ "PhyResetProblemCount", KSTAT_DATA_ULONGLONG);
+
+ phyp->phy_stats->ks_private = phyp;
+ phyp->phy_stats->ks_update = pmcs_update_phy_stats;
+ kstat_install(phyp->phy_stats);
+}
+
+static void
+pmcs_create_all_phy_stats(pmcs_iport_t *iport)
+{
+ pmcs_hw_t *pwp;
+ pmcs_phy_t *phyp;
+
ASSERT(iport != NULL);
pwp = iport->pwp;
ASSERT(pwp != NULL);
@@ -3027,58 +3090,9 @@
phyp != NULL;
phyp = list_next(&iport->phys, phyp)) {
- pmcs_lock_phy(phyp);
-
- if (phyp->phy_stats != NULL) {
- pmcs_unlock_phy(phyp);
- /* We've already created this kstat instance */
- continue;
- }
-
- ndata = (sizeof (sas_phy_stats_t)/sizeof (kstat_named_t));
-
- (void) snprintf(ks_name, sizeof (ks_name),
- "%s.%llx.%d.%d", ddi_driver_name(iport->dip),
- (longlong_t)pwp->sas_wwns[0],
- ddi_get_instance(iport->dip), phyp->phynum);
-
- phyp->phy_stats = kstat_create("pmcs",
- ddi_get_instance(iport->dip), ks_name, KSTAT_SAS_PHY_CLASS,
- KSTAT_TYPE_NAMED, ndata, 0);
-
- if (phyp->phy_stats == NULL) {
- pmcs_unlock_phy(phyp);
- pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
- "%s: Failed to create %s kstats", __func__,
- ks_name);
- continue;
- }
-
- ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
-
- kstat_named_init(&ps->seconds_since_last_reset,
- "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->tx_frames,
- "TxFrames", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->rx_frames,
- "RxFrames", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->tx_words,
- "TxWords", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->rx_words,
- "RxWords", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->invalid_dword_count,
- "InvalidDwordCount", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->running_disparity_error_count,
- "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->loss_of_dword_sync_count,
- "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG);
- kstat_named_init(&ps->phy_reset_problem_count,
- "PhyResetProblemCount", KSTAT_DATA_ULONGLONG);
-
- phyp->phy_stats->ks_private = phyp;
- phyp->phy_stats->ks_update = pmcs_update_phy_stats;
- kstat_install(phyp->phy_stats);
- pmcs_unlock_phy(phyp);
+ mutex_enter(&phyp->phy_lock);
+ pmcs_create_one_phy_stats(iport, phyp);
+ mutex_exit(&phyp->phy_lock);
}
mutex_exit(&iport->lock);
@@ -3141,12 +3155,17 @@
return;
}
- pmcs_lock_phy(phyp);
- if (phyp->phy_stats != NULL) {
- kstat_delete(phyp->phy_stats);
- phyp->phy_stats = NULL;
+ for (phyp = list_head(&iport->phys);
+ phyp != NULL;
+ phyp = list_next(&iport->phys, phyp)) {
+
+ mutex_enter(&phyp->phy_lock);
+ if (phyp->phy_stats != NULL) {
+ kstat_delete(phyp->phy_stats);
+ phyp->phy_stats = NULL;
+ }
+ mutex_exit(&phyp->phy_lock);
}
- pmcs_unlock_phy(phyp);
mutex_exit(&iport->lock);
}
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c Mon Apr 05 15:52:44 2010 -0700
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c Mon Apr 05 18:56:56 2010 -0400
@@ -7897,6 +7897,9 @@
list_insert_tail(&iport->phys, phyp);
pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS,
&iport->nphy);
+ mutex_enter(&phyp->phy_lock);
+ pmcs_create_one_phy_stats(iport, phyp);
+ mutex_exit(&phyp->phy_lock);
mutex_enter(&iport->refcnt_lock);
iport->refcnt++;
mutex_exit(&iport->refcnt_lock);
@@ -7920,6 +7923,10 @@
pptr = next_pptr) {
next_pptr = list_next(&iport->phys, pptr);
mutex_enter(&pptr->phy_lock);
+ if (pptr->phy_stats != NULL) {
+ kstat_delete(pptr->phy_stats);
+ pptr->phy_stats = NULL;
+ }
pptr->iport = NULL;
pmcs_update_phy_pm_props(pptr, pptr->att_port_pm_tmp,
pptr->tgt_port_pm_tmp, B_FALSE);
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h Mon Apr 05 15:52:44 2010 -0700
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h Mon Apr 05 18:56:56 2010 -0400
@@ -289,7 +289,7 @@
*/
void pmcs_check_iomb_status(pmcs_hw_t *pwp, uint32_t *iomb);
void pmcs_clear_xp(pmcs_hw_t *, pmcs_xscsi_t *);
-
+void pmcs_create_one_phy_stats(pmcs_iport_t *, pmcs_phy_t *);
int pmcs_run_sata_cmd(pmcs_hw_t *, pmcs_phy_t *, fis_t, uint32_t,
uint32_t, uint32_t);
int pmcs_sata_identify(pmcs_hw_t *, pmcs_phy_t *);