PERFORCE change 189247 for review

Matt Jacob mjacob at FreeBSD.org
Sun Feb 27 16:38:01 UTC 2011


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

Change 189247 by mjacob at mjacob-sandbox on 2011/02/27 16:37:34

	Some more fixes. If a bad drive is attached, port enebles can fail,
	so set things up to come back later to try again.

Affected files ...

.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2cam.c#2 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2pci.c#3 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.c#3 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.h#3 edit

Differences ...

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

@@ -677,6 +677,7 @@
 	}
 }
 
+
 void
 mpt2sas_cam_done(mpt2sas_t *mpt, request_t *req, MPI2_SCSI_IO_REPLY *srf)
 {
@@ -734,6 +735,11 @@
 	if ((req->state & (REQ_STATE_LOCKED|REQ_STATE_POLLED)) == 0) {
 		mpt2sas_free_request(mpt, req);
 	}
+	if (dp->active == 0 && dp->state != STABLE) {
+		if (dp->need_destroy) {
+			(void) mpt2sas_destroy_dev_part2(mpt, dp->AttachedDevHandle);
+		}
+	}
 }
 
 static void
@@ -752,12 +758,22 @@
 
 	switch (ccb->ccb_h.func_code) {
 	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
+		if (mpt->portenabled == 0) {
+			mpt2sas_send_port_enable(mpt);
+			if (mpt->portenabled == 0) {
+				ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
+				break;
+			}
+		}
+		/*
+		 * We don't support external CDBs
+		 */
 		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) && (ccb->ccb_h.flags & CAM_CDB_PHYS)) {
 			ccb->ccb_h.status = CAM_REQ_INVALID;
 			break;
 		}
 		/*
-		 * We don't support external CDBs
+		 * We don't support CDBs larger than we can stuff into a single SGE
 		 */
 		if (ccb->csio.cdb_len > sizeof (MPI2_SCSI_IO_CDB_UNION)) {
 			ccb->ccb_h.status = CAM_REQ_INVALID;

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

@@ -226,8 +226,8 @@
 
         ctx = device_get_sysctl_ctx(mpt->dev);
         tree = device_get_sysctl_tree(mpt->dev);
-        SYSCTL_ADD_XINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "prt_mask", CTLFLAG_RW, &mpt->prt_mask, 0, "logging mask");
-        SYSCTL_ADD_XINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "config_buf_mask", CTLFLAG_RD, &mpt->config_buf_mask, 0, "logging mask");
+        SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "prt_mask", CTLFLAG_RW, &mpt->prt_mask, 0, "logging mask");
+        SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "config_buf_mask", CTLFLAG_RD, &mpt->config_buf_mask, 0, "logging mask");
         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "nactive", CTLFLAG_RD, &mpt->nactive, 0, "number of active commands");
         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "nreq_total", CTLFLAG_RD, &mpt->nreq_total, 0, "total number of requests for this HBA");
         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "nreq_allocated", CTLFLAG_RD, &mpt->nreq_allocated, 0, "number of allocated requests currently allocated");
@@ -419,7 +419,7 @@
 {
 	switch (type) {
 	case MOD_LOAD:
-		mtx_init(&mpt2sas_global_lock, "mpt2global", NULL, MTX_DEF);
+		mtx_init(&mpt2sas_global_lock, "mpt2global", NULL, MTX_SPIN);
 		TAILQ_INIT(&mpt2sas_tailq);
 		break;
 	case MOD_UNLOAD:
@@ -800,6 +800,7 @@
 	}
 	MPT2_DMA_SET_STEP(mpt, 25);
 
+
 	return (0);
 failure:
 	mpt2sas_mem_free(mpt);

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

@@ -269,52 +269,95 @@
 static void
 mpt2sas_topology_change(mpt2sas_t *mpt, MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *tpl)
 {
+	sas_dev_t *dp;
+	struct topochg *tp;
+	U16 hdl;
+	U8 status;
 	int i;
+
 	if (tpl->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) {
 		mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: expander added\n", __func__);
 		return;
 	}
+
 	for (i = 0; i < tpl->NumEntries; i++) {
-		U8 status;
 		if (tpl->PHY[i].PhyStatus & MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) {
 			continue;
 		}
+		hdl = le16toh(tpl->PHY[i].AttachedDevHandle);
 		status = tpl->PHY[i].PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK;
-		switch(status) {
+		switch (status) {
 		case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
-			mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: PHY chanded at entry %d\n", __func__, i);
-			break;
+			mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: PHY changed at entry %d for hdl %x\n", __func__, i, hdl);
+			if (hdl) {
+				dp = mpt2_hdl2dev(mpt, hdl);
+				if (dp) {
+					break;
+				}
+				/* otherwise fall thru to 'add' case */
+			} else {
+				break;
+			}
+			/* FALLTHROUGH */
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
-			if (le16toh(tpl->PHY[i].AttachedDevHandle)) {
-				struct topochg *tp = TAILQ_FIRST(&mpt->topo_free_list);
+			if (hdl) {
+				tp = TAILQ_FIRST(&mpt->topo_free_list);
 				if (tp == NULL) {
-					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Arrived - event lost\n", le16toh(tpl->PHY[i].AttachedDevHandle));
+					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Arrived - event lost\n", hdl);
 				} else {
-					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Arrived - scheduling for attach\n", le16toh(tpl->PHY[i].AttachedDevHandle));
+					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Arrived - scheduling for attach\n", hdl);
 					TAILQ_REMOVE(&mpt->topo_free_list, tp, links);
-					tp->hdl = le16toh(tpl->PHY[i].AttachedDevHandle);
+					tp->hdl = hdl;
 					tp->create = 1;
 					TAILQ_INSERT_TAIL(&mpt->topo_wait_list, tp, links);
 				}
 			}
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
-			if (le16toh(tpl->PHY[i].AttachedDevHandle)) {
-				struct topochg *tp = TAILQ_FIRST(&mpt->topo_free_list);
+		case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
+			if (status == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
+				mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: DevHandle 0x%x delayed not responding\n", __func__, hdl);
+			if (hdl) {
+				/*
+				 * See if we already have a topology event for this.
+				 */
+				TAILQ_FOREACH(tp, &mpt->topo_wait_list, links) {
+					if (tp->create && tp->hdl == hdl) {
+						TAILQ_REMOVE(&mpt->topo_wait_list, tp, links);
+						break;
+					}
+				}
+				if (tp) {
+					mpt2sas_prt(mpt, MP2PRT_CONFIG, "hdl 0x%x departed before it was seen\n", hdl);
+					break;
+				}
+				/*
+				 * See if we already have a device structure for this.
+				 */
+				dp = mpt2_hdl2dev(mpt, hdl);
+				if (dp) {
+					switch (dp->state) {
+					case NEW:
+					case ATTACHING:
+						dp->state = DETACHING;
+						break;
+					default:
+						dp->state = FAILED;
+						break;
+					}
+				}
+				tp = TAILQ_FIRST(&mpt->topo_free_list);
 				if (tp == NULL) {
-					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Departed- event lost\n", le16toh(tpl->PHY[i].AttachedDevHandle));
+					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Departed- event lost\n", hdl);
 				} else {
-					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Departed- scheduling for detach\n", le16toh(tpl->PHY[i].AttachedDevHandle));
+					mpt2sas_prt(mpt, MP2PRT_CONFIG, "DevHandle 0x%x Departed- scheduling for detach\n", hdl);
 					TAILQ_REMOVE(&mpt->topo_free_list, tp, links);
-					tp->hdl = le16toh(tpl->PHY[i].AttachedDevHandle);
+					tp->hdl = hdl;
 					tp->create = 0;
 					TAILQ_INSERT_TAIL(&mpt->topo_wait_list, tp, links);
 				}
 			}
 			break;
-		case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
-			mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: DevHandle 0x%x delayed not responding\n", __func__, le16toh(tpl->PHY[i].AttachedDevHandle));
-			break;
 		default:
 			mpt2sas_prt(mpt, MP2PRT_WARN, "%s: unknown status %x at entry %d\n", __func__, status, i);
 			break;
@@ -439,17 +482,10 @@
 		reply = MPT2_RFA2PTR(mpt, le32toh(dsc->ReplyFrameAddress));
 		addr = (uint8_t *)reply;
 		bus_dmamap_sync(mpt->replies.dmat, mpt->replies.dmap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-#if 0
-		if (addr < mpt->replies.vaddr || addr >= &mpt->replies.vaddr[MPT2_REPLY_MEM_SIZE(mpt)]) {
-			mpt2sas_prt(mpt, MP2PRT_ERR, "bad reply address %p SMID %u\n", reply, le16toh(dsc->SMID));
-			reply = NULL;
-		}
-#else
 		if (addr < mpt->replies.vaddr || addr > &mpt->replies.vaddr[MPT2_REPLY_MEM_SIZE(mpt)]) {
 			mpt2sas_prt(mpt, MP2PRT_ERR, "bad reply address %p SMID %u\n", reply, le16toh(dsc->SMID));
 			reply = NULL;
 		}
-#endif
 		if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff && addr[3] == 0xff) {
 			mpt2sas_prt(mpt, MP2PRT_ERR, "bad reply address %p free_host_index = %u\n", reply, mpt->free_host_index);
 			reply = NULL;
@@ -867,10 +903,49 @@
 #endif
 /******************************* Discovery and SAS/IOC Config Routines **************************/
 
-void
+int
 mpt2sas_destroy_dev(mpt2sas_t *mpt, U16 hdl)
 {
 	MPI2_SCSI_TASK_MANAGE_REQUEST *abt;
+	request_t *req;
+	sas_dev_t *dp;
+	int error;
+
+	KASSERT(hdl < mpt->ioc_facts.MaxTargets, ("%s: oops", __func__));
+	dp = &mpt->sas_dev_pool[hdl];
+	if (dp->AttachedDevHandle == 0) {
+		return (0);
+	}
+	KASSERT(hdl == dp->AttachedDevHandle, ("%s: oops2", __func__));
+	if (dp->active) {
+		int nreq = dp->active;
+		req = mpt2sas_get_request(mpt);
+		if (req == NULL) {
+			mpt2sas_prt(mpt, MP2PRT_ERR, "%s: cannot allocat request\n", __func__);
+			return (ENOBUFS);
+		}
+		dp->need_destroy = 1;
+		req->flags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
+		abt = MPT2_REQ2RQS(mpt, req);
+		memset(abt, 0,  sizeof (MPI2_SCSI_TASK_MANAGE_REQUEST));
+		abt->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
+		abt->DevHandle = htole16(dp->AttachedDevHandle);
+		abt->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+		abt->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET | MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU;
+		mpt2sas_send_cmd(mpt, req);
+		error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 1000);
+		MPT2SAS_SYNC_ERR_NORET(mpt, error);
+		mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: %d requests were still in play, deferred calling MPI2_SAS_OP_REMOVE_DEVICE (which %s been called)\n", __func__, nreq, dp->destroy_called? "*has*" : "has *not*");
+		return (0);
+	} else {
+		mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: calling dd2 hdl %x directly\n", __func__, hdl);
+		return mpt2sas_destroy_dev_part2(mpt, hdl);
+	}
+}
+
+int
+mpt2sas_destroy_dev_part2(mpt2sas_t *mpt, U16 hdl)
+{
 	MPI2_SAS_IOUNIT_CONTROL_REQUEST *ucr;
 	request_t *req;
 	sas_dev_t *dp;
@@ -879,26 +954,16 @@
 	KASSERT(hdl < mpt->ioc_facts.MaxTargets, ("%s: oops", __func__));
 	dp = &mpt->sas_dev_pool[hdl];
 	if (dp->AttachedDevHandle == 0) {
-		return;
+		return (0);
 	}
+	mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: destroy hdl %x active %u\n", __func__, dp->AttachedDevHandle, dp->active);
 	req = mpt2sas_get_request(mpt);
 	if (req == NULL) {
-		return;
- 	}
-	req->flags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
-	abt = MPT2_REQ2RQS(mpt, req);
-	memset(abt, 0,  sizeof (MPI2_SCSI_TASK_MANAGE_REQUEST));
-	abt->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
-	abt->DevHandle = htole16(dp->AttachedDevHandle);
-	abt->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-	abt->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET | MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU;
-	mpt2sas_send_cmd(mpt, req);
-	error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 1000);
-	MPT2SAS_SYNC_ERR_NORET(mpt, error);
-	req = mpt2sas_get_request(mpt);
-	if (req == NULL) {
-		return;
+		mpt2sas_prt(mpt, MP2PRT_ERR, "%s: cannot allocat request\n", __func__);
+		return (ENOBUFS);
 	}
+	dp->destroy_called = 1;
+	dp->need_destroy = 0;
 	req->flags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
 	ucr = MPT2_REQ2RQS(mpt, req);
 	memset(ucr, 0,  sizeof (MPI2_SAS_IOUNIT_CONTROL_REQUEST));
@@ -906,13 +971,14 @@
 	ucr->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
 	ucr->DevHandle = htole16(dp->AttachedDevHandle);
 	mpt2sas_send_cmd(mpt, req);
-	error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 1000);
+	error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 10000);
 	MPT2SAS_SYNC_ERR_NORET(mpt, error);
 	dp->state = DETACHING;
 	mpt->devchanged = 1;
+	return (0);
 }
 
-void
+int
 mpt2sas_create_dev(mpt2sas_t *mpt, U16 hdl)
 {
 	sas_dev_t *dp;
@@ -921,26 +987,36 @@
 	KASSERT(hdl < mpt->ioc_facts.MaxTargets, ("%s: oops", __func__));
 	dp = &mpt->sas_dev_pool[hdl];
 	if (dp->AttachedDevHandle) {
-		return;
+		mpt2sas_prt(mpt, MP2PRT_WARN, "%s: device 0x%x already attached as hdl 0x%x\n", __func__, dp->AttachedDevHandle, hdl);
+		return (0);
 	}
 	if (mpt2sas_get_cfgbuf(mpt, &off)) {
 		mpt2sas_prt(mpt, MP2PRT_WARN, "%s: cannot allocate config buffer\n", __func__);
-		return;
+		return (ENOMEM);
 	}
 	mpt2sas_prt(mpt, MP2PRT_CONFIG, "creating device (hdl %x)\n", hdl);
 	dp->AttachedDevHandle = hdl;
 	dp->state = NEW;
 	error = mpt2sas_read_vpd(mpt, dp, off);
-	if (error != MPT2_OK) {
-		mpt2sas_prt(mpt, MP2PRT_ERR, "mpt2sas_read_vpd failed (error %d)\n", error);
+	mpt2sas_free_cfgbuf(mpt, off);
+	if (error == ENOMEM) {
+		dp->AttachedDevHandle = 0;
 		dp->state = NIL;
+		return (error);
+	} else if (error) {
 		dp->AttachedDevHandle = 0;
-		mpt2sas_free_cfgbuf(mpt, off);
-		return;
+		dp->state = NIL;
+		mpt2sas_prt(mpt, MP2PRT_ERR, "mpt2sas_read_vpd failed (error %d)\n", error);
+		return (0);
+	}
+	/*
+	 * Catch the case here where we never made it.
+	 */
+	if (dp->state == NEW) {
+		dp->state = ATTACHING;
+		mpt->devchanged = 1;
 	}
-	dp->state = ATTACHING;
-	mpt->devchanged = 1;
-	mpt2sas_free_cfgbuf(mpt, off);
+	return (0);
 }
 
 static int
@@ -1075,7 +1151,7 @@
 		error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 1000);
 		MPT2SAS_SYNC_ERR_NORET(mpt, error);
 		if (error) {
-			return (MPT2_FAIL);
+			return (error);
 		}
 		/*
 		 * Okay, now that we have this ATA IDENTIFY data, we can find our NCQ queue depth
@@ -1234,8 +1310,10 @@
 void
 mpt2sas_free_request(mpt2sas_t *mpt, request_t *req)
 {
+	mpt2sas_dma_chunk_t *cl, *nxt;
+
 	KASSERT((req > &mpt->request_pool[0] && req < &mpt->request_pool[MPT2_MAX_REQUESTS(mpt)]), ("bad request pointer"));
-	mpt2sas_dma_chunk_t *cl, *nxt;
+	KASSERT((mpt->nreq_allocated > 1), ("bad allocation arithmetic"));
 
 	if ((cl = req->chain) != NULL) {
 		while (cl) {
@@ -1247,6 +1325,9 @@
 	}
 	req->chain = NULL;
 	req->ccb = NULL;
+	if (req->state & REQ_STATE_TIMEDOUT) {
+		mpt2sas_prt(mpt, MP2PRT_ERR, "request %p:%u now being freed\n", req, req->serno);
+	}
 	req->serno = 0;
 	req->state = REQ_STATE_FREE;
 	req->IOCStatus = 0;
@@ -1402,7 +1483,7 @@
 /*
  * Enable IOC port
  */
-static int
+void
 mpt2sas_send_port_enable(mpt2sas_t *mpt)
 {
 	MPI2_PORT_ENABLE_REQUEST *rqs;
@@ -1411,7 +1492,8 @@
  
 	req = mpt2sas_get_request(mpt);
 	if (req == NULL) {
-		return (ENOMEM);
+		mpt2sas_prt(mpt, MP2PRT_ERR, "%s: unable to get request\n", __func__);
+		return;
  	}
 	req->flags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	rqs = MPT2_REQ2RQS(mpt, req);
@@ -1419,7 +1501,11 @@
 	rqs->Function = MPI2_FUNCTION_PORT_ENABLE;
 	mpt2sas_send_cmd(mpt, req);
 	error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 30000);
-	MPT2SAS_SYNC_ERR(mpt, error);
+	MPT2SAS_SYNC_ERR_NORET(mpt, error);
+	if (error == 0) {
+		mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: port enabled\n", __func__);
+		mpt->portenabled = 1;
+	}
 }
 
 /*
@@ -1615,12 +1701,12 @@
 	 * Free all allocated host side requests
 	 */
 	mpt->nreq_total = MPT2_MAX_REQUESTS(mpt);
+	mpt->nreq_allocated = MPT2_MAX_REQUESTS(mpt);
 	for (val = 1; val < MPT2_MAX_REQUESTS(mpt); val++) {
 		request_t *req = &mpt->request_pool[val];
 		req->state = REQ_STATE_ALLOCATED;
 		mpt2sas_free_request(mpt, req);
 	}
-	mpt->nreq_allocated = 0;
 
 	/*
 	 * Initialize the DMA sge chunks
@@ -1704,14 +1790,10 @@
 	    MPT2_CHUNK_MEM_SIZE(mpt) / MPT2_CHUNK_SIZE(mpt), mpt->sge_per_chunk);
 
 	/*
-	 * Enable the port.
+	 * Enable the port. Port enable can fail if you have a bad drive, so if we fail to eanble the port,
+	 * we still consider ourselves 'here' (but need to try again later).
 	 */
-	if (mpt2sas_send_port_enable(mpt) != MPT2_OK) {
-		mpt2sas_disable_ints(mpt);
-		MPT2_UNLOCK(mpt);
-		return (ENXIO);
-	}
-
+	mpt2sas_send_port_enable(mpt);
 	MPT2_UNLOCK(mpt);
 	return (0);
 }
@@ -1826,13 +1908,14 @@
 	mpt2sas_t *mpt = arg;
 	uint32_t mselapsed;
 	struct timeval now, save;
+	request_t *req;
 	struct topochg *tp;
-	request_t *req;
+	int r;
+
+	MPT2_LOCK(mpt);
 
 	microtime(&save);
 	now = save;
-
-	MPT2_LOCK(mpt);
 	timevalsub(&now, &mpt->watchdog_then);
 	mselapsed = (now.tv_sec * 1000) + (now.tv_usec / 1000);
 	mpt->watchdog_then = save;
@@ -1851,23 +1934,29 @@
 			mpt2sas_scsi_abort(mpt, req);
 		}
 	}
+
 	while ((tp = TAILQ_FIRST(&mpt->topo_wait_list)) != NULL) {
-		TAILQ_REMOVE(&mpt->topo_wait_list, tp, links);
 		if (tp->create) {
-			mpt2sas_create_dev(mpt, tp->hdl);
+			r = mpt2sas_create_dev(mpt, tp->hdl);
+		} else {
+			r = mpt2sas_destroy_dev(mpt, tp->hdl);
+		}
+		if (r == 0) {
+			TAILQ_REMOVE(&mpt->topo_wait_list, tp, links);
+			TAILQ_INSERT_TAIL(&mpt->topo_free_list, tp, links);
 		} else {
-			mpt2sas_destroy_dev(mpt, tp->hdl);
+			break;
 		}
-		TAILQ_INSERT_TAIL(&mpt->topo_free_list, tp, links);
 	}
-	callout_reset(&mpt->watchdog, hz, mpt2sas_watchdog, mpt);
 	if (mpt->ehook_active == 0 && mpt->path && mpt->devchanged) {
 		sas_dev_t *dp;
 		int r;
-
 		for (dp = mpt->sas_dev_pool; dp < &mpt->sas_dev_pool[mpt->ioc_facts.MaxTargets]; dp++) {
-			if (dp->state == ATTACHING) {
-				dp->state = STABLE;	/* XXX */
+			if (dp->state == DETACHING) {
+				dp->state = NIL;
+				dp->AttachedDevHandle = 0;
+			} else if (dp->state == ATTACHING) {
+				dp->state = STABLE;
 			}
 		}
 		mpt->devchanged = 0;
@@ -1878,20 +1967,25 @@
 			mpt->devchanged = 1;
 		}
 	}
+	callout_reset(&mpt->watchdog, hz, mpt2sas_watchdog, mpt);
 	MPT2_UNLOCK(mpt);
 }
 
 void
 mpt2sas_prt(mpt2sas_t *mpt, int mask, const char *fmt, ...)
 {
+	char buf[256];
+	int used;
 	va_list ap;
         if (mask != MP2PRT_ALL && (mask & mpt->prt_mask) == 0) {
                 return;
         }
-        printf("%s: ", device_get_nameunit(mpt->dev));
+        snprintf(buf, sizeof buf, "%s: ", device_get_nameunit(mpt->dev));
+	used = strlen(buf);
         va_start(ap, fmt);
-        vprintf(fmt, ap);
+        vsnprintf(&buf[used], sizeof (buf) - used, fmt, ap);
         va_end(ap);
+	printf("%s", buf);
 }
 
 void
@@ -1953,7 +2047,7 @@
 	MPT2_LOCK(mpt);
 	TAILQ_INSERT_TAIL(&mpt2sas_tailq, mpt, links);
 	MPT2_UNLOCK(mpt);
-	callout_reset(&mpt->watchdog, hz/10, mpt2sas_watchdog, mpt);
+	callout_reset(&mpt->watchdog, hz, mpt2sas_watchdog, mpt);
 	return (0);
 }
 

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

@@ -179,6 +179,7 @@
 #include <dev/mpt2sas/mpt2reg.h>
 #include <dev/mpt2sas/mpt2cam.h>
 
+
 /****************************** Misc Definitions ******************************/
 #define MPT2_OK		(0)
 #define MPT2_FAIL	(0x10000)
@@ -227,7 +228,7 @@
 	if (e == ETIMEDOUT) {											\
 		mpt2sas_prt(m, MP2PRT_ERR, "%s: request timed out (@line %d)\n", __func__, __LINE__);		\
  	} else if (error) {											\
-		mpt2sas_prt(m, MP2PRT_ERR, "%s: error 0x%x (@line %d)\n", __func__, m->iocsts, __LINE__);	\
+		mpt2sas_prt(m, MP2PRT_ERR, "%s: error %d:0x%x (@line %d)\n", __func__, e, m->iocsts, __LINE__);	\
 	}													\
 	do  { ; } while (0)
 
@@ -349,11 +350,13 @@
 	U32	SlotStatus;
 	MPI2_SAS_IO_UNIT0_PHY_DATA phy;
 	uint32_t
+		destroy_called	: 1,
+		need_destroy	: 1,
 		is_sata		: 1,
 		set_qfull 	: 1;
 	uint16_t	active;
 	uint16_t	qdepth;
-	enum { NIL, NEW, ATTACHING, STABLE, DETACHING } state;
+	enum { NIL, NEW, ATTACHING, VALIDATING, VALIDATING_DONE, STABLE, FAILED, DETACHING } state;
 };
 
 /*
@@ -494,6 +497,7 @@
 	 * Flags and misc
 	 */
 	unsigned int
+		portenabled	:	1,
 		devchanged	:	1,
 		outofbeer	:	1,
 		acks_needed	:	1,
@@ -715,6 +719,7 @@
 /***************************** IOC Initialization *****************************/
 extern struct mpt2sas_tq mpt2sas_tailq;
 int mpt2sas_reset(mpt2sas_t *);
+void mpt2sas_send_port_enable(mpt2sas_t *);
 
 /**************************** CAM Routines ***************************/
 int		mpt2sas_cam_attach(mpt2sas_t *);
@@ -736,10 +741,11 @@
 request_t *	mpt2sas_get_request(mpt2sas_t *);
 void		mpt2sas_free_request(mpt2sas_t *, request_t *);
 void		mpt2sas_intr(void *);
-void		mpt2sas_create_dev(mpt2sas_t *, U16);
+int		mpt2sas_create_dev(mpt2sas_t *, U16);
 void		mpt2sas_build_ata_passthru(mpt2sas_t *, sas_dev_t *, U8 *, request_t *, bus_addr_t, uint32_t);
 int		mpt2sas_check_sata_passthru_failure(mpt2sas_t *, MPI2_SATA_PASSTHROUGH_REPLY *);
-void		mpt2sas_destroy_dev(mpt2sas_t *, U16);
+int		mpt2sas_destroy_dev(mpt2sas_t *, U16);
+int		mpt2sas_destroy_dev_part2(mpt2sas_t *, U16);
 void		mpt2sas_prt(mpt2sas_t *, int, const char *, ...) __printflike(3, 4);
 void		mpt2sas_prt_cont(mpt2sas_t *, int, const char *, ...) __printflike(3, 4);
 int		mpt2sas_read_sep(mpt2sas_t *, sas_dev_t *);


More information about the p4-projects mailing list