Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Oct 2009 23:14:07 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r198639 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/usb/storage dev/xen/xenpci
Message-ID:  <200910292314.n9TNE7TL014189@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: thompsa
Date: Thu Oct 29 23:14:06 2009
New Revision: 198639
URL: http://svn.freebsd.org/changeset/base/198639

Log:
  MFC r196826
  
   Make umass(4) pass device USB serial number to CAM, making it possible
   to e.g. retrieve it using camcontrol(8).

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/usb/storage/umass.c
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/usb/storage/umass.c
==============================================================================
--- stable/8/sys/dev/usb/storage/umass.c	Thu Oct 29 23:13:36 2009	(r198638)
+++ stable/8/sys/dev/usb/storage/umass.c	Thu Oct 29 23:14:06 2009	(r198639)
@@ -124,6 +124,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
+#include <dev/usb/usb_device.h>
 #include "usbdevs.h"
 
 #include <cam/cam.h>
@@ -2979,6 +2980,28 @@ umass_cam_action(struct cam_sim *sim, un
 				if (sc->sc_transfer.cmd_data[0] == INQUIRY) {
 
 					/*
+					 * Umass devices don't generally report their serial numbers
+					 * in the usual SCSI way.  Emulate it here.
+					 */
+					if ((sc->sc_transfer.cmd_data[1] & SI_EVPD) &&
+					    sc->sc_transfer.cmd_data[2] == SVPD_UNIT_SERIAL_NUMBER &&
+					    sc->sc_udev != NULL &&
+					    sc->sc_udev->serial != NULL &&
+					    sc->sc_udev->serial[0] != '\0') {
+						struct scsi_vpd_unit_serial_number *vpd_serial;
+
+						vpd_serial = (struct scsi_vpd_unit_serial_number *)ccb->csio.data_ptr;
+						vpd_serial->length = strlen(sc->sc_udev->serial);
+						if (vpd_serial->length > sizeof(vpd_serial->serial_num))
+							vpd_serial->length = sizeof(vpd_serial->serial_num);
+						memcpy(vpd_serial->serial_num, sc->sc_udev->serial, vpd_serial->length);
+						ccb->csio.scsi_status = SCSI_STATUS_OK;
+						ccb->ccb_h.status = CAM_REQ_CMP;
+						xpt_done(ccb);
+						goto done;
+					}
+
+					/*
 					 * Handle EVPD inquiry for broken devices first
 					 * NO_INQUIRY also implies NO_INQUIRY_EVPD
 					 */
@@ -3194,6 +3217,29 @@ umass_cam_cb(struct umass_softc *sc, uni
 			maxsector = scsi_4btoul(rcap->addr) - 1;
 			scsi_ulto4b(maxsector, rcap->addr);
 		}
+		/*
+		 * We have to add SVPD_UNIT_SERIAL_NUMBER to the list
+		 * of pages supported by the device - otherwise, CAM
+		 * will never ask us for the serial number if the
+		 * device cannot handle that by itself.
+		 */
+		if (ccb->ccb_h.func_code == XPT_SCSI_IO &&
+		    sc->sc_transfer.cmd_data[0] == INQUIRY &&
+		    (sc->sc_transfer.cmd_data[1] & SI_EVPD) &&
+		    sc->sc_transfer.cmd_data[2] == SVPD_SUPPORTED_PAGE_LIST &&
+		    sc->sc_udev != NULL &&
+		    sc->sc_udev->serial != NULL &&
+		    sc->sc_udev->serial[0] != '\0') {
+			struct ccb_scsiio *csio;
+			struct scsi_vpd_supported_page_list *page_list;
+
+			csio = &ccb->csio;
+			page_list = (struct scsi_vpd_supported_page_list *)csio->data_ptr;
+			if (page_list->length + 1 < SVPD_SUPPORTED_PAGES_SIZE) {
+				page_list->list[page_list->length] = SVPD_UNIT_SERIAL_NUMBER;
+				page_list->length++;
+			}
+		}
 		xpt_done(ccb);
 		break;
 



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