Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Feb 2012 23:59:14 +0530
From:      "Desai, Kashyap" <Kashyap.Desai@lsi.com>
To:        =?iso-8859-1?Q?Leon_Me=DFner?= <l.messner@physik.tu-berlin.de>, "freebsd-scsi@freebsd.org" <freebsd-scsi@freebsd.org>
Cc:        "Kenneth D. Merry" <ken@FreeBSD.org>, "McConnell, Stephen" <Stephen.McConnell@lsi.com>
Subject:   RE: getencstat and smp_discover get stuck with lsi mps
Message-ID:  <B2FD678A64EAAD45B089B123FDFC3ED729A3415109@inbmail01.lsi.com>
In-Reply-To: <20120208152507.GA17395@emmi.physik-pool.tu-berlin.de>
References:  <20120208152507.GA17395@emmi.physik-pool.tu-berlin.de>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
There are couple of fix went after 11.255.x version of mps driver. (which currently upstreamed)
I have attached those fixes here as combined patch.

I have also observed this issue in my lab. (so most likely you will see fix using attached patch.)

` Kashyap

> -----Original Message-----
> From: owner-freebsd-scsi@freebsd.org [mailto:owner-freebsd-
> scsi@freebsd.org] On Behalf Of Leon Meßner
> Sent: Wednesday, February 08, 2012 8:55 PM
> To: freebsd-scsi@freebsd.org
> Subject: getencstat and smp_discover get stuck with lsi mps
> 
> Hi,
> at first thank you for the new LSI mps driver. Works like a charm until
> now. I do see a problem using getencstat or smp_discover from the
> smp_utils-0.97 package. Both just hang and dont recover.
> 
> # ps axlwww | grep getenc
>   UID   PID  PPID CPU PRI NI    VSZ    RSS MWCHAN STAT  TT      TIME
> COMMAND
>     0  1879  1717   0  20  0   3924    836 cgticb D+     0   0:00.00
> ./getencstat /dev/ses0
> 
> I did get some output from getencstat while using the old driver under
> 8-STABLE (now running 9-STABLE from the 6th). Hardware is a 9200-8e
> (mps0) and one Supermicro SC847E16-RJBOD1 which features two expander
> chips. There is also another onboard mps controller which has only
> drives attached. pciconf -lv and dmesg regarding ses devices attached.
> 
> Greetings,
> Leon
> 
> mps0@pci0:1:0:0:        class=0x010700 card=0x30801000 chip=0x00721000
> rev=0x03 hdr=0x00
>     vendor     = 'LSI Logic / Symbios Logic'
>     device     = 'SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon]'
>     class      = mass storage
>     subclass   = SAS
> 
> # dmesg | grep ses
> ses0 at mps0 bus 0 scbus0 target 8 lun 0
> ses0: <LSI CORP SAS2X36 0417> Fixed Enclosure Services SCSI-5 device
> ses0: 600.000MB/s transfers
> ses0: Command Queueing enabled
> ses0: SCSI-3 SES Device
> ses1 at mps0 bus 0 scbus0 target 29 lun 0
> ses1: <LSI CORP SAS2X36 0417> Fixed Enclosure Services SCSI-5 device
> ses1: 600.000MB/s transfers
> ses1: Command Queueing enabled
> ses1: SCSI-3 SES Device
> _______________________________________________
> freebsd-scsi@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-scsi
> To unsubscribe, send any mail to "freebsd-scsi-unsubscribe@freebsd.org"

[-- Attachment #2 --]
diff -arup mps_11.255.03.00-fbsd/mps.c mps_13.00.00.00-fbsd/mps.c
--- mps_11.255.03.00-fbsd/mps.c	2012-02-06 21:48:09.024731549 +0530
+++ mps_13.00.00.00-fbsd/mps.c	2012-02-06 21:47:34.612007527 +0530
@@ -529,7 +529,7 @@ mps_enqueue_request(struct mps_softc *sc
 	mps_dprint(sc, MPS_TRACE, "%s SMID %u cm %p ccb %p\n", __func__,
 	    cm->cm_desc.Default.SMID, cm, cm->cm_ccb);
 
-	if (sc->mps_flags & MPS_FLAGS_ATTACH_DONE)
+	if (sc->mps_flags & MPS_FLAGS_ATTACH_DONE && !(sc->mps_flags & MPS_FLAGS_SHUTDOWN))
 		mtx_assert(&sc->mps_mtx, MA_OWNED);
 
 	if (++sc->io_cmds_active > sc->io_cmds_highwater)
@@ -1335,6 +1335,8 @@ mps_free(struct mps_softc *sc)
 	    ((error = mps_detach_sas(sc)) != 0))
 		return (error);
 
+	mps_detach_user(sc);
+
 	/* Put the IOC back in the READY state. */
 	mps_lock(sc);
 	if ((error = mps_transition_ready(sc)) != 0) {
@@ -2142,7 +2144,7 @@ mps_wait_command(struct mps_softc *sc, s
 	error = mps_map_command(sc, cm);
 	if ((error != 0) && (error != EINPROGRESS))
 		return (error);
-	error = msleep(cm, &sc->mps_mtx, 0, "mpswait", timeout);
+	error = msleep(cm, &sc->mps_mtx, 0, "mpswait", timeout*hz);
 	if (error == EWOULDBLOCK)
 		error = ETIMEDOUT;
 	return (error);
diff -arup mps_11.255.03.00-fbsd/mps_sas.c mps_13.00.00.00-fbsd/mps_sas.c
--- mps_11.255.03.00-fbsd/mps_sas.c	2012-02-06 21:48:09.037671214 +0530
+++ mps_13.00.00.00-fbsd/mps_sas.c	2012-02-06 21:47:34.614996075 +0530
@@ -139,7 +139,6 @@ static uint8_t op_code_prot[256] = {
 
 MALLOC_DEFINE(M_MPSSAS, "MPSSAS", "MPS SAS memory");
 
-static struct mpssas_target * mpssas_find_target_by_handle(struct mpssas_softc *, int, uint16_t);
 static void mpssas_discovery_timeout(void *data);
 static void mpssas_remove_device(struct mps_softc *, struct mps_command *);
 static void mpssas_remove_complete(struct mps_softc *, struct mps_command *);
@@ -175,7 +174,7 @@ static int mpssas_send_portenable(struct
 static void mpssas_portenable_complete(struct mps_softc *sc,
     struct mps_command *cm);
 
-static struct mpssas_target *
+struct mpssas_target *
 mpssas_find_target_by_handle(struct mpssas_softc *sassc, int start, uint16_t handle)
 {
 	struct mpssas_target *target;
@@ -351,22 +350,123 @@ mpssas_log_command(struct mps_command *c
 	va_end(ap);
 }
 
+
 static void
-mpssas_lost_target(struct mps_softc *sc, struct mpssas_target *targ)
+mpssas_remove_volume(struct mps_softc *sc, struct mps_command *tm)
 {
-	struct mpssas_softc *sassc = sc->sassc;
-	path_id_t pathid = cam_sim_path(sassc->sim);
-	struct cam_path *path;
+	MPI2_SCSI_TASK_MANAGE_REPLY *reply;
+	struct mpssas_target *targ;
+	uint16_t handle;
+
+	mps_dprint(sc, MPS_INFO, "%s\n", __func__);
+
+	reply = (MPI2_SCSI_TASK_MANAGE_REPLY *)tm->cm_reply;
+	handle = (uint16_t)(uintptr_t)tm->cm_complete_data;
+	targ = tm->cm_targ;
 
-	mps_printf(sc, "%s targetid %u\n", __func__, targ->tid);
-	if (xpt_create_path(&path, NULL, pathid, targ->tid, 0) != CAM_REQ_CMP) {
-		mps_printf(sc, "unable to create path for lost target %d\n", 
-		    targ->tid);
+	if (reply == NULL) {
+		/* XXX retry the remove after the diag reset completes? */
+		mps_printf(sc, "%s NULL reply reseting device 0x%04x\n", 
+		    __func__, handle);
+		mpssas_free_tm(sc, tm);
 		return;
 	}
 
-	xpt_async(AC_LOST_DEVICE, path, NULL);
-	xpt_free_path(path);
+	if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
+		mps_printf(sc, "IOCStatus = 0x%x while resetting device 0x%x\n",
+		   reply->IOCStatus, handle);
+		mpssas_free_tm(sc, tm);
+		return;
+	}
+
+	mps_printf(sc, "Reset aborted %u commands\n", reply->TerminationCount);
+	mps_free_reply(sc, tm->cm_reply_data);
+	tm->cm_reply = NULL;	/* Ensures the the reply won't get re-freed */
+
+	mps_printf(sc, "clearing target %u handle 0x%04x\n", targ->tid, handle);
+	
+	/*
+	 * Don't clear target if remove fails because things will get confusing.
+	 * Leave the devname and sasaddr intact so that we know to avoid reusing
+	 * this target id if possible, and so we can assign the same target id
+	 * to this device if it comes back in the future.
+	 */
+	if (reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) {
+		targ = tm->cm_targ;
+		targ->handle = 0x0;
+		targ->encl_handle = 0x0;
+		targ->encl_slot = 0x0;
+		targ->exp_dev_handle = 0x0;
+		targ->phy_num = 0x0;
+		targ->linkrate = 0x0;
+		targ->devinfo = 0x0;
+		targ->flags = 0x0;
+	}
+
+	mpssas_free_tm(sc, tm);
+}
+
+
+/*
+ * No Need to call "MPI2_SAS_OP_REMOVE_DEVICE" For Volume removal.
+ * Otherwise Volume Delete is same as Bare Drive Removal.
+ */
+void
+mpssas_prepare_volume_remove(struct mpssas_softc *sassc, uint16_t handle)
+{
+	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
+	struct mps_softc *sc;
+	struct mps_command *cm;
+	struct mpssas_target *targ = NULL;
+
+	mps_dprint(sassc->sc, MPS_INFO, "%s\n", __func__);
+	sc = sassc->sc;
+
+#ifdef WD_SUPPORT
+	/*
+	 * If this is a WD controller, determine if the disk should be exposed
+	 * to the OS or not.  If disk should be exposed, return from this
+	 * function without doing anything.
+	 */
+	if (sc->WD_available && (sc->WD_hide_expose ==
+	    MPS_WD_EXPOSE_ALWAYS)) {
+		return;
+	}
+#endif //WD_SUPPORT
+
+	targ = mpssas_find_target_by_handle(sassc, 0, handle);
+	if (targ == NULL) {
+		/* FIXME: what is the action? */
+		/* We don't know about this device? */
+		printf("%s %d : invalid handle 0x%x \n", __func__,__LINE__, handle);
+		return;
+	}
+
+	targ->flags |= MPSSAS_TARGET_INREMOVAL;
+
+	cm = mpssas_alloc_tm(sc);
+	if (cm == NULL) {
+		mps_printf(sc, "%s: command alloc failure\n", __func__);
+		return;
+	}
+
+	mpssas_rescan_target(sc, targ);
+
+	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
+	req->DevHandle = targ->handle;
+	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
+	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+
+	/* SAS Hard Link Reset / SATA Link Reset */
+	req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
+
+	cm->cm_targ = targ;
+	cm->cm_data = NULL;
+	cm->cm_desc.HighPriority.RequestFlags =
+	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
+	cm->cm_complete = mpssas_remove_volume;
+	cm->cm_complete_data = (void *)(uintptr_t)handle;
+	mps_map_command(sc, cm);
 }
 
 /*
@@ -386,7 +486,7 @@ mpssas_prepare_remove(struct mpssas_soft
 	struct mps_command *cm;
 	struct mpssas_target *targ = NULL;
 
-	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
+	mps_dprint(sassc->sc, MPS_INFO, "%s\n", __func__);
 
 	/*
 	 * If this is a WD controller, determine if the disk should be exposed
@@ -403,7 +503,7 @@ mpssas_prepare_remove(struct mpssas_soft
 	if (targ == NULL) {
 		/* FIXME: what is the action? */
 		/* We don't know about this device? */
-		printf("%s: invalid handle 0x%x \n", __func__, handle);
+		printf("%s %d : invalid handle 0x%x \n", __func__,__LINE__, handle);
 		return;
 	}
 
@@ -415,7 +515,7 @@ mpssas_prepare_remove(struct mpssas_soft
 		return;
 	}
 
-	mpssas_lost_target(sc, targ);
+	mpssas_rescan_target(sc, targ);
 
 	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
 	memset(req, 0, sizeof(*req));
@@ -443,7 +543,7 @@ mpssas_remove_device(struct mps_softc *s
 	struct mps_command *next_cm;
 	uint16_t handle;
 
-	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+	mps_dprint(sc, MPS_INFO, "%s\n", __func__);
 
 	reply = (MPI2_SCSI_TASK_MANAGE_REPLY *)tm->cm_reply;
 	handle = (uint16_t)(uintptr_t)tm->cm_complete_data;
@@ -514,7 +614,7 @@ mpssas_remove_complete(struct mps_softc 
 	uint16_t handle;
 	struct mpssas_target *targ;
 
-	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+	mps_dprint(sc, MPS_INFO, "%s\n", __func__);
 
 	reply = (MPI2_SAS_IOUNIT_CONTROL_REPLY *)tm->cm_reply;
 	handle = (uint16_t)(uintptr_t)tm->cm_complete_data;
@@ -558,6 +658,7 @@ mpssas_remove_complete(struct mps_softc 
 		targ->phy_num = 0x0;
 		targ->linkrate = 0x0;
 		targ->devinfo = 0x0;
+		targ->flags = 0x0;
 	}
 
 	mpssas_free_tm(sc, tm);
@@ -690,7 +791,7 @@ mps_detach_sas(struct mps_softc *sc)
 {
 	struct mpssas_softc *sassc;
 
-	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+	mps_dprint(sc, MPS_INFO, "%s\n", __func__);
 
 	if (sc->sassc == NULL)
 		return (0);
@@ -733,6 +834,7 @@ mps_detach_sas(struct mps_softc *sc)
 	}
 	mps_unlock(sc);
 
+	mps_dprint(sc, MPS_INFO, "%s:%d\n", __func__,__LINE__);
 	if (sassc->devq != NULL)
 		cam_simq_free(sassc->devq);
 
@@ -1475,11 +1577,11 @@ mpssas_action_scsiio(struct mpssas_softc
 	uint16_t eedp_flags;
 
 	sc = sassc->sc;
-	mps_dprint(sc, MPS_TRACE, "%s ccb %p\n", __func__, ccb);
 	mtx_assert(&sc->mps_mtx, MA_OWNED);
 
 	csio = &ccb->csio;
 	targ = &sassc->targets[csio->ccb_h.target_id];
+	mps_dprint(sc, MPS_TRACE, "%s ccb %p target flag %x\n", __func__, ccb, targ->flags);
 	if (targ->handle == 0x0) {
 		mps_dprint(sc, MPS_TRACE, "%s NULL handle for target %u\n", 
 		    __func__, csio->ccb_h.target_id);
@@ -1487,6 +1589,13 @@ mpssas_action_scsiio(struct mpssas_softc
 		xpt_done(ccb);
 		return;
 	}
+	if (targ->flags & MPS_TARGET_FLAGS_RAID_COMPONENT) {
+		mps_dprint(sc, MPS_TRACE, "%s Raid component no SCSI IO supported %u\n", 
+		    __func__, csio->ccb_h.target_id);
+		csio->ccb_h.status = CAM_TID_INVALID;
+		xpt_done(ccb);
+		return;
+	}
 	/*
 	 * If devinfo is 0 this will be a volume.  In that case don't tell CAM
 	 * that the volume has timed out.  We want volumes to be enumerated
@@ -1684,6 +1793,198 @@ mpssas_action_scsiio(struct mpssas_softc
 }
 
 static void
+mps_response_code(struct mps_softc *sc, u8 response_code)
+{
+        char *desc;
+ 
+        switch (response_code) {
+        case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
+                desc = "task management request completed";
+                break;
+        case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
+                desc = "invalid frame";
+                break;
+        case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
+                desc = "task management request not supported";
+                break;
+        case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
+                desc = "task management request failed";
+                break;
+        case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
+                desc = "task management request succeeded";
+                break;
+        case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
+                desc = "invalid lun";
+                break;
+        case 0xA:
+                desc = "overlapped tag attempted";
+                break;
+        case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
+                desc = "task queued, however not sent to target";
+                break;
+        default:
+                desc = "unknown";
+                break;
+        }
+		mps_dprint(sc, MPS_INFO, "response_code(0x%01x): %s\n",
+                response_code, desc);
+}
+/**
+ * mps_sc_failed_io_info - translated non-succesfull SCSI_IO request
+ */
+static void
+mps_sc_failed_io_info(struct mps_softc *sc, struct ccb_scsiio *csio,
+    Mpi2SCSIIOReply_t *mpi_reply)
+{
+	u32 response_info;
+	u8 *response_bytes;
+	u16 ioc_status = le16toh(mpi_reply->IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	u8 scsi_state = mpi_reply->SCSIState;
+	u8 scsi_status = mpi_reply->SCSIStatus;
+	char *desc_ioc_state = NULL;
+	char *desc_scsi_status = NULL;
+	char *desc_scsi_state = sc->tmp_string;
+	u32 log_info = le32toh(mpi_reply->IOCLogInfo);
+	
+	if (log_info == 0x31170000)
+		return;
+
+	switch (ioc_status) {
+	case MPI2_IOCSTATUS_SUCCESS:
+		desc_ioc_state = "success";
+		break;
+	case MPI2_IOCSTATUS_INVALID_FUNCTION:
+		desc_ioc_state = "invalid function";
+		break;
+	case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
+		desc_ioc_state = "scsi recovered error";
+		break;
+	case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
+		desc_ioc_state = "scsi invalid dev handle";
+		break;
+	case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
+		desc_ioc_state = "scsi device not there";
+		break;
+	case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
+		desc_ioc_state = "scsi data overrun";
+		break;
+	case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
+		desc_ioc_state = "scsi data underrun";
+		break;
+	case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
+		desc_ioc_state = "scsi io data error";
+		break;
+	case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
+		desc_ioc_state = "scsi protocol error";
+		break;
+	case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
+		desc_ioc_state = "scsi task terminated";
+		break;
+	case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
+		desc_ioc_state = "scsi residual mismatch";
+		break;
+	case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
+		desc_ioc_state = "scsi task mgmt failed";
+		break;
+	case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
+		desc_ioc_state = "scsi ioc terminated";
+		break;
+	case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
+		desc_ioc_state = "scsi ext terminated";
+		break;
+	case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
+		desc_ioc_state = "eedp guard error";
+		break;
+	case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
+		desc_ioc_state = "eedp ref tag error";
+		break;
+	case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
+		desc_ioc_state = "eedp app tag error";
+		break;
+	default:
+		desc_ioc_state = "unknown";
+		break;
+	}
+
+	switch (scsi_status) {
+	case MPI2_SCSI_STATUS_GOOD:
+		desc_scsi_status = "good";
+		break;
+	case MPI2_SCSI_STATUS_CHECK_CONDITION:
+		desc_scsi_status = "check condition";
+		break;
+	case MPI2_SCSI_STATUS_CONDITION_MET:
+		desc_scsi_status = "condition met";
+		break;
+	case MPI2_SCSI_STATUS_BUSY:
+		desc_scsi_status = "busy";
+		break;
+	case MPI2_SCSI_STATUS_INTERMEDIATE:
+		desc_scsi_status = "intermediate";
+		break;
+	case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET:
+		desc_scsi_status = "intermediate condmet";
+		break;
+	case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
+		desc_scsi_status = "reservation conflict";
+		break;
+	case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
+		desc_scsi_status = "command terminated";
+		break;
+	case MPI2_SCSI_STATUS_TASK_SET_FULL:
+		desc_scsi_status = "task set full";
+		break;
+	case MPI2_SCSI_STATUS_ACA_ACTIVE:
+		desc_scsi_status = "aca active";
+		break;
+	case MPI2_SCSI_STATUS_TASK_ABORTED:
+		desc_scsi_status = "task aborted";
+		break;
+	default:
+		desc_scsi_status = "unknown";
+		break;
+	}
+
+	desc_scsi_state[0] = '\0';
+	if (!scsi_state)
+		desc_scsi_state = " ";
+	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
+		strcat(desc_scsi_state, "response info ");
+	if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
+		strcat(desc_scsi_state, "state terminated ");
+	if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS)
+		strcat(desc_scsi_state, "no status ");
+	if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
+		strcat(desc_scsi_state, "autosense failed ");
+	if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)
+		strcat(desc_scsi_state, "autosense valid ");
+
+	mps_dprint(sc, MPS_INFO, "\thandle(0x%04x), ioc_status(%s)(0x%04x), \n",
+		le16toh(mpi_reply->DevHandle),
+	    desc_ioc_state, ioc_status);
+	/* We can add more detail about underflow data here
+	 * TO-DO
+	 * */
+	mps_dprint(sc, MPS_INFO, "\tscsi_status(%s)(0x%02x), "
+	    "scsi_state(%s)(0x%02x)\n", desc_scsi_status,
+	    scsi_status, desc_scsi_state, scsi_state);
+
+	if (sc->mps_debug & MPS_INFO &&
+		scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
+		mps_dprint(sc, MPS_INFO, "-> Sense Buffer Data : Start :\n");
+		scsi_sense_print(csio);
+		mps_dprint(sc, MPS_INFO, "-> Sense Buffer Data : End :\n");
+	}
+
+	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
+		response_info = le32toh(mpi_reply->ResponseInfo);
+		response_bytes = (u8 *)&response_info;
+		mps_response_code(sc,response_bytes[0]);
+	}
+}
+
+static void
 mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
 {
 	MPI2_SCSI_IO_REPLY *rep;
@@ -2018,6 +2319,8 @@ mpssas_scsiio_complete(struct mps_softc 
 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 		break;
 	}
+	
+	mps_sc_failed_io_info(sc,csio,rep);
 
 	if (sassc->flags & MPSSAS_QUEUE_FROZEN) {
 		ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
@@ -2799,17 +3102,26 @@ mpssas_scanner_thread(void *arg)
 
 	mps_lock(sc);
 	for (;;) {
+		/* Sleep for 1 second and check the queue status*/
 		msleep(&sassc->ccb_scanq, &sc->mps_mtx, PRIBIO,
-		       "mps_scanq", 0);
+		       "mps_scanq", 1 * hz);
 		if (sassc->flags & MPSSAS_SHUTDOWN) {
 			mps_dprint(sc, MPS_TRACE, "Scanner shutting down\n");
 			break;
 		}
+next_work:
+		// Get first work.
 		ccb = (union ccb *)TAILQ_FIRST(&sassc->ccb_scanq);
 		if (ccb == NULL)
 			continue;
+		// Got first work.
 		TAILQ_REMOVE(&sassc->ccb_scanq, &ccb->ccb_h, sim_links.tqe);
 		xpt_action(ccb);
+		if (sassc->flags & MPSSAS_SHUTDOWN) {
+			mps_dprint(sc, MPS_TRACE, "Scanner shutting down\n");
+			break;
+		}
+		goto next_work;
 	}
 
 	sassc->flags &= ~MPSSAS_SCANTHREAD;
@@ -3009,7 +3321,7 @@ mpssas_check_eedp(struct mpssas_softc *s
 				}
 				if (!found_lun) {
 					lun = malloc(sizeof(struct mpssas_lun),
-					    M_MPT2, M_WAITOK | M_ZERO);
+					    M_MPT2, M_NOWAIT | M_ZERO);
 					if (lun == NULL) {
 						mps_dprint(sc, MPS_FAULT,
 						    "Unable to alloc LUN for "
@@ -3084,6 +3396,20 @@ mpssas_read_cap_done(struct cam_periph *
 
 	if (done_ccb == NULL)
 		return;
+	
+	/* Driver need to release devq, it Scsi command is
+	 * generated by driver internally.
+	 * Currently there is a single place where driver
+	 * calls scsi command internally. In future if driver
+	 * calls more scsi command internally, it needs to release
+	 * devq internally, since those command will not go back to
+	 * cam_periph.
+	 */
+	if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) ) {
+        	done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
+		xpt_release_devq(done_ccb->ccb_h.path,
+			       	/*count*/ 1, /*run_queue*/TRUE);
+	}
 
 	rcap_buf = (struct scsi_read_capacity_eedp *)done_ccb->csio.data_ptr;
 
diff -arup mps_11.255.03.00-fbsd/mps_sas.h mps_13.00.00.00-fbsd/mps_sas.h
--- mps_11.255.03.00-fbsd/mps_sas.h	2012-02-06 21:48:09.051603337 +0530
+++ mps_13.00.00.00-fbsd/mps_sas.h	2012-02-06 21:47:34.615994119 +0530
@@ -49,8 +49,11 @@ struct mpssas_target {
 #define MPSSAS_TARGET_INRESET	(1 << 1)
 #define MPSSAS_TARGET_INDIAGRESET (1 << 2)
 #define MPSSAS_TARGET_INREMOVAL	(1 << 3)
+#define MPS_TARGET_FLAGS_RAID_COMPONENT (1 << 4)
+#define MPS_TARGET_FLAGS_VOLUME         (1 << 5)
 #define MPSSAS_TARGET_INRECOVERY (MPSSAS_TARGET_INABORT | \
     MPSSAS_TARGET_INRESET | MPSSAS_TARGET_INCHIPRESET)
+
 #define MPSSAS_TARGET_ADD       (1 << 29)
 #define MPSSAS_TARGET_REMOVE    (1 << 30)
 	uint16_t	tid;
diff -arup mps_11.255.03.00-fbsd/mps_sas_lsi.c mps_13.00.00.00-fbsd/mps_sas_lsi.c
--- mps_11.255.03.00-fbsd/mps_sas_lsi.c	2012-02-06 21:48:09.055582108 +0530
+++ mps_13.00.00.00-fbsd/mps_sas_lsi.c	2012-02-06 21:47:34.616991047 +0530
@@ -107,7 +107,7 @@ struct _ata_identify_device_data {
 	u16 model_number[20];	/* 27-46*/
 	u16 reserved3[209];	/* 47-255*/
 };
-
+static u32 event_count;
 static void mpssas_fw_work(struct mps_softc *sc,
     struct mps_fw_event_work *fw_event);
 static void mpssas_fw_event_free(struct mps_softc *,
@@ -119,7 +119,7 @@ static int mpssas_get_sata_identify(stru
 int mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc,
     u64 *sas_address, u16 handle, u32 device_info);
 static int mpssas_volume_add(struct mps_softc *sc,
-    Mpi2EventIrConfigElement_t *element);
+    u16 handle);
 
 void
 mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
@@ -191,6 +191,8 @@ mpssas_fw_work(struct mps_softc *sc, str
 	struct mpssas_softc *sassc;
 	sassc = sc->sassc;
 
+	mps_dprint(sc, MPS_INFO, "(%d)->(%s) Working on  Event: [%x]\n",
+			event_count++,__func__,fw_event->event);
 	switch (fw_event->event) {
 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 
 	{
@@ -284,7 +286,7 @@ mpssas_fw_work(struct mps_softc *sc, str
 			case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
 			case MPI2_EVENT_IR_CHANGE_RC_ADDED:
 				if (!foreign_config) {
-					if (mpssas_volume_add(sc, element)) {
+					if (mpssas_volume_add(sc, le16toh(element->VolDevHandle))){
 						printf("%s: failed to add RAID "
 						    "volume with handle 0x%x\n",
 						    __func__, le16toh(element->
@@ -319,12 +321,18 @@ mpssas_fw_work(struct mps_softc *sc, str
 				}
 				break;
 			case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
+			case MPI2_EVENT_IR_CHANGE_RC_HIDE:
 				/*
 				 * Phys Disk of a volume has been created.  Hide
 				 * it from the OS.
 				 */
-				mpssas_prepare_remove(sassc, element->
-				    PhysDiskDevHandle);
+				targ = mpssas_find_target_by_handle(sassc, 0, element->PhysDiskDevHandle);
+				if (targ == NULL) 
+					break;
+
+				targ->flags |= MPS_TARGET_FLAGS_RAID_COMPONENT;
+				mpssas_rescan_target(sc, targ);
+				
 				break;
 			case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
 				/*
@@ -379,6 +387,35 @@ mpssas_fw_work(struct mps_softc *sc, str
 			    "handle 0x%x", event_data->PreviousValue,
 			    event_data->NewValue,
 			    event_data->VolDevHandle);
+				u32 state;
+				struct mpssas_target *targ;
+				state = le32toh(event_data->NewValue);
+				switch (state) {
+				case MPI2_RAID_VOL_STATE_MISSING:
+				case MPI2_RAID_VOL_STATE_FAILED:
+					mpssas_prepare_volume_remove(sassc, event_data->
+							VolDevHandle);
+					break;
+		 
+				case MPI2_RAID_VOL_STATE_ONLINE:
+				case MPI2_RAID_VOL_STATE_DEGRADED:
+				case MPI2_RAID_VOL_STATE_OPTIMAL:
+					targ = mpssas_find_target_by_handle(sassc, 0, event_data->VolDevHandle);
+					if (targ) {
+						printf("%s %d: Volume handle 0x%x is already added \n",
+							       	__func__, __LINE__ , event_data->VolDevHandle);
+						break;
+					}
+					if (mpssas_volume_add(sc, le16toh(event_data->VolDevHandle))) {
+						printf("%s: failed to add RAID "
+							"volume with handle 0x%x\n",
+							__func__, le16toh(event_data->
+							VolDevHandle));
+					}
+					break;
+				default:
+					break;
+				}
 			break;
 		default:
 			break;
@@ -389,6 +426,7 @@ mpssas_fw_work(struct mps_softc *sc, str
 	{
 		Mpi2EventDataIrPhysicalDisk_t *event_data =
 		    fw_event->event_data;
+		struct mpssas_target *targ;
 
 		/*
 		 * Informational only.
@@ -399,7 +437,7 @@ mpssas_fw_work(struct mps_softc *sc, str
 			mps_dprint(sc, MPS_INFO, "   Phys Disk Settings "
 			    "changed from 0x%x to 0x%x for Phys Disk Number "
 			    "%d and handle 0x%x at Enclosure handle 0x%x, Slot "
-			    "%d", event_data->PreviousValue,
+			    "%d\n", event_data->PreviousValue,
 			    event_data->NewValue, event_data->PhysDiskNum,
 			    event_data->PhysDiskDevHandle,
 			    event_data->EnclosureHandle, event_data->Slot);
@@ -407,7 +445,7 @@ mpssas_fw_work(struct mps_softc *sc, str
 		case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
 			mps_dprint(sc, MPS_INFO, "   Phys Disk Status changed "
 			    "from 0x%x to 0x%x for Phys Disk Number %d and "
-			    "handle 0x%x at Enclosure handle 0x%x, Slot %d",
+			    "handle 0x%x at Enclosure handle 0x%x, Slot %d\n",
 			    event_data->PreviousValue, event_data->NewValue,
 			    event_data->PhysDiskNum,
 			    event_data->PhysDiskDevHandle,
@@ -416,12 +454,38 @@ mpssas_fw_work(struct mps_softc *sc, str
 		case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
 			mps_dprint(sc, MPS_INFO, "   Phys Disk State changed "
 			    "from 0x%x to 0x%x for Phys Disk Number %d and "
-			    "handle 0x%x at Enclosure handle 0x%x, Slot %d",
+			    "handle 0x%x at Enclosure handle 0x%x, Slot %d\n",
 			    event_data->PreviousValue, event_data->NewValue,
 			    event_data->PhysDiskNum,
 			    event_data->PhysDiskDevHandle,
 			    event_data->EnclosureHandle, event_data->Slot);
-			break;
+			switch (event_data->NewValue) {
+				case MPI2_RAID_PD_STATE_ONLINE:
+				case MPI2_RAID_PD_STATE_DEGRADED:
+				case MPI2_RAID_PD_STATE_REBUILDING:
+				case MPI2_RAID_PD_STATE_OPTIMAL:
+				case MPI2_RAID_PD_STATE_HOT_SPARE:
+					targ = mpssas_find_target_by_handle(sassc, 0, 
+							event_data->PhysDiskDevHandle);
+					if (targ) {
+						targ->flags |= MPS_TARGET_FLAGS_RAID_COMPONENT;
+						printf("%s %d: Found Target for handle 0x%x.  \n",
+						__func__, __LINE__ , event_data->PhysDiskDevHandle);
+					}
+				break;
+				case MPI2_RAID_PD_STATE_OFFLINE:
+				case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
+				case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
+				default:
+					targ = mpssas_find_target_by_handle(sassc, 0, 
+							event_data->PhysDiskDevHandle);
+					if (targ) {
+						targ->flags |= ~MPS_TARGET_FLAGS_RAID_COMPONENT;
+						printf("%s %d: Found Target for handle 0x%x.  \n",
+						__func__, __LINE__ , event_data->PhysDiskDevHandle);
+					}
+				break;
+			}
 		default:
 			break;
 		}
@@ -494,6 +558,7 @@ mpssas_fw_work(struct mps_softc *sc, str
 		break;
 
 	}
+	mps_dprint(sc, MPS_INFO, "(%d)->(%s) Event Free: [%x]\n",event_count,__func__, fw_event->event);
 	mpssas_fw_event_free(sc, fw_event);
 }
 
@@ -584,7 +649,7 @@ mpssas_add_device(struct mps_softc *sc, 
 		error = ENXIO;
 		goto out;
 	}
-	mps_vprintf(sc, "SAS Address from SAS device page0 = %jx\n",
+	mps_dprint(sc, MPS_INFO, "SAS Address from SAS device page0 = %jx\n",
 	    sas_address);
 	targ = &sassc->targets[id];
 	targ->devinfo = device_info;
@@ -605,12 +670,12 @@ mpssas_add_device(struct mps_softc *sc, 
 	TAILQ_INIT(&targ->timedout_commands);
 	SLIST_INIT(&targ->luns);
 	mps_describe_devinfo(targ->devinfo, devstring, 80);
-	mps_vprintf(sc, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring,
+	mps_dprint(sc, MPS_INFO, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring,
 	    mps_describe_table(mps_linkrate_names, targ->linkrate),
 	    targ->handle, targ->encl_handle, targ->encl_slot);
 	if ((sassc->flags & MPSSAS_IN_STARTUP) == 0)
 		mpssas_rescan_target(sc, targ);
-	mps_vprintf(sc, "Target id 0x%x added\n", targ->tid);
+	mps_dprint(sc, MPS_INFO, "Target id 0x%x added\n", targ->tid);
 out:
 	mpssas_startup_decrement(sassc);
 	return (error);
@@ -751,12 +816,11 @@ out:
 }
 
 static int
-mpssas_volume_add(struct mps_softc *sc, Mpi2EventIrConfigElement_t *element)
+mpssas_volume_add(struct mps_softc *sc, u16 handle)
 {
 	struct mpssas_softc *sassc;
 	struct mpssas_target *targ;
 	u64 wwid;
-	u16 handle = le16toh(element->VolDevHandle);
 	unsigned int id;
 	int error = 0;
 
@@ -855,7 +919,9 @@ mpssas_ir_shutdown(struct mps_softc *sc)
 	action->Function = MPI2_FUNCTION_RAID_ACTION;
 	action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+	mps_lock(sc);
 	mps_request_polled(sc, cm);
+	mps_unlock(sc);
 
 	/*
 	 * Don't check for reply, just leave.
diff -arup mps_11.255.03.00-fbsd/mps_user.c mps_13.00.00.00-fbsd/mps_user.c
--- mps_11.255.03.00-fbsd/mps_user.c	2012-02-06 21:48:09.061562834 +0530
+++ mps_13.00.00.00-fbsd/mps_user.c	2012-02-06 21:47:34.619976522 +0530
@@ -712,7 +712,7 @@ mps_user_command(struct mps_softc *sc, s
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 
 	mps_lock(sc);
-	err = mps_wait_command(sc, cm, 0);
+	err = mps_wait_command(sc, cm, 30);
 
 	if (err) {
 		mps_printf(sc, "%s: invalid request: error %d\n",
@@ -842,7 +842,7 @@ mps_user_pass_thru(struct mps_softc *sc,
 		cm->cm_complete = NULL;
 		cm->cm_complete_data = NULL;
 
-		err = mps_wait_command(sc, cm, 0);
+		err = mps_wait_command(sc, cm, 30);
 
 		if (err != 0) {
 			err = EIO;
@@ -979,7 +979,7 @@ mps_user_pass_thru(struct mps_softc *sc,
 
 	mps_lock(sc);
 
-	err = mps_wait_command(sc, cm, 0);
+	err = mps_wait_command(sc, cm, 30);
 
 	if (err) {
 		mps_printf(sc, "%s: invalid request: error %d\n", __func__,
@@ -1098,10 +1098,12 @@ mps_user_get_adapter_data(struct mps_sof
 	 * Need to get BIOS Config Page 3 for the BIOS Version.
 	 */
 	data->BiosVersion = 0;
+	mps_lock(sc);
 	if (mps_config_get_bios_pg3(sc, &mpi_reply, &config_page))
 		printf("%s: Error while retrieving BIOS Version\n", __func__);
 	else
 		data->BiosVersion = config_page.BiosVersion;
+	mps_unlock(sc);
 }
 
 static void
@@ -1194,7 +1196,7 @@ mps_post_fw_diag_buffer(struct mps_softc
 	/*
 	 * Send command synchronously.
 	 */
-	status = mps_wait_command(sc, cm, 0);
+	status = mps_wait_command(sc, cm, 30);
 	if (status) {
 		mps_printf(sc, "%s: invalid request: error %d\n", __func__,
 		    status);
@@ -1278,7 +1280,7 @@ mps_release_fw_diag_buffer(struct mps_so
 	/*
 	 * Send command synchronously.
 	 */
-	status = mps_wait_command(sc, cm, 0);
+	status = mps_wait_command(sc, cm, 30);
 	if (status) {
 		mps_printf(sc, "%s: invalid request: error %d\n", __func__,
 		    status);
diff -arup mps_11.255.03.00-fbsd/mpsvar.h mps_13.00.00.00-fbsd/mpsvar.h
--- mps_11.255.03.00-fbsd/mpsvar.h	2012-02-06 21:48:09.064546913 +0530
+++ mps_13.00.00.00-fbsd/mpsvar.h	2012-02-06 21:48:54.037698309 +0530
@@ -58,7 +58,7 @@
 #ifndef _MPSVAR_H
 #define _MPSVAR_H
 
-#define MPS_DRIVER_VERSION	"11.255.03.00-fbsd"
+#define MPS_DRIVER_VERSION	"13.00.00.00-fbsd"
 
 #define MPS_DB_MAX_WAIT		2500
 
@@ -78,6 +78,7 @@
 #define MPS_PERIODIC_DELAY	1	/* 1 second heartbeat/watchdog check */
 
 #define MPS_SCSI_RI_INVALID_FRAME	(0x00000002)
+#define MPS_STRING_LENGTH               64
 
 /*
  * host mapping related macro definitions
@@ -309,7 +310,7 @@ struct mps_softc {
 	struct callout			periodic;
 
 	struct mpssas_softc		*sassc;
-
+	char            tmp_string[MPS_STRING_LENGTH];
 	TAILQ_HEAD(, mps_command)	req_list;
 	TAILQ_HEAD(, mps_command)	high_priority_req_list;
 	TAILQ_HEAD(, mps_chain)		chain_list;
@@ -521,6 +522,12 @@ mps_free_command(struct mps_softc *sc, s
 	cm->cm_max_segs = 0;
 	cm->cm_lun = 0;
 	cm->cm_state = MPS_CM_STATE_FREE;
+	cm->cm_data = NULL;
+	cm->cm_length = 0;
+	cm->cm_out_len = 0;
+	cm->cm_sglsize = 0;
+	cm->cm_sge = NULL;
+
 	TAILQ_FOREACH_SAFE(chain, &cm->cm_chain_list, chain_link, chain_temp) {
 		TAILQ_REMOVE(&cm->cm_chain_list, chain, chain_link);
 		mps_free_chain(sc, chain);
@@ -749,7 +756,9 @@ void mps_mapping_ir_config_change_event(
 void mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
     MPI2_EVENT_NOTIFICATION_REPLY *event);
 void mpssas_prepare_remove(struct mpssas_softc *sassc, uint16_t handle);
+void mpssas_prepare_volume_remove(struct mpssas_softc *sassc, uint16_t handle);
 int mpssas_startup(struct mps_softc *sc);
+struct mpssas_target * mpssas_find_target_by_handle(struct mpssas_softc *, int, uint16_t);
 
 SYSCTL_DECL(_hw_mps);
 

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B2FD678A64EAAD45B089B123FDFC3ED729A3415109>