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

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