diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-05-10 05:28:45 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:47 -0400 |
commit | f1f52e75939b56c40b3d153ae99faf2720250242 (patch) | |
tree | 9c5ba4f8bb6a589c6a038dac5bbba280f9de3ebe /drivers/scsi/isci/request.h | |
parent | 3bff9d54ecba84e538da822349a9a6fd6e534539 (diff) |
isci: uplevel request infrastructure
* Consolidate tiny header files
* Move files out of core/ (drop core/scic_sds_ prefix)
* Merge core/scic_sds_request.[ch] into request.[ch]
* Cleanup request.c namespace (clean forward declarations and global
namespace pollution)
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/request.h')
-rw-r--r-- | drivers/scsi/isci/request.h | 442 |
1 files changed, 426 insertions, 16 deletions
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index 06786ece9bb2..932ea767c8c2 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h | |||
@@ -58,7 +58,8 @@ | |||
58 | 58 | ||
59 | #include "isci.h" | 59 | #include "isci.h" |
60 | #include "host.h" | 60 | #include "host.h" |
61 | #include "scic_sds_request.h" | 61 | #include "scu_task_context.h" |
62 | #include "stp_request.h" | ||
62 | 63 | ||
63 | /** | 64 | /** |
64 | * struct isci_request_status - This enum defines the possible states of an I/O | 65 | * struct isci_request_status - This enum defines the possible states of an I/O |
@@ -82,6 +83,151 @@ enum task_type { | |||
82 | tmf_task = 1 | 83 | tmf_task = 1 |
83 | }; | 84 | }; |
84 | 85 | ||
86 | enum sci_request_protocol { | ||
87 | SCIC_NO_PROTOCOL, | ||
88 | SCIC_SMP_PROTOCOL, | ||
89 | SCIC_SSP_PROTOCOL, | ||
90 | SCIC_STP_PROTOCOL | ||
91 | }; /* XXX remove me, use sas_task.dev instead */; | ||
92 | |||
93 | struct scic_sds_request { | ||
94 | /** | ||
95 | * This field contains the information for the base request state machine. | ||
96 | */ | ||
97 | struct sci_base_state_machine state_machine; | ||
98 | |||
99 | /** | ||
100 | * This field simply points to the controller to which this IO request | ||
101 | * is associated. | ||
102 | */ | ||
103 | struct scic_sds_controller *owning_controller; | ||
104 | |||
105 | /** | ||
106 | * This field simply points to the remote device to which this IO request | ||
107 | * is associated. | ||
108 | */ | ||
109 | struct scic_sds_remote_device *target_device; | ||
110 | |||
111 | /** | ||
112 | * This field is utilized to determine if the SCI user is managing | ||
113 | * the IO tag for this request or if the core is managing it. | ||
114 | */ | ||
115 | bool was_tag_assigned_by_user; | ||
116 | |||
117 | /** | ||
118 | * This field indicates the IO tag for this request. The IO tag is | ||
119 | * comprised of the task_index and a sequence count. The sequence count | ||
120 | * is utilized to help identify tasks from one life to another. | ||
121 | */ | ||
122 | u16 io_tag; | ||
123 | |||
124 | /** | ||
125 | * This field specifies the protocol being utilized for this | ||
126 | * IO request. | ||
127 | */ | ||
128 | enum sci_request_protocol protocol; | ||
129 | |||
130 | /** | ||
131 | * This field indicates the completion status taken from the SCUs | ||
132 | * completion code. It indicates the completion result for the SCU hardware. | ||
133 | */ | ||
134 | u32 scu_status; | ||
135 | |||
136 | /** | ||
137 | * This field indicates the completion status returned to the SCI user. It | ||
138 | * indicates the users view of the io request completion. | ||
139 | */ | ||
140 | u32 sci_status; | ||
141 | |||
142 | /** | ||
143 | * This field contains the value to be utilized when posting (e.g. Post_TC, | ||
144 | * Post_TC_Abort) this request to the silicon. | ||
145 | */ | ||
146 | u32 post_context; | ||
147 | |||
148 | struct scu_task_context *task_context_buffer; | ||
149 | struct scu_task_context tc ____cacheline_aligned; | ||
150 | |||
151 | /* could be larger with sg chaining */ | ||
152 | #define SCU_SGL_SIZE ((SCU_IO_REQUEST_SGE_COUNT + 1) / 2) | ||
153 | struct scu_sgl_element_pair sg_table[SCU_SGL_SIZE] __attribute__ ((aligned(32))); | ||
154 | |||
155 | /** | ||
156 | * This field indicates if this request is a task management request or | ||
157 | * normal IO request. | ||
158 | */ | ||
159 | bool is_task_management_request; | ||
160 | |||
161 | /** | ||
162 | * This field indicates that this request contains an initialized started | ||
163 | * substate machine. | ||
164 | */ | ||
165 | bool has_started_substate_machine; | ||
166 | |||
167 | /** | ||
168 | * This field is a pointer to the stored rx frame data. It is used in STP | ||
169 | * internal requests and SMP response frames. If this field is non-NULL the | ||
170 | * saved frame must be released on IO request completion. | ||
171 | * | ||
172 | * @todo In the future do we want to keep a list of RX frame buffers? | ||
173 | */ | ||
174 | u32 saved_rx_frame_index; | ||
175 | |||
176 | /** | ||
177 | * This field specifies the data necessary to manage the sub-state | ||
178 | * machine executed while in the SCI_BASE_REQUEST_STATE_STARTED state. | ||
179 | */ | ||
180 | struct sci_base_state_machine started_substate_machine; | ||
181 | |||
182 | /** | ||
183 | * This field specifies the current state handlers in place for this | ||
184 | * IO Request object. This field is updated each time the request | ||
185 | * changes state. | ||
186 | */ | ||
187 | const struct scic_sds_io_request_state_handler *state_handlers; | ||
188 | |||
189 | /** | ||
190 | * This field in the recorded device sequence for the io request. This is | ||
191 | * recorded during the build operation and is compared in the start | ||
192 | * operation. If the sequence is different then there was a change of | ||
193 | * devices from the build to start operations. | ||
194 | */ | ||
195 | u8 device_sequence; | ||
196 | |||
197 | union { | ||
198 | struct { | ||
199 | union { | ||
200 | struct ssp_cmd_iu cmd; | ||
201 | struct ssp_task_iu tmf; | ||
202 | }; | ||
203 | union { | ||
204 | struct ssp_response_iu rsp; | ||
205 | u8 rsp_buf[SSP_RESP_IU_MAX_SIZE]; | ||
206 | }; | ||
207 | } ssp; | ||
208 | |||
209 | struct { | ||
210 | struct smp_req cmd; | ||
211 | struct smp_resp rsp; | ||
212 | } smp; | ||
213 | |||
214 | struct { | ||
215 | struct scic_sds_stp_request req; | ||
216 | struct host_to_dev_fis cmd; | ||
217 | struct dev_to_host_fis rsp; | ||
218 | } stp; | ||
219 | }; | ||
220 | |||
221 | }; | ||
222 | |||
223 | static inline struct scic_sds_request *to_sci_req(struct scic_sds_stp_request *stp_req) | ||
224 | { | ||
225 | struct scic_sds_request *sci_req; | ||
226 | |||
227 | sci_req = container_of(stp_req, typeof(*sci_req), stp.req); | ||
228 | return sci_req; | ||
229 | } | ||
230 | |||
85 | struct isci_request { | 231 | struct isci_request { |
86 | enum isci_request_status status; | 232 | enum isci_request_status status; |
87 | enum task_type ttype; | 233 | enum task_type ttype; |
@@ -126,6 +272,273 @@ static inline struct isci_request *sci_req_to_ireq(struct scic_sds_request *sci_ | |||
126 | } | 272 | } |
127 | 273 | ||
128 | /** | 274 | /** |
275 | * enum sci_base_request_states - This enumeration depicts all the states for | ||
276 | * the common request state machine. | ||
277 | * | ||
278 | * | ||
279 | */ | ||
280 | enum sci_base_request_states { | ||
281 | /** | ||
282 | * Simply the initial state for the base request state machine. | ||
283 | */ | ||
284 | SCI_BASE_REQUEST_STATE_INITIAL, | ||
285 | |||
286 | /** | ||
287 | * This state indicates that the request has been constructed. This state | ||
288 | * is entered from the INITIAL state. | ||
289 | */ | ||
290 | SCI_BASE_REQUEST_STATE_CONSTRUCTED, | ||
291 | |||
292 | /** | ||
293 | * This state indicates that the request has been started. This state is | ||
294 | * entered from the CONSTRUCTED state. | ||
295 | */ | ||
296 | SCI_BASE_REQUEST_STATE_STARTED, | ||
297 | |||
298 | /** | ||
299 | * This state indicates that the request has completed. | ||
300 | * This state is entered from the STARTED state. This state is entered from | ||
301 | * the ABORTING state. | ||
302 | */ | ||
303 | SCI_BASE_REQUEST_STATE_COMPLETED, | ||
304 | |||
305 | /** | ||
306 | * This state indicates that the request is in the process of being | ||
307 | * terminated/aborted. | ||
308 | * This state is entered from the CONSTRUCTED state. | ||
309 | * This state is entered from the STARTED state. | ||
310 | */ | ||
311 | SCI_BASE_REQUEST_STATE_ABORTING, | ||
312 | |||
313 | /** | ||
314 | * Simply the final state for the base request state machine. | ||
315 | */ | ||
316 | SCI_BASE_REQUEST_STATE_FINAL, | ||
317 | }; | ||
318 | |||
319 | typedef enum sci_status (*scic_sds_io_request_handler_t) | ||
320 | (struct scic_sds_request *request); | ||
321 | typedef enum sci_status (*scic_sds_io_request_frame_handler_t) | ||
322 | (struct scic_sds_request *req, u32 frame); | ||
323 | typedef enum sci_status (*scic_sds_io_request_event_handler_t) | ||
324 | (struct scic_sds_request *req, u32 event); | ||
325 | typedef enum sci_status (*scic_sds_io_request_task_completion_handler_t) | ||
326 | (struct scic_sds_request *req, u32 completion_code); | ||
327 | |||
328 | /** | ||
329 | * struct scic_sds_io_request_state_handler - This is the SDS core definition | ||
330 | * of the state handlers. | ||
331 | * | ||
332 | * | ||
333 | */ | ||
334 | struct scic_sds_io_request_state_handler { | ||
335 | /** | ||
336 | * The start_handler specifies the method invoked when a user attempts to | ||
337 | * start a request. | ||
338 | */ | ||
339 | scic_sds_io_request_handler_t start_handler; | ||
340 | |||
341 | /** | ||
342 | * The abort_handler specifies the method invoked when a user attempts to | ||
343 | * abort a request. | ||
344 | */ | ||
345 | scic_sds_io_request_handler_t abort_handler; | ||
346 | |||
347 | /** | ||
348 | * The complete_handler specifies the method invoked when a user attempts to | ||
349 | * complete a request. | ||
350 | */ | ||
351 | scic_sds_io_request_handler_t complete_handler; | ||
352 | |||
353 | scic_sds_io_request_task_completion_handler_t tc_completion_handler; | ||
354 | scic_sds_io_request_event_handler_t event_handler; | ||
355 | scic_sds_io_request_frame_handler_t frame_handler; | ||
356 | |||
357 | }; | ||
358 | |||
359 | extern const struct sci_base_state scic_sds_io_request_started_task_mgmt_substate_table[]; | ||
360 | |||
361 | /** | ||
362 | * scic_sds_request_get_controller() - | ||
363 | * | ||
364 | * This macro will return the controller for this io request object | ||
365 | */ | ||
366 | #define scic_sds_request_get_controller(sci_req) \ | ||
367 | ((sci_req)->owning_controller) | ||
368 | |||
369 | /** | ||
370 | * scic_sds_request_get_device() - | ||
371 | * | ||
372 | * This macro will return the device for this io request object | ||
373 | */ | ||
374 | #define scic_sds_request_get_device(sci_req) \ | ||
375 | ((sci_req)->target_device) | ||
376 | |||
377 | /** | ||
378 | * scic_sds_request_get_port() - | ||
379 | * | ||
380 | * This macro will return the port for this io request object | ||
381 | */ | ||
382 | #define scic_sds_request_get_port(sci_req) \ | ||
383 | scic_sds_remote_device_get_port(scic_sds_request_get_device(sci_req)) | ||
384 | |||
385 | /** | ||
386 | * scic_sds_request_get_post_context() - | ||
387 | * | ||
388 | * This macro returns the constructed post context result for the io request. | ||
389 | */ | ||
390 | #define scic_sds_request_get_post_context(sci_req) \ | ||
391 | ((sci_req)->post_context) | ||
392 | |||
393 | /** | ||
394 | * scic_sds_request_get_task_context() - | ||
395 | * | ||
396 | * This is a helper macro to return the os handle for this request object. | ||
397 | */ | ||
398 | #define scic_sds_request_get_task_context(request) \ | ||
399 | ((request)->task_context_buffer) | ||
400 | |||
401 | /** | ||
402 | * scic_sds_request_set_status() - | ||
403 | * | ||
404 | * This macro will set the scu hardware status and sci request completion | ||
405 | * status for an io request. | ||
406 | */ | ||
407 | #define scic_sds_request_set_status(request, scu_status_code, sci_status_code) \ | ||
408 | { \ | ||
409 | (request)->scu_status = (scu_status_code); \ | ||
410 | (request)->sci_status = (sci_status_code); \ | ||
411 | } | ||
412 | |||
413 | #define scic_sds_request_complete(a_request) \ | ||
414 | ((a_request)->state_handlers->complete_handler(a_request)) | ||
415 | |||
416 | |||
417 | extern enum sci_status | ||
418 | scic_sds_io_request_tc_completion(struct scic_sds_request *request, u32 completion_code); | ||
419 | |||
420 | /** | ||
421 | * SCU_SGL_ZERO() - | ||
422 | * | ||
423 | * This macro zeros the hardware SGL element data | ||
424 | */ | ||
425 | #define SCU_SGL_ZERO(scu_sge) \ | ||
426 | { \ | ||
427 | (scu_sge).length = 0; \ | ||
428 | (scu_sge).address_lower = 0; \ | ||
429 | (scu_sge).address_upper = 0; \ | ||
430 | (scu_sge).address_modifier = 0; \ | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * SCU_SGL_COPY() - | ||
435 | * | ||
436 | * This macro copys the SGL Element data from the host os to the hardware SGL | ||
437 | * elment data | ||
438 | */ | ||
439 | #define SCU_SGL_COPY(scu_sge, os_sge) \ | ||
440 | { \ | ||
441 | (scu_sge).length = sg_dma_len(sg); \ | ||
442 | (scu_sge).address_upper = \ | ||
443 | upper_32_bits(sg_dma_address(sg)); \ | ||
444 | (scu_sge).address_lower = \ | ||
445 | lower_32_bits(sg_dma_address(sg)); \ | ||
446 | (scu_sge).address_modifier = 0; \ | ||
447 | } | ||
448 | |||
449 | void scic_sds_request_build_sgl(struct scic_sds_request *sci_req); | ||
450 | void scic_sds_stp_request_assign_buffers(struct scic_sds_request *sci_req); | ||
451 | void scic_sds_smp_request_assign_buffers(struct scic_sds_request *sci_req); | ||
452 | enum sci_status scic_sds_request_start(struct scic_sds_request *sci_req); | ||
453 | enum sci_status scic_sds_io_request_terminate(struct scic_sds_request *sci_req); | ||
454 | void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req); | ||
455 | enum sci_status scic_sds_io_request_event_handler(struct scic_sds_request *sci_req, | ||
456 | u32 event_code); | ||
457 | enum sci_status scic_sds_io_request_frame_handler(struct scic_sds_request *sci_req, | ||
458 | u32 frame_index); | ||
459 | enum sci_status scic_sds_task_request_terminate(struct scic_sds_request *sci_req); | ||
460 | enum sci_status scic_sds_request_started_state_abort_handler(struct scic_sds_request *sci_req); | ||
461 | |||
462 | /** | ||
463 | * enum _scic_sds_io_request_started_task_mgmt_substates - This enumeration | ||
464 | * depicts all of the substates for a task management request to be | ||
465 | * performed in the STARTED super-state. | ||
466 | * | ||
467 | * | ||
468 | */ | ||
469 | enum scic_sds_raw_request_started_task_mgmt_substates { | ||
470 | /** | ||
471 | * The AWAIT_TC_COMPLETION sub-state indicates that the started raw | ||
472 | * task management request is waiting for the transmission of the | ||
473 | * initial frame (i.e. command, task, etc.). | ||
474 | */ | ||
475 | SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION, | ||
476 | |||
477 | /** | ||
478 | * This sub-state indicates that the started task management request | ||
479 | * is waiting for the reception of an unsolicited frame | ||
480 | * (i.e. response IU). | ||
481 | */ | ||
482 | SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE, | ||
483 | }; | ||
484 | |||
485 | |||
486 | /** | ||
487 | * enum _scic_sds_smp_request_started_substates - This enumeration depicts all | ||
488 | * of the substates for a SMP request to be performed in the STARTED | ||
489 | * super-state. | ||
490 | * | ||
491 | * | ||
492 | */ | ||
493 | enum scic_sds_smp_request_started_substates { | ||
494 | /** | ||
495 | * This sub-state indicates that the started task management request | ||
496 | * is waiting for the reception of an unsolicited frame | ||
497 | * (i.e. response IU). | ||
498 | */ | ||
499 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE, | ||
500 | |||
501 | /** | ||
502 | * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP request is | ||
503 | * waiting for the transmission of the initial frame (i.e. command, task, etc.). | ||
504 | */ | ||
505 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION, | ||
506 | }; | ||
507 | |||
508 | |||
509 | |||
510 | /* XXX open code in caller */ | ||
511 | static inline void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, | ||
512 | dma_addr_t phys_addr) | ||
513 | { | ||
514 | struct isci_request *ireq = sci_req_to_ireq(sci_req); | ||
515 | dma_addr_t offset; | ||
516 | |||
517 | BUG_ON(phys_addr < ireq->request_daddr); | ||
518 | |||
519 | offset = phys_addr - ireq->request_daddr; | ||
520 | |||
521 | BUG_ON(offset >= sizeof(*ireq)); | ||
522 | |||
523 | return (char *)ireq + offset; | ||
524 | } | ||
525 | |||
526 | /* XXX open code in caller */ | ||
527 | static inline dma_addr_t scic_io_request_get_dma_addr(struct scic_sds_request *sci_req, | ||
528 | void *virt_addr) | ||
529 | { | ||
530 | struct isci_request *ireq = sci_req_to_ireq(sci_req); | ||
531 | |||
532 | char *requested_addr = (char *)virt_addr; | ||
533 | char *base_addr = (char *)ireq; | ||
534 | |||
535 | BUG_ON(requested_addr < base_addr); | ||
536 | BUG_ON((requested_addr - base_addr) >= sizeof(*ireq)); | ||
537 | |||
538 | return ireq->request_daddr + (requested_addr - base_addr); | ||
539 | } | ||
540 | |||
541 | /** | ||
129 | * This function gets the status of the request object. | 542 | * This function gets the status of the request object. |
130 | * @request: This parameter points to the isci_request object | 543 | * @request: This parameter points to the isci_request object |
131 | * | 544 | * |
@@ -337,12 +750,6 @@ static inline void isci_request_unmap_sgl( | |||
337 | } | 750 | } |
338 | } | 751 | } |
339 | 752 | ||
340 | |||
341 | void isci_request_io_request_complete( | ||
342 | struct isci_host *isci_host, | ||
343 | struct isci_request *request, | ||
344 | enum sci_io_status completion_status); | ||
345 | |||
346 | /** | 753 | /** |
347 | * isci_request_io_request_get_next_sge() - This function is called by the sci | 754 | * isci_request_io_request_get_next_sge() - This function is called by the sci |
348 | * core to retrieve the next sge for a given request. | 755 | * core to retrieve the next sge for a given request. |
@@ -385,13 +792,16 @@ static inline void *isci_request_io_request_get_next_sge( | |||
385 | return ret; | 792 | return ret; |
386 | } | 793 | } |
387 | 794 | ||
388 | 795 | void isci_terminate_pending_requests(struct isci_host *isci_host, | |
389 | void isci_terminate_pending_requests( | 796 | struct isci_remote_device *isci_device, |
390 | struct isci_host *isci_host, | 797 | enum isci_request_status new_request_state); |
391 | struct isci_remote_device *isci_device, | 798 | enum sci_status scic_task_request_construct(struct scic_sds_controller *scic, |
392 | enum isci_request_status new_request_state); | 799 | struct scic_sds_remote_device *sci_dev, |
393 | 800 | u16 io_tag, | |
394 | 801 | struct scic_sds_request *sci_req); | |
395 | 802 | enum sci_status scic_task_request_construct_ssp(struct scic_sds_request *sci_req); | |
396 | 803 | enum sci_status scic_task_request_construct_sata(struct scic_sds_request *sci_req); | |
804 | enum sci_status scic_io_request_construct_smp(struct scic_sds_request *sci_req); | ||
805 | void scic_stp_io_request_set_ncq_tag(struct scic_sds_request *sci_req, u16 ncq_tag); | ||
806 | void scic_sds_smp_request_copy_response(struct scic_sds_request *sci_req); | ||
397 | #endif /* !defined(_ISCI_REQUEST_H_) */ | 807 | #endif /* !defined(_ISCI_REQUEST_H_) */ |