Use Linux native swab32() call instead of SCIC_SWAP_DWORD().
We need to swab() because the hardware munges the data into a
"big-endian dword" stream which is byte-swapped from the sas definition
regardless of host endian.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
#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;
#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) \
((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);
{
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(
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),
__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);
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)
* 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(
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):
/*
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;
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);
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),
&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;
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);