summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 @@
#include "sci_util.h"
#include "sci_environment.h"
-void scic_word_copy_with_swap(
- u32 *destination,
- u32 *source,
- u32 word_count)
-{
- while (word_count--) {
- *destination = SCIC_SWAP_DWORD(*source);
-
- source++;
- destination++;
- }
-}
-
void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, dma_addr_t phys_addr)
{
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 @@
#ifndef _SCI_UTIL_H_
#define _SCI_UTIL_H_
-#include <linux/string.h>
#include "scic_sds_request.h"
-/**
- * SCIC_SWAP_DWORD() -
- *
- * Normal byte swap macro
- */
-#define SCIC_SWAP_DWORD(x) \
- (\
- (((x) >> 24) & 0x000000FF) \
- | (((x) >> 8) & 0x0000FF00) \
- | (((x) << 8) & 0x00FF0000) \
- | (((x) << 24) & 0xFF000000) \
- )
-
#define SCIC_BUILD_DWORD(char_buffer) \
(\
((char_buffer)[0] << 24) \
@@ -87,17 +73,23 @@
((physical_addr) = (addr_lower) | ((u64)addr_upper) << 32)
/**
- * scic_word_copy_with_swap() - Copy the data from source to destination and
- * swap the bytes during the copy.
- * @destination: This parameter specifies the destination address to which the
- * data is to be copied.
- * @source: This parameter specifies the source address from which data is to
- * be copied.
- * @word_count: This parameter specifies the number of 32-bit words to copy and
- * byte swap.
+ * sci_swab32_cpy - convert between scsi and scu-hardware byte format
+ * @dest: receive the 4-byte endian swapped version of src
+ * @src: word aligned source buffer
*
+ * scu hardware handles SSP/SMP control, response, and unidentified
+ * frames in "big endian dword" order. Regardless of host endian this
+ * is always a swab32()-per-dword conversion of the standard definition,
+ * i.e. single byte fields swapped and multi-byte fields in little-
+ * endian
*/
-void scic_word_copy_with_swap(u32 *destination, u32 *source, u32 word_count);
+static inline void sci_swab32_cpy(void *_dest, void *_src, ssize_t word_cnt)
+{
+ u32 *dest = _dest, *src = _src;
+
+ while (--word_cnt >= 0)
+ dest[word_cnt] = swab32(src[word_cnt]);
+}
void *scic_request_get_virt_addr(struct scic_sds_request *sds_request,
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
{
enum sci_status result;
u32 *frame_words;
- struct sas_identify_frame *identify_frame;
+ struct sas_identify_frame iaf;
struct isci_phy *iphy = sci_phy->iphy;
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
frame_index,
(void **)&frame_words);
- if (result != SCI_SUCCESS) {
+ if (result != SCI_SUCCESS)
return result;
- }
-
- frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]);
- identify_frame = (struct sas_identify_frame *)frame_words;
- if (identify_frame->frame_type == 0) {
+ sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
+ if (iaf.frame_type == 0) {
u32 state;
- /* Byte swap the rest of the frame so we can make
- * a copy of the buffer
- */
- frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]);
- frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]);
- frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]);
- frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]);
- frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]);
-
- memcpy(&iphy->frame_rcvd.iaf, identify_frame, sizeof(*identify_frame));
-
- if (identify_frame->smp_tport) {
- /* We got the IAF for an expander PHY go to the final state since
- * there are no power requirements for expander phys.
+ memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
+ if (iaf.smp_tport) {
+ /* We got the IAF for an expander PHY go to the final
+ * state since there are no power requirements for
+ * expander phys.
*/
state = SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL;
} else {
- /* We got the IAF we can now go to the await spinup semaphore state */
+ /* We got the IAF we can now go to the await spinup
+ * semaphore state
+ */
state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER;
}
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
- state);
+ sci_base_state_machine_change_state(
+ &sci_phy->starting_substate_machine,
+ state);
result = SCI_SUCCESS;
} else
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
__func__,
frame_index);
- /* Regardless of the result release this frame since we are done with it */
scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy),
frame_index);
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
cmd_iu->task_attr = task->ssp_task.task_attr;
cmd_iu->_r_c = 0;
- scic_word_copy_with_swap(
- (u32 *)(&cmd_iu->cdb),
- (u32 *)task->ssp_task.cdb,
- sizeof(task->ssp_task.cdb) / sizeof(u32));
+ sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb,
+ sizeof(task->ssp_task.cdb) / sizeof(u32));
}
static 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(
* completed early.
*/
struct ssp_response_iu *resp = sci_req->response_buffer;
- scic_word_copy_with_swap(
- sci_req->response_buffer,
- sci_req->response_buffer,
- SSP_RESP_IU_MAX_SIZE / sizeof(u32));
+ ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
+
+ sci_swab32_cpy(sci_req->response_buffer,
+ sci_req->response_buffer,
+ word_cnt);
if (resp->status == 0) {
scic_sds_request_set_status(
@@ -1140,16 +1139,18 @@ scic_sds_request_started_state_tc_completion_handler(
break;
case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE):
- scic_word_copy_with_swap(
- sci_req->response_buffer,
- sci_req->response_buffer,
- SSP_RESP_IU_MAX_SIZE / sizeof(u32));
+ {
+ ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
- scic_sds_request_set_status(
- sci_req,
- SCU_TASK_DONE_CHECK_RESPONSE,
- SCI_FAILURE_IO_RESPONSE_VALID);
+ sci_swab32_cpy(sci_req->response_buffer,
+ sci_req->response_buffer,
+ word_cnt);
+
+ scic_sds_request_set_status(sci_req,
+ SCU_TASK_DONE_CHECK_RESPONSE,
+ SCI_FAILURE_IO_RESPONSE_VALID);
break;
+ }
case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
/*
@@ -1273,15 +1274,15 @@ scic_sds_request_started_state_frame_handler(struct scic_sds_request *sci_req,
if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) {
struct ssp_response_iu *resp_iu;
+ ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
status = scic_sds_unsolicited_frame_control_get_buffer(
&(scic_sds_request_get_controller(sci_req)->uf_control),
frame_index,
(void **)&resp_iu);
- scic_word_copy_with_swap(sci_req->response_buffer,
- (u32 *)resp_iu,
- SSP_RESP_IU_MAX_SIZE);
+ sci_swab32_cpy(sci_req->response_buffer,
+ resp_iu, word_cnt);
resp_iu = sci_req->response_buffer;
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,
struct scic_sds_remote_device *sci_dev;
struct scic_sds_port *sci_port;
struct scu_task_context *task_context;
+ ssize_t word_cnt = sizeof(struct smp_req) / sizeof(u32);
/* byte swap the smp request. */
- scic_word_copy_with_swap(sci_req->command_buffer,
- (u32 *)smp_req,
- sizeof(struct smp_req) / sizeof(u32));
+ sci_swab32_cpy(sci_req->command_buffer, smp_req,
+ word_cnt);
task_context = scic_sds_request_get_task_context(sci_req);
@@ -295,6 +295,7 @@ scic_sds_smp_request_await_response_frame_handler(
void *frame_header;
struct smp_resp *rsp_hdr;
u8 *usr_smp_buf = sci_req->response_buffer;
+ ssize_t word_cnt = SMP_RESP_HDR_SZ / sizeof(u32);
status = scic_sds_unsolicited_frame_control_get_header(
&(scic_sds_request_get_controller(sci_req)->uf_control),
@@ -302,9 +303,7 @@ scic_sds_smp_request_await_response_frame_handler(
&frame_header);
/* byte swap the header. */
- scic_word_copy_with_swap((u32 *)usr_smp_buf,
- frame_header,
- SMP_RESP_HDR_SZ / sizeof(u32));
+ sci_swab32_cpy(usr_smp_buf, frame_header, word_cnt);
rsp_hdr = (struct smp_resp *)usr_smp_buf;
@@ -316,11 +315,11 @@ scic_sds_smp_request_await_response_frame_handler(
frame_index,
&smp_resp);
- scic_word_copy_with_swap(
- (u32 *)(usr_smp_buf + SMP_RESP_HDR_SZ),
- smp_resp,
- (sizeof(struct smp_req) - SMP_RESP_HDR_SZ) /
- sizeof(u32));
+ word_cnt = (sizeof(struct smp_req) - SMP_RESP_HDR_SZ) /
+ sizeof(u32);
+
+ sci_swab32_cpy(usr_smp_buf + SMP_RESP_HDR_SZ,
+ smp_resp, word_cnt);
scic_sds_request_set_status(
sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS);
OpenPOWER on IntegriCloud