diff options
-rw-r--r-- | drivers/scsi/isci/core/intel_sas.h | 178 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_smp_request.c | 77 | ||||
-rw-r--r-- | drivers/scsi/isci/sas.h | 2 |
3 files changed, 34 insertions, 223 deletions
diff --git a/drivers/scsi/isci/core/intel_sas.h b/drivers/scsi/isci/core/intel_sas.h index d10c3824dbe4..58bf1fb9b2f5 100644 --- a/drivers/scsi/isci/core/intel_sas.h +++ b/drivers/scsi/isci/core/intel_sas.h | |||
@@ -198,184 +198,6 @@ struct sci_ssp_frame_header { | |||
198 | 198 | ||
199 | }; | 199 | }; |
200 | 200 | ||
201 | /** | ||
202 | * struct smp_response_header - This structure depicts the contents of the SAS | ||
203 | * SMP DISCOVER RESPONSE frame. For specific information on each of these | ||
204 | * individual fields please reference the SAS specification Link layer | ||
205 | * section on address frames. | ||
206 | * | ||
207 | * | ||
208 | */ | ||
209 | struct smp_response_header { | ||
210 | u8 smp_frame_type; /* byte 0 */ | ||
211 | u8 function; /* byte 1 */ | ||
212 | u8 function_result; /* byte 2 */ | ||
213 | u8 response_length; /* byte 3 */ | ||
214 | }; | ||
215 | |||
216 | |||
217 | /** | ||
218 | * struct smp_response_report_general - This structure depicts the SMP Report | ||
219 | * General for expander devices. It adheres to the SAS-2.1 specification. | ||
220 | * | ||
221 | * For specific information on each of these individual fields please reference | ||
222 | * the SAS specification Application layer section on SMP. | ||
223 | */ | ||
224 | struct smp_response_report_general { | ||
225 | u16 expander_change_count; /* byte 4-5 */ | ||
226 | u16 expander_route_indexes; /* byte 6-7 */ | ||
227 | |||
228 | u32 reserved_byte8:7; /* byte 8 bit 0-6 */ | ||
229 | u32 long_response:1; /* byte 8 bit 7 */ | ||
230 | |||
231 | u32 number_of_phys:8; /* byte 9 */ | ||
232 | |||
233 | u32 configurable_route_table:1; /* byte 10 */ | ||
234 | u32 configuring:1; | ||
235 | u32 configures_others:1; | ||
236 | u32 open_reject_retry_supported:1; | ||
237 | u32 stp_continue_awt:1; | ||
238 | u32 self_configuring:1; | ||
239 | u32 zone_configuring:1; | ||
240 | u32 table_to_table_supported:1; | ||
241 | |||
242 | u32 reserved_byte11:8; /* byte 11 */ | ||
243 | |||
244 | u32 enclosure_logical_identifier_high; /* byte 12-15 */ | ||
245 | u32 enclosure_logical_identifier_low; /* byte 16-19 */ | ||
246 | |||
247 | u32 reserved_byte20_23; | ||
248 | u32 reserved_byte24_27; | ||
249 | |||
250 | }; | ||
251 | |||
252 | struct smp_response_report_general_long { | ||
253 | struct smp_response_report_general sas1_1; | ||
254 | |||
255 | struct { | ||
256 | u16 reserved1; | ||
257 | u16 stp_bus_inactivity_time_limit; | ||
258 | u16 stp_max_connect_time_limit; | ||
259 | u16 stp_smp_i_t_nexus_loss_time; | ||
260 | |||
261 | u32 zoning_enabled:1; | ||
262 | u32 zoning_supported:1; | ||
263 | u32 physicaL_presence_asserted:1; | ||
264 | u32 zone_locked:1; | ||
265 | u32 reserved2:1; | ||
266 | u32 num_zone_groups:3; | ||
267 | u32 saving_zoning_enabled_supported:3; | ||
268 | u32 saving_zone_perms_table_supported:1; | ||
269 | u32 saving_zone_phy_info_supported:1; | ||
270 | u32 saving_zone_manager_password_supported:1; | ||
271 | u32 saving:1; | ||
272 | u32 reserved3:1; | ||
273 | u32 max_number_routed_sas_addresses:16; | ||
274 | |||
275 | struct sci_sas_address active_zone_manager_sas_address; | ||
276 | |||
277 | u16 zone_lock_inactivity_time_limit; | ||
278 | u16 reserved4; | ||
279 | |||
280 | u8 reserved5; | ||
281 | u8 first_enclosure_connector_element_index; | ||
282 | u8 number_of_enclosure_connector_element_indices; | ||
283 | u8 reserved6; | ||
284 | |||
285 | u32 reserved7:7; | ||
286 | u32 reduced_functionality:1; | ||
287 | u32 time_to_reduce_functionality:8; | ||
288 | u32 initial_time_to_reduce_functionality:8; | ||
289 | u8 max_reduced_functionality_time; | ||
290 | |||
291 | u16 last_self_config_status_descriptor_index; | ||
292 | u16 max_number_of_stored_self_config_status_descriptors; | ||
293 | |||
294 | u16 last_phy_event_list_descriptor_index; | ||
295 | u16 max_number_of_stored_phy_event_list_descriptors; | ||
296 | } sas2; | ||
297 | |||
298 | }; | ||
299 | |||
300 | /** | ||
301 | * struct smp_response_report_manufacturer_information - This structure depicts | ||
302 | * the SMP report manufacturer information for expander devices. It adheres | ||
303 | * to the SAS-2.1 specification. | ||
304 | * | ||
305 | * For specific information on each of these individual fields please reference | ||
306 | * the SAS specification Application layer section on SMP. | ||
307 | */ | ||
308 | struct smp_response_report_manufacturer_information { | ||
309 | u32 expander_change_count:16; /* bytes 4-5 */ | ||
310 | u32 reserved1:16; | ||
311 | |||
312 | u32 sas1_1_format:1; | ||
313 | u32 reserved2:31; | ||
314 | |||
315 | u8 vendor_id[8]; | ||
316 | u8 product_id[16]; | ||
317 | u8 product_revision_level[4]; | ||
318 | u8 component_vendor_id[8]; | ||
319 | u8 component_id[2]; | ||
320 | u8 component_revision_level; | ||
321 | u8 reserved3; | ||
322 | u8 vendor_specific[8]; | ||
323 | |||
324 | }; | ||
325 | |||
326 | /** | ||
327 | * struct smp_response_report_phy_sata - This structure depicts the contents of | ||
328 | * the SAS SMP REPORT PHY SATA frame. For specific information on each of | ||
329 | * these individual fields please reference the SAS specification Link layer | ||
330 | * section on address frames. | ||
331 | * | ||
332 | * | ||
333 | */ | ||
334 | struct smp_response_report_phy_sata { | ||
335 | u32 ignored_byte_4_7; /* bytes 4-7 */ | ||
336 | |||
337 | u32 affiliations_valid:1; | ||
338 | u32 affiliations_supported:1; | ||
339 | u32 reserved_byte11:6; /* byte 11 */ | ||
340 | u32 ignored_byte10:8; /* byte 10 */ | ||
341 | u32 phy_identifier:8; /* byte 9 */ | ||
342 | u32 reserved_byte_8:8; /* byte 8 */ | ||
343 | |||
344 | u32 reserved_12_15; | ||
345 | u32 stp_sas_address[2]; | ||
346 | u8 device_to_host_fis[20]; | ||
347 | u32 reserved_44_47; | ||
348 | u32 affiliated_stp_initiator_sas_address[2]; | ||
349 | |||
350 | }; | ||
351 | |||
352 | #define SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH 1016 | ||
353 | struct smp_response_vendor_specific { | ||
354 | u8 response_bytes[SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH]; | ||
355 | }; | ||
356 | |||
357 | union smp_response_body { | ||
358 | struct smp_response_report_general report_general; | ||
359 | struct smp_response_report_manufacturer_information report_manufacturer_information; | ||
360 | struct smp_response_report_phy_sata report_phy_sata; | ||
361 | struct smp_response_vendor_specific vendor_specific_response; | ||
362 | }; | ||
363 | |||
364 | /** | ||
365 | * struct smp_response - This structure simply unionizes the existing response | ||
366 | * structures into a common response type. | ||
367 | * | ||
368 | * | ||
369 | */ | ||
370 | struct smp_response { | ||
371 | struct smp_response_header header; | ||
372 | |||
373 | union smp_response_body response; | ||
374 | |||
375 | }; | ||
376 | |||
377 | #define SMP_FRAME_TYPE_REQUEST 0x40 | ||
378 | #define SMP_FRAME_TYPE_RESPONSE 0x41 | ||
379 | 201 | ||
380 | #define PHY_OPERATION_NOP 0x00 | 202 | #define PHY_OPERATION_NOP 0x00 |
381 | #define PHY_OPERATION_LINK_RESET 0x01 | 203 | #define PHY_OPERATION_LINK_RESET 0x01 |
diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.c b/drivers/scsi/isci/core/scic_sds_smp_request.c index 7d7bd2e29d8f..e6cfcbba9f9d 100644 --- a/drivers/scsi/isci/core/scic_sds_smp_request.c +++ b/drivers/scsi/isci/core/scic_sds_smp_request.c | |||
@@ -53,6 +53,7 @@ | |||
53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
54 | */ | 54 | */ |
55 | 55 | ||
56 | #include <scsi/sas.h> | ||
56 | #include "sas.h" | 57 | #include "sas.h" |
57 | #include "intel_sas.h" | 58 | #include "intel_sas.h" |
58 | #include "sci_base_state_machine.h" | 59 | #include "sci_base_state_machine.h" |
@@ -79,7 +80,7 @@ u32 scic_sds_smp_request_get_object_size(void) | |||
79 | { | 80 | { |
80 | return sizeof(struct scic_sds_request) | 81 | return sizeof(struct scic_sds_request) |
81 | + sizeof(struct smp_req) | 82 | + sizeof(struct smp_req) |
82 | + sizeof(struct smp_response) | 83 | + sizeof(struct smp_resp) |
83 | + sizeof(struct scu_task_context) | 84 | + sizeof(struct scu_task_context) |
84 | + SMP_CACHE_BYTES; | 85 | + SMP_CACHE_BYTES; |
85 | } | 86 | } |
@@ -111,7 +112,7 @@ u32 scic_sds_smp_request_get_object_size(void) | |||
111 | #define scic_sds_smp_request_get_task_context_buffer(memory) \ | 112 | #define scic_sds_smp_request_get_task_context_buffer(memory) \ |
112 | ((struct scu_task_context *)(\ | 113 | ((struct scu_task_context *)(\ |
113 | ((char *)(scic_sds_smp_request_get_response_buffer(memory))) \ | 114 | ((char *)(scic_sds_smp_request_get_response_buffer(memory))) \ |
114 | + sizeof(struct smp_response) \ | 115 | + sizeof(struct smp_resp) \ |
115 | )) | 116 | )) |
116 | 117 | ||
117 | 118 | ||
@@ -271,8 +272,8 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req, | |||
271 | task_context->response_iu_lower = 0; | 272 | task_context->response_iu_lower = 0; |
272 | } | 273 | } |
273 | 274 | ||
274 | /** | 275 | /* |
275 | * This method processes an unsolicited frame while the SMP request is waiting | 276 | * This function processes an unsolicited frame while the SMP request is waiting |
276 | * for a response frame. It will copy the response data, release the | 277 | * for a response frame. It will copy the response data, release the |
277 | * unsolicited frame, and transition the request to the | 278 | * unsolicited frame, and transition the request to the |
278 | * SCI_BASE_REQUEST_STATE_COMPLETED state. | 279 | * SCI_BASE_REQUEST_STATE_COMPLETED state. |
@@ -281,63 +282,52 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req, | |||
281 | * @frame_index: This parameter indicates the unsolicited frame index that | 282 | * @frame_index: This parameter indicates the unsolicited frame index that |
282 | * should contain the response. | 283 | * should contain the response. |
283 | * | 284 | * |
284 | * This method returns an indication of whether the response frame was handled | 285 | * This function returns an indication of whether the response frame was handled |
285 | * successfully or not. SCI_SUCCESS Currently this value is always returned and | 286 | * successfully or not. SCI_SUCCESS Currently this value is always returned and |
286 | * indicates successful processing of the TC response. | 287 | * indicates successful processing of the TC response. |
287 | */ | 288 | */ |
288 | static enum sci_status scic_sds_smp_request_await_response_frame_handler( | 289 | static enum sci_status |
289 | struct scic_sds_request *sci_req, | 290 | scic_sds_smp_request_await_response_frame_handler( |
290 | u32 frame_index) | 291 | struct scic_sds_request *sci_req, |
292 | u32 frame_index) | ||
291 | { | 293 | { |
292 | enum sci_status status; | 294 | enum sci_status status; |
293 | void *frame_header; | 295 | void *frame_header; |
294 | struct smp_response_header *rsp_hdr; | 296 | struct smp_resp *rsp_hdr; |
295 | u8 *user_smp_buffer = sci_req->response_buffer; | 297 | u8 *usr_smp_buf = sci_req->response_buffer; |
296 | 298 | ||
297 | status = scic_sds_unsolicited_frame_control_get_header( | 299 | status = scic_sds_unsolicited_frame_control_get_header( |
298 | &(scic_sds_request_get_controller(sci_req)->uf_control), | 300 | &(scic_sds_request_get_controller(sci_req)->uf_control), |
299 | frame_index, | 301 | frame_index, |
300 | &frame_header | 302 | &frame_header); |
301 | ); | ||
302 | 303 | ||
303 | /* byte swap the header. */ | 304 | /* byte swap the header. */ |
304 | scic_word_copy_with_swap( | 305 | scic_word_copy_with_swap((u32 *)usr_smp_buf, |
305 | (u32 *)user_smp_buffer, | 306 | frame_header, |
306 | frame_header, | 307 | SMP_RESP_HDR_SZ / sizeof(u32)); |
307 | sizeof(struct smp_response_header) / sizeof(u32) | ||
308 | ); | ||
309 | rsp_hdr = (struct smp_response_header *)user_smp_buffer; | ||
310 | 308 | ||
311 | if (rsp_hdr->smp_frame_type == SMP_FRAME_TYPE_RESPONSE) { | 309 | rsp_hdr = (struct smp_resp *)usr_smp_buf; |
312 | void *smp_response_buffer; | 310 | |
311 | if (rsp_hdr->frame_type == SMP_RESPONSE) { | ||
312 | void *smp_resp; | ||
313 | 313 | ||
314 | status = scic_sds_unsolicited_frame_control_get_buffer( | 314 | status = scic_sds_unsolicited_frame_control_get_buffer( |
315 | &(scic_sds_request_get_controller(sci_req)->uf_control), | 315 | &(scic_sds_request_get_controller(sci_req)->uf_control), |
316 | frame_index, | 316 | frame_index, |
317 | &smp_response_buffer | 317 | &smp_resp); |
318 | ); | ||
319 | 318 | ||
320 | scic_word_copy_with_swap( | 319 | scic_word_copy_with_swap( |
321 | (u32 *)(user_smp_buffer + sizeof(struct smp_response_header)), | 320 | (u32 *)(usr_smp_buf + SMP_RESP_HDR_SZ), |
322 | smp_response_buffer, | 321 | smp_resp, |
323 | sizeof(union smp_response_body) / sizeof(u32) | 322 | (sizeof(struct smp_req) - SMP_RESP_HDR_SZ) / |
324 | ); | 323 | sizeof(u32)); |
325 | /* | ||
326 | * Don't need to copy to user space. User instead will refer to | ||
327 | * core request's response buffer. */ | ||
328 | |||
329 | /* | ||
330 | * copy the smp response to framework smp request's response buffer. | ||
331 | * scic_sds_smp_request_copy_response(sci_req); */ | ||
332 | 324 | ||
333 | scic_sds_request_set_status( | 325 | scic_sds_request_set_status( |
334 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS | 326 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS); |
335 | ); | ||
336 | 327 | ||
337 | sci_base_state_machine_change_state( | 328 | sci_base_state_machine_change_state( |
338 | &sci_req->started_substate_machine, | 329 | &sci_req->started_substate_machine, |
339 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION | 330 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION); |
340 | ); | ||
341 | } else { | 331 | } else { |
342 | /* This was not a response frame why did it get forwarded? */ | 332 | /* This was not a response frame why did it get forwarded? */ |
343 | dev_err(scic_to_dev(sci_req->owning_controller), | 333 | dev_err(scic_to_dev(sci_req->owning_controller), |
@@ -346,23 +336,20 @@ static enum sci_status scic_sds_smp_request_await_response_frame_handler( | |||
346 | __func__, | 336 | __func__, |
347 | sci_req, | 337 | sci_req, |
348 | frame_index, | 338 | frame_index, |
349 | rsp_hdr->smp_frame_type); | 339 | rsp_hdr->frame_type); |
350 | 340 | ||
351 | scic_sds_request_set_status( | 341 | scic_sds_request_set_status( |
352 | sci_req, | 342 | sci_req, |
353 | SCU_TASK_DONE_SMP_FRM_TYPE_ERR, | 343 | SCU_TASK_DONE_SMP_FRM_TYPE_ERR, |
354 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR | 344 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); |
355 | ); | ||
356 | 345 | ||
357 | sci_base_state_machine_change_state( | 346 | sci_base_state_machine_change_state( |
358 | &sci_req->state_machine, | 347 | &sci_req->state_machine, |
359 | SCI_BASE_REQUEST_STATE_COMPLETED | 348 | SCI_BASE_REQUEST_STATE_COMPLETED); |
360 | ); | ||
361 | } | 349 | } |
362 | 350 | ||
363 | scic_sds_controller_release_frame( | 351 | scic_sds_controller_release_frame(sci_req->owning_controller, |
364 | sci_req->owning_controller, frame_index | 352 | frame_index); |
365 | ); | ||
366 | 353 | ||
367 | return SCI_SUCCESS; | 354 | return SCI_SUCCESS; |
368 | } | 355 | } |
diff --git a/drivers/scsi/isci/sas.h b/drivers/scsi/isci/sas.h index f5d7e6a51070..83eab4671958 100644 --- a/drivers/scsi/isci/sas.h +++ b/drivers/scsi/isci/sas.h | |||
@@ -213,4 +213,6 @@ struct smp_req { | |||
213 | }; | 213 | }; |
214 | } __packed; | 214 | } __packed; |
215 | 215 | ||
216 | #define SMP_RESP_HDR_SZ 4 | ||
217 | |||
216 | #endif | 218 | #endif |