Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Oct 2014 14:48:49 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r273038 - in head/sys/cam: ctl scsi
Message-ID:  <201410131448.s9DEmnHq083654@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Oct 13 14:48:49 2014
New Revision: 273038
URL: https://svnweb.freebsd.org/changeset/base/273038

Log:
  Add support for READ DEFECT DATA (10/12) commands.
  
  SPC-4 r2 allows to return empty defect list if the list is not supported.
  We don't reallu support defect data lists, but this suppresses some errors.
  
  MFC after:	1 week

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/ctl/ctl_cmd_table.c
  head/sys/cam/ctl/ctl_private.h
  head/sys/cam/scsi/scsi_da.h

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Mon Oct 13 14:40:00 2014	(r273037)
+++ head/sys/cam/ctl/ctl.c	Mon Oct 13 14:48:49 2014	(r273038)
@@ -7389,6 +7389,89 @@ ctl_read_capacity_16(struct ctl_scsiio *
 }
 
 int
+ctl_read_defect(struct ctl_scsiio *ctsio)
+{
+	struct scsi_read_defect_data_10 *ccb10;
+	struct scsi_read_defect_data_12 *ccb12;
+	struct scsi_read_defect_data_hdr_10 *data10;
+	struct scsi_read_defect_data_hdr_12 *data12;
+	struct ctl_lun *lun;
+	uint32_t alloc_len, data_len;
+	uint8_t format;
+
+	CTL_DEBUG_PRINT(("ctl_read_defect\n"));
+
+	lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+	if (lun->flags & CTL_LUN_PR_RESERVED) {
+		uint32_t residx;
+
+		/*
+		 * XXX KDM need a lock here.
+		 */
+		residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
+		if ((lun->res_type == SPR_TYPE_EX_AC
+		  && residx != lun->pr_res_idx)
+		 || ((lun->res_type == SPR_TYPE_EX_AC_RO
+		   || lun->res_type == SPR_TYPE_EX_AC_AR)
+		  && lun->pr_keys[residx] == 0)) {
+			ctl_set_reservation_conflict(ctsio);
+			ctl_done((union ctl_io *)ctsio);
+			return (CTL_RETVAL_COMPLETE);
+	        }
+	}
+
+	if (ctsio->cdb[0] == READ_DEFECT_DATA_10) {
+		ccb10 = (struct scsi_read_defect_data_10 *)&ctsio->cdb;
+		format = ccb10->format;
+		alloc_len = scsi_2btoul(ccb10->alloc_length);
+		data_len = sizeof(*data10);
+	} else {
+		ccb12 = (struct scsi_read_defect_data_12 *)&ctsio->cdb;
+		format = ccb12->format;
+		alloc_len = scsi_4btoul(ccb12->alloc_length);
+		data_len = sizeof(*data12);
+	}
+	if (alloc_len == 0) {
+		ctl_set_success(ctsio);
+		ctl_done((union ctl_io *)ctsio);
+		return (CTL_RETVAL_COMPLETE);
+	}
+
+	ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
+	if (data_len < alloc_len) {
+		ctsio->residual = alloc_len - data_len;
+		ctsio->kern_data_len = data_len;
+		ctsio->kern_total_len = data_len;
+	} else {
+		ctsio->residual = 0;
+		ctsio->kern_data_len = alloc_len;
+		ctsio->kern_total_len = alloc_len;
+	}
+	ctsio->kern_data_resid = 0;
+	ctsio->kern_rel_offset = 0;
+	ctsio->kern_sg_entries = 0;
+
+	if (ctsio->cdb[0] == READ_DEFECT_DATA_10) {
+		data10 = (struct scsi_read_defect_data_hdr_10 *)
+		    ctsio->kern_data_ptr;
+		data10->format = format;
+		scsi_ulto2b(0, data10->length);
+	} else {
+		data12 = (struct scsi_read_defect_data_hdr_12 *)
+		    ctsio->kern_data_ptr;
+		data12->format = format;
+		scsi_ulto2b(0, data12->generation);
+		scsi_ulto4b(0, data12->length);
+	}
+
+	ctsio->scsi_status = SCSI_STATUS_OK;
+	ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
+	ctsio->be_move_done = ctl_config_move_done;
+	ctl_datamove((union ctl_io *)ctsio);
+	return (CTL_RETVAL_COMPLETE);
+}
+
+int
 ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
 {
 	struct scsi_maintenance_in *cdb;

Modified: head/sys/cam/ctl/ctl_cmd_table.c
==============================================================================
--- head/sys/cam/ctl/ctl_cmd_table.c	Mon Oct 13 14:40:00 2014	(r273037)
+++ head/sys/cam/ctl/ctl_cmd_table.c	Mon Oct 13 14:48:49 2014	(r273038)
@@ -768,7 +768,11 @@ const struct ctl_cmd_entry ctl_cmd_table
 {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
 
 /* 37 READ DEFECT DATA(10) */
-{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
+{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
+				     CTL_FLAG_DATA_IN |
+				     CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_LUN_PAT_NONE,
+ 10, {0, 0x1f, 0, 0, 0, 0, 0xff, 0xff, 0x07}},
 
 /* 38 MEDIUM SCAN */
 {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
@@ -1247,7 +1251,11 @@ const struct ctl_cmd_entry ctl_cmd_table
 {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
 
 /* B7 READ DEFECT DATA(12) */
-{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
+{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
+				     CTL_FLAG_DATA_IN |
+				     CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_LUN_PAT_NONE,
+ 12, {0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
 
 /* B8 READ ELEMENT STATUS */
 {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},

Modified: head/sys/cam/ctl/ctl_private.h
==============================================================================
--- head/sys/cam/ctl/ctl_private.h	Mon Oct 13 14:40:00 2014	(r273037)
+++ head/sys/cam/ctl/ctl_private.h	Mon Oct 13 14:48:49 2014	(r273038)
@@ -486,6 +486,7 @@ int ctl_mode_select(struct ctl_scsiio *c
 int ctl_mode_sense(struct ctl_scsiio *ctsio);
 int ctl_read_capacity(struct ctl_scsiio *ctsio);
 int ctl_read_capacity_16(struct ctl_scsiio *ctsio);
+int ctl_read_defect(struct ctl_scsiio *ctsio);
 int ctl_read_write(struct ctl_scsiio *ctsio);
 int ctl_cnw(struct ctl_scsiio *ctsio);
 int ctl_report_luns(struct ctl_scsiio *ctsio);

Modified: head/sys/cam/scsi/scsi_da.h
==============================================================================
--- head/sys/cam/scsi/scsi_da.h	Mon Oct 13 14:40:00 2014	(r273037)
+++ head/sys/cam/scsi/scsi_da.h	Mon Oct 13 14:48:49 2014	(r273038)
@@ -92,28 +92,19 @@ struct scsi_reassign_blocks
 
 struct scsi_read_defect_data_10
 {
-	u_int8_t opcode;
-
-	/* 
-	 * The most significant 3 bits are the LUN, the other 5 are
-	 * reserved.
-	 */
-#define SRDD10_LUN_MASK 0xE0
-	u_int8_t byte2;
+	uint8_t opcode;
+	uint8_t byte2;
 #define SRDD10_GLIST 0x08
 #define SRDD10_PLIST 0x10
 #define SRDD10_DLIST_FORMAT_MASK 0x07
 #define SRDD10_BLOCK_FORMAT            0x00
 #define SRDD10_BYTES_FROM_INDEX_FORMAT 0x04
 #define SRDD10_PHYSICAL_SECTOR_FORMAT  0x05
-	u_int8_t format;
-
-	u_int8_t reserved[4];
-
-	u_int8_t alloc_length[2];
+	uint8_t format;
+	uint8_t reserved[4];
+	uint8_t alloc_length[2];
 #define	SRDD10_MAX_LENGTH		0xffff
-
-	u_int8_t control;
+	uint8_t control;
 };
 
 struct scsi_sanitize
@@ -143,29 +134,18 @@ struct scsi_sanitize_parameter_list
 
 struct scsi_read_defect_data_12
 {
-	u_int8_t opcode;
-
-	/* 
-	 * The most significant 3 bits are the LUN, the other 5 are
-	 * reserved.
-	 */
-#define SRDD12_LUN_MASK 0xE0
-	u_int8_t byte2;
-
+	uint8_t opcode;
 #define SRDD12_GLIST 0x08
 #define SRDD12_PLIST 0x10
 #define SRDD12_DLIST_FORMAT_MASK 0x07
 #define SRDD12_BLOCK_FORMAT            0x00
 #define SRDD12_BYTES_FROM_INDEX_FORMAT 0x04
 #define SRDD12_PHYSICAL_SECTOR_FORMAT  0x05
-	u_int8_t format;
-
-	u_int8_t reserved[4];
-
-	u_int8_t alloc_length[4];
-
-	u_int8_t control;
-	
+	uint8_t format;
+	uint8_t address_descriptor_index[4];
+	uint8_t alloc_length[4];
+	uint8_t reserved;
+	uint8_t control;
 };
 
 
@@ -376,6 +356,7 @@ struct scsi_read_defect_data_hdr_12
 #define SRDDH12_BYTES_FROM_INDEX_FORMAT 0x04
 #define SRDDH12_PHYSICAL_SECTOR_FORMAT  0x05
 	u_int8_t format;
+	u_int8_t generation[2];
 	u_int8_t length[4];
 };
 



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