Blame SOURCES/0015-fix-arm-aliasing-problem.patch

dc245c
From 709410b1d7f3d0b2b4e342cc46de2b45453d6c5c Mon Sep 17 00:00:00 2001
dc245c
From: Ronnie Sahlberg <ronniesahlberg@gmail.com>
dc245c
Date: Sat, 18 May 2013 13:56:02 -0700
dc245c
Subject: [RHEL7 libiscsi PATCH 15/18] TESTS: Add some REPORT SUPPORTED OPCODES tests
dc245c
dc245c
Add a simple test that it works or is not implemented.
dc245c
dc245c
Add a RCTD test to verify that with this flag clear we get command descriptors without CTDP set  and with it set we get command descriptors with CTDP set and a timeout descriptor
dc245c
dc245c
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
dc245c
(cherry-picked from upstream commit 709410b1d7f3d0b2b4e342cc46de2b45453d6c5c)
dc245c
dc245c
Fixes these errors in ARM compilation:
dc245c
dc245c
lib/scsi-lowlevel.c: In function 'scsi_maintenancein_datain_unmarshall':
dc245c
lib/scsi-lowlevel.c:862:12: error: cast increases required alignment of target type [-Werror=cast-align]
dc245c
   datain = (struct scsi_command_descriptor *)&task->datain.data[4];
dc245c
            ^
dc245c
lib/scsi-lowlevel.c:876:11: error: cast increases required alignment of target type [-Werror=cast-align]
dc245c
    desc = (struct scsi_command_descriptor *)((char *)desc + desc_size);
dc245c
           ^
dc245c
lib/scsi-lowlevel.c:877:13: error: cast increases required alignment of target type [-Werror=cast-align]
dc245c
    datain = (struct scsi_command_descriptor *)((char *)datain + desc_size);
dc245c
             ^
dc245c
---
dc245c
 include/scsi-lowlevel.h                          | 60 +++++++-------
dc245c
 lib/scsi-lowlevel.c                              | 77 +++++++++---------
dc245c
dc245c
diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h
dc245c
index 5693129..acdc936 100644
dc245c
--- a/include/scsi-lowlevel.h
dc245c
+++ b/include/scsi-lowlevel.h
dc245c
@@ -739,24 +739,24 @@ struct scsi_get_lba_status {
dc245c
 
dc245c
 struct scsi_op_timeout_descriptor {
dc245c
 	uint16_t descriptor_length;
dc245c
-	uint8_t reserved;
dc245c
 	uint8_t command_specific;
dc245c
 	uint32_t nominal_processing_timeout;
dc245c
 	uint32_t recommended_timeout;
dc245c
 
dc245c
 };
dc245c
 struct scsi_command_descriptor {
dc245c
-	uint8_t op_code;
dc245c
-	uint8_t reserved1;
dc245c
-	uint16_t service_action;
dc245c
-	uint8_t reserved2;
dc245c
-	uint8_t reserved3;
dc245c
-	uint16_t cdb_length;
dc245c
-	struct scsi_op_timeout_descriptor to[0];
dc245c
+	uint8_t opcode;
dc245c
+	uint16_t sa;
dc245c
+	uint8_t ctdp;
dc245c
+	uint8_t servactv;
dc245c
+	uint16_t cdb_len;
dc245c
+
dc245c
+	/* only present if CTDP==1 */
dc245c
+	struct scsi_op_timeout_descriptor to;
dc245c
 };
dc245c
 
dc245c
 struct scsi_report_supported_op_codes {
dc245c
-	uint32_t num_descriptors;
dc245c
+	int num_descriptors;
dc245c
 	struct scsi_command_descriptor descriptors[0];
dc245c
 };
dc245c
 
dc245c
diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c
dc245c
index 3c02ace..c091539 100644
dc245c
--- a/lib/scsi-lowlevel.c
dc245c
+++ b/lib/scsi-lowlevel.c
dc245c
@@ -806,12 +806,6 @@ scsi_persistentreservein_datain_unmarshall(struct scsi_task *task)
dc245c
 	}
dc245c
 }
dc245c
 
dc245c
-static inline int
dc245c
-scsi_maintenancein_return_timeouts(const struct scsi_task *task)
dc245c
-{
dc245c
-	return task->cdb[2] & 0x80;
dc245c
-}
dc245c
-
dc245c
 static inline uint8_t
dc245c
 scsi_maintenancein_sa(const struct scsi_task *task)
dc245c
 {
dc245c
@@ -841,9 +835,7 @@ static void *
dc245c
 scsi_maintenancein_datain_unmarshall(struct scsi_task *task)
dc245c
 {
dc245c
 	struct scsi_report_supported_op_codes *rsoc;
dc245c
-	struct scsi_command_descriptor *desc, *datain;
dc245c
-	uint32_t len, i;
dc245c
-	int return_timeouts, desc_size;
dc245c
+	int len, i;
dc245c
 
dc245c
 	switch (scsi_maintenancein_sa(task)) {
dc245c
 	case SCSI_REPORT_SUPPORTED_OP_CODES:
dc245c
@@ -852,37 +844,52 @@ scsi_maintenancein_datain_unmarshall(struct scsi_task *task)
dc245c
 		}
dc245c
 
dc245c
 		len = task_get_uint32(task, 0);
dc245c
-		rsoc = scsi_malloc(task, sizeof(struct scsi_report_supported_op_codes) + len);
dc245c
+		/* len / 8 is not always correct since if CTDP==1 then the
dc245c
+		 * descriptor is 20 bytes in size intead of 8.
dc245c
+		 * It doesnt matter here though since it just means we would
dc245c
+		 * allocate more descriptors at the end of the structure than
dc245c
+		 * we strictly need. This avoids having to traverse the
dc245c
+		 * datain buffer twice.
dc245c
+		 */
dc245c
+		rsoc = scsi_malloc(task,
dc245c
+			offsetof(struct scsi_report_supported_op_codes,
dc245c
+				 descriptors) +
dc245c
+			len / 8 * sizeof(struct scsi_command_descriptor));
dc245c
 		if (rsoc == NULL) {
dc245c
 			return NULL;
dc245c
 		}
dc245c
-		/* Does the descriptor include command timeout info? */
dc245c
-		return_timeouts = scsi_maintenancein_return_timeouts(task);
dc245c
 
dc245c
-		/* Size of descriptor depends on whether timeout included. */
dc245c
-		desc_size = sizeof (struct scsi_command_descriptor);
dc245c
-		if (return_timeouts) {
dc245c
-			desc_size += sizeof (struct scsi_op_timeout_descriptor);
dc245c
-		}
dc245c
-		rsoc->num_descriptors = len / desc_size;
dc245c
-
dc245c
-		desc = &rsoc->descriptors[0];
dc245c
-		datain = (struct scsi_command_descriptor *)&task->datain.data[4];
dc245c
-
dc245c
-		for (i=0; i < rsoc->num_descriptors; i++) {
dc245c
-			desc->op_code = datain->op_code;
dc245c
-			desc->service_action = ntohs(datain->service_action);
dc245c
-			desc->cdb_length =  ntohs(datain->cdb_length);
dc245c
-			if (return_timeouts) {
dc245c
-				desc->to[0].descriptor_length = ntohs(datain->to[0].descriptor_length);
dc245c
-				desc->to[0].command_specific = datain->to[0].command_specific;
dc245c
-				desc->to[0].nominal_processing_timeout
dc245c
-					= ntohl(datain->to[0].nominal_processing_timeout);
dc245c
-				desc->to[0].recommended_timeout
dc245c
-					= ntohl(datain->to[0].recommended_timeout);
dc245c
+		rsoc->num_descriptors = 0;
dc245c
+		i = 4;
dc245c
+		while (len >= 8) {
dc245c
+			struct scsi_command_descriptor *desc;
dc245c
+			
dc245c
+			desc = &rsoc->descriptors[rsoc->num_descriptors++];
dc245c
+			desc->opcode = task_get_uint8(task, i);
dc245c
+			desc->sa = task_get_uint16(task, i + 2);
dc245c
+			desc->ctdp = !!(task_get_uint8(task, i + 5) & 0x02);
dc245c
+			desc->servactv = !!(task_get_uint8(task, i + 5) & 0x01);
dc245c
+			desc->cdb_len = task_get_uint16(task, i + 6);
dc245c
+
dc245c
+			len -= 8;
dc245c
+			i += 8;
dc245c
+
dc245c
+			/* No tiemout description */
dc245c
+			if (!desc->ctdp) {
dc245c
+				continue;
dc245c
 			}
dc245c
-			desc = (struct scsi_command_descriptor *)((char *)desc + desc_size);
dc245c
-			datain = (struct scsi_command_descriptor *)((char *)datain + desc_size);
dc245c
+
dc245c
+			desc->to.descriptor_length =
dc245c
+				task_get_uint16(task, i);
dc245c
+			desc->to.command_specific =
dc245c
+				task_get_uint8(task, i + 3);
dc245c
+			desc->to.nominal_processing_timeout =
dc245c
+				task_get_uint32(task, i + 4);
dc245c
+			desc->to.recommended_timeout =
dc245c
+				task_get_uint32(task, i + 8);
dc245c
+
dc245c
+			len -= desc->to.descriptor_length + 2;
dc245c
+			i += desc->to.descriptor_length + 2;
dc245c
 		}
dc245c
 
dc245c
 		return rsoc;
dc245c