[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree

zrouter-src-freebsd at zrouter.org zrouter-src-freebsd at zrouter.org
Wed Feb 1 10:56:20 UTC 2012


details:   http://zrouter.org/hg/FreeBSD/head//rev/6ab479c649a8
changeset: 303:6ab479c649a8
user:      ray at terran.dlink.ua
date:      Wed Feb 01 11:29:57 2012 +0200
description:
Update CAM subsystem

diffstat:

 head/sys/cam/cam_ccb.h                 |    3 +-
 head/sys/cam/cam_periph.c              |   17 +++-
 head/sys/cam/cam_xpt.c                 |   13 +++-
 head/sys/cam/cam_xpt_internal.h        |    4 +-
 head/sys/cam/ctl/ctl.c                 |   33 ++++---
 head/sys/cam/ctl/ctl_backend_block.c   |   20 ++--
 head/sys/cam/ctl/ctl_backend_ramdisk.c |   18 ++--
 head/sys/cam/ctl/ctl_error.c           |   19 +----
 head/sys/cam/ctl/ctl_error.h           |   11 +--
 head/sys/cam/scsi/scsi_all.c           |   10 +-
 head/sys/cam/scsi/scsi_all.h           |   24 ++++-
 head/sys/cam/scsi/scsi_da.c            |  127 ++++++++++++++++++++++++--------
 head/sys/cam/scsi/scsi_xpt.c           |   36 ++++++++-
 13 files changed, 223 insertions(+), 112 deletions(-)

diffs (739 lines):

diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/cam_ccb.h
--- a/head/sys/cam/cam_ccb.h	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/cam_ccb.h	Wed Feb 01 11:29:57 2012 +0200
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/cam/cam_ccb.h 225950 2011-10-03 20:32:55Z ken $
+ * $FreeBSD: head/sys/cam/cam_ccb.h 230590 2012-01-26 18:09:28Z ken $
  */
 
 #ifndef _CAM_CAM_CCB_H
@@ -1118,6 +1118,7 @@
 #define	CDAI_TYPE_SCSI_DEVID	1
 #define	CDAI_TYPE_SERIAL_NUM	2
 #define	CDAI_TYPE_PHYS_PATH	3
+#define	CDAI_TYPE_RCAPLONG	4
 	off_t bufsiz;			/* IN: Size of external buffer */
 #define	CAM_SCSI_DEVID_MAXLEN	65536	/* length in buffer is an uint16_t */
 	off_t provsiz;			/* OUT: Size required/used */
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/cam_periph.c
--- a/head/sys/cam/cam_periph.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/cam_periph.c	Wed Feb 01 11:29:57 2012 +0200
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/cam_periph.c 230000 2012-01-12 00:41:48Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/cam_periph.c 230544 2012-01-25 17:58:47Z ken $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1864,13 +1864,26 @@
 	case CAM_DEV_NOT_THERE:
 	{
 		struct cam_path *newpath;
+		lun_id_t lun_id;
 
 		error = ENXIO;
+
+		/*
+		 * For a selection timeout, we consider all of the LUNs on
+		 * the target to be gone.  If the status is CAM_DEV_NOT_THERE,
+		 * then we only get rid of the device(s) specified by the
+		 * path in the original CCB.
+		 */
+		if (status == CAM_DEV_NOT_THERE)
+			lun_id = xpt_path_lun_id(ccb->ccb_h.path);
+		else
+			lun_id = CAM_LUN_WILDCARD;
+
 		/* Should we do more if we can't create the path?? */
 		if (xpt_create_path(&newpath, periph,
 				    xpt_path_path_id(ccb->ccb_h.path),
 				    xpt_path_target_id(ccb->ccb_h.path),
-				    CAM_LUN_WILDCARD) != CAM_REQ_CMP) 
+				    lun_id) != CAM_REQ_CMP) 
 			break;
 
 		/*
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/cam_xpt.c
--- a/head/sys/cam/cam_xpt.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/cam_xpt.c	Wed Feb 01 11:29:57 2012 +0200
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/cam_xpt.c 230000 2012-01-12 00:41:48Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/cam_xpt.c 230590 2012-01-26 18:09:28Z ken $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -4588,6 +4588,17 @@
 		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->device_id, M_CAMXPT);
+		free(device->physpath, M_CAMXPT);
+		free(device->rcap_buf, M_CAMXPT);
+		free(device->serial_num, M_CAMXPT);
+
 		xpt_release_target(device->target);
 		free(device, M_CAMXPT);
 	} else
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/cam_xpt_internal.h
--- a/head/sys/cam/cam_xpt_internal.h	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/cam_xpt_internal.h	Wed Feb 01 11:29:57 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/cam/cam_xpt_internal.h 223081 2011-06-14 14:53:17Z gibbs $
+ * $FreeBSD: head/sys/cam/cam_xpt_internal.h 230590 2012-01-26 18:09:28Z ken $
  */
 
 #ifndef _CAM_CAM_XPT_INTERNAL_H
@@ -99,6 +99,8 @@
 	uint8_t		 *device_id;
 	uint8_t		 physpath_len;
 	uint8_t		 *physpath;	/* physical path string form */
+	uint32_t	 rcap_len;
+	uint8_t		 *rcap_buf;
 	struct		 ata_params ident_data;
 	u_int8_t	 inq_flags;	/*
 					 * Current settings for inquiry flags.
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/ctl/ctl.c
--- a/head/sys/cam/ctl/ctl.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/ctl/ctl.c	Wed Feb 01 11:29:57 2012 +0200
@@ -38,7 +38,7 @@
 #define _CTL_C
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 229997 2012-01-12 00:34:33Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 230334 2012-01-19 18:42:03Z ken $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -8736,7 +8736,7 @@
 	struct ctl_lun *lun;
 	uint32_t initidx;
 	int have_error;
-	ctl_sense_format sense_format;
+	scsi_sense_data_type sense_format;
 
 	cdb = (struct scsi_request_sense *)ctsio->cdb;
 
@@ -8748,9 +8748,9 @@
 	 * Determine which sense format the user wants.
 	 */
 	if (cdb->byte2 & SRS_DESC)
-		sense_format = CTL_SENSE_DESCRIPTOR;
+		sense_format = SSD_TYPE_DESC;
 	else
-		sense_format = CTL_SENSE_FIXED;
+		sense_format = SSD_TYPE_FIXED;
 
 	ctsio->kern_data_ptr = malloc(sizeof(*sense_ptr), M_CTL, M_WAITOK);
 	if (ctsio->kern_data_ptr == NULL) {
@@ -8789,13 +8789,13 @@
 	 */
 	mtx_lock(&lun->ctl_softc->ctl_lock);
 	if (ctl_is_set(lun->have_ca, initidx)) {
-		ctl_sense_format stored_format;
+		scsi_sense_data_type stored_format;
 
 		/*
 		 * Check to see which sense format was used for the stored
 		 * sense data.
 		 */
-		stored_format = ctl_get_sense_format(
+		stored_format = scsi_sense_type(
 		    &lun->pending_sense[initidx].sense);
 
 		/*
@@ -8804,14 +8804,17 @@
 		 * format.  If we're going from descriptor to fixed format
 		 * sense data, we may lose things in translation, depending
 		 * on what options were used.
-		 */
-		if ((stored_format == CTL_SENSE_FIXED)
-		 && (sense_format == CTL_SENSE_DESCRIPTOR))
+		 *
+		 * If the stored format is SSD_TYPE_NONE (i.e. invalid),
+		 * for some reason we'll just copy it out as-is.
+		 */
+		if ((stored_format == SSD_TYPE_FIXED)
+		 && (sense_format == SSD_TYPE_DESC))
 			ctl_sense_to_desc((struct scsi_sense_data_fixed *)
 			    &lun->pending_sense[initidx].sense,
 			    (struct scsi_sense_data_desc *)sense_ptr);
-		else if ((stored_format == CTL_SENSE_DESCRIPTOR)
-		      && (sense_format == CTL_SENSE_FIXED))
+		else if ((stored_format == SSD_TYPE_DESC)
+		      && (sense_format == SSD_TYPE_FIXED))
 			ctl_sense_to_fixed((struct scsi_sense_data_desc *)
 			    &lun->pending_sense[initidx].sense,
 			    (struct scsi_sense_data_fixed *)sense_ptr);
@@ -10459,14 +10462,14 @@
 
 		ua_type = lun->pending_sense[initidx].ua_pending;
 		if (ua_type != CTL_UA_NONE) {
-			ctl_sense_format sense_format;
+			scsi_sense_data_type sense_format;
 
 			if (lun != NULL)
 				sense_format = (lun->flags &
-				    CTL_LUN_SENSE_DESC) ? CTL_SENSE_DESCRIPTOR :
-				    CTL_SENSE_FIXED;
+				    CTL_LUN_SENSE_DESC) ? SSD_TYPE_DESC :
+				    SSD_TYPE_FIXED;
 			else
-				sense_format = CTL_SENSE_FIXED;
+				sense_format = SSD_TYPE_FIXED;
 
 			ua_type = ctl_build_ua(ua_type, &ctsio->sense_data,
 					       sense_format);
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/ctl/ctl_backend_block.c
--- a/head/sys/cam/ctl/ctl_backend_block.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/ctl/ctl_backend_block.c	Wed Feb 01 11:29:57 2012 +0200
@@ -36,7 +36,7 @@
  * Author: Ken Merry <ken at FreeBSD.org>
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 229997 2012-01-12 00:34:33Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_block.c 230334 2012-01-19 18:42:03Z ken $");
 
 #include <opt_kdtrace.h>
 
@@ -260,15 +260,15 @@
 
 static struct ctl_backend_driver ctl_be_block_driver = 
 {
-	name: "block",
-	flags: CTL_BE_FLAG_HAS_CONFIG,
-	init: ctl_be_block_init,
-	data_submit: ctl_be_block_submit,
-	data_move_done: ctl_be_block_move_done,
-	config_read: ctl_be_block_config_read,
-	config_write: ctl_be_block_config_write,
-	ioctl: ctl_be_block_ioctl,
-	lun_info: ctl_be_block_lun_info
+	.name = "block",
+	.flags = CTL_BE_FLAG_HAS_CONFIG,
+	.init = ctl_be_block_init,
+	.data_submit = ctl_be_block_submit,
+	.data_move_done = ctl_be_block_move_done,
+	.config_read = ctl_be_block_config_read,
+	.config_write = ctl_be_block_config_write,
+	.ioctl = ctl_be_block_ioctl,
+	.lun_info = ctl_be_block_lun_info
 };
 
 MALLOC_DEFINE(M_CTLBLK, "ctlblk", "Memory used for CTL block backend");
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/ctl/ctl_backend_ramdisk.c
--- a/head/sys/cam/ctl/ctl_backend_ramdisk.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/ctl/ctl_backend_ramdisk.c	Wed Feb 01 11:29:57 2012 +0200
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_ramdisk.c 229997 2012-01-12 00:34:33Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_backend_ramdisk.c 230334 2012-01-19 18:42:03Z ken $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -110,14 +110,14 @@
 
 static struct ctl_backend_driver ctl_be_ramdisk_driver = 
 {
-	name: "ramdisk",
-	flags: CTL_BE_FLAG_HAS_CONFIG,
-	init: ctl_backend_ramdisk_init,
-	data_submit: ctl_backend_ramdisk_submit,
-	data_move_done: ctl_backend_ramdisk_move_done,
-	config_read: ctl_backend_ramdisk_config_read,
-	config_write: ctl_backend_ramdisk_config_write,
-	ioctl: ctl_backend_ramdisk_ioctl
+	.name = "ramdisk",
+	.flags = CTL_BE_FLAG_HAS_CONFIG,
+	.init = ctl_backend_ramdisk_init,
+	.data_submit = ctl_backend_ramdisk_submit,
+	.data_move_done = ctl_backend_ramdisk_move_done,
+	.config_read = ctl_backend_ramdisk_config_read,
+	.config_write = ctl_backend_ramdisk_config_write,
+	.ioctl = ctl_backend_ramdisk_ioctl
 };
 
 MALLOC_DEFINE(M_RAMDISK, "ramdisk", "Memory used for CTL RAMdisk");
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/ctl/ctl_error.c
--- a/head/sys/cam/ctl/ctl_error.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/ctl/ctl_error.c	Wed Feb 01 11:29:57 2012 +0200
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_error.c 229997 2012-01-12 00:34:33Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_error.c 230334 2012-01-19 18:42:03Z ken $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -354,21 +354,6 @@
 			   SSD_ELEM_NONE);
 }
 
-ctl_sense_format
-ctl_get_sense_format(struct scsi_sense_data *sense_data)
-{
-	switch (sense_data->error_code & SSD_ERRCODE) {
-	case SSD_DESC_CURRENT_ERROR:
-	case SSD_DESC_DEFERRED_ERROR:
-		return (SSD_TYPE_DESC);
-	case SSD_CURRENT_ERROR:
-	case SSD_DEFERRED_ERROR:
-	default:
-		return (SSD_TYPE_FIXED);
-		break;
-	}
-}
-
 void
 ctl_set_ua(struct ctl_scsiio *ctsio, int asc, int ascq)
 {
@@ -382,7 +367,7 @@
 
 ctl_ua_type
 ctl_build_ua(ctl_ua_type ua_type, struct scsi_sense_data *sense,
-	     ctl_sense_format sense_format)
+	     scsi_sense_data_type sense_format)
 {
 	ctl_ua_type ua_to_build;
 	int i, asc, ascq;
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/ctl/ctl_error.h
--- a/head/sys/cam/ctl/ctl_error.h	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/ctl/ctl_error.h	Wed Feb 01 11:29:57 2012 +0200
@@ -28,7 +28,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  *
  * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_error.h#1 $
- * $FreeBSD: head/sys/cam/ctl/ctl_error.h 229997 2012-01-12 00:34:33Z ken $
+ * $FreeBSD: head/sys/cam/ctl/ctl_error.h 230334 2012-01-19 18:42:03Z ken $
  */
 /*
  * Function definitions for various error reporting routines used both
@@ -42,12 +42,6 @@
 #ifndef	_CTL_ERROR_H_
 #define	_CTL_ERROR_H_
 
-typedef enum {
-	CTL_SENSE_NOT_SPECIFIED,
-	CTL_SENSE_FIXED,
-	CTL_SENSE_DESCRIPTOR
-} ctl_sense_format;
-
 void ctl_set_sense_data_va(struct scsi_sense_data *sense_data, void *lun,
 			   scsi_sense_data_type sense_format, int current_error,
 			   int sense_key, int asc, int ascq, va_list ap); 
@@ -60,10 +54,9 @@
 		      struct scsi_sense_data_desc *sense_dest);
 void ctl_sense_to_fixed(struct scsi_sense_data_desc *sense_src,
 			struct scsi_sense_data_fixed *sense_dest);
-ctl_sense_format ctl_get_sense_format(struct scsi_sense_data *sense_data);
 void ctl_set_ua(struct ctl_scsiio *ctsio, int asc, int ascq);
 ctl_ua_type ctl_build_ua(ctl_ua_type ua_type, struct scsi_sense_data *sense,
-			 ctl_sense_format sense_format);
+			 scsi_sense_data_type sense_format);
 void ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio);
 void ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag);
 void ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command,
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/scsi/scsi_all.c
--- a/head/sys/cam/scsi/scsi_all.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/scsi/scsi_all.c	Wed Feb 01 11:29:57 2012 +0200
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 230053 2012-01-13 10:21:17Z mav $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 230590 2012-01-26 18:09:28Z ken $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -5325,8 +5325,8 @@
 scsi_read_capacity_16(struct ccb_scsiio *csio, uint32_t retries,
 		      void (*cbfcnp)(struct cam_periph *, union ccb *),
 		      uint8_t tag_action, uint64_t lba, int reladr, int pmi,
-		      struct scsi_read_capacity_data_long *rcap_buf,
-		      uint8_t sense_len, uint32_t timeout)
+		      uint8_t *rcap_buf, int rcap_buf_len, uint8_t sense_len,
+		      uint32_t timeout)
 {
 	struct scsi_read_capacity_16 *scsi_cmd;
 
@@ -5337,7 +5337,7 @@
 		      /*flags*/CAM_DIR_IN,
 		      tag_action,
 		      /*data_ptr*/(u_int8_t *)rcap_buf,
-		      /*dxfer_len*/sizeof(*rcap_buf),
+		      /*dxfer_len*/rcap_buf_len,
 		      sense_len,
 		      sizeof(*scsi_cmd),
 		      timeout);
@@ -5346,7 +5346,7 @@
 	scsi_cmd->opcode = SERVICE_ACTION_IN;
 	scsi_cmd->service_action = SRC16_SERVICE_ACTION;
 	scsi_u64to8b(lba, scsi_cmd->addr);
-	scsi_ulto4b(sizeof(*rcap_buf), scsi_cmd->alloc_len);
+	scsi_ulto4b(rcap_buf_len, scsi_cmd->alloc_len);
 	if (pmi)
 		reladr |= SRC16_PMI;
 	if (reladr)
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/scsi/scsi_all.h
--- a/head/sys/cam/scsi/scsi_all.h	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/scsi/scsi_all.h	Wed Feb 01 11:29:57 2012 +0200
@@ -14,7 +14,7 @@
  *
  * Ported to run under 386BSD by Julian Elischer (julian at tfs.com) Sept 1992
  *
- * $FreeBSD: head/sys/cam/scsi/scsi_all.h 230053 2012-01-13 10:21:17Z mav $
+ * $FreeBSD: head/sys/cam/scsi/scsi_all.h 230590 2012-01-26 18:09:28Z ken $
  */
 
 /*
@@ -1437,15 +1437,26 @@
 	uint8_t length[4];
 #define	SRC16_PROT_EN		0x01
 #define	SRC16_P_TYPE		0x0e
+#define	SRC16_PTYPE_1		0x00
+#define	SRC16_PTYPE_2		0x02
+#define	SRC16_PTYPE_3		0x04
 	uint8_t prot;
 #define	SRC16_LBPPBE		0x0f
 #define	SRC16_PI_EXPONENT	0xf0
 #define	SRC16_PI_EXPONENT_SHIFT	4
 	uint8_t prot_lbppbe;
-#define	SRC16_LALBA		0x3fff
-#define	SRC16_LBPRZ		0x4000
-#define	SRC16_LBPME		0x8000
+#define	SRC16_LALBA		0x3f
+#define	SRC16_LBPRZ		0x40
+#define	SRC16_LBPME		0x80
+/*
+ * Alternate versions of these macros that are intended for use on a 16-bit
+ * version of the lalba_lbp field instead of the array of 2 8 bit numbers.
+ */
+#define	SRC16_LALBA_A		0x3fff
+#define	SRC16_LBPRZ_A		0x4000
+#define	SRC16_LBPME_A		0x8000
 	uint8_t lalba_lbp[2];
+	uint8_t	reserved[16];
 };
 
 struct scsi_report_luns
@@ -2293,9 +2304,8 @@
 				      void (*cbfcnp)(struct cam_periph *,
 				      union ccb *), uint8_t tag_action,
 				      uint64_t lba, int reladr, int pmi,
-				      struct scsi_read_capacity_data_long
-				      *rcap_buf, uint8_t sense_len,
-				      uint32_t timeout);
+				      uint8_t *rcap_buf, int rcap_buf_len,
+				      uint8_t sense_len, uint32_t timeout);
 
 void		scsi_report_luns(struct ccb_scsiio *csio, u_int32_t retries,
 				 void (*cbfcnp)(struct cam_periph *, 
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/scsi/scsi_da.c
--- a/head/sys/cam/scsi/scsi_da.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/scsi/scsi_da.c	Wed Feb 01 11:29:57 2012 +0200
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 230157 2012-01-15 20:43:39Z avg $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 230590 2012-01-26 18:09:28Z ken $");
 
 #include <sys/param.h>
 
@@ -160,6 +160,7 @@
 	struct callout		sendordered_c;
 	uint64_t wwpn;
 	uint8_t	 unmap_buf[UNMAP_MAX_RANGES * 16 + 8];
+	struct scsi_read_capacity_data_long rcaplong;
 };
 
 struct da_quirk_entry {
@@ -830,7 +831,9 @@
 static void		daprevent(struct cam_periph *periph, int action);
 static int		dagetcapacity(struct cam_periph *periph);
 static void		dasetgeom(struct cam_periph *periph, uint32_t block_len,
-				  uint64_t maxsector, u_int lbppbe, u_int lalba);
+				  uint64_t maxsector,
+				  struct scsi_read_capacity_data_long *rcaplong,
+				  size_t rcap_size);
 static timeout_t	dasendorderedtag;
 static void		dashutdown(void *arg, int howto);
 
@@ -1948,7 +1951,8 @@
 				      /*lba*/ 0,
 				      /*reladr*/ 0,
 				      /*pmi*/ 0,
-				      rcaplong,
+				      /*rcap_buf*/ (uint8_t *)rcaplong,
+				      /*rcap_buf_len*/ sizeof(*rcaplong),
 				      /*sense_len*/ SSD_FULL_SIZE,
 				      /*timeout*/ 60000);
 		start_ccb->ccb_h.ccb_bp = NULL;
@@ -2227,10 +2231,15 @@
 				announce_buf[0] = '\0';
 				cam_periph_invalidate(periph);
 			} else {
+				/*
+				 * We pass rcaplong into dasetgeom(),
+				 * because it will only use it if it is
+				 * non-NULL.
+				 */
 				dasetgeom(periph, block_size, maxsector,
-				    lbppbe, lalba & SRC16_LALBA);
-				if ((lalba & SRC16_LBPME) &&
-				    softc->delete_method == DA_DELETE_NONE)
+					  rcaplong, sizeof(*rcaplong));
+				if ((lalba & SRC16_LBPME_A)
+				 && softc->delete_method == DA_DELETE_NONE)
 					softc->delete_method = DA_DELETE_UNMAP;
 				dp = &softc->params;
 				snprintf(announce_buf, sizeof(announce_buf),
@@ -2504,6 +2513,7 @@
 	lalba = 0;
 	error = 0;
 	rc16failed = 0;
+	rcaplong = NULL;
 	sense_flags = SF_RETRY_UA;
 	if (softc->flags & DA_FLAG_PACK_REMOVABLE)
 		sense_flags |= SF_NO_PRINT;
@@ -2521,39 +2531,47 @@
 	/* Try READ CAPACITY(16) first if we think it should work. */
 	if (softc->flags & DA_FLAG_CAN_RC16) {
 		scsi_read_capacity_16(&ccb->csio,
-			      /*retries*/ 4,
-			      /*cbfcnp*/ dadone,
-			      /*tag_action*/ MSG_SIMPLE_Q_TAG,
-			      /*lba*/ 0,
-			      /*reladr*/ 0,
-			      /*pmi*/ 0,
-			      rcaplong,
-			      /*sense_len*/ SSD_FULL_SIZE,
-			      /*timeout*/ 60000);
+				      /*retries*/ 4,
+				      /*cbfcnp*/ dadone,
+				      /*tag_action*/ MSG_SIMPLE_Q_TAG,
+				      /*lba*/ 0,
+				      /*reladr*/ 0,
+				      /*pmi*/ 0,
+				      /*rcap_buf*/ (uint8_t *)rcaplong,
+				      /*rcap_buf_len*/ sizeof(*rcaplong),
+				      /*sense_len*/ SSD_FULL_SIZE,
+				      /*timeout*/ 60000);
 		ccb->ccb_h.ccb_bp = NULL;
 
 		error = cam_periph_runccb(ccb, daerror,
-				  /*cam_flags*/CAM_RETRY_SELTO,
-				  sense_flags,
-				  softc->disk->d_devstat);
+					  /*cam_flags*/CAM_RETRY_SELTO,
+					  sense_flags, softc->disk->d_devstat);
 		if (error == 0)
 			goto rc16ok;
 
 		/* If we got ILLEGAL REQUEST, do not prefer RC16 any more. */
-		if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
-		     CAM_REQ_INVALID) {
+		if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
 			softc->flags &= ~DA_FLAG_CAN_RC16;
 		} else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
-		     CAM_SCSI_STATUS_ERROR) &&
-		    (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) &&
-		    (ccb->ccb_h.status & CAM_AUTOSNS_VALID) &&
-		    ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0) &&
-		    ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
+			     CAM_SCSI_STATUS_ERROR)
+			&& (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
+			&& (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
+			&& ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
+			&& ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
 			int sense_key, error_code, asc, ascq;
 
-			scsi_extract_sense(&ccb->csio.sense_data,
-				   &error_code, &sense_key, &asc, &ascq);
-			if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
+			scsi_extract_sense_len(&ccb->csio.sense_data,
+					       ccb->csio.sense_len -
+					       ccb->csio.sense_resid,
+					       &error_code, &sense_key,
+					       &asc, &ascq, /*show_errors*/1);
+			/*
+			 * If we don't have enough sense to get the sense
+			 * key, or if it's illegal request, turn off
+			 * READ CAPACITY (16).
+			 */
+			if ((sense_key == -1)
+			 || (sense_key == SSD_KEY_ILLEGAL_REQUEST))
 				softc->flags &= ~DA_FLAG_CAN_RC16;
 		}
 		rc16failed = 1;
@@ -2590,7 +2608,8 @@
 			      /*lba*/ 0,
 			      /*reladr*/ 0,
 			      /*pmi*/ 0,
-			      rcaplong,
+			      /*rcap_buf*/ (uint8_t *)rcaplong,
+			      /*rcap_buf_len*/ sizeof(*rcaplong),
 			      /*sense_len*/ SSD_FULL_SIZE,
 			      /*timeout*/ 60000);
 	ccb->ccb_h.ccb_bp = NULL;
@@ -2617,9 +2636,9 @@
 			error = EINVAL;
 		} else {
 			dasetgeom(periph, block_len, maxsector,
-			    lbppbe, lalba & SRC16_LALBA);
-			if ((lalba & SRC16_LBPME) &&
-			    softc->delete_method == DA_DELETE_NONE)
+				  rcaplong, sizeof(*rcaplong));
+			if ((lalba & SRC16_LBPME)
+			 && softc->delete_method == DA_DELETE_NONE)
 				softc->delete_method = DA_DELETE_UNMAP;
 		}
 	}
@@ -2633,17 +2652,27 @@
 
 static void
 dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector,
-    u_int lbppbe, u_int lalba)
+	  struct scsi_read_capacity_data_long *rcaplong, size_t rcap_len)
 {
 	struct ccb_calc_geometry ccg;
 	struct da_softc *softc;
 	struct disk_params *dp;
+	u_int lbppbe, lalba;
 
 	softc = (struct da_softc *)periph->softc;
 
 	dp = &softc->params;
 	dp->secsize = block_len;
 	dp->sectors = maxsector + 1;
+	if (rcaplong != NULL) {
+		lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
+		lalba = scsi_2btoul(rcaplong->lalba_lbp);
+		lalba &= SRC16_LALBA_A;
+	} else {
+		lbppbe = 0;
+		lalba = 0;
+	}
+
 	if (lbppbe > 0) {
 		dp->stripesize = block_len << lbppbe;
 		dp->stripeoffset = (dp->stripesize - block_len * lalba) %
@@ -2688,6 +2717,38 @@
 		dp->secs_per_track = ccg.secs_per_track;
 		dp->cylinders = ccg.cylinders;
 	}
+
+	/*
+	 * If the user supplied a read capacity buffer, and if it is
+	 * different than the previous buffer, update the data in the EDT.
+	 * If it's the same, we don't bother.  This avoids sending an
+	 * update every time someone opens this device.
+	 */
+	if ((rcaplong != NULL)
+	 && (bcmp(rcaplong, &softc->rcaplong,
+		  min(sizeof(softc->rcaplong), rcap_len)) != 0)) {
+		struct ccb_dev_advinfo cdai;
+
+		xpt_setup_ccb(&cdai.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
+		cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
+		cdai.buftype = CDAI_TYPE_RCAPLONG;
+		cdai.flags |= CDAI_FLAG_STORE;
+		cdai.bufsiz = rcap_len;
+		cdai.buf = (uint8_t *)rcaplong;
+		xpt_action((union ccb *)&cdai);
+		if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
+			cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
+		if (cdai.ccb_h.status != CAM_REQ_CMP) {
+			xpt_print(periph->path, "%s: failed to set read "
+				  "capacity advinfo\n", __func__);
+			/* Use cam_error_print() to decode the status */
+			cam_error_print((union ccb *)&cdai, CAM_ESF_CAM_STATUS,
+					CAM_EPF_ALL);
+		} else {
+			bcopy(rcaplong, &softc->rcaplong,
+			      min(sizeof(softc->rcaplong), rcap_len));
+		}
+	}
 }
 
 static void
diff -r b584ac3f214f -r 6ab479c649a8 head/sys/cam/scsi/scsi_xpt.c
--- a/head/sys/cam/scsi/scsi_xpt.c	Wed Feb 01 11:29:19 2012 +0200
+++ b/head/sys/cam/scsi/scsi_xpt.c	Wed Feb 01 11:29:57 2012 +0200
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_xpt.c 228442 2011-12-12 18:43:18Z mdf $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_xpt.c 230590 2012-01-26 18:09:28Z ken $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -2468,8 +2468,10 @@
 		break;
 	case CDAI_TYPE_PHYS_PATH:
 		if (cdai->flags & CDAI_FLAG_STORE) {
-			if (device->physpath != NULL)
+			if (device->physpath != NULL) {
 				free(device->physpath, M_CAMXPT);
+				device->physpath = NULL;
+			}
 			device->physpath_len = cdai->bufsiz;
 			/* Clear existing buffer if zero length */
 			if (cdai->bufsiz == 0)
@@ -2490,6 +2492,36 @@
 			memcpy(cdai->buf, device->physpath, amt);
 		}
 		break;
+	case CDAI_TYPE_RCAPLONG:
+		if (cdai->flags & CDAI_FLAG_STORE) {
+			if (device->rcap_buf != NULL) {
+				free(device->rcap_buf, M_CAMXPT);
+				device->rcap_buf = NULL;
+			}
+
+			device->rcap_len = cdai->bufsiz;
+			/* Clear existing buffer if zero length */
+			if (cdai->bufsiz == 0)
+				break;
+
+			device->rcap_buf = malloc(cdai->bufsiz, M_CAMXPT,
+						  M_NOWAIT);
+			if (device->rcap_buf == NULL) {
+				start_ccb->ccb_h.status = CAM_REQ_ABORTED;
+				return;
+			}
+
+			memcpy(device->rcap_buf, cdai->buf, cdai->bufsiz);
+		} else {
+			cdai->provsiz = device->rcap_len;
+			if (device->rcap_len == 0)
+				break;
+			amt = device->rcap_len;
+			if (cdai->provsiz > cdai->bufsiz)
+				amt = cdai->bufsiz;
+			memcpy(cdai->buf, device->rcap_buf, amt);
+		}
+		break;
 	default:
 		return;
 	}


More information about the Zrouter-src-freebsd mailing list