svn commit: r303468 - in head/sys: cam cam/ata cam/nvme cam/scsi conf

Warner Losh imp at FreeBSD.org
Thu Jul 28 22:55:24 UTC 2016


Author: imp
Date: Thu Jul 28 22:55:21 2016
New Revision: 303468
URL: https://svnweb.freebsd.org/changeset/base/303468

Log:
  Move protocol specific stuff into a linker set object that's
  per-protocol. This reduces the number scsi symbols references by
  cam_xpt significantly, and eliminates all ata / nvme symbols. There's
  still some NVME / ATA specific code for dealing with XPT_NVME_IO and
  XPT_ATA_IO respectively, and a bunch of scsi-specific code, but this
  is progress.
  
  Differential Revision: https://reviews.freebsd.org/D7289

Modified:
  head/sys/cam/ata/ata_xpt.c
  head/sys/cam/cam_xpt.c
  head/sys/cam/cam_xpt_internal.h
  head/sys/cam/nvme/nvme_xpt.c
  head/sys/cam/scsi/scsi_xpt.c
  head/sys/conf/files

Modified: head/sys/cam/ata/ata_xpt.c
==============================================================================
--- head/sys/cam/ata/ata_xpt.c	Thu Jul 28 22:55:14 2016	(r303467)
+++ head/sys/cam/ata/ata_xpt.c	Thu Jul 28 22:55:21 2016	(r303468)
@@ -188,6 +188,11 @@ static void	 ata_dev_async(u_int32_t asy
 				void *async_arg);
 static void	 ata_action(union ccb *start_ccb);
 static void	 ata_announce_periph(struct cam_periph *periph);
+static void	 ata_proto_announce(struct cam_ed *device);
+static void	 ata_proto_denounce(struct cam_ed *device);
+static void	 ata_proto_debug_out(union ccb *ccb);
+static void	 semb_proto_announce(struct cam_ed *device);
+static void	 semb_proto_denounce(struct cam_ed *device);
 
 static int ata_dma = 1;
 static int atapi_dma = 1;
@@ -214,6 +219,43 @@ ATA_XPT_XPORT(sata, SATA);
 
 #undef ATA_XPORT_XPORT
 
+static struct xpt_proto_ops ata_proto_ops_ata = {
+	.announce = ata_proto_announce,
+	.denounce = ata_proto_denounce,
+	.debug_out = ata_proto_debug_out,
+};
+static struct xpt_proto ata_proto_ata = {
+	.proto = PROTO_ATA,
+	.name = "ata",
+	.ops = &ata_proto_ops_ata,
+};
+
+static struct xpt_proto_ops ata_proto_ops_satapm = {
+	.announce = ata_proto_announce,
+	.denounce = ata_proto_denounce,
+	.debug_out = ata_proto_debug_out,
+};
+static struct xpt_proto ata_proto_satapm = {
+	.proto = PROTO_SATAPM,
+	.name = "satapm",
+	.ops = &ata_proto_ops_satapm,
+};
+
+static struct xpt_proto_ops ata_proto_ops_semb = {
+	.announce = semb_proto_announce,
+	.denounce = semb_proto_denounce,
+	.debug_out = ata_proto_debug_out,
+};
+static struct xpt_proto ata_proto_semb = {
+	.proto = PROTO_SEMB,
+	.name = "semb",
+	.ops = &ata_proto_ops_semb,
+};
+
+CAM_XPT_PROTO(ata_proto_ata);
+CAM_XPT_PROTO(ata_proto_satapm);
+CAM_XPT_PROTO(ata_proto_semb);
+
 static void
 probe_periph_init()
 {
@@ -2094,3 +2136,40 @@ ata_announce_periph(struct cam_periph *p
 	}
 	printf("\n");
 }
+
+static void
+ata_proto_announce(struct cam_ed *device)
+{
+	ata_print_ident(&device->ident_data);
+}
+
+static void
+ata_proto_denounce(struct cam_ed *device)
+{
+	ata_print_ident_short(&device->ident_data);
+}
+
+static void
+semb_proto_announce(struct cam_ed *device)
+{
+	semb_print_ident((struct sep_identify_data *)&device->ident_data);
+}
+
+static void
+semb_proto_denounce(struct cam_ed *device)
+{
+	semb_print_ident_short((struct sep_identify_data *)&device->ident_data);
+}
+
+static void
+ata_proto_debug_out(union ccb *ccb)
+{
+	char cdb_str[(sizeof(struct ata_cmd) * 3) + 1];
+
+	if (ccb->ccb_h.func_code != XPT_ATA_IO)
+		return;
+
+	CAM_DEBUG(ccb->ccb_h.path,
+	    CAM_DEBUG_CDB,("%s. ACB: %s\n", ata_op_string(&ccb->ataio.cmd),
+		ata_cmd_string(&ccb->ataio.cmd, cdb_str, sizeof(cdb_str))));
+}

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Thu Jul 28 22:55:14 2016	(r303467)
+++ head/sys/cam/cam_xpt.c	Thu Jul 28 22:55:21 2016	(r303468)
@@ -746,6 +746,19 @@ cam_module_event_handler(module_t mod, i
 	return 0;
 }
 
+static struct xpt_proto *
+xpt_proto_find(cam_proto proto)
+{
+	struct xpt_proto **pp;
+
+	SET_FOREACH(pp, cam_xpt_proto_set) {
+		if ((*pp)->proto == proto)
+			return *pp;
+	}
+
+	return NULL;
+}
+
 static void
 xpt_rescan_done(struct cam_periph *periph, union ccb *done_ccb)
 {
@@ -1012,6 +1025,7 @@ void
 xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 {
 	struct	cam_path *path = periph->path;
+	struct  xpt_proto *proto;
 
 	cam_periph_assert(periph, MA_OWNED);
 	periph->flags |= CAM_PERIPH_ANNOUNCED;
@@ -1025,25 +1039,20 @@ xpt_announce_periph(struct cam_periph *p
 	       path->target->target_id,
 	       (uintmax_t)path->device->lun_id);
 	printf("%s%d: ", periph->periph_name, periph->unit_number);
-	if (path->device->protocol == PROTO_SCSI)
-		scsi_print_inquiry(&path->device->inq_data);
-	else if (path->device->protocol == PROTO_ATA ||
-	    path->device->protocol == PROTO_SATAPM)
-		ata_print_ident(&path->device->ident_data);
-	else if (path->device->protocol == PROTO_SEMB)
-		semb_print_ident(
-		    (struct sep_identify_data *)&path->device->ident_data);
-	else if (path->device->protocol == PROTO_NVME)
-		nvme_print_ident(path->device->nvme_cdata, path->device->nvme_data);
+	proto = xpt_proto_find(path->device->protocol);
+	if (proto)
+		proto->ops->announce(path->device);
 	else
-		printf("Unknown protocol device\n");
+		printf("%s%d: Unknown protocol device %d\n",
+		    periph->periph_name, periph->unit_number,
+		    path->device->protocol);
 	if (path->device->serial_num_len > 0) {
 		/* Don't wrap the screen  - print only the first 60 chars */
 		printf("%s%d: Serial Number %.60s\n", periph->periph_name,
 		       periph->unit_number, path->device->serial_num);
 	}
 	/* Announce transport details. */
-	(*(path->bus->xport->ops->announce))(periph);
+	path->bus->xport->ops->announce(periph);
 	/* Announce command queueing. */
 	if (path->device->inq_flags & SID_CmdQue
 	 || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) {
@@ -1069,6 +1078,7 @@ void
 xpt_denounce_periph(struct cam_periph *periph)
 {
 	struct	cam_path *path = periph->path;
+	struct  xpt_proto *proto;
 
 	cam_periph_assert(periph, MA_OWNED);
 	printf("%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
@@ -1080,18 +1090,13 @@ xpt_denounce_periph(struct cam_periph *p
 	       path->target->target_id,
 	       (uintmax_t)path->device->lun_id);
 	printf("%s%d: ", periph->periph_name, periph->unit_number);
-	if (path->device->protocol == PROTO_SCSI)
-		scsi_print_inquiry_short(&path->device->inq_data);
-	else if (path->device->protocol == PROTO_ATA ||
-	    path->device->protocol == PROTO_SATAPM)
-		ata_print_ident_short(&path->device->ident_data);
-	else if (path->device->protocol == PROTO_SEMB)
-		semb_print_ident_short(
-		    (struct sep_identify_data *)&path->device->ident_data);
-	else if (path->device->protocol == PROTO_NVME)
-		nvme_print_ident(path->device->nvme_cdata, path->device->nvme_data);
+	proto = xpt_proto_find(path->device->protocol);
+	if (proto)
+		proto->ops->denounce(path->device);
 	else
-		printf("Unknown protocol device");
+		printf("%s%d: Unknown protocol device %d\n",
+		    periph->periph_name, periph->unit_number,
+		    path->device->protocol);
 	if (path->device->serial_num_len > 0)
 		printf(" s/n %.60s", path->device->serial_num);
 	printf(" detached\n");
@@ -3234,7 +3239,6 @@ restart:
 static void
 xpt_run_devq(struct cam_devq *devq)
 {
-	char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
 	int lock;
 
 	CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_devq\n"));
@@ -3246,6 +3250,7 @@ xpt_run_devq(struct cam_devq *devq)
 		struct	cam_ed *device;
 		union ccb *work_ccb;
 		struct	cam_sim *sim;
+		struct xpt_proto *proto;
 
 		device = (struct cam_ed *)camq_remove(&devq->send_queue,
 							   CAMQ_HEAD);
@@ -3311,32 +3316,12 @@ xpt_run_devq(struct cam_devq *devq)
 				work_ccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
 		}
 
-		switch (work_ccb->ccb_h.func_code) {
-		case XPT_SCSI_IO:
-			CAM_DEBUG(work_ccb->ccb_h.path,
-			    CAM_DEBUG_CDB,("%s. CDB: %s\n",
-			     scsi_op_desc(work_ccb->csio.cdb_io.cdb_bytes[0],
-					  &device->inq_data),
-			     scsi_cdb_string(work_ccb->csio.cdb_io.cdb_bytes,
-					     cdb_str, sizeof(cdb_str))));
-			break;
-		case XPT_ATA_IO:
-			CAM_DEBUG(work_ccb->ccb_h.path,
-			    CAM_DEBUG_CDB,("%s. ACB: %s\n",
-			     ata_op_string(&work_ccb->ataio.cmd),
-			     ata_cmd_string(&work_ccb->ataio.cmd,
-					    cdb_str, sizeof(cdb_str))));
-			break;
-		case XPT_NVME_IO:
-			CAM_DEBUG(work_ccb->ccb_h.path,
-			    CAM_DEBUG_CDB,("%s. NCB: %s\n",
-			     nvme_op_string(&work_ccb->nvmeio.cmd),
-			     nvme_cmd_string(&work_ccb->nvmeio.cmd,
-					    cdb_str, sizeof(cdb_str))));
-			break;
-		default:
-			break;
-		}
+		KASSERT(device == work_ccb->ccb_h.path->device,
+		    ("device (%p) / path->device (%p) mismatch",
+			device, work_ccb->ccb_h.path->device));
+		proto = xpt_proto_find(device->protocol);
+		if (proto && proto->ops->debug_out)
+			proto->ops->debug_out(work_ccb);
 
 		/*
 		 * Device queues can be shared among multiple SIM instances

Modified: head/sys/cam/cam_xpt_internal.h
==============================================================================
--- head/sys/cam/cam_xpt_internal.h	Thu Jul 28 22:55:14 2016	(r303467)
+++ head/sys/cam/cam_xpt_internal.h	Thu Jul 28 22:55:21 2016	(r303468)
@@ -66,6 +66,26 @@ SET_DECLARE(cam_xpt_xport_set, struct xp
 #define CAM_XPT_XPORT(data) 				\
 	DATA_SET(cam_xpt_xport_set, data)
 
+typedef void (*xpt_proto_announce_func)(struct cam_ed *);
+typedef void (*xpt_proto_debug_out_func)(union ccb *);
+
+struct xpt_proto_ops {
+	xpt_proto_announce_func	announce;
+	xpt_proto_announce_func	denounce;
+	xpt_proto_debug_out_func debug_out;
+};
+
+struct xpt_proto {
+	cam_proto		proto;
+	const char		*name;
+	struct xpt_proto_ops	*ops;
+};
+
+SET_DECLARE(cam_xpt_proto_set, struct xpt_proto);
+#define CAM_XPT_PROTO(data) 				\
+	DATA_SET(cam_xpt_proto_set, data)
+
+
 /*
  * The CAM EDT (Existing Device Table) contains the device information for
  * all devices for all busses in the system.  The table contains a

Modified: head/sys/cam/nvme/nvme_xpt.c
==============================================================================
--- head/sys/cam/nvme/nvme_xpt.c	Thu Jul 28 22:55:14 2016	(r303467)
+++ head/sys/cam/nvme/nvme_xpt.c	Thu Jul 28 22:55:21 2016	(r303468)
@@ -152,6 +152,9 @@ static void	 nvme_dev_async(u_int32_t as
 				void *async_arg);
 static void	 nvme_action(union ccb *start_ccb);
 static void	 nvme_announce_periph(struct cam_periph *periph);
+static void	 nvme_proto_announce(struct cam_ed *device);
+static void	 nvme_proto_denounce(struct cam_ed *device);
+static void	 nvme_proto_debug_out(union ccb *ccb);
 
 static struct xpt_xport_ops nvme_xport_ops = {
 	.alloc_device = nvme_alloc_device,
@@ -171,6 +174,18 @@ NVME_XPT_XPORT(nvme, NVME);
 
 #undef NVME_XPT_XPORT
 
+static struct xpt_proto_ops nvme_proto_ops = {
+	.announce = nvme_proto_announce,
+	.denounce = nvme_proto_denounce,
+	.debug_out = nvme_proto_debug_out,
+};
+static struct xpt_proto nvme_proto = {
+	.proto = PROTO_NVME,
+	.name = "nvme",
+	.ops = &nvme_proto_ops,
+};
+CAM_XPT_PROTO(nvme_proto);
+
 static void
 nvme_probe_periph_init()
 {
@@ -602,3 +617,29 @@ nvme_announce_periph(struct cam_periph *
 	/* XXX NVME STUFF HERE */
 	printf("\n");
 }
+
+static void
+nvme_proto_announce(struct cam_ed *device)
+{
+	nvme_print_ident(device->nvme_cdata, device->nvme_data);
+}
+
+static void
+nvme_proto_denounce(struct cam_ed *device)
+{
+	nvme_print_ident(device->nvme_cdata, device->nvme_data);
+}
+
+static void
+nvme_proto_debug_out(union ccb *ccb)
+{
+	char cdb_str[(sizeof(struct nvme_command) * 3) + 1];
+
+	if (ccb->ccb_h.func_code != XPT_NVME_IO)
+		return;
+
+	CAM_DEBUG(ccb->ccb_h.path,
+	    CAM_DEBUG_CDB,("%s. NCB: %s\n", nvme_op_string(&ccb->nvmeio.cmd),
+		nvme_cmd_string(&ccb->nvmeio.cmd, cdb_str, sizeof(cdb_str))));
+}
+

Modified: head/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- head/sys/cam/scsi/scsi_xpt.c	Thu Jul 28 22:55:14 2016	(r303467)
+++ head/sys/cam/scsi/scsi_xpt.c	Thu Jul 28 22:55:21 2016	(r303468)
@@ -589,6 +589,9 @@ static void	 scsi_dev_async(u_int32_t as
 				void *async_arg);
 static void	 scsi_action(union ccb *start_ccb);
 static void	 scsi_announce_periph(struct cam_periph *periph);
+static void	 scsi_proto_announce(struct cam_ed *device);
+static void	 scsi_proto_denounce(struct cam_ed *device);
+static void	 scsi_proto_debug_out(union ccb *ccb);
 
 static struct xpt_xport_ops scsi_xport_ops = {
 	.alloc_device = scsi_alloc_device,
@@ -614,6 +617,18 @@ SCSI_XPT_XPORT(ppb, PPB);
 
 #undef SCSI_XPORT_XPORT
 
+static struct xpt_proto_ops scsi_proto_ops = {
+	.announce = scsi_proto_announce,
+	.denounce = scsi_proto_denounce,
+	.debug_out = scsi_proto_debug_out,
+};
+static struct xpt_proto scsi_proto = {
+	.proto = PROTO_SCSI,
+	.name = "scsi",
+	.ops = &scsi_proto_ops,
+};
+CAM_XPT_PROTO(scsi_proto);
+
 static void
 probe_periph_init()
 {
@@ -3100,3 +3115,30 @@ scsi_announce_periph(struct cam_periph *
 	printf("\n");
 }
 
+static void
+scsi_proto_announce(struct cam_ed *device)
+{
+	scsi_print_inquiry(&device->inq_data);
+}
+
+static void
+scsi_proto_denounce(struct cam_ed *device)
+{
+	scsi_print_inquiry_short(&device->inq_data);
+}
+
+static void
+scsi_proto_debug_out(union ccb *ccb)
+{
+	char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
+	struct cam_ed *device;
+
+	if (ccb->ccb_h.func_code != XPT_SCSI_IO)
+		return;
+
+	device = ccb->ccb_h.path->device;
+	CAM_DEBUG(ccb->ccb_h.path,
+	    CAM_DEBUG_CDB,("%s. CDB: %s\n",
+		scsi_op_desc(ccb->csio.cdb_io.cdb_bytes[0], &device->inq_data),
+		scsi_cdb_string(ccb->csio.cdb_io.cdb_bytes, cdb_str, sizeof(cdb_str))));
+}

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Thu Jul 28 22:55:14 2016	(r303467)
+++ head/sys/conf/files	Thu Jul 28 22:55:21 2016	(r303468)
@@ -86,9 +86,9 @@ cam/cam_xpt.c			optional scbus
 cam/ata/ata_all.c		optional scbus
 cam/ata/ata_xpt.c		optional scbus
 cam/ata/ata_pmp.c		optional scbus
-cam/nvme/nvme_all.c		optional scbus
+cam/nvme/nvme_all.c		optional scbus nvmd !nvd
 cam/nvme/nvme_da.c		optional scbus nvme da !nvd
-cam/nvme/nvme_xpt.c		optional scbus
+cam/nvme/nvme_xpt.c		optional scbus nvmd !nvd
 cam/scsi/scsi_xpt.c		optional scbus
 cam/scsi/scsi_all.c		optional scbus
 cam/scsi/scsi_cd.c		optional cd


More information about the svn-src-all mailing list