Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Apr 2017 15:04:53 +0000 (UTC)
From:      Scott Long <scottl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r317143 - in head/sys/cam: . ata scsi
Message-ID:  <201704191504.v3JF4r5T050468@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: scottl
Date: Wed Apr 19 15:04:52 2017
New Revision: 317143
URL: https://svnweb.freebsd.org/changeset/base/317143

Log:
  Add infrastructure to the ATA and SCSI transports that supports
  using a driver-supplied sbuf for printing device discovery
  announcements. This helps ensure that messages to the console
  will be properly serialized (through sbuf_putbuf) and not be
  truncated and interleaved with other messages. The
  infrastructure mirrors the existing xpt_announce_periph()
  entry point and is opt-in for now. No content or formatting
  changes are visible to the operator other than the new coherency.
  
  While here, eliminate the stack usage of the temporary
  announcement buffer in some of the drivers. It's moved to the
  softc for now, but future work will eliminate it entirely by
  making the code flow more linear. Future work will also address
  locking so that the sbufs can be dynamically sized.
  
  The scsi_da, scs_cd, scsi_ses, and ata_da drivers are converted
  at this point, other drivers can be converted at a later date.
  A tunable+sysctl, kern.cam.announce_nosbuf, exists for testing
  purposes but will be removed later.
  
  TODO:
  Eliminate all of the code duplication and temporary buffers.  The
  old printf-based methods will be retired, and xpt_announce_periph()
  will just be a wrapper that uses a dynamically sized sbuf.  This
  requires that the register and deregister paths be made malloc-safe,
  which they aren't currently.
  
  Sponsored by:	Netflix

Modified:
  head/sys/cam/ata/ata_all.c
  head/sys/cam/ata/ata_all.h
  head/sys/cam/ata/ata_da.c
  head/sys/cam/ata/ata_xpt.c
  head/sys/cam/cam_periph.c
  head/sys/cam/cam_xpt.c
  head/sys/cam/cam_xpt_internal.h
  head/sys/cam/cam_xpt_periph.h
  head/sys/cam/scsi/scsi_all.c
  head/sys/cam/scsi/scsi_all.h
  head/sys/cam/scsi/scsi_cd.c
  head/sys/cam/scsi/scsi_da.c
  head/sys/cam/scsi/scsi_enc.c
  head/sys/cam/scsi/scsi_enc_internal.h
  head/sys/cam/scsi/scsi_xpt.c

Modified: head/sys/cam/ata/ata_all.c
==============================================================================
--- head/sys/cam/ata/ata_all.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/ata/ata_all.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -382,12 +382,10 @@ void
 ata_print_ident(struct ata_params *ident_data)
 {
 	const char *proto;
-	char product[48], revision[16], ata[12], sata[12];
+	char ata[12], sata[12];
+
+	ata_print_ident_short(ident_data);
 
-	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
-		   sizeof(product));
-	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
-		   sizeof(revision));
 	proto = (ident_data->config == ATA_PROTO_CFA) ? "CFA" :
 		(ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
 	if (ata_version(ident_data->version_major) == 0) {
@@ -412,7 +410,55 @@ ata_print_ident(struct ata_params *ident
 			snprintf(sata, sizeof(sata), " SATA");
 	} else
 		sata[0] = 0;
-	printf("<%s %s> %s%s device\n", product, revision, ata, sata);
+	printf(" %s%s device\n", ata, sata);
+}
+
+void
+ata_print_ident_sbuf(struct ata_params *ident_data, struct sbuf *sb)
+{
+	const char *proto, *sata;
+	int version;
+
+	ata_print_ident_short_sbuf(ident_data, sb);
+	sbuf_printf(sb, " ");
+
+	proto = (ident_data->config == ATA_PROTO_CFA) ? "CFA" :
+		(ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
+	version = ata_version(ident_data->version_major);
+
+	switch (version) {
+	case 0:
+		sbuf_printf(sb, "%s", proto);
+		break;
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+	case 6:
+	case 7:
+		sbuf_printf(sb, "%s-%d", proto, version);
+		break;
+	case 8:
+		sbuf_printf(sb, "%s8-ACS", proto);
+		break;
+	default:
+		sbuf_printf(sb, "ACS-%d %s", version - 7, proto);
+		break;
+	}
+
+	if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) {
+		if (ident_data->satacapabilities & ATA_SATA_GEN3)
+			sata = " SATA 3.x";
+		else if (ident_data->satacapabilities & ATA_SATA_GEN2)
+			sata = " SATA 2.x";
+		else if (ident_data->satacapabilities & ATA_SATA_GEN1)
+			sata = " SATA 1.x";
+		else
+			sata = " SATA";
+	} else
+		sata = "";
+	sbuf_printf(sb, "%s device\n", sata);
 }
 
 void
@@ -428,18 +474,38 @@ ata_print_ident_short(struct ata_params 
 }
 
 void
+ata_print_ident_short_sbuf(struct ata_params *ident_data, struct sbuf *sb)
+{
+
+	sbuf_printf(sb, "<");
+	cam_strvis_sbuf(sb, ident_data->model, sizeof(ident_data->model), 0);
+	sbuf_printf(sb, " ");
+	cam_strvis_sbuf(sb, ident_data->revision, sizeof(ident_data->revision), 0);
+	sbuf_printf(sb, ">");
+}
+
+void
 semb_print_ident(struct sep_identify_data *ident_data)
 {
-	char vendor[9], product[17], revision[5], fw[5], in[7], ins[5];
+	char in[7], ins[5];
 
-	cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor));
-	cam_strvis(product, ident_data->product_id, 16, sizeof(product));
-	cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision));
-	cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw));
+	semb_print_ident_short(ident_data);
 	cam_strvis(in, ident_data->interface_id, 6, sizeof(in));
 	cam_strvis(ins, ident_data->interface_rev, 4, sizeof(ins));
-	printf("<%s %s %s %s> SEMB %s %s device\n",
-	    vendor, product, revision, fw, in, ins);
+	printf(" SEMB %s %s device\n", in, ins);
+}
+
+void
+semb_print_ident_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb)
+{
+
+	semb_print_ident_short_sbuf(ident_data, sb);
+
+	sbuf_printf(sb, " SEMB ");
+	cam_strvis_sbuf(sb, ident_data->interface_id, 6, 0);
+	sbuf_printf(sb, " ");
+	cam_strvis_sbuf(sb, ident_data->interface_rev, 4, 0);
+	sbuf_printf(sb, " device\n");
 }
 
 void
@@ -454,6 +520,21 @@ semb_print_ident_short(struct sep_identi
 	printf("<%s %s %s %s>", vendor, product, revision, fw);
 }
 
+void
+semb_print_ident_short_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb)
+{
+
+	sbuf_printf(sb, "<");
+	cam_strvis_sbuf(sb, ident_data->vendor_id, 8, 0);
+	sbuf_printf(sb, " ");
+	cam_strvis_sbuf(sb, ident_data->product_id, 16, 0);
+	sbuf_printf(sb, " ");
+	cam_strvis_sbuf(sb, ident_data->product_rev, 4, 0);
+	sbuf_printf(sb, " ");
+	cam_strvis_sbuf(sb, ident_data->firmware_rev, 4, 0);
+	sbuf_printf(sb, ">");
+}
+
 uint32_t
 ata_logical_sector_size(struct ata_params *ident_data)
 {

Modified: head/sys/cam/ata/ata_all.h
==============================================================================
--- head/sys/cam/ata/ata_all.h	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/ata/ata_all.h	Wed Apr 19 15:04:52 2017	(r317143)
@@ -110,7 +110,9 @@ int	ata_status_sbuf(struct ccb_ataio *at
 int	ata_res_sbuf(struct ata_res *res, struct sbuf *sb);
 
 void	ata_print_ident(struct ata_params *ident_data);
+void	ata_print_ident_sbuf(struct ata_params *ident_data, struct sbuf *sb);
 void	ata_print_ident_short(struct ata_params *ident_data);
+void	ata_print_ident_short_sbuf(struct ata_params *ident_data, struct sbuf *sb);
 
 uint32_t	ata_logical_sector_size(struct ata_params *ident_data);
 uint64_t	ata_physical_sector_size(struct ata_params *ident_data);
@@ -150,7 +152,9 @@ int	ata_identify_match(caddr_t identbuff
 int	ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry);
 
 void	semb_print_ident(struct sep_identify_data *ident_data);
+void	semb_print_ident_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb);
 void	semb_print_ident_short(struct sep_identify_data *ident_data);
+void	semb_print_ident_short_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb);
 
 void semb_receive_diagnostic_results(struct ccb_ataio *ataio,
 	u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),

Modified: head/sys/cam/ata/ata_da.c
==============================================================================
--- head/sys/cam/ata/ata_da.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/ata/ata_da.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -256,6 +256,10 @@ struct ada_softc {
 	u_int	errors;
 	u_int	invalidations;
 #endif
+#define ADA_ANNOUNCETMP_SZ 80
+	char	announce_temp[ADA_ANNOUNCETMP_SZ];
+#define ADA_ANNOUNCE_SZ 400
+	char	announce_buffer[ADA_ANNOUNCE_SZ];
 };
 
 struct ada_quirk_entry {
@@ -1659,8 +1663,9 @@ adaregister(struct cam_periph *periph, v
 	struct ada_softc *softc;
 	struct ccb_pathinq cpi;
 	struct ccb_getdev *cgd;
-	char   announce_buf[80];
 	struct disk_params *dp;
+	struct sbuf sb;
+	char   *announce_buf;
 	caddr_t match;
 	u_int maxio;
 	int quirks;
@@ -1680,6 +1685,9 @@ adaregister(struct cam_periph *periph, v
 		return(CAM_REQ_CMP_ERR);
 	}
 
+	announce_buf = softc->announce_temp;
+	bzero(announce_buf, ADA_ANNOUNCETMP_SZ);
+
 	if (cam_iosched_init(&softc->cam_iosched, periph) != 0) {
 		printf("adaregister: Unable to probe new device. "
 		       "Unable to allocate iosched memory\n");
@@ -1713,17 +1721,17 @@ adaregister(struct cam_periph *periph, v
 	 */
 	(void)cam_periph_hold(periph, PRIBIO);
 	cam_periph_unlock(periph);
-	snprintf(announce_buf, sizeof(announce_buf),
+	snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 	    "kern.cam.ada.%d.quirks", periph->unit_number);
 	quirks = softc->quirks;
 	TUNABLE_INT_FETCH(announce_buf, &quirks);
 	softc->quirks = quirks;
 	softc->read_ahead = -1;
-	snprintf(announce_buf, sizeof(announce_buf),
+	snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 	    "kern.cam.ada.%d.read_ahead", periph->unit_number);
 	TUNABLE_INT_FETCH(announce_buf, &softc->read_ahead);
 	softc->write_cache = -1;
-	snprintf(announce_buf, sizeof(announce_buf),
+	snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 	    "kern.cam.ada.%d.write_cache", periph->unit_number);
 	TUNABLE_INT_FETCH(announce_buf, &softc->write_cache);
 
@@ -1829,12 +1837,16 @@ adaregister(struct cam_periph *periph, v
 	cam_periph_lock(periph);
 
 	dp = &softc->params;
-	snprintf(announce_buf, sizeof(announce_buf),
+	snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 	    "%juMB (%ju %u byte sectors)",
 	    ((uintmax_t)dp->secsize * dp->sectors) / (1024 * 1024),
 	    (uintmax_t)dp->sectors, dp->secsize);
-	xpt_announce_periph(periph, announce_buf);
-	xpt_announce_quirks(periph, softc->quirks, ADA_Q_BIT_STRING);
+
+	sbuf_new(&sb, softc->announce_buffer, ADA_ANNOUNCE_SZ, SBUF_FIXEDLEN);
+	xpt_announce_periph_sbuf(periph, &sb, announce_buf);
+	xpt_announce_quirks_sbuf(periph, &sb, softc->quirks, ADA_Q_BIT_STRING);
+	sbuf_finish(&sb);
+	sbuf_putbuf(&sb);
 
 	/*
 	 * Create our sysctl variables, now that we know

Modified: head/sys/cam/ata/ata_xpt.c
==============================================================================
--- head/sys/cam/ata/ata_xpt.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/ata/ata_xpt.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -189,11 +189,16 @@ 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_announce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb);
 static void	 ata_proto_announce(struct cam_ed *device);
+static void	 ata_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb);
 static void	 ata_proto_denounce(struct cam_ed *device);
+static void	 ata_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb);
 static void	 ata_proto_debug_out(union ccb *ccb);
 static void	 semb_proto_announce(struct cam_ed *device);
+static void	 semb_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb);
 static void	 semb_proto_denounce(struct cam_ed *device);
+static void	 semb_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb);
 
 static int ata_dma = 1;
 static int atapi_dma = 1;
@@ -206,6 +211,7 @@ static struct xpt_xport_ops ata_xport_op
 	.action = ata_action,
 	.async = ata_dev_async,
 	.announce = ata_announce_periph,
+	.announce_sbuf = ata_announce_periph_sbuf,
 };
 #define ATA_XPT_XPORT(x, X)			\
 static struct xpt_xport ata_xport_ ## x = {	\
@@ -222,7 +228,9 @@ ATA_XPT_XPORT(sata, SATA);
 
 static struct xpt_proto_ops ata_proto_ops_ata = {
 	.announce = ata_proto_announce,
+	.announce_sbuf = ata_proto_announce_sbuf,
 	.denounce = ata_proto_denounce,
+	.denounce_sbuf = ata_proto_denounce_sbuf,
 	.debug_out = ata_proto_debug_out,
 };
 static struct xpt_proto ata_proto_ata = {
@@ -233,7 +241,9 @@ static struct xpt_proto ata_proto_ata = 
 
 static struct xpt_proto_ops ata_proto_ops_satapm = {
 	.announce = ata_proto_announce,
+	.announce_sbuf = ata_proto_announce_sbuf,
 	.denounce = ata_proto_denounce,
+	.denounce_sbuf = ata_proto_denounce_sbuf,
 	.debug_out = ata_proto_debug_out,
 };
 static struct xpt_proto ata_proto_satapm = {
@@ -244,7 +254,9 @@ static struct xpt_proto ata_proto_satapm
 
 static struct xpt_proto_ops ata_proto_ops_semb = {
 	.announce = semb_proto_announce,
+	.announce_sbuf = semb_proto_announce_sbuf,
 	.denounce = semb_proto_denounce,
+	.denounce_sbuf = semb_proto_denounce_sbuf,
 	.debug_out = ata_proto_debug_out,
 };
 static struct xpt_proto ata_proto_semb = {
@@ -2072,42 +2084,51 @@ ata_dev_async(u_int32_t async_code, stru
 }
 
 static void
-ata_announce_periph(struct cam_periph *periph)
+_ata_announce_periph(struct cam_periph *periph, struct ccb_trans_settings *cts, u_int *speed)
 {
 	struct	ccb_pathinq cpi;
-	struct	ccb_trans_settings cts;
 	struct	cam_path *path = periph->path;
-	u_int	speed;
-	u_int	mb;
 
 	cam_periph_assert(periph, MA_OWNED);
 
-	xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
-	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
-	cts.type = CTS_TYPE_CURRENT_SETTINGS;
-	xpt_action((union ccb*)&cts);
-	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+	xpt_setup_ccb(&cts->ccb_h, path, CAM_PRIORITY_NORMAL);
+	cts->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
+	cts->type = CTS_TYPE_CURRENT_SETTINGS;
+	xpt_action((union ccb*)cts);
+	if ((cts->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
 		return;
 	/* Ask the SIM for its base transfer speed */
 	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
 	/* Report connection speed */
-	speed = cpi.base_transfer_speed;
-	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
+	*speed = cpi.base_transfer_speed;
+	if (cts->transport == XPORT_ATA) {
 		struct	ccb_trans_settings_pata *pata =
-		    &cts.xport_specific.ata;
+		    &cts->xport_specific.ata;
 
 		if (pata->valid & CTS_ATA_VALID_MODE)
-			speed = ata_mode2speed(pata->mode);
+			*speed = ata_mode2speed(pata->mode);
 	}
-	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
+	if (cts->transport == XPORT_SATA) {
 		struct	ccb_trans_settings_sata *sata =
-		    &cts.xport_specific.sata;
+		    &cts->xport_specific.sata;
 
 		if (sata->valid & CTS_SATA_VALID_REVISION)
-			speed = ata_revision2speed(sata->revision);
+			*speed = ata_revision2speed(sata->revision);
 	}
+}
+
+static void
+ata_announce_periph(struct cam_periph *periph)
+{
+	struct ccb_trans_settings cts;
+	u_int speed, mb;
+
+	_ata_announce_periph(periph, &cts, &speed);
+	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+		return;
+
 	mb = speed / 1000;
 	if (mb > 0)
 		printf("%s%d: %d.%03dMB/s transfers",
@@ -2117,7 +2138,7 @@ ata_announce_periph(struct cam_periph *p
 		printf("%s%d: %dKB/s transfers", periph->periph_name,
 		       periph->unit_number, speed);
 	/* Report additional information about connection */
-	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
+	if (cts.transport == XPORT_ATA) {
 		struct ccb_trans_settings_pata *pata =
 		    &cts.xport_specific.ata;
 
@@ -2130,7 +2151,7 @@ ata_announce_periph(struct cam_periph *p
 			printf("PIO %dbytes", pata->bytecount);
 		printf(")");
 	}
-	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
+	if (cts.transport == XPORT_SATA) {
 		struct ccb_trans_settings_sata *sata =
 		    &cts.xport_specific.sata;
 
@@ -2151,6 +2172,64 @@ ata_announce_periph(struct cam_periph *p
 }
 
 static void
+ata_announce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb)
+{
+	struct ccb_trans_settings cts;
+	u_int speed, mb;
+
+	_ata_announce_periph(periph, &cts, &speed);
+	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+		return;
+
+	mb = speed / 1000;
+	if (mb > 0)
+		sbuf_printf(sb, "%s%d: %d.%03dMB/s transfers",
+		       periph->periph_name, periph->unit_number,
+		       mb, speed % 1000);
+	else
+		sbuf_printf(sb, "%s%d: %dKB/s transfers", periph->periph_name,
+		       periph->unit_number, speed);
+	/* Report additional information about connection */
+	if (cts.transport == XPORT_ATA) {
+		struct ccb_trans_settings_pata *pata =
+		    &cts.xport_specific.ata;
+
+		sbuf_printf(sb, " (");
+		if (pata->valid & CTS_ATA_VALID_MODE)
+			sbuf_printf(sb, "%s, ", ata_mode2string(pata->mode));
+		if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
+			sbuf_printf(sb, "ATAPI %dbytes, ", pata->atapi);
+		if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
+			sbuf_printf(sb, "PIO %dbytes", pata->bytecount);
+		sbuf_printf(sb, ")");
+	}
+	if (cts.transport == XPORT_SATA) {
+		struct ccb_trans_settings_sata *sata =
+		    &cts.xport_specific.sata;
+
+		sbuf_printf(sb, " (");
+		if (sata->valid & CTS_SATA_VALID_REVISION)
+			sbuf_printf(sb, "SATA %d.x, ", sata->revision);
+		else
+			sbuf_printf(sb, "SATA, ");
+		if (sata->valid & CTS_SATA_VALID_MODE)
+			sbuf_printf(sb, "%s, ", ata_mode2string(sata->mode));
+		if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0)
+			sbuf_printf(sb, "ATAPI %dbytes, ", sata->atapi);
+		if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
+			sbuf_printf(sb, "PIO %dbytes", sata->bytecount);
+		sbuf_printf(sb, ")");
+	}
+	sbuf_printf(sb, "\n");
+}
+
+static void
+ata_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb)
+{
+	ata_print_ident_sbuf(&device->ident_data, sb);
+}
+
+static void
 ata_proto_announce(struct cam_ed *device)
 {
 	ata_print_ident(&device->ident_data);
@@ -2163,6 +2242,18 @@ ata_proto_denounce(struct cam_ed *device
 }
 
 static void
+ata_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb)
+{
+	ata_print_ident_short_sbuf(&device->ident_data, sb);
+}
+
+static void
+semb_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb)
+{
+	semb_print_ident_sbuf((struct sep_identify_data *)&device->ident_data, sb);
+}
+
+static void
 semb_proto_announce(struct cam_ed *device)
 {
 	semb_print_ident((struct sep_identify_data *)&device->ident_data);
@@ -2175,6 +2266,12 @@ semb_proto_denounce(struct cam_ed *devic
 }
 
 static void
+semb_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb)
+{
+	semb_print_ident_short_sbuf((struct sep_identify_data *)&device->ident_data, sb);
+}
+
+static void
 ata_proto_debug_out(union ccb *ccb)
 {
 	char cdb_str[(sizeof(struct ata_cmd) * 3) + 1];

Modified: head/sys/cam/cam_periph.c
==============================================================================
--- head/sys/cam/cam_periph.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/cam_periph.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -641,8 +641,14 @@ cam_periph_invalidate(struct cam_periph 
 		return;
 
 	CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n"));
-	if ((periph->flags & CAM_PERIPH_ANNOUNCED) && !rebooting)
-		xpt_denounce_periph(periph);
+	if ((periph->flags & CAM_PERIPH_ANNOUNCED) && !rebooting) {
+		struct sbuf sb;
+
+		sbuf_new(&sb, NULL, 160, SBUF_FIXEDLEN);
+		xpt_denounce_periph_sbuf(periph, &sb);
+		sbuf_finish(&sb);
+		sbuf_putbuf(&sb);
+	}
 	periph->flags |= CAM_PERIPH_INVALID;
 	periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND;
 	if (periph->periph_oninval != NULL)

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/cam_xpt.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -116,6 +116,7 @@ struct xpt_softc {
 	TAILQ_HEAD(, ccb_hdr) ccb_scanq;
 	int buses_to_config;
 	int buses_config_done;
+	int announce_nosbuf;
 
 	/*
 	 * Registered buses
@@ -174,6 +175,8 @@ SYSCTL_INT(_kern_cam, OID_AUTO, boot_del
            &xsoftc.boot_delay, 0, "Bus registration wait time");
 SYSCTL_UINT(_kern_cam, OID_AUTO, xpt_generation, CTLFLAG_RD,
 	    &xsoftc.xpt_generation, 0, "CAM peripheral generation count");
+SYSCTL_INT(_kern_cam, OID_AUTO, announce_nosbuf, CTLFLAG_RWTUN,
+	    &xsoftc.announce_nosbuf, 0, "Don't use sbuf for announcements");
 
 struct cam_doneq {
 	struct mtx_padalign	cam_doneq_mtx;
@@ -1094,6 +1097,64 @@ xpt_announce_periph(struct cam_periph *p
 }
 
 void
+xpt_announce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb,
+    char *announce_string)
+{
+	struct	cam_path *path = periph->path;
+	struct  xpt_proto *proto;
+
+	cam_periph_assert(periph, MA_OWNED);
+	periph->flags |= CAM_PERIPH_ANNOUNCED;
+
+	/* Fall back to the non-sbuf method if necessary */
+	if (xsoftc.announce_nosbuf != 0) {
+		xpt_announce_periph(periph, announce_string);
+		return;
+	}
+	proto = xpt_proto_find(path->device->protocol);
+	if (((proto != NULL) && (proto->ops->announce_sbuf == NULL)) ||
+	    (path->bus->xport->ops->announce_sbuf == NULL)) {
+		xpt_announce_periph(periph, announce_string);
+		return;
+	}
+
+	sbuf_printf(sb, "%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
+	    periph->periph_name, periph->unit_number,
+	    path->bus->sim->sim_name,
+	    path->bus->sim->unit_number,
+	    path->bus->sim->bus_id,
+	    path->bus->path_id,
+	    path->target->target_id,
+	    (uintmax_t)path->device->lun_id);
+	sbuf_printf(sb, "%s%d: ", periph->periph_name, periph->unit_number);
+
+	if (proto)
+		proto->ops->announce_sbuf(path->device, sb);
+	else
+		sbuf_printf(sb, "%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 */
+		sbuf_printf(sb, "%s%d: Serial Number %.60s\n",
+		    periph->periph_name, periph->unit_number,
+		    path->device->serial_num);
+	}
+	/* Announce transport details. */
+	path->bus->xport->ops->announce_sbuf(periph, sb);
+	/* Announce command queueing. */
+	if (path->device->inq_flags & SID_CmdQue
+	 || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) {
+		sbuf_printf(sb, "%s%d: Command Queueing enabled\n",
+		    periph->periph_name, periph->unit_number);
+	}
+	/* Announce caller's details if they've passed in. */
+	if (announce_string != NULL)
+		sbuf_printf(sb, "%s%d: %s\n", periph->periph_name,
+		    periph->unit_number, announce_string);
+}
+
+void
 xpt_announce_quirks(struct cam_periph *periph, int quirks, char *bit_string)
 {
 	if (quirks != 0) {
@@ -1103,6 +1164,21 @@ xpt_announce_quirks(struct cam_periph *p
 }
 
 void
+xpt_announce_quirks_sbuf(struct cam_periph *periph, struct sbuf *sb,
+			 int quirks, char *bit_string)
+{
+	if (xsoftc.announce_nosbuf != 0) {
+		xpt_announce_quirks(periph, quirks, bit_string);
+		return;
+	}
+
+	if (quirks != 0) {
+		sbuf_printf(sb, "%s%d: quirks=0x%b\n", periph->periph_name,
+		    periph->unit_number, quirks, bit_string);
+	}
+}
+
+void
 xpt_denounce_periph(struct cam_periph *periph)
 {
 	struct	cam_path *path = periph->path;
@@ -1130,6 +1206,45 @@ xpt_denounce_periph(struct cam_periph *p
 	printf(" detached\n");
 }
 
+void
+xpt_denounce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb)
+{
+	struct cam_path *path = periph->path;
+	struct xpt_proto *proto;
+
+	cam_periph_assert(periph, MA_OWNED);
+
+	/* Fall back to the non-sbuf method if necessary */
+	if (xsoftc.announce_nosbuf != 0) {
+		xpt_denounce_periph(periph);
+		return;
+	}
+	proto = xpt_proto_find(path->device->protocol);
+	if ((proto != NULL) && (proto->ops->denounce_sbuf == NULL)) {
+		xpt_denounce_periph(periph);
+		return;
+	}
+
+	sbuf_printf(sb, "%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
+	    periph->periph_name, periph->unit_number,
+	    path->bus->sim->sim_name,
+	    path->bus->sim->unit_number,
+	    path->bus->sim->bus_id,
+	    path->bus->path_id,
+	    path->target->target_id,
+	    (uintmax_t)path->device->lun_id);
+	sbuf_printf(sb, "%s%d: ", periph->periph_name, periph->unit_number);
+
+	if (proto)
+		proto->ops->denounce_sbuf(path->device, sb);
+	else
+		sbuf_printf(sb, "%s%d: Unknown protocol device %d\n",
+		    periph->periph_name, periph->unit_number,
+		    path->device->protocol);
+	if (path->device->serial_num_len > 0)
+		sbuf_printf(sb, " s/n %.60s", path->device->serial_num);
+	sbuf_printf(sb, " detached\n");
+}
 
 int
 xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)

Modified: head/sys/cam/cam_xpt_internal.h
==============================================================================
--- head/sys/cam/cam_xpt_internal.h	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/cam_xpt_internal.h	Wed Apr 19 15:04:52 2017	(r317143)
@@ -47,6 +47,7 @@ typedef void (*xpt_dev_async_func)(u_int
 				   struct cam_ed *device,
 				   void *async_arg);
 typedef void (*xpt_announce_periph_func)(struct cam_periph *periph);
+typedef void (*xpt_announce_periph_sbuf_func)(struct cam_periph *periph, struct sbuf *sbuf);
 
 struct xpt_xport_ops {
 	xpt_alloc_device_func	alloc_device;
@@ -54,6 +55,7 @@ struct xpt_xport_ops {
 	xpt_action_func		action;
 	xpt_dev_async_func	async;
 	xpt_announce_periph_func announce;
+	xpt_announce_periph_sbuf_func announce_sbuf;
 };
 
 struct xpt_xport {
@@ -67,11 +69,14 @@ SET_DECLARE(cam_xpt_xport_set, struct xp
 	DATA_SET(cam_xpt_xport_set, data)
 
 typedef void (*xpt_proto_announce_func)(struct cam_ed *);
+typedef void (*xpt_proto_announce_sbuf_func)(struct cam_ed *, struct sbuf *);
 typedef void (*xpt_proto_debug_out_func)(union ccb *);
 
 struct xpt_proto_ops {
 	xpt_proto_announce_func	announce;
+	xpt_proto_announce_sbuf_func	announce_sbuf;
 	xpt_proto_announce_func	denounce;
+	xpt_proto_announce_sbuf_func	denounce_sbuf;
 	xpt_proto_debug_out_func debug_out;
 };
 

Modified: head/sys/cam/cam_xpt_periph.h
==============================================================================
--- head/sys/cam/cam_xpt_periph.h	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/cam_xpt_periph.h	Wed Apr 19 15:04:52 2017	(r317143)
@@ -45,9 +45,16 @@ int32_t		xpt_add_periph(struct cam_perip
 void		xpt_remove_periph(struct cam_periph *periph);
 void		xpt_announce_periph(struct cam_periph *periph,
 				    char *announce_string);
+void		xpt_announce_periph_sbuf(struct cam_periph *periph,
+					 struct sbuf *sb,
+					 char *announce_string);
 void		xpt_announce_quirks(struct cam_periph *periph,
 				    int quirks, char *bit_string);
+void		xpt_announce_quirks_sbuf(struct cam_periph *periph,
+				    struct sbuf *sb,
+				    int quirks, char *bit_string);
 void		xpt_denounce_periph(struct cam_periph *periph);
+void		xpt_denounce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb);
 #endif
 
 #endif /* _CAM_CAM_XPT_PERIPH_H */

Modified: head/sys/cam/scsi/scsi_all.c
==============================================================================
--- head/sys/cam/scsi/scsi_all.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/scsi/scsi_all.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -5169,7 +5169,7 @@ scsi_sense_print(struct ccb_scsiio *csio
 
 	sbuf_finish(&sb);
 
-	printf("%s", sbuf_data(&sb));
+	sbuf_putbuf(&sb);
 }
 
 #else /* !_KERNEL */
@@ -5361,11 +5361,10 @@ scsi_get_ascq(struct scsi_sense_data *se
  * for this routine to function properly.
  */
 void
-scsi_print_inquiry(struct scsi_inquiry_data *inq_data)
+scsi_print_inquiry_sbuf(struct sbuf *sb, struct scsi_inquiry_data *inq_data)
 {
 	u_int8_t type;
 	char *dtype, *qtype;
-	char vendor[16], product[48], revision[16], rstr[12];
 
 	type = SID_TYPE(inq_data);
 
@@ -5454,41 +5453,55 @@ scsi_print_inquiry(struct scsi_inquiry_d
 		break;
 	}
 
-	cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor),
-		   sizeof(vendor));
-	cam_strvis(product, inq_data->product, sizeof(inq_data->product),
-		   sizeof(product));
-	cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision),
-		   sizeof(revision));
+	scsi_print_inquiry_short_sbuf(sb, inq_data);
+
+	sbuf_printf(sb, "%s %s ", SID_IS_REMOVABLE(inq_data) ? "Removable" : "Fixed", dtype);
 
 	if (SID_ANSI_REV(inq_data) == SCSI_REV_0)
-		snprintf(rstr, sizeof(rstr), "SCSI");
+		sbuf_printf(sb, "SCSI ");
 	else if (SID_ANSI_REV(inq_data) <= SCSI_REV_SPC) {
-		snprintf(rstr, sizeof(rstr), "SCSI-%d",
-		    SID_ANSI_REV(inq_data));
+		sbuf_printf(sb, "SCSI-%d ", SID_ANSI_REV(inq_data));
 	} else {
-		snprintf(rstr, sizeof(rstr), "SPC-%d SCSI",
-		    SID_ANSI_REV(inq_data) - 2);
+		sbuf_printf(sb, "SPC-%d SCSI ", SID_ANSI_REV(inq_data) - 2);
 	}
-	printf("<%s %s %s> %s %s %s device%s\n",
-	       vendor, product, revision,
-	       SID_IS_REMOVABLE(inq_data) ? "Removable" : "Fixed",
-	       dtype, rstr, qtype);
+	sbuf_printf(sb, "device%s\n", qtype);
 }
 
 void
-scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data)
+scsi_print_inquiry(struct scsi_inquiry_data *inq_data)
+{
+	struct sbuf	sb;
+	char		buffer[120];
+
+	sbuf_new(&sb, buffer, 120, SBUF_FIXEDLEN);
+	scsi_print_inquiry_sbuf(&sb, inq_data);
+	sbuf_finish(&sb);
+	sbuf_putbuf(&sb);
+}
+
+void
+scsi_print_inquiry_short_sbuf(struct sbuf *sb, struct scsi_inquiry_data *inq_data)
 {
-	char vendor[16], product[48], revision[16];
 
-	cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor),
-		   sizeof(vendor));
-	cam_strvis(product, inq_data->product, sizeof(inq_data->product),
-		   sizeof(product));
-	cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision),
-		   sizeof(revision));
+	sbuf_printf(sb, "<");
+	cam_strvis_sbuf(sb, inq_data->vendor, sizeof(inq_data->vendor), 0);
+	sbuf_printf(sb, " ");
+	cam_strvis_sbuf(sb, inq_data->product, sizeof(inq_data->product), 0);
+	sbuf_printf(sb, " ");
+	cam_strvis_sbuf(sb, inq_data->revision, sizeof(inq_data->revision), 0);
+	sbuf_printf(sb, "> ");
+}
+
+void
+scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data)
+{
+	struct sbuf	sb;
+	char		buffer[84];
 
-	printf("<%s %s %s>", vendor, product, revision);
+	sbuf_new(&sb, buffer, 84, SBUF_FIXEDLEN);
+	scsi_print_inquiry_short_sbuf(&sb, inq_data);
+	sbuf_finish(&sb);
+	sbuf_putbuf(&sb);
 }
 
 /*

Modified: head/sys/cam/scsi/scsi_all.h
==============================================================================
--- head/sys/cam/scsi/scsi_all.h	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/scsi/scsi_all.h	Wed Apr 19 15:04:52 2017	(r317143)
@@ -3820,7 +3820,11 @@ char *		scsi_cdb_string(u_int8_t *cdb_pt
 void		scsi_cdb_sbuf(u_int8_t *cdb_ptr, struct sbuf *sb);
 
 void		scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
+void		scsi_print_inquiry_sbuf(struct sbuf *sb,
+				        struct scsi_inquiry_data *inq_data);
 void		scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data);
+void		scsi_print_inquiry_short_sbuf(struct sbuf *sb,
+					      struct scsi_inquiry_data *inq_data);
 
 u_int		scsi_calc_syncsrate(u_int period_factor);
 u_int		scsi_calc_syncparam(u_int period);

Modified: head/sys/cam/scsi/scsi_cd.c
==============================================================================
--- head/sys/cam/scsi/scsi_cd.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/scsi/scsi_cd.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/cdrio.h>
 #include <sys/dvdio.h>
 #include <sys/devicestat.h>
+#include <sys/sbuf.h>
 #include <sys/sysctl.h>
 #include <sys/taskqueue.h>
 #include <geom/geom_disk.h>
@@ -158,6 +159,11 @@ struct cd_softc {
 	struct cd_tocdata	toc;
 	struct disk		*disk;
 	struct callout		mediapoll_c;
+
+#define CD_ANNOUNCETMP_SZ 120
+	char			announce_temp[CD_ANNOUNCETMP_SZ];
+#define CD_ANNOUNCE_SZ 400
+	char			announce_buf[CD_ANNOUNCE_SZ];
 };
 
 struct cd_page_sizes {
@@ -1046,28 +1052,12 @@ cddone(struct cam_periph *periph, union 
 	case CD_CCB_PROBE:
 	{
 		struct	   scsi_read_capacity_data *rdcap;
-		char	   announce_buf[120]; /*
-					       * Currently (9/30/97) the 
-					       * longest possible announce 
-					       * buffer is 108 bytes, for the 
-					       * first error case below.  
-					       * That is 39 bytes for the 
-					       * basic string, 16 bytes for the
-					       * biggest sense key (hardware 
-					       * error), 52 bytes for the
-					       * text of the largest sense 
-					       * qualifier valid for a CDROM,
-					       * (0x72, 0x03 or 0x04,
-					       * 0x03), and one byte for the
-					       * null terminating character.
-					       * To allow for longer strings, 
-					       * the announce buffer is 120
-					       * bytes.
-					       */
+		char	   *announce_buf;
 		struct	   cd_params *cdp;
 		int error;
 
 		cdp = &softc->params;
+		announce_buf = softc->announce_temp;
 
 		rdcap = (struct scsi_read_capacity_data *)csio->data_ptr;
 		
@@ -1081,7 +1071,7 @@ cddone(struct cam_periph *periph, union 
 		if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP ||
 		    (error = cderror(done_ccb, CAM_RETRY_SELTO,
 				SF_RETRY_UA | SF_NO_PRINT)) == 0) {
-			snprintf(announce_buf, sizeof(announce_buf),
+			snprintf(announce_buf, CD_ANNOUNCETMP_SZ,
 			    "%juMB (%ju %u byte sectors)",
 			    ((uintmax_t)cdp->disksize * cdp->blksize) /
 			     (1024 * 1024),
@@ -1186,22 +1176,29 @@ cddone(struct cam_periph *periph, union 
 					 */
 					cam_periph_invalidate(periph);
 
-					announce_buf[0] = '\0';
+					announce_buf = NULL;
 				} else {
 
 					/*
 					 * Invalidate this peripheral.
 					 */
 					cam_periph_invalidate(periph);
-					announce_buf[0] = '\0';
+					announce_buf = NULL;
 				}
 			}
 		}
 		free(rdcap, M_SCSICD);
-		if (announce_buf[0] != '\0') {
-			xpt_announce_periph(periph, announce_buf);
-			xpt_announce_quirks(periph, softc->quirks,
+		if (announce_buf != NULL) {
+			struct sbuf sb;
+
+			sbuf_new(&sb, softc->announce_buf, CD_ANNOUNCE_SZ,
+			    SBUF_FIXEDLEN);
+			xpt_announce_periph_sbuf(periph, &sb, announce_buf);
+			xpt_announce_quirks_sbuf(periph, &sb, softc->quirks,
 			    CD_Q_BIT_STRING);
+			sbuf_finish(&sb);
+			sbuf_putbuf(&sb);
+
 			/*
 			 * Create our sysctl variables, now that we know
 			 * we have successfully attached.

Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c	Wed Apr 19 14:49:18 2017	(r317142)
+++ head/sys/cam/scsi/scsi_da.c	Wed Apr 19 15:04:52 2017	(r317143)
@@ -338,6 +338,10 @@ struct da_softc {
 	u_int	timeouts;
 	u_int	invalidations;
 #endif
+#define DA_ANNOUNCETMP_SZ 80
+	char			announce_temp[DA_ANNOUNCETMP_SZ];
+#define DA_ANNOUNCE_SZ 400
+	char			announcebuf[DA_ANNOUNCE_SZ];
 };
 
 #define dadeleteflag(softc, delete_method, enable)			\
@@ -4219,12 +4223,16 @@ dadone(struct cam_periph *periph, union 
 	{
 		struct	   scsi_read_capacity_data *rdcap;
 		struct     scsi_read_capacity_data_long *rcaplong;
-		char	   announce_buf[80];
+		char	   *announce_buf;
 		int	   lbp;
 
 		lbp = 0;
 		rdcap = NULL;
 		rcaplong = NULL;
+		/* XXX TODO: can this be a malloc? */
+		announce_buf = softc->announce_temp;
+		bzero(announce_buf, DA_ANNOUNCETMP_SZ);
+
 		if (state == DA_CCB_PROBE_RC)
 			rdcap =(struct scsi_read_capacity_data *)csio->data_ptr;
 		else
@@ -4277,7 +4285,7 @@ dadone(struct cam_periph *periph, union 
 				xpt_print(periph->path,
 				    "unsupportable block size %ju\n",
 				    (uintmax_t) block_size);
-				announce_buf[0] = '\0';
+				announce_buf = NULL;
 				cam_periph_invalidate(periph);
 			} else {
 				/*
@@ -4289,7 +4297,7 @@ dadone(struct cam_periph *periph, union 
 					  rcaplong, sizeof(*rcaplong));
 				lbp = (lalba & SRC16_LBPME_A);
 				dp = &softc->params;
-				snprintf(announce_buf, sizeof(announce_buf),
+				snprintf(announce_buf, DA_ANNOUNCETMP_SZ,
 				    "%juMB (%ju %u byte sectors)",
 				    ((uintmax_t)dp->secsize * dp->sectors) /
 				     (1024 * 1024),
@@ -4298,8 +4306,6 @@ dadone(struct cam_periph *periph, union 
 		} else {
 			int	error;
 
-			announce_buf[0] = '\0';
-
 			/*
 			 * Retry any UNIT ATTENTION type errors.  They
 			 * are expected at boot.
@@ -4383,11 +4389,10 @@ dadone(struct cam_periph *periph, union 
 							&sense_key_desc,
 							&asc_desc);
 					snprintf(announce_buf,
-					    sizeof(announce_buf),
-						"Attempt to query device "
-						"size failed: %s, %s",
-						sense_key_desc,
-						asc_desc);
+					    DA_ANNOUNCETMP_SZ,
+					    "Attempt to query device "
+					    "size failed: %s, %s",
+					    sense_key_desc, asc_desc);
 				} else { 
 					if (have_sense)
 						scsi_sense_print(
@@ -4401,6 +4406,8 @@ dadone(struct cam_periph *periph, union 
 					xpt_print(periph->path, "fatal error, "
 					    "failed to attach to device\n");
 
+					announce_buf = NULL;
+
 					/*
 					 * Free up resources.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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