mps0-troubles

Kenneth D. Merry ken at freebsd.org
Fri Feb 4 00:02:51 UTC 2011


On Fri, Feb 04, 2011 at 00:53:07 +0100, Joachim Tingvold wrote:
> On Thu, Feb 03, 2011, at 23:10:56PM GMT+01:00, Kenneth D. Merry wrote:
> >I've attached a patch that has a number of debugging sysctls, a  
> >change from
> >gibbs@ that has to do with device removal, and some other extra  
> >debugging
> >cruft.  (i.e. this patch won't go into the tree as-is, it's just for
> >debugging.)
> 
> 	Index: mps.c
> 	|===================================================================
> 	|--- mps.c	(revision 218241)
> 	|+++ mps.c	(working copy)
> 	--------------------------
> 	Patching file mps.c using Plan A...
> 	Hunk #1 succeeded at 386 (offset -1 lines).
> 	Hunk #2 succeeded at 734 (offset -7 lines).
> 	Hunk #3 succeeded at 812 (offset -9 lines).
> 	Hunk #4 failed at 847.
> 
> The patch is looking for
> 
> 	SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),  
> [...]
> 	SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),  
> [...]
> 
> but my mps.c has
> 
> 	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 
> 	[...]
> 	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 
> 	[...]
> 
> That, and all the offsets; maybe my mps-driver is a bit outdated?  
> Maybe this is a stupid question, but I'm no FreeBSD-expert. (-:

That change went in a few weeks ago.  Try this patch, perhaps it will work.

Ken
-- 
Kenneth Merry
ken at FreeBSD.ORG
-------------- next part --------------
Index: mps.c
===================================================================
--- mps.c	(revision 218241)
+++ mps.c	(working copy)
@@ -387,6 +387,15 @@
 
 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
 
+	if (sc->mps_flags & MPS_FLAGS_ATTACH_DONE)
+		mtx_assert(&sc->mps_mtx, MA_OWNED);
+
+	if ((cm->cm_desc.Default.SMID < 1)
+	 || (cm->cm_desc.Default.SMID >= sc->num_reqs)) {
+		mps_printf(sc, "%s: invalid SMID %d, desc %#x %#x\n",
+			   __func__, cm->cm_desc.Default.SMID,
+			   cm->cm_desc.Words.High, cm->cm_desc.Words.Low);
+	}
 	mps_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET,
 	    cm->cm_desc.Words.Low);
 	mps_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET,
@@ -732,6 +741,7 @@
 		chain->chain_busaddr = sc->chain_busaddr +
 		    i * sc->facts->IOCRequestFrameSize * 4;
 		mps_free_chain(sc, chain);
+		sc->chain_free_lowwater++;
 	}
 
 	/* XXX Need to pick a more precise value */
@@ -811,7 +821,7 @@
 int
 mps_attach(struct mps_softc *sc)
 {
-	int i, error;
+	int i, error, old_debug;
 	char tmpstr[80], tmpstr2[80];
 
 	/*
@@ -855,6 +865,26 @@
 	    &sc->allow_multiple_tm_cmds, 0,
 	    "allow multiple simultaneous task management cmds");
 
+	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+	    OID_AUTO, "io_cmds_active", CTLFLAG_RD,
+	    &sc->io_cmds_active, 0, "number of currently active commands");
+
+	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+	    OID_AUTO, "io_cmds_highwater", CTLFLAG_RD,
+	    &sc->io_cmds_highwater, 0, "maximum active commands seen");
+
+	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+	    OID_AUTO, "chain_free", CTLFLAG_RD,
+	    &sc->chain_free, 0, "number of free chain elements");
+
+	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+	    OID_AUTO, "chain_free_lowwater", CTLFLAG_RD,
+	    &sc->chain_free_lowwater, 0,"lowest number of free chain elements");
+
+	SYSCTL_ADD_UQUAD(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+	    OID_AUTO, "chain_alloc_fail", CTLFLAG_RD,
+	    &sc->chain_alloc_fail, "chain allocation failures");
+
 	if ((error = mps_transition_ready(sc)) != 0)
 		return (error);
 
@@ -863,7 +893,10 @@
 	if ((error = mps_get_iocfacts(sc, sc->facts)) != 0)
 		return (error);
 
+	old_debug = sc->mps_debug;
+	sc->mps_debug = MPS_INFO;
 	mps_print_iocfacts(sc, sc->facts);
+	sc->mps_debug = old_debug;
 
 	mps_printf(sc, "Firmware: %02d.%02d.%02d.%02d\n",
 	    sc->facts->FWVersion.Struct.Major,
@@ -895,9 +928,12 @@
 	sc->num_reqs = MIN(MPS_REQ_FRAMES, sc->facts->RequestCredit);
 	sc->num_replies = MIN(MPS_REPLY_FRAMES + MPS_EVT_REPLY_FRAMES,
 	    sc->facts->MaxReplyDescriptorPostQueueDepth) - 1;
+	mps_printf(sc, "num_reqs %d, num_replies %d\n", sc->num_reqs,
+		   sc->num_replies);
 	TAILQ_INIT(&sc->req_list);
 	TAILQ_INIT(&sc->chain_list);
 	TAILQ_INIT(&sc->tm_list);
+	TAILQ_INIT(&sc->io_list);
 
 	if (((error = mps_alloc_queues(sc)) != 0) ||
 	    ((error = mps_alloc_replies(sc)) != 0) ||
@@ -967,6 +1003,8 @@
 		error = EINVAL;
 	}
 
+	sc->mps_flags |= MPS_FLAGS_ATTACH_DONE;
+
 	return (error);
 }
 
@@ -1299,8 +1337,11 @@
 			if (cm->cm_complete != NULL)
 				cm->cm_complete(sc, cm);
 
-			if (cm->cm_flags & MPS_CM_FLAGS_WAKEUP)
+			if (cm->cm_flags & MPS_CM_FLAGS_WAKEUP) {
+				mps_printf(sc, "%s: waking up %p\n", __func__,
+					   cm);
 				wakeup(cm);
+			}
 		}
 
 		desc->Words.Low = 0xffffffff;
Index: mps_sas.c
===================================================================
--- mps_sas.c	(revision 218241)
+++ mps_sas.c	(working copy)
@@ -486,7 +486,10 @@
 		return;
 	}
 
+	mps_dprint(sc, MPS_INFO, "Preparing to remove target %d\n", targ->tid);
+
 	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
+	memset(req, 0, sizeof(*req));
 	req->DevHandle = targ->handle;
 	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
 	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
@@ -507,6 +510,7 @@
 	MPI2_SCSI_TASK_MANAGE_REPLY *reply;
 	MPI2_SAS_IOUNIT_CONTROL_REQUEST *req;
 	struct mpssas_target *targ;
+	struct mps_command *next_cm;
 	uint16_t handle;
 
 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
@@ -523,11 +527,13 @@
 		return;
 	}
 
-	mps_printf(sc, "Reset aborted %d commands\n", reply->TerminationCount);
+	mps_dprint(sc, MPS_INFO, "Reset aborted %u commands\n",
+	    reply->TerminationCount);
 	mps_free_reply(sc, cm->cm_reply_data);
 
 	/* Reuse the existing command */
 	req = (MPI2_SAS_IOUNIT_CONTROL_REQUEST *)cm->cm_req;
+	memset(req, 0, sizeof(*req));
 	req->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
 	req->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
 	req->DevHandle = handle;
@@ -539,6 +545,17 @@
 	mps_map_command(sc, cm);
 
 	mps_dprint(sc, MPS_INFO, "clearing target handle 0x%04x\n", handle);
+	TAILQ_FOREACH_SAFE(cm, &sc->io_list, cm_link, next_cm) {
+		union ccb *ccb;
+
+		if (cm->cm_targ->handle != handle)
+			continue;
+
+		mps_dprint(sc, MPS_INFO, "Completing missed command %p\n", cm);
+		ccb = cm->cm_complete_data;
+		ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+		mpssas_scsiio_complete(sc, cm);
+	}
 	targ = mpssas_find_target(sc->sassc, 0, handle);
 	if (targ != NULL) {
 		targ->handle = 0x0;
@@ -1349,6 +1366,7 @@
 	}
 
 	req = (MPI2_SCSI_IO_REQUEST *)cm->cm_req;
+	bzero(req, sizeof(*req));
 	req->DevHandle = targ->handle;
 	req->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
 	req->MsgFlags = 0;
@@ -1430,6 +1448,11 @@
 	cm->cm_complete_data = ccb;
 	cm->cm_targ = targ;
 
+	sc->io_cmds_active++;
+	if (sc->io_cmds_active > sc->io_cmds_highwater)
+		sc->io_cmds_highwater = sc->io_cmds_active;
+
+	TAILQ_INSERT_TAIL(&sc->io_list, cm, cm_link);
 	callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000,
 	   mpssas_scsiio_timeout, cm);
 
@@ -1449,6 +1472,8 @@
 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
 
 	callout_stop(&cm->cm_callout);
+	TAILQ_REMOVE(&sc->io_list, cm, cm_link);
+	sc->io_cmds_active--;
 
 	sassc = sc->sassc;
 	ccb = cm->cm_complete_data;
@@ -1470,8 +1495,10 @@
 
 	/* Take the fast path to completion */
 	if (cm->cm_reply == NULL) {
-		ccb->ccb_h.status = CAM_REQ_CMP;
-		ccb->csio.scsi_status = SCSI_STATUS_OK;
+		if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
+			ccb->ccb_h.status = CAM_REQ_CMP;
+			ccb->csio.scsi_status = SCSI_STATUS_OK;
+		}
 		mps_free_command(sc, cm);
 		xpt_done(ccb);
 		return;
@@ -1526,7 +1553,16 @@
 		break;
 	case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
 	case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
+#if 0
 		ccb->ccb_h.status = CAM_REQ_ABORTED;
+#endif
+		mps_printf(sc, "(%d:%d:%d) terminated ioc %x scsi %x state %x "
+			   "xfer %u\n", xpt_path_path_id(ccb->ccb_h.path),
+			   xpt_path_target_id(ccb->ccb_h.path),
+			   xpt_path_lun_id(ccb->ccb_h.path),
+			   rep->IOCStatus, rep->SCSIStatus, rep->SCSIState,
+			   rep->TransferCount);
+		ccb->ccb_h.status = CAM_REQUEUE_REQ;
 		break;
 	case MPI2_IOCSTATUS_INVALID_SGL:
 		mps_print_scsiio_cmd(sc, cm);
@@ -1904,7 +1940,6 @@
 	xpt_done(ccb);
 
 }
-
 #endif /* __FreeBSD_version >= 900026 */
 
 static void
Index: mps_table.c
===================================================================
--- mps_table.c	(revision 218241)
+++ mps_table.c	(working copy)
@@ -46,6 +46,8 @@
 #include <machine/resource.h>
 #include <sys/rman.h>
 
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
 #include <cam/scsi/scsi_all.h>
 
 #include <dev/mps/mpi/mpi2_type.h>
@@ -486,8 +488,16 @@
 mps_print_scsiio_cmd(struct mps_softc *sc, struct mps_command *cm)
 {
 	MPI2_SCSI_IO_REQUEST *req;
+	union ccb *ccb;
 
 	req = (MPI2_SCSI_IO_REQUEST *)cm->cm_req;
+	printf("SCSI command [SMID %d]: len %u data %p flags %#x\n",
+	       cm->cm_desc.Default.SMID, cm->cm_length, cm->cm_data,
+	       cm->cm_flags);
+	ccb = (union ccb *)cm->cm_complete_data;
+	scsi_sense_print(&ccb->csio);
 	mps_print_sgl(sc, cm, req->SGLOffset0);
+
+	hexdump(req, sizeof(*req), "mps: ", 0);
 }
 
Index: mpsvar.h
===================================================================
--- mpsvar.h	(revision 218241)
+++ mpsvar.h	(working copy)
@@ -119,9 +119,15 @@
 #define MPS_FLAGS_MSI		(1 << 1)
 #define MPS_FLAGS_BUSY		(1 << 2)
 #define MPS_FLAGS_SHUTDOWN	(1 << 3)
+#define	MPS_FLAGS_ATTACH_DONE	(1 << 4)
 	u_int				mps_debug;
 	u_int				allow_multiple_tm_cmds;
 	int				tm_cmds_active;
+	int				io_cmds_active;
+	int				io_cmds_highwater;
+	int				chain_free;
+	int				chain_free_lowwater;
+	uint64_t			chain_alloc_fail;
 	struct sysctl_ctx_list		sysctl_ctx;
 	struct sysctl_oid		*sysctl_tree;
 	struct mps_command		*commands;
@@ -133,6 +139,7 @@
 	TAILQ_HEAD(, mps_command)	req_list;
 	TAILQ_HEAD(, mps_chain)		chain_list;
 	TAILQ_HEAD(, mps_command)	tm_list;
+	TAILQ_HEAD(, mps_command)	io_list;
 	int				replypostindex;
 	int				replyfreeindex;
 
@@ -228,8 +235,13 @@
 {
 	struct mps_chain *chain;
 
-	if ((chain = TAILQ_FIRST(&sc->chain_list)) != NULL)
+	if ((chain = TAILQ_FIRST(&sc->chain_list)) != NULL) {
 		TAILQ_REMOVE(&sc->chain_list, chain, chain_link);
+		sc->chain_free--;
+		if (sc->chain_free < sc->chain_free_lowwater)
+			sc->chain_free_lowwater = sc->chain_free;
+	} else
+		sc->chain_alloc_fail++;
 	return (chain);
 }
 
@@ -239,6 +251,7 @@
 #if 0
 	bzero(chain->chain, 128);
 #endif
+	sc->chain_free++;
 	TAILQ_INSERT_TAIL(&sc->chain_list, chain, chain_link);
 }
 
Index: mps_user.c
===================================================================
--- mps_user.c	(revision 218241)
+++ mps_user.c	(working copy)
@@ -400,10 +400,12 @@
 	if (cmd->len == 0)
 		return (EINVAL);
 
+	printf("%s: about to copyin firmware\n", __func__);
 	error = copyin(cmd->buf, cm->cm_data, cmd->len);
 	if (error != 0)
 		return (error);
 
+	printf("%s: about to init sge\n", __func__);
 	mpi_init_sge(cm, req, &req->SGL);
 	bzero(&tc, sizeof tc);
 
@@ -425,7 +427,10 @@
 	tc.ImageSize = cmd->len;
 
 	cm->cm_flags |= MPS_CM_FLAGS_DATAOUT;
+	cm->cm_max_segs = 1;
 
+	printf("%s: about to push sge\n", __func__);
+
 	return (mps_push_sge(cm, &tc, sizeof tc, 0));
 }
 
@@ -595,7 +600,7 @@
 
 	hdr = (MPI2_REQUEST_HEADER *)cm->cm_req;
 
-	mps_dprint(sc, MPS_INFO, "mps_user_command: req %p %d  rpl %p %d\n",
+	mps_printf(sc, "mps_user_command: req %p %d  rpl %p %d\n",
 		    cmd->req, cmd->req_len, cmd->rpl, cmd->rpl_len );
 
 	if (cmd->req_len > (int)sc->facts->IOCRequestFrameSize * 4) {
@@ -606,17 +611,11 @@
 	if (err != 0)
 		goto RetFreeUnlocked;
 
-	mps_dprint(sc, MPS_INFO, "mps_user_command: Function %02X  "
+	mps_printf(sc, "mps_user_command: Function %02X  "
 	    "MsgFlags %02X\n", hdr->Function, hdr->MsgFlags );
 
-	err = mps_user_setup_request(cm, cmd);
-	if (err != 0) {
-		mps_printf(sc, "mps_user_command: unsupported function 0x%X\n",
-		    hdr->Function );
-		goto RetFreeUnlocked;
-	}
-
 	if (cmd->len > 0) {
+		mps_printf(sc, "%s: allocating %d bytes\n", __func__, cmd->len);
 		buf = malloc(cmd->len, M_MPSUSER, M_WAITOK|M_ZERO);
 		cm->cm_data = buf;
 		cm->cm_length = cmd->len;
@@ -625,6 +624,13 @@
 		cm->cm_length = 0;
 	}
 
+	err = mps_user_setup_request(cm, cmd);
+	if (err != 0) {
+		mps_printf(sc, "mps_user_command: unsupported function 0x%X\n",
+		    hdr->Function );
+		goto RetFreeUnlocked;
+	}
+
 	cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_WAKEUP;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 
@@ -653,7 +659,7 @@
 	copyout(rpl, cmd->rpl, sz);
 	if (buf != NULL)
 		copyout(buf, cmd->buf, cmd->len);
-	mps_dprint(sc, MPS_INFO, "mps_user_command: reply size %d\n", sz );
+	mps_printf(sc, "mps_user_command: reply size %d\n", sz );
 
 RetFreeUnlocked:
 	mps_lock(sc);


More information about the freebsd-scsi mailing list