aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/isci/core/sci_util.c13
-rw-r--r--drivers/scsi/isci/core/sci_util.h38
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.c40
-rw-r--r--drivers/scsi/isci/core/scic_sds_request.c39
-rw-r--r--drivers/scsi/isci/core/scic_sds_smp_request.c21
5 files changed, 60 insertions, 91 deletions
diff --git a/drivers/scsi/isci/core/sci_util.c b/drivers/scsi/isci/core/sci_util.c
index ebf0ed919a9f..0c75d14240a1 100644
--- a/drivers/scsi/isci/core/sci_util.c
+++ b/drivers/scsi/isci/core/sci_util.c
@@ -57,19 +57,6 @@
57#include "sci_util.h" 57#include "sci_util.h"
58#include "sci_environment.h" 58#include "sci_environment.h"
59 59
60void scic_word_copy_with_swap(
61 u32 *destination,
62 u32 *source,
63 u32 word_count)
64{
65 while (word_count--) {
66 *destination = SCIC_SWAP_DWORD(*source);
67
68 source++;
69 destination++;
70 }
71}
72
73void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, dma_addr_t phys_addr) 60void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, dma_addr_t phys_addr)
74{ 61{
75 struct isci_request *ireq = sci_req->ireq; 62 struct isci_request *ireq = sci_req->ireq;
diff --git a/drivers/scsi/isci/core/sci_util.h b/drivers/scsi/isci/core/sci_util.h
index b6f43e27c615..4e9c3189cf95 100644
--- a/drivers/scsi/isci/core/sci_util.h
+++ b/drivers/scsi/isci/core/sci_util.h
@@ -56,22 +56,8 @@
56#ifndef _SCI_UTIL_H_ 56#ifndef _SCI_UTIL_H_
57#define _SCI_UTIL_H_ 57#define _SCI_UTIL_H_
58 58
59#include <linux/string.h>
60#include "scic_sds_request.h" 59#include "scic_sds_request.h"
61 60
62/**
63 * SCIC_SWAP_DWORD() -
64 *
65 * Normal byte swap macro
66 */
67#define SCIC_SWAP_DWORD(x) \
68 (\
69 (((x) >> 24) & 0x000000FF) \
70 | (((x) >> 8) & 0x0000FF00) \
71 | (((x) << 8) & 0x00FF0000) \
72 | (((x) << 24) & 0xFF000000) \
73 )
74
75#define SCIC_BUILD_DWORD(char_buffer) \ 61#define SCIC_BUILD_DWORD(char_buffer) \
76 (\ 62 (\
77 ((char_buffer)[0] << 24) \ 63 ((char_buffer)[0] << 24) \
@@ -87,17 +73,23 @@
87 ((physical_addr) = (addr_lower) | ((u64)addr_upper) << 32) 73 ((physical_addr) = (addr_lower) | ((u64)addr_upper) << 32)
88 74
89/** 75/**
90 * scic_word_copy_with_swap() - Copy the data from source to destination and 76 * sci_swab32_cpy - convert between scsi and scu-hardware byte format
91 * swap the bytes during the copy. 77 * @dest: receive the 4-byte endian swapped version of src
92 * @destination: This parameter specifies the destination address to which the 78 * @src: word aligned source buffer
93 * data is to be copied.
94 * @source: This parameter specifies the source address from which data is to
95 * be copied.
96 * @word_count: This parameter specifies the number of 32-bit words to copy and
97 * byte swap.
98 * 79 *
80 * scu hardware handles SSP/SMP control, response, and unidentified
81 * frames in "big endian dword" order. Regardless of host endian this
82 * is always a swab32()-per-dword conversion of the standard definition,
83 * i.e. single byte fields swapped and multi-byte fields in little-
84 * endian
99 */ 85 */
100void scic_word_copy_with_swap(u32 *destination, u32 *source, u32 word_count); 86static inline void sci_swab32_cpy(void *_dest, void *_src, ssize_t word_cnt)
87{
88 u32 *dest = _dest, *src = _src;
89
90 while (--word_cnt >= 0)
91 dest[word_cnt] = swab32(src[word_cnt]);
92}
101 93
102void *scic_request_get_virt_addr(struct scic_sds_request *sds_request, 94void *scic_request_get_virt_addr(struct scic_sds_request *sds_request,
103 dma_addr_t phys_addr); 95 dma_addr_t phys_addr);
diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c
index b9d6fc7e8ae0..18dc14a8f0ba 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.c
+++ b/drivers/scsi/isci/core/scic_sds_phy.c
@@ -1098,7 +1098,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
1098{ 1098{
1099 enum sci_status result; 1099 enum sci_status result;
1100 u32 *frame_words; 1100 u32 *frame_words;
1101 struct sas_identify_frame *identify_frame; 1101 struct sas_identify_frame iaf;
1102 struct isci_phy *iphy = sci_phy->iphy; 1102 struct isci_phy *iphy = sci_phy->iphy;
1103 1103
1104 result = scic_sds_unsolicited_frame_control_get_header( 1104 result = scic_sds_unsolicited_frame_control_get_header(
@@ -1106,38 +1106,29 @@ static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
1106 frame_index, 1106 frame_index,
1107 (void **)&frame_words); 1107 (void **)&frame_words);
1108 1108
1109 if (result != SCI_SUCCESS) { 1109 if (result != SCI_SUCCESS)
1110 return result; 1110 return result;
1111 }
1112
1113 frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]);
1114 identify_frame = (struct sas_identify_frame *)frame_words;
1115 1111
1116 if (identify_frame->frame_type == 0) { 1112 sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
1113 if (iaf.frame_type == 0) {
1117 u32 state; 1114 u32 state;
1118 1115
1119 /* Byte swap the rest of the frame so we can make 1116 memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
1120 * a copy of the buffer 1117 if (iaf.smp_tport) {
1121 */ 1118 /* We got the IAF for an expander PHY go to the final
1122 frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]); 1119 * state since there are no power requirements for
1123 frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]); 1120 * expander phys.
1124 frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]);
1125 frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]);
1126 frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]);
1127
1128 memcpy(&iphy->frame_rcvd.iaf, identify_frame, sizeof(*identify_frame));
1129
1130 if (identify_frame->smp_tport) {
1131 /* We got the IAF for an expander PHY go to the final state since
1132 * there are no power requirements for expander phys.
1133 */ 1121 */
1134 state = SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL; 1122 state = SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL;
1135 } else { 1123 } else {
1136 /* We got the IAF we can now go to the await spinup semaphore state */ 1124 /* We got the IAF we can now go to the await spinup
1125 * semaphore state
1126 */
1137 state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER; 1127 state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER;
1138 } 1128 }
1139 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine, 1129 sci_base_state_machine_change_state(
1140 state); 1130 &sci_phy->starting_substate_machine,
1131 state);
1141 result = SCI_SUCCESS; 1132 result = SCI_SUCCESS;
1142 } else 1133 } else
1143 dev_warn(sciphy_to_dev(sci_phy), 1134 dev_warn(sciphy_to_dev(sci_phy),
@@ -1146,7 +1137,6 @@ static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
1146 __func__, 1137 __func__,
1147 frame_index); 1138 frame_index);
1148 1139
1149 /* Regardless of the result release this frame since we are done with it */
1150 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy), 1140 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy),
1151 frame_index); 1141 frame_index);
1152 1142
diff --git a/drivers/scsi/isci/core/scic_sds_request.c b/drivers/scsi/isci/core/scic_sds_request.c
index 8eb3c7e59ec5..e9c69d451f43 100644
--- a/drivers/scsi/isci/core/scic_sds_request.c
+++ b/drivers/scsi/isci/core/scic_sds_request.c
@@ -362,10 +362,8 @@ static void scic_sds_io_request_build_ssp_command_iu(struct scic_sds_request *sc
362 cmd_iu->task_attr = task->ssp_task.task_attr; 362 cmd_iu->task_attr = task->ssp_task.task_attr;
363 cmd_iu->_r_c = 0; 363 cmd_iu->_r_c = 0;
364 364
365 scic_word_copy_with_swap( 365 sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb,
366 (u32 *)(&cmd_iu->cdb), 366 sizeof(task->ssp_task.cdb) / sizeof(u32));
367 (u32 *)task->ssp_task.cdb,
368 sizeof(task->ssp_task.cdb) / sizeof(u32));
369} 367}
370 368
371static void scic_sds_task_request_build_ssp_task_iu(struct scic_sds_request *sci_req) 369static void scic_sds_task_request_build_ssp_task_iu(struct scic_sds_request *sci_req)
@@ -1120,10 +1118,11 @@ scic_sds_request_started_state_tc_completion_handler(
1120 * completed early. 1118 * completed early.
1121 */ 1119 */
1122 struct ssp_response_iu *resp = sci_req->response_buffer; 1120 struct ssp_response_iu *resp = sci_req->response_buffer;
1123 scic_word_copy_with_swap( 1121 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
1124 sci_req->response_buffer, 1122
1125 sci_req->response_buffer, 1123 sci_swab32_cpy(sci_req->response_buffer,
1126 SSP_RESP_IU_MAX_SIZE / sizeof(u32)); 1124 sci_req->response_buffer,
1125 word_cnt);
1127 1126
1128 if (resp->status == 0) { 1127 if (resp->status == 0) {
1129 scic_sds_request_set_status( 1128 scic_sds_request_set_status(
@@ -1140,16 +1139,18 @@ scic_sds_request_started_state_tc_completion_handler(
1140 break; 1139 break;
1141 1140
1142 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE): 1141 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE):
1143 scic_word_copy_with_swap( 1142 {
1144 sci_req->response_buffer, 1143 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
1145 sci_req->response_buffer,
1146 SSP_RESP_IU_MAX_SIZE / sizeof(u32));
1147 1144
1148 scic_sds_request_set_status( 1145 sci_swab32_cpy(sci_req->response_buffer,
1149 sci_req, 1146 sci_req->response_buffer,
1150 SCU_TASK_DONE_CHECK_RESPONSE, 1147 word_cnt);
1151 SCI_FAILURE_IO_RESPONSE_VALID); 1148
1149 scic_sds_request_set_status(sci_req,
1150 SCU_TASK_DONE_CHECK_RESPONSE,
1151 SCI_FAILURE_IO_RESPONSE_VALID);
1152 break; 1152 break;
1153 }
1153 1154
1154 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR): 1155 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
1155 /* 1156 /*
@@ -1273,15 +1274,15 @@ scic_sds_request_started_state_frame_handler(struct scic_sds_request *sci_req,
1273 1274
1274 if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) { 1275 if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) {
1275 struct ssp_response_iu *resp_iu; 1276 struct ssp_response_iu *resp_iu;
1277 ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
1276 1278
1277 status = scic_sds_unsolicited_frame_control_get_buffer( 1279 status = scic_sds_unsolicited_frame_control_get_buffer(
1278 &(scic_sds_request_get_controller(sci_req)->uf_control), 1280 &(scic_sds_request_get_controller(sci_req)->uf_control),
1279 frame_index, 1281 frame_index,
1280 (void **)&resp_iu); 1282 (void **)&resp_iu);
1281 1283
1282 scic_word_copy_with_swap(sci_req->response_buffer, 1284 sci_swab32_cpy(sci_req->response_buffer,
1283 (u32 *)resp_iu, 1285 resp_iu, word_cnt);
1284 SSP_RESP_IU_MAX_SIZE);
1285 1286
1286 resp_iu = sci_req->response_buffer; 1287 resp_iu = sci_req->response_buffer;
1287 1288
diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.c b/drivers/scsi/isci/core/scic_sds_smp_request.c
index e6cfcbba9f9d..bca51a72ee86 100644
--- a/drivers/scsi/isci/core/scic_sds_smp_request.c
+++ b/drivers/scsi/isci/core/scic_sds_smp_request.c
@@ -164,11 +164,11 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
164 struct scic_sds_remote_device *sci_dev; 164 struct scic_sds_remote_device *sci_dev;
165 struct scic_sds_port *sci_port; 165 struct scic_sds_port *sci_port;
166 struct scu_task_context *task_context; 166 struct scu_task_context *task_context;
167 ssize_t word_cnt = sizeof(struct smp_req) / sizeof(u32);
167 168
168 /* byte swap the smp request. */ 169 /* byte swap the smp request. */
169 scic_word_copy_with_swap(sci_req->command_buffer, 170 sci_swab32_cpy(sci_req->command_buffer, smp_req,
170 (u32 *)smp_req, 171 word_cnt);
171 sizeof(struct smp_req) / sizeof(u32));
172 172
173 task_context = scic_sds_request_get_task_context(sci_req); 173 task_context = scic_sds_request_get_task_context(sci_req);
174 174
@@ -295,6 +295,7 @@ scic_sds_smp_request_await_response_frame_handler(
295 void *frame_header; 295 void *frame_header;
296 struct smp_resp *rsp_hdr; 296 struct smp_resp *rsp_hdr;
297 u8 *usr_smp_buf = sci_req->response_buffer; 297 u8 *usr_smp_buf = sci_req->response_buffer;
298 ssize_t word_cnt = SMP_RESP_HDR_SZ / sizeof(u32);
298 299
299 status = scic_sds_unsolicited_frame_control_get_header( 300 status = scic_sds_unsolicited_frame_control_get_header(
300 &(scic_sds_request_get_controller(sci_req)->uf_control), 301 &(scic_sds_request_get_controller(sci_req)->uf_control),
@@ -302,9 +303,7 @@ scic_sds_smp_request_await_response_frame_handler(
302 &frame_header); 303 &frame_header);
303 304
304 /* byte swap the header. */ 305 /* byte swap the header. */
305 scic_word_copy_with_swap((u32 *)usr_smp_buf, 306 sci_swab32_cpy(usr_smp_buf, frame_header, word_cnt);
306 frame_header,
307 SMP_RESP_HDR_SZ / sizeof(u32));
308 307
309 rsp_hdr = (struct smp_resp *)usr_smp_buf; 308 rsp_hdr = (struct smp_resp *)usr_smp_buf;
310 309
@@ -316,11 +315,11 @@ scic_sds_smp_request_await_response_frame_handler(
316 frame_index, 315 frame_index,
317 &smp_resp); 316 &smp_resp);
318 317
319 scic_word_copy_with_swap( 318 word_cnt = (sizeof(struct smp_req) - SMP_RESP_HDR_SZ) /
320 (u32 *)(usr_smp_buf + SMP_RESP_HDR_SZ), 319 sizeof(u32);
321 smp_resp, 320
322 (sizeof(struct smp_req) - SMP_RESP_HDR_SZ) / 321 sci_swab32_cpy(usr_smp_buf + SMP_RESP_HDR_SZ,
323 sizeof(u32)); 322 smp_resp, word_cnt);
324 323
325 scic_sds_request_set_status( 324 scic_sds_request_set_status(
326 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS); 325 sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS);