PERFORCE change 197444 for review

Matt Jacob mjacob at FreeBSD.org
Tue Aug 9 22:33:09 UTC 2011


http://p4web.freebsd.org/@@197444?ac=10

Change 197444 by mjacob at mjacob-sandbox on 2011/08/09 22:32:23

	Do some cleanup so that this SIM can unload too.
	
	Handle the case that seems to occur with Phase 10 FW where
	Gen1 enclosure disks (not the SES) don't attach. Key off
	of SAS_DISCOVERY_EVENT end and then get SAS extended device
	config with the NxtHandle option to see who to add. It turns
	out there a bunch of devices without PHYs filled out, but
	the ones that are then can actually get attached.

Affected files ...

.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2cam.c#5 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2pci.c#5 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.c#7 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.h#8 edit
.. //depot/projects/mjacob-dev/sys/modules/mpt2sas/Makefile#1 add

Differences ...

==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2cam.c#5 (text+ko) ====

@@ -191,15 +191,21 @@
 }
 
 
-void
+/*
+ * Should be called locked
+ */
+int
 mpt2sas_cam_detach(mpt2sas_t *mpt)
 {
-	if (mpt->sim != NULL) {
-		xpt_free_path(mpt->path);
-		xpt_bus_deregister(cam_sim_path(mpt->sim));
-		cam_sim_free(mpt->sim, TRUE);
-		mpt->sim = NULL;
-	}
+	if (mpt->sim == NULL)
+		return (ENODEV);
+	if (mpt->sim->refcount > 2)
+		return (EBUSY);
+	xpt_free_path(mpt->path);
+	xpt_bus_deregister(cam_sim_path(mpt->sim));
+	cam_sim_free(mpt->sim, TRUE);
+	mpt->sim = NULL;
+	return (0);
 }
 
 /* This routine is used after a system crash to dump core onto the swap device.

==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2pci.c#5 (text+ko) ====

@@ -203,6 +203,7 @@
 		if (bootverbose) {
 			mpt->prt_mask |= MP2PRT_INFO;
 		}
+		mpt->prt_mask = 0x3f;
 
 	}
 }
@@ -213,13 +214,14 @@
         struct sysctl_ctx_list *ctx;
         struct sysctl_oid *tree;
 	mpt2sas_t *mpt;
-	int iqd;
+	int iqd, result;
 
 	mpt  = (mpt2sas_t *)device_get_softc(dev);
 	if (mpt == NULL) {
 		device_printf(dev, "cannot allocate softc\n");
 		return (ENOMEM);
 	}
+	result = 0;
 	memset(mpt, 0, sizeof(mpt2sas_t));
 	mpt->dev = dev;
 	mpt2sas_set_options(mpt);
@@ -259,6 +261,7 @@
 	mpt->pci_mem_reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &mpt->pci_mem_rid, 0, ~0, 0, RF_ACTIVE);
 	if (mpt->pci_mem_reg == NULL) {
 		mpt2sas_prt(mpt, MP2PRT_ERR, "Unable to memory map registers.\n");
+		result = ENXIO;
 		goto bad;
 	} else {
 		mpt->pci_mem_st = rman_get_bustag(mpt->pci_mem_reg);
@@ -290,6 +293,7 @@
 	}
 	mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, RF_ACTIVE | RF_SHAREABLE);
 	if (mpt->pci_irq == NULL) {
+		result = ENXIO;
 		mpt2sas_prt(mpt, MP2PRT_ERR, "could not allocate interrupt\n");
 		goto bad;
 	}
@@ -301,6 +305,7 @@
 
 	/* Register the interrupt handler */
 	if (bus_setup_intr(dev, mpt->pci_irq, MPT2_IFLAGS, NULL, mpt2sas_pci_intr, mpt, &mpt->ih)) {
+		result = ENXIO;
 		mpt2sas_prt(mpt, MP2PRT_ERR, "could not setup interrupt\n");
 		goto bad;
 	}
@@ -312,7 +317,8 @@
 
 	/* Initialize the hardware */
 	if (mpt->disabled == 0) {
-		if (mpt2sas_attach(mpt) != 0) {
+		result = mpt2sas_attach(mpt);
+		if (result != 0) {
 			goto bad;
 		}
 	} else {
@@ -333,7 +339,7 @@
 	/*
 	 * but return zero to preserve unit numbering
 	 */
-	return (0);
+	return (result);
 }
 
 static void
@@ -390,10 +396,11 @@
 {
 	mpt2sas_t *mpt = (mpt2sas_t*)device_get_softc(dev);
 
-	if (mpt) {
+	if (mpt && mpt->disabled == 0) {
+		int r = mpt2sas_detach(mpt);
+		if (r)
+			return (r);
 		mpt2sas_disable_ints(mpt);
-		mpt2sas_detach(mpt);
-		mpt2sas_reset(mpt);
 		mpt2sas_mem_free(mpt);
 		mpt2sas_free_bus_resources(mpt);
 	}

==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.c#7 (text+ko) ====

@@ -210,8 +210,6 @@
 					mpt->cfg_ExtPageLength = le16toh(m->ExtPageLength);
 					mpt->cfg_ExtPageType = m->ExtPageType;
 				}
-			} else {
-				mpt2sas_prt(mpt, MP2PRT_ERR, "%s: MPI2_CONFIG_REPLY IOC STATUS %#x\n", __func__, req->IOCStatus);
 			}
 		} else {
 			mpt2sas_prt(mpt, MP2PRT_ERR, "%s: MPI2_FUNCTION_CONFIG with no reply frame\n", __func__);
@@ -339,6 +337,86 @@
 }
 
 static void
+mpt2sas_discovery_change(mpt2sas_t *mpt)
+{
+	int off, error;
+	MPI2_CONFIG_REQUEST *rqs;
+	MPI2_CONFIG_PAGE_HEADER hdr;
+	MPI2_CONFIG_PAGE_SAS_DEV_0 *sio;
+	U16 handle, cfglen;
+	struct topochg *tp;
+	request_t *req;
+
+	if (mpt2sas_get_cfgbuf(mpt, &off)) {
+		mpt2sas_prt(mpt, MP2PRT_WARN, "%s: cannot allocate config buffer\n", __func__);
+		return;
+	}
+	error = mpt2sas_read_config_header(mpt, MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0);
+	if (error) {
+		mpt2sas_free_cfgbuf(mpt, off);
+		return;
+	}
+	cfglen = mpt->cfg_ExtPageLength;
+	hdr = mpt->cfg_hdr;
+	handle = 0xffff;
+	for (;;) {
+		MPT2SAS_GET_REQUEST(mpt, req);
+		if (req == NULL) {
+			mpt2sas_free_cfgbuf(mpt, off);
+			return;
+		}
+		req->flags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+		rqs = MPT2_REQ2RQS(mpt, req);
+		memset(rqs, 0,  sizeof (MPI2_CONFIG_REQUEST));
+		rqs->Function = MPI2_FUNCTION_CONFIG;
+		rqs->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+		rqs->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
+		rqs->ExtPageLength = htole16(cfglen);
+		rqs->PageAddress = htole32(MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE | handle);
+		rqs->Header = hdr;
+		mpt2sas_single_sge(&rqs->PageBufferSGE.MpiSimple, mpt->config.paddr + off, cfglen << 2, MPI2_SGE_FLAGS_IOC_TO_HOST|SINGLE_SGE);
+		memset(&mpt->config.vaddr[off], 0, MPT2_CONFIG_DATA_SIZE(mpt));
+		mpt2sas_send_cmd(mpt, req);
+		error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 1000);
+		if (error) {
+			if (error != EIO || mpt->iocsts != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
+				MPT2SAS_SYNC_ERR_NORET(mpt, error);
+			}
+			break;
+		}
+		bus_dmamap_sync(mpt->config.dmat, mpt->config.dmap, BUS_DMASYNC_POSTREAD);
+		sio = (MPI2_CONFIG_PAGE_SAS_DEV_0 *) &mpt->config.vaddr[off];
+		mpt2host_sas_dev_page0_convert(dsc);
+		mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: DevHandle %x SAS Address 0x%016jx Name 0x%016jx DeviceInfo 0x%08x PhyNum 0x%02x\n", __func__,
+		    sio->DevHandle, (uintmax_t) le64toh(sio->SASAddress), (uintmax_t) le64toh(sio->DeviceName),  le32toh(sio->DeviceInfo),
+		    sio->PhyNum);
+		handle = sio->DevHandle;
+		if (mpt2_hdl2dev(mpt, handle)) {
+			continue;
+		}
+		TAILQ_FOREACH(tp, &mpt->topo_wait_list, links) {
+			if (tp->create && tp->hdl == handle) {
+				break;
+			}
+		}
+		if (tp) {
+			continue;
+		}
+		tp = TAILQ_FIRST(&mpt->topo_free_list);
+		if (tp == NULL) {
+			mpt2sas_free_cfgbuf(mpt, off);
+			return;
+		}
+		TAILQ_REMOVE(&mpt->topo_free_list, tp, links);
+		tp->hdl = handle;
+		tp->create = 1;
+		TAILQ_INSERT_TAIL(&mpt->topo_wait_list, tp, links);
+	}
+	mpt2sas_free_cfgbuf(mpt, off);
+	mpt->fabchanged = 0;
+}
+
+static void
 mpt2sas_topology_change(mpt2sas_t *mpt, MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *tpl)
 {
 	static const char *lrstat[16] = {
@@ -552,8 +630,16 @@
 		mpt2sas_prt(mpt, MP2PRT_INFO, "MPI2_EVENT_IS_OPERATION_STATUS\n");
 		break;
 	case MPI2_EVENT_SAS_DISCOVERY:
-		mpt2sas_prt(mpt, MP2PRT_CONFIG, "MPI2_EVENT_SAS_DISCOVERY\n");
+	{
+		MPI2_EVENT_DATA_SAS_DISCOVERY *p = (MPI2_EVENT_DATA_SAS_DISCOVERY *)evp->EventData;
+		mpt2host_sas_discovery_event_convert(p);
+		mpt2sas_prt(mpt, MP2PRT_CONFIG2, "MPI2_EVENT_SAS_DISCOVERY: Flags=%x ReasonCode=%x PhysicalPort=%x DiscoveryStatus=%x\n",
+		    p->Flags, p->ReasonCode, p->PhysicalPort, p->DiscoveryStatus);
+		if (p->Flags == MPI2_EVENT_SAS_DISC_DEVICE_CHANGE && p->ReasonCode == MPI2_EVENT_SAS_DISC_RC_COMPLETED) {
+			mpt->fabchanged = 1;
+		}
 		break;
+	}
 	case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
 		mpt2sas_prt(mpt, MP2PRT_CONFIG, "MPI2_EVENT_SAS_BROADCAST_PRIMITIVE\n");
 		break;
@@ -1052,6 +1138,11 @@
 	MPT2_2_HOST32(sio, Reserved2);
 	MPT2_2_HOST32(sio, Reserved3);
 }
+
+void mpt2host_sas_discovery_event_convert(MPI2_EVENT_DATA_SAS_DISCOVERY *sp)
+{
+	MPT2_2_HOST32(sp, DiscoveryStatus);
+}
 #endif
 /******************************* Discovery and SAS/IOC Config Routines **************************/
 
@@ -2009,6 +2100,7 @@
 		return (EIO);
 	}
 
+	mpt2sas_prt(mpt, MP2PRT_CONFIG, "IO Unit Page 1 Flags = 0x%x\n", mpt->iounit_pg1_flags);
 	base = mpt->iounit_pg1_flags;
 	if (mpt->ioc_facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) {
 		base &= ~MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
@@ -2222,6 +2314,9 @@
 			break;
 		}
 	}
+	if (mpt->fabchanged) {
+		mpt2sas_discovery_change(mpt);
+	}
 	if (mpt->ehook_active == 0 && mpt->path && mpt->devchanged) {
 		sas_dev_t *dp;
 		int r;
@@ -2294,17 +2389,20 @@
 	MPT2_LOCK(mpt);
 	mpt->ehook.ich_func = mpt2sas_intr_enable;
 	mpt->ehook.ich_arg = mpt;
+        mpt->ehook_active = 1;
 	if (config_intrhook_establish(&mpt->ehook) != 0) {
+		mpt->ehook_active = 0;
                 return (-EIO);
         }
-        mpt->ehook_active = 1;
 	callout_init(&mpt->watchdog, 1);
 	MPT2_UNLOCK(mpt);
 	error = mpt2sas_init(mpt);
 	if (error) {
 		MPT2_LOCK(mpt);
-		config_intrhook_disestablish(&mpt->ehook);
-		mpt->ehook_active = 0;
+		if (mpt->ehook_active) {
+			mpt->ehook_active = 0;
+			config_intrhook_disestablish(&mpt->ehook);
+		}
 		MPT2_UNLOCK(mpt);
 		return (error);
 	}
@@ -2316,8 +2414,10 @@
 	error = mpt2sas_cam_attach(mpt);
 	if (error) {
 		MPT2_LOCK(mpt);
-		config_intrhook_disestablish(&mpt->ehook);
-		mpt->ehook_active = 0;
+		if (mpt->ehook_active) {
+			mpt->ehook_active = 0;
+			config_intrhook_disestablish(&mpt->ehook);
+		}
 		MPT2_UNLOCK(mpt);
 		return (error);
 	}
@@ -2331,14 +2431,20 @@
 int
 mpt2sas_detach(mpt2sas_t *mpt)
 {
+	int res;
+
 	MPT2_LOCK(mpt);
+	res = mpt2sas_cam_detach(mpt);
+	if (res) {
+		MPT2_UNLOCK(mpt);
+		return (res);
+	}
 	if (mpt->ehook_active) {
 		config_intrhook_disestablish(&mpt->ehook);
 		mpt->ehook_active = 0;
 	}
-	if (callout_active(&mpt->watchdog)) {
+	if (callout_active(&mpt->watchdog))
 		callout_drain(&mpt->watchdog);
-	}
 	TAILQ_REMOVE(&mpt2sas_tailq, mpt, links);
 	MPT2_UNLOCK(mpt);
 	return (0);

==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.h#8 (text+ko) ====

@@ -307,11 +307,13 @@
 void mpt2host_portfacts_convert(MPI2_PORT_FACTS_REPLY *);
 void mpt2host_phydata_convert(MPI2_SAS_IO_UNIT0_PHY_DATA *);
 void mpt2host_sas_dev_page0_convert(MPI2_CONFIG_PAGE_SAS_DEV_0 *);
+void mpt2host_sas_discovery_event_convert(MPI2_EVENT_DATA_SAS_DISCOVERY *);
 #else
 #define	mpt2host_iocfacts_convert(x)		do { ; } while (0)
 #define	mpt2host_portfacts_convert(x)		do { ; } while (0)
 #define	mpt2host_phydata_convert(x)		do { ; } while (0)
 #define	mpt2host_sas_dev_page0_convert(x)	do { ; } while (0)
+#define	mpt2host_sas_discovery_event_convert(x)	do { ; } while (0)
 #endif
 
 
@@ -529,6 +531,7 @@
 	 */
 	unsigned int
 		portenabled	:	1,
+		fabchanged	:	1,
 		devchanged	:	1,
 		outofbeer	:	1,
 		acks_needed	:	1,
@@ -696,7 +699,7 @@
 
 /**************************** CAM Routines ***************************/
 int		mpt2sas_cam_attach(mpt2sas_t *);
-void		mpt2sas_cam_detach(mpt2sas_t *);
+int		mpt2sas_cam_detach(mpt2sas_t *);
 void		mpt2sas_cam_done(mpt2sas_t *, request_t *, MPI2_SCSI_IO_REPLY *);
 int		mpt2sas_run_scsicmd(mpt2sas_t *, U16, U8 *, int, bus_addr_t, bus_size_t, boolean_t);
 int		mpt2sas_scsi_abort(mpt2sas_t *, request_t *);


More information about the p4-projects mailing list