From owner-svn-src-head@FreeBSD.ORG  Tue Sep 25 19:12:13 2012
Return-Path: <owner-svn-src-head@FreeBSD.ORG>
Delivered-To: svn-src-head@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id F37091065678;
	Tue, 25 Sep 2012 19:12:12 +0000 (UTC)
	(envelope-from rstone@FreeBSD.org)
Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c])
	by mx1.freebsd.org (Postfix) with ESMTP id DECEB8FC0A;
	Tue, 25 Sep 2012 19:12:12 +0000 (UTC)
Received: from svn.freebsd.org (localhost [127.0.0.1])
	by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q8PJCC8w080585;
	Tue, 25 Sep 2012 19:12:12 GMT (envelope-from rstone@svn.freebsd.org)
Received: (from rstone@localhost)
	by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8PJCCrj080583;
	Tue, 25 Sep 2012 19:12:12 GMT (envelope-from rstone@svn.freebsd.org)
Message-Id: <201209251912.q8PJCCrj080583@svn.freebsd.org>
From: Ryan Stone <rstone@FreeBSD.org>
Date: Tue, 25 Sep 2012 19:12:12 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
	svn-src-head@freebsd.org
X-SVN-Group: head
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Cc: 
Subject: svn commit: r240923 - head/sys/dev/aac
X-BeenThere: svn-src-head@freebsd.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: SVN commit messages for the src tree for head/-current
	<svn-src-head.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-head>,
	<mailto:svn-src-head-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-head>
List-Post: <mailto:svn-src-head@freebsd.org>
List-Help: <mailto:svn-src-head-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-head>,
	<mailto:svn-src-head-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Tue, 25 Sep 2012 19:12:13 -0000

Author: rstone
Date: Tue Sep 25 19:12:12 2012
New Revision: 240923
URL: http://svn.freebsd.org/changeset/base/240923

Log:
  Some aac(4) adapters will always report that a direct access device is
  offline in response to a INQUIRY command that does not retreive vital
  product data(I personally have observed the behaviour on an Adaptec 2405
  and a 5805).  Force the peripheral qualifier to "connected" so that upper
  layers correctly recognize that a disk is present.
  
  This bug was uncovered by r216236.  Prior to that fix, aac(4) was
  accidentally clearing the peripheral qualifier for all inquiry commands.
  
  This fixes an issue where passthrough devices were not created for
  disks behind aac(4) controllers suffering from the bug.  I have
  verified that if a disk is not present that we still properly detect
  that and not create the passthrough device.
  
  Sponsored by:	Sandvine Incorporated
  MFC after:	1 week

Modified:
  head/sys/dev/aac/aac_cam.c

Modified: head/sys/dev/aac/aac_cam.c
==============================================================================
--- head/sys/dev/aac/aac_cam.c	Tue Sep 25 19:08:51 2012	(r240922)
+++ head/sys/dev/aac/aac_cam.c	Tue Sep 25 19:12:12 2012	(r240923)
@@ -527,6 +527,53 @@ aac_cam_poll(struct cam_sim *sim)
 }
 
 static void
+aac_cam_fix_inquiry(struct aac_softc *sc, union ccb *ccb)
+{
+	struct scsi_inquiry_data *inq;
+	uint8_t *data;
+	uint8_t device, qual;
+
+	/* If this is an inquiry command, fake things out */
+	if (ccb->ccb_h.flags & CAM_CDB_POINTER)
+		data = ccb->csio.cdb_io.cdb_ptr;
+	else
+		data = ccb->csio.cdb_io.cdb_bytes;
+
+	if (data[0] != INQUIRY)
+		return;
+
+	if (ccb->ccb_h.status == CAM_REQ_CMP) {
+		inq = (struct scsi_inquiry_data *)ccb->csio.data_ptr;
+		device = SID_TYPE(inq);
+		qual = SID_QUAL(inq);
+
+		/*
+		 * We want DASD and PROC devices to only be
+		 * visible through the pass device.
+		 */
+		if (((device == T_DIRECT) ||
+		    (device == T_PROCESSOR) ||
+		    (sc->flags & AAC_FLAGS_CAM_PASSONLY))) {
+			/*
+			 * Some aac(4) adapters will always report that a direct
+			 * access device is offline in response to a INQUIRY
+			 * command that does not retreive vital product data.
+			 * Force the qualifier to connected so that upper layers
+			 * correctly recognize that a disk is present.
+			 */
+			if ((data[1] & SI_EVPD) == 0 && device == T_DIRECT &&
+			    qual == SID_QUAL_LU_OFFLINE)
+				qual = SID_QUAL_LU_CONNECTED;
+			ccb->csio.data_ptr[0] = (qual << 5) | T_NODEVICE;
+		}
+	} else if (ccb->ccb_h.status == CAM_SEL_TIMEOUT &&
+		ccb->ccb_h.target_lun != 0) {
+		/* fix for INQUIRYs on Lun>0 */
+		ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+	}
+}
+
+static void
 aac_cam_complete(struct aac_command *cm)
 {
 	union	ccb *ccb;
@@ -551,8 +598,6 @@ aac_cam_complete(struct aac_command *cm)
 
 		/* Take care of SCSI_IO ops. */
 		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
-			u_int8_t command, device;
-
 			ccb->csio.scsi_status = srbr->scsi_status;
 
 			/* Take care of autosense */
@@ -572,31 +617,7 @@ aac_cam_complete(struct aac_command *cm)
 				// scsi_sense_print(&ccb->csio);
 			}
 
-			/* If this is an inquiry command, fake things out */
-			if (ccb->ccb_h.flags & CAM_CDB_POINTER)
-				command = ccb->csio.cdb_io.cdb_ptr[0];
-			else
-				command = ccb->csio.cdb_io.cdb_bytes[0];
-
-			if (command == INQUIRY) {
-				if (ccb->ccb_h.status == CAM_REQ_CMP) {
-				device = ccb->csio.data_ptr[0] & 0x1f;
-				/*
-				 * We want DASD and PROC devices to only be
-				 * visible through the pass device.
-				 */
-				if ((device == T_DIRECT) ||
-				    (device == T_PROCESSOR) ||
-				    (sc->flags & AAC_FLAGS_CAM_PASSONLY))
-					ccb->csio.data_ptr[0] =
-					    ((ccb->csio.data_ptr[0] & 0xe0) |
-					    T_NODEVICE);
-				} else if (ccb->ccb_h.status == CAM_SEL_TIMEOUT &&
-					ccb->ccb_h.target_lun != 0) {
-					/* fix for INQUIRYs on Lun>0 */
-					ccb->ccb_h.status = CAM_DEV_NOT_THERE;
-				}
-			}
+			aac_cam_fix_inquiry(sc, ccb);
 		}
 	}