svn commit: r251477 - in stable/8/sys/cam: . scsi

Steven Hartland smh at FreeBSD.org
Thu Jun 6 22:31:54 UTC 2013


Author: smh
Date: Thu Jun  6 22:31:52 2013
New Revision: 251477
URL: http://svnweb.freebsd.org/changeset/base/251477

Log:
  MFC r216088:
  Manual partial MFC of only basic VPD support for scsi_xpt
  
  MFC r249937:
  Refactored scsi_xpt use of device_has_vpd

Modified:
  stable/8/sys/cam/cam_xpt.c
  stable/8/sys/cam/cam_xpt_internal.h
  stable/8/sys/cam/scsi/scsi_all.c
  stable/8/sys/cam/scsi/scsi_all.h
  stable/8/sys/cam/scsi/scsi_xpt.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/cam/   (props changed)

Modified: stable/8/sys/cam/cam_xpt.c
==============================================================================
--- stable/8/sys/cam/cam_xpt.c	Thu Jun  6 22:02:03 2013	(r251476)
+++ stable/8/sys/cam/cam_xpt.c	Thu Jun  6 22:31:52 2013	(r251477)
@@ -4497,7 +4497,7 @@ xpt_alloc_device(struct cam_eb *bus, str
 		device = NULL;
 	} else {
 		device = (struct cam_ed *)malloc(sizeof(*device),
-						 M_CAMXPT, M_NOWAIT);
+						 M_CAMXPT, M_NOWAIT|M_ZERO);
 	}
 
 	if (device != NULL) {
@@ -4568,6 +4568,14 @@ xpt_release_device(struct cam_ed *device
 		cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
 		camq_fini(&device->drvq);
 		cam_ccbq_fini(&device->ccbq);
+		/*
+		 * Free allocated memory.  free(9) does nothing if the
+		 * supplied pointer is NULL, so it is safe to call without
+		 * checking.
+		 */
+		free(device->supported_vpds, M_CAMXPT);
+		free(device->serial_num, M_CAMXPT);
+
 		xpt_release_target(device->target);
 		free(device, M_CAMXPT);
 	} else

Modified: stable/8/sys/cam/cam_xpt_internal.h
==============================================================================
--- stable/8/sys/cam/cam_xpt_internal.h	Thu Jun  6 22:02:03 2013	(r251476)
+++ stable/8/sys/cam/cam_xpt_internal.h	Thu Jun  6 22:31:52 2013	(r251477)
@@ -93,6 +93,8 @@ struct cam_ed {
 	cam_xport	 transport;
 	u_int		 transport_version;
 	struct		 scsi_inquiry_data inq_data;
+	uint8_t		 *supported_vpds;
+	uint8_t		 supported_vpds_len;
 	struct		 ata_params ident_data;
 	u_int8_t	 inq_flags;	/*
 					 * Current settings for inquiry flags.

Modified: stable/8/sys/cam/scsi/scsi_all.c
==============================================================================
--- stable/8/sys/cam/scsi/scsi_all.c	Thu Jun  6 22:02:03 2013	(r251476)
+++ stable/8/sys/cam/scsi/scsi_all.c	Thu Jun  6 22:31:52 2013	(r251477)
@@ -38,6 +38,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/libkern.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
 #include <sys/sysctl.h>
 #else
 #include <errno.h>
@@ -53,7 +56,13 @@ __FBSDID("$FreeBSD$");
 #include <cam/scsi/scsi_all.h>
 #include <sys/ata.h>
 #include <sys/sbuf.h>
-#ifndef _KERNEL
+
+#ifdef _KERNEL
+#include <cam/cam_periph.h>
+#include <cam/cam_xpt_sim.h>
+#include <cam/cam_xpt_periph.h>
+#include <cam/cam_xpt_internal.h>
+#else
 #include <camlib.h>
 
 #ifndef FALSE
@@ -4605,6 +4614,28 @@ scsi_static_inquiry_match(caddr_t inqbuf
 }
 
 #ifdef _KERNEL
+int
+scsi_vpd_supported_page(struct cam_periph *periph, uint8_t page_id)
+{
+	struct cam_ed *device;
+	struct scsi_vpd_supported_pages *vpds;
+	int i, num_pages;
+
+	device = periph->path->device;
+	vpds = (struct scsi_vpd_supported_pages *)device->supported_vpds;
+
+	if (vpds != NULL) {
+		num_pages = device->supported_vpds_len -
+		    SVPD_SUPPORTED_PAGES_HDR_LEN;
+		for (i = 0; i < num_pages; i++) {
+			if (vpds->page_list[i] == page_id)
+				return (1);
+		}
+	}
+
+	return (0);
+}
+
 static void
 init_scsi_delay(void)
 {

Modified: stable/8/sys/cam/scsi/scsi_all.h
==============================================================================
--- stable/8/sys/cam/scsi/scsi_all.h	Thu Jun  6 22:02:03 2013	(r251476)
+++ stable/8/sys/cam/scsi/scsi_all.h	Thu Jun  6 22:31:52 2013	(r251477)
@@ -857,13 +857,28 @@ struct scsi_vpd_supported_page_list
 {
 	u_int8_t device;
 	u_int8_t page_code;
-#define	SVPD_SUPPORTED_PAGE_LIST 0x00
+#define	SVPD_SUPPORTED_PAGE_LIST	0x00
+#define	SVPD_SUPPORTED_PAGES_HDR_LEN	4
 	u_int8_t reserved;
 	u_int8_t length;	/* number of VPD entries */
 #define	SVPD_SUPPORTED_PAGES_SIZE	251
 	u_int8_t list[SVPD_SUPPORTED_PAGES_SIZE];
 };
 
+/*
+ * This structure is more suited to target operation, because the
+ * number of supported pages is left to the user to allocate.
+ */
+struct scsi_vpd_supported_pages
+{
+	u_int8_t device;
+	u_int8_t page_code;
+	u_int8_t reserved;
+#define	SVPD_SUPPORTED_PAGES	0x00
+	u_int8_t length;
+	u_int8_t page_list[0];
+};
+
 struct scsi_vpd_unit_serial_number
 {
 	u_int8_t device;
@@ -1250,6 +1265,8 @@ int		scsi_sense_sbuf(struct ccb_scsiio *
 char *		scsi_sense_string(struct ccb_scsiio *csio,
 				  char *str, int str_len);
 void		scsi_sense_print(struct ccb_scsiio *csio);
+int 		scsi_vpd_supported_page(struct cam_periph *periph,
+					uint8_t page_id);
 #else /* _KERNEL */
 int		scsi_command_string(struct cam_device *device,
 				    struct ccb_scsiio *csio, struct sbuf *sb);

Modified: stable/8/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- stable/8/sys/cam/scsi/scsi_xpt.c	Thu Jun  6 22:02:03 2013	(r251476)
+++ stable/8/sys/cam/scsi/scsi_xpt.c	Thu Jun  6 22:31:52 2013	(r251477)
@@ -134,8 +134,8 @@ typedef enum {
 	PROBE_FULL_INQUIRY,
 	PROBE_REPORT_LUNS,
 	PROBE_MODE_SENSE,
-	PROBE_SERIAL_NUM_0,
-	PROBE_SERIAL_NUM_1,
+	PROBE_SUPPORTED_VPD_LIST,
+	PROBE_SERIAL_NUM,
 	PROBE_TUR_FOR_NEGOTIATION,
 	PROBE_INQUIRY_BASIC_DV1,
 	PROBE_INQUIRY_BASIC_DV2,
@@ -150,8 +150,8 @@ static char *probe_action_text[] = {
 	"PROBE_FULL_INQUIRY",
 	"PROBE_REPORT_LUNS",
 	"PROBE_MODE_SENSE",
-	"PROBE_SERIAL_NUM_0",
-	"PROBE_SERIAL_NUM_1",
+	"PROBE_SUPPORTED_VPD_LIST",
+	"PROBE_SERIAL_NUM",
 	"PROBE_TUR_FOR_NEGOTIATION",
 	"PROBE_INQUIRY_BASIC_DV1",
 	"PROBE_INQUIRY_BASIC_DV2",
@@ -824,7 +824,8 @@ again:
 			if (INQ_DATA_TQ_ENABLED(inq_buf))
 				PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
 			else
-				PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+				PROBE_SET_ACTION(softc,
+				    PROBE_SUPPORTED_VPD_LIST);
 			goto again;
 		}
 		scsi_report_luns(csio, 5, probedone, MSG_SIMPLE_Q_TAG,
@@ -857,10 +858,10 @@ again:
 		}
 		xpt_print(periph->path, "Unable to mode sense control page - "
 		    "malloc failure\n");
-		PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+		PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
 	}
 	/* FALLTHROUGH */
-	case PROBE_SERIAL_NUM_0:
+	case PROBE_SUPPORTED_VPD_LIST:
 	{
 		struct scsi_vpd_supported_page_list *vpd_list = NULL;
 		struct cam_ed *device;
@@ -892,7 +893,7 @@ again:
 		probedone(periph, start_ccb);
 		return;
 	}
-	case PROBE_SERIAL_NUM_1:
+	case PROBE_SERIAL_NUM:
 	{
 		struct scsi_vpd_unit_serial_number *serial_buf;
 		struct cam_ed* device;
@@ -905,8 +906,10 @@ again:
 			device->serial_num_len = 0;
 		}
 
-		serial_buf = (struct scsi_vpd_unit_serial_number *)
-			malloc(sizeof(*serial_buf), M_CAMXPT, M_NOWAIT|M_ZERO);
+		if (scsi_vpd_supported_page(periph, SVPD_UNIT_SERIAL_NUMBER))
+			serial_buf = (struct scsi_vpd_unit_serial_number *)
+				malloc(sizeof(*serial_buf), M_CAMXPT,
+				    M_NOWAIT|M_ZERO);
 
 		if (serial_buf != NULL) {
 			scsi_inquiry(csio,
@@ -1144,7 +1147,7 @@ probedone(struct cam_periph *periph, uni
 					    PROBE_MODE_SENSE);
 				else
 					PROBE_SET_ACTION(softc,
-					    PROBE_SERIAL_NUM_0);
+					    PROBE_SUPPORTED_VPD_LIST);
 
 				if (path->device->flags & CAM_DEV_UNCONFIGURED) {
 					path->device->flags &= ~CAM_DEV_UNCONFIGURED;
@@ -1303,7 +1306,8 @@ probedone(struct cam_periph *periph, uni
 			if (INQ_DATA_TQ_ENABLED(inq_buf))
 				PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
 			else
-				PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+				PROBE_SET_ACTION(softc,
+				    PROBE_SUPPORTED_VPD_LIST);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
 			return;
@@ -1339,36 +1343,40 @@ probedone(struct cam_periph *periph, uni
 		}
 		xpt_release_ccb(done_ccb);
 		free(mode_hdr, M_CAMXPT);
-		PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
+		PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
 		xpt_schedule(periph, priority);
 		return;
 	}
-	case PROBE_SERIAL_NUM_0:
+	case PROBE_SUPPORTED_VPD_LIST:
 	{
 		struct ccb_scsiio *csio;
 		struct scsi_vpd_supported_page_list *page_list;
-		int length, serialnum_supported, i;
 
-		serialnum_supported = 0;
 		csio = &done_ccb->csio;
 		page_list =
 		    (struct scsi_vpd_supported_page_list *)csio->data_ptr;
 
+		if (path->device->supported_vpds != NULL) {
+			free(path->device->supported_vpds, M_CAMXPT);
+			path->device->supported_vpds = NULL;
+			path->device->supported_vpds_len = 0;
+		}
+
 		if (page_list == NULL) {
 			/*
 			 * Don't process the command as it was never sent
 			 */
-		} else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
-		    && (page_list->length > 0)) {
-			length = min(page_list->length,
-			    SVPD_SUPPORTED_PAGES_SIZE);
-			for (i = 0; i < length; i++) {
-				if (page_list->list[i] ==
-				    SVPD_UNIT_SERIAL_NUMBER) {
-					serialnum_supported = 1;
-					break;
-				}
-			}
+		} else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			/* Got vpd list */
+			path->device->supported_vpds_len = page_list->length +
+			    SVPD_SUPPORTED_PAGES_HDR_LEN;
+			path->device->supported_vpds = (uint8_t *)page_list;
+
+			xpt_release_ccb(done_ccb);
+			PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM);
+			xpt_schedule(periph, priority);
+			return;
+
 		} else if (cam_periph_error(done_ccb, 0,
 					    SF_RETRY_UA|SF_NO_PRINT,
 					    &softc->saved_ccb) == ERESTART) {
@@ -1382,18 +1390,12 @@ probedone(struct cam_periph *periph, uni
 		if (page_list != NULL)
 			free(page_list, M_CAMXPT);
 
-		if (serialnum_supported) {
-			xpt_release_ccb(done_ccb);
-			PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_1);
-			xpt_schedule(periph, priority);
-			return;
-		}
-
+		/* No VPDs available, skip to device check. */
 		csio->data_ptr = NULL;
 		/* FALLTHROUGH */
 	}
 
-	case PROBE_SERIAL_NUM_1:
+	case PROBE_SERIAL_NUM:
 	{
 		struct ccb_scsiio *csio;
 		struct scsi_vpd_unit_serial_number *serial_buf;
@@ -2245,6 +2247,8 @@ scsi_alloc_device(struct cam_eb *bus, st
 	device->queue_flags = 0;
 	device->serial_num = NULL;
 	device->serial_num_len = 0;
+	device->supported_vpds = NULL;
+	device->supported_vpds_len  = 0;
 
 	/*
 	 * XXX should be limited by number of CCBs this bus can


More information about the svn-src-all mailing list