Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Mar 2013 18:00:07 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r248900 - projects/camlock/sys/cam/scsi
Message-ID:  <201303291800.r2TI07O0079570@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Mar 29 18:00:07 2013
New Revision: 248900
URL: http://svnweb.freebsd.org/changeset/base/248900

Log:
  Modify probe periph to freeze queue after sending each command to prevent
  other requests with lower priority from slip through instead of using
  multilevel freezing.

Modified:
  projects/camlock/sys/cam/scsi/scsi_xpt.c

Modified: projects/camlock/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_xpt.c	Fri Mar 29 17:57:24 2013	(r248899)
+++ projects/camlock/sys/cam/scsi/scsi_xpt.c	Fri Mar 29 18:00:07 2013	(r248900)
@@ -648,11 +648,6 @@ proberegister(struct cam_periph *periph,
 	 */
 	cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
 				      scsi_delay);
-	/*
-	 * Ensure nobody slip in until probe finish.
-	 */
-	cam_freeze_devq_arg(periph->path,
-	    RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1);
 	probeschedule(periph);
 	return(CAM_REQ_CMP);
 }
@@ -981,6 +976,7 @@ again:
 	default:
 		panic("probestart: invalid action state 0x%x\n", softc->action);
 	}
+	start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 	xpt_action(start_ccb);
 }
 
@@ -1127,8 +1123,12 @@ probedone(struct cam_periph *periph, uni
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 
 			if (cam_periph_error(done_ccb, 0,
-					     SF_NO_PRINT, NULL) == ERESTART)
+					     SF_NO_PRINT, NULL) == ERESTART) {
+out:
+				/* Drop freeze taken due to CAM_DEV_QFREEZE */
+				cam_release_devq(path, 0, 0, 0, FALSE);
 				return;
+			}
 			else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 				/* Don't wedge the queue */
 				xpt_release_devq(done_ccb->ccb_h.path,
@@ -1138,7 +1138,7 @@ probedone(struct cam_periph *periph, uni
 		PROBE_SET_ACTION(softc, PROBE_INQUIRY);
 		xpt_release_ccb(done_ccb);
 		xpt_schedule(periph, priority);
-		return;
+		goto out;
 	}
 	case PROBE_INQUIRY:
 	case PROBE_FULL_INQUIRY:
@@ -1173,7 +1173,7 @@ probedone(struct cam_periph *periph, uni
 					PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
 					xpt_release_ccb(done_ccb);
 					xpt_schedule(periph, priority);
-					return;
+					goto out;
 				}
 
 				scsi_find_quirk(path->device);
@@ -1203,7 +1203,7 @@ probedone(struct cam_periph *periph, uni
 				}
 				xpt_release_ccb(done_ccb);
 				xpt_schedule(periph, priority);
-				return;
+				goto out;
 			} else if (path->device->lun_id == 0 &&
 			    SID_ANSI_REV(inq_buf) > SCSI_REV_SPC2 &&
 			    (SCSI_QUIRK(path->device)->quirks &
@@ -1218,14 +1218,14 @@ probedone(struct cam_periph *periph, uni
 				periph->path->target->rpl_size = 16;
 				xpt_release_ccb(done_ccb);
 				xpt_schedule(periph, priority);
-				return;
+				goto out;
 			}
 		} else if (cam_periph_error(done_ccb, 0,
 					    done_ccb->ccb_h.target_lun > 0
 					    ? SF_RETRY_UA|SF_QUIET_IR
 					    : SF_RETRY_UA,
 					    &softc->saved_ccb) == ERESTART) {
-			return;
+			goto out;
 		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 			/* Don't wedge the queue */
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1266,7 +1266,7 @@ probedone(struct cam_periph *periph, uni
 			    done_ccb->ccb_h.target_lun > 0 ?
 			    SF_RETRY_UA|SF_QUIET_IR : SF_RETRY_UA,
 			    &softc->saved_ccb) == ERESTART) {
-				return;
+				goto out;
 			}
 			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 				xpt_release_devq(done_ccb->ccb_h.path, 1,
@@ -1285,7 +1285,7 @@ probedone(struct cam_periph *periph, uni
 			path->target->rpl_size = (nlun << 3) + 8;
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
-			return;
+			goto out;
 		} else if (nlun == 0) {
 			/*
 			 * If there don't appear to be any luns, bail.
@@ -1358,7 +1358,7 @@ probedone(struct cam_periph *periph, uni
 				    PROBE_SUPPORTED_VPD_LIST);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
-			return;
+			goto out;
 		}
 		if (lp) {
 			free(lp, M_CAMXPT);
@@ -1383,7 +1383,7 @@ probedone(struct cam_periph *periph, uni
 		} else if (cam_periph_error(done_ccb, 0,
 					    SF_RETRY_UA|SF_NO_PRINT,
 					    &softc->saved_ccb) == ERESTART) {
-			return;
+			goto out;
 		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 			/* Don't wedge the queue */
 			xpt_release_devq(done_ccb->ccb_h.path,
@@ -1393,7 +1393,7 @@ probedone(struct cam_periph *periph, uni
 		free(mode_hdr, M_CAMXPT);
 		PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
 		xpt_schedule(periph, priority);
-		return;
+		goto out;
 	}
 	case PROBE_SUPPORTED_VPD_LIST:
 	{
@@ -1422,11 +1422,11 @@ probedone(struct cam_periph *periph, uni
 			xpt_release_ccb(done_ccb);
 			PROBE_SET_ACTION(softc, PROBE_DEVICE_ID);
 			xpt_schedule(periph, priority);
-			return;
+			goto out;
 		} else if (cam_periph_error(done_ccb, 0,
 					    SF_RETRY_UA|SF_NO_PRINT,
 					    &softc->saved_ccb) == ERESTART) {
-			return;
+			goto out;
 		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 			/* Don't wedge the queue */
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1471,7 +1471,7 @@ probedone(struct cam_periph *periph, uni
 		} else if (cam_periph_error(done_ccb, 0,
 					    SF_RETRY_UA,
 					    &softc->saved_ccb) == ERESTART) {
-			return;
+			goto out;
 		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 			/* Don't wedge the queue */
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1484,7 +1484,7 @@ probedone(struct cam_periph *periph, uni
 		xpt_release_ccb(done_ccb);
 		PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM);
 		xpt_schedule(periph, priority);
-		return;
+		goto out;
 	}
 
 probe_device_check:
@@ -1526,7 +1526,7 @@ probe_device_check:
 		} else if (cam_periph_error(done_ccb, 0,
 					    SF_RETRY_UA|SF_NO_PRINT,
 					    &softc->saved_ccb) == ERESTART) {
-			return;
+			goto out;
 		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 			/* Don't wedge the queue */
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1585,7 +1585,7 @@ probe_device_check:
 			 */
 			PROBE_SET_ACTION(softc, PROBE_TUR_FOR_NEGOTIATION);
 			xpt_schedule(periph, priority);
-			return;
+			goto out;
 		}
 		xpt_release_ccb(done_ccb);
 		break;
@@ -1615,7 +1615,7 @@ probe_device_check:
 			xpt_release_ccb(done_ccb);
 			PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV1);
 			xpt_schedule(periph, priority);
-			return;
+			goto out;
 		}
 		if (softc->action == PROBE_DV_EXIT) {
 			CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
@@ -1668,14 +1668,14 @@ probe_device_check:
 			free(nbuf, M_CAMXPT);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
-			return;
+			goto out;
 		}
 		free(nbuf, M_CAMXPT);
 		if (softc->action == PROBE_INQUIRY_BASIC_DV1) {
 			PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV2);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
-			return;
+			goto out;
 		}
 		if (softc->action == PROBE_INQUIRY_BASIC_DV2) {
 			CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
@@ -1707,12 +1707,13 @@ probe_device_check:
 	xpt_done(done_ccb);
 	if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
 		CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n"));
+		/* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */
+		cam_release_devq(path, 0, 0, 0, FALSE);
 		cam_periph_invalidate(periph);
-		cam_release_devq(periph->path,
-		    RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
 		cam_periph_release_locked(periph);
 	} else {
 		probeschedule(periph);
+		goto out;
 	}
 }
 



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