diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/core/sci_util.c | 13 | ||||
-rw-r--r-- | drivers/scsi/isci/core/sci_util.h | 38 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_phy.c | 40 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_request.c | 39 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_smp_request.c | 21 |
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 | ||
60 | void 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 | |||
73 | void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, dma_addr_t phys_addr) | 60 | void *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 | */ |
100 | void scic_word_copy_with_swap(u32 *destination, u32 *source, u32 word_count); | 86 | static 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 | ||
102 | void *scic_request_get_virt_addr(struct scic_sds_request *sds_request, | 94 | void *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 | ||
371 | static void scic_sds_task_request_build_ssp_task_iu(struct scic_sds_request *sci_req) | 369 | 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( | |||
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); |