1 /* 2 * This file is provided under a dual BSD/GPLv2 license. When using or 3 * redistributing this file, you may do so under either license. 4 * 5 * GPL LICENSE SUMMARY 6 * 7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21 * The full GNU General Public License is included in this distribution 22 * in the file called LICENSE.GPL. 23 * 24 * BSD LICENSE 25 * 26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 33 * * Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * * Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in 37 * the documentation and/or other materials provided with the 38 * distribution. 39 * * Neither the name of Intel Corporation nor the names of its 40 * contributors may be used to endorse or promote products derived 41 * from this software without specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 */ 55 56 #if !defined(_ISCI_REQUEST_H_) 57 #define _ISCI_REQUEST_H_ 58 59 #include "isci.h" 60 61 /** 62 * struct isci_request_status - This enum defines the possible states of an I/O 63 * request. 64 * 65 * 66 */ 67 enum isci_request_status { 68 unallocated = 0x00, 69 allocated = 0x01, 70 started = 0x02, 71 completed = 0x03, 72 aborting = 0x04, 73 aborted = 0x05, 74 terminating = 0x06 75 }; 76 77 enum task_type { 78 io_task = 0, 79 tmf_task = 1 80 }; 81 82 /** 83 * struct isci_request - This class represents the request object used to track 84 * IO, smp and TMF request internal. It wraps the SCIC request object. 85 * 86 * 87 */ 88 struct isci_request { 89 90 struct scic_sds_request *sci_request_handle; 91 92 enum isci_request_status status; 93 enum task_type ttype; 94 unsigned short io_tag; 95 bool complete_in_target; 96 97 union ttype_ptr_union { 98 struct sas_task *io_task_ptr; /* When ttype==io_task */ 99 struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */ 100 } ttype_ptr; 101 struct isci_host *isci_host; 102 struct isci_remote_device *isci_device; 103 /* For use in the requests_to_{complete|abort} lists: */ 104 struct list_head completed_node; 105 /* For use in the reqs_in_process list: */ 106 struct list_head dev_node; 107 void *sci_request_mem_ptr; 108 spinlock_t state_lock; 109 dma_addr_t request_daddr; 110 dma_addr_t zero_scatter_daddr; 111 112 unsigned int num_sg_entries; /* returned by pci_alloc_sg */ 113 unsigned int request_alloc_size; /* size of block from dma_pool_alloc */ 114 115 /** Note: "io_request_completion" is completed in two different ways 116 * depending on whether this is a TMF or regular request. 117 * - TMF requests are completed in the thread that started them; 118 * - regular requests are completed in the request completion callback 119 * function. 120 * This difference in operation allows the aborter of a TMF request 121 * to be sure that once the TMF request completes, the I/O that the 122 * TMF was aborting is guaranteed to have completed. 123 */ 124 struct completion *io_request_completion; 125 }; 126 127 /** 128 * This function gets the status of the request object. 129 * @request: This parameter points to the isci_request object 130 * 131 * status of the object as a isci_request_status enum. 132 */ 133 static inline 134 enum isci_request_status isci_request_get_state( 135 struct isci_request *isci_request) 136 { 137 BUG_ON(isci_request == NULL); 138 139 /*probably a bad sign... */ 140 if (isci_request->status == unallocated) 141 dev_warn(&isci_request->isci_host->pdev->dev, 142 "%s: isci_request->status == unallocated\n", 143 __func__); 144 145 return isci_request->status; 146 } 147 148 149 /** 150 * isci_request_change_state() - This function sets the status of the request 151 * object. 152 * @request: This parameter points to the isci_request object 153 * @status: This Parameter is the new status of the object 154 * 155 */ 156 static inline enum isci_request_status isci_request_change_state( 157 struct isci_request *isci_request, 158 enum isci_request_status status) 159 { 160 enum isci_request_status old_state; 161 unsigned long flags; 162 163 dev_dbg(&isci_request->isci_host->pdev->dev, 164 "%s: isci_request = %p, state = 0x%x\n", 165 __func__, 166 isci_request, 167 status); 168 169 BUG_ON(isci_request == NULL); 170 171 spin_lock_irqsave(&isci_request->state_lock, flags); 172 old_state = isci_request->status; 173 isci_request->status = status; 174 spin_unlock_irqrestore(&isci_request->state_lock, flags); 175 176 return old_state; 177 } 178 179 /** 180 * isci_request_change_started_to_newstate() - This function sets the status of 181 * the request object. 182 * @request: This parameter points to the isci_request object 183 * @status: This Parameter is the new status of the object 184 * 185 * state previous to any change. 186 */ 187 static inline enum isci_request_status isci_request_change_started_to_newstate( 188 struct isci_request *isci_request, 189 struct completion *completion_ptr, 190 enum isci_request_status newstate) 191 { 192 enum isci_request_status old_state; 193 unsigned long flags; 194 195 BUG_ON(isci_request == NULL); 196 197 spin_lock_irqsave(&isci_request->state_lock, flags); 198 199 old_state = isci_request->status; 200 201 if (old_state == started) { 202 BUG_ON(isci_request->io_request_completion != NULL); 203 204 isci_request->io_request_completion = completion_ptr; 205 isci_request->status = newstate; 206 } 207 spin_unlock_irqrestore(&isci_request->state_lock, flags); 208 209 dev_dbg(&isci_request->isci_host->pdev->dev, 210 "%s: isci_request = %p, old_state = 0x%x\n", 211 __func__, 212 isci_request, 213 old_state); 214 215 return old_state; 216 } 217 218 /** 219 * isci_request_change_started_to_aborted() - This function sets the status of 220 * the request object. 221 * @request: This parameter points to the isci_request object 222 * @completion_ptr: This parameter is saved as the kernel completion structure 223 * signalled when the old request completes. 224 * 225 * state previous to any change. 226 */ 227 static inline enum isci_request_status isci_request_change_started_to_aborted( 228 struct isci_request *isci_request, 229 struct completion *completion_ptr) 230 { 231 return isci_request_change_started_to_newstate( 232 isci_request, completion_ptr, aborted 233 ); 234 } 235 /** 236 * isci_request_free() - This function frees the request object. 237 * @isci_host: This parameter specifies the ISCI host object 238 * @isci_request: This parameter points to the isci_request object 239 * 240 */ 241 static inline void isci_request_free( 242 struct isci_host *isci_host, 243 struct isci_request *isci_request) 244 { 245 BUG_ON(isci_request == NULL); 246 247 /* release the dma memory if we fail. */ 248 dma_pool_free(isci_host->dma_pool, isci_request, 249 isci_request->request_daddr); 250 } 251 252 253 /* #define ISCI_REQUEST_VALIDATE_ACCESS 254 */ 255 256 #ifdef ISCI_REQUEST_VALIDATE_ACCESS 257 258 static inline 259 struct sas_task *isci_request_access_task(struct isci_request *isci_request) 260 { 261 BUG_ON(isci_request->ttype != io_task); 262 return isci_request->ttype_ptr.io_task_ptr; 263 } 264 265 static inline 266 struct isci_tmf *isci_request_access_tmf(struct isci_request *isci_request) 267 { 268 BUG_ON(isci_request->ttype != tmf_task); 269 return isci_request->ttype_ptr.tmf_task_ptr; 270 } 271 272 #else /* not ISCI_REQUEST_VALIDATE_ACCESS */ 273 274 #define isci_request_access_task(RequestPtr) \ 275 ((RequestPtr)->ttype_ptr.io_task_ptr) 276 277 #define isci_request_access_tmf(RequestPtr) \ 278 ((RequestPtr)->ttype_ptr.tmf_task_ptr) 279 280 #endif /* not ISCI_REQUEST_VALIDATE_ACCESS */ 281 282 283 int isci_request_alloc_tmf( 284 struct isci_host *isci_host, 285 struct isci_tmf *isci_tmf, 286 struct isci_request **isci_request, 287 struct isci_remote_device *isci_device, 288 gfp_t gfp_flags); 289 290 291 int isci_request_execute( 292 struct isci_host *isci_host, 293 struct sas_task *task, 294 struct isci_request **request, 295 gfp_t gfp_flags); 296 297 /** 298 * isci_request_unmap_sgl() - This function unmaps the DMA address of a given 299 * sgl 300 * @request: This parameter points to the isci_request object 301 * @*pdev: This Parameter is the pci_device struct for the controller 302 * 303 */ 304 static inline void isci_request_unmap_sgl( 305 struct isci_request *request, 306 struct pci_dev *pdev) 307 { 308 struct sas_task *task = isci_request_access_task(request); 309 310 dev_dbg(&request->isci_host->pdev->dev, 311 "%s: request = %p, task = %p,\n" 312 "task->data_dir = %d, is_sata = %d\n ", 313 __func__, 314 request, 315 task, 316 task->data_dir, 317 sas_protocol_ata(task->task_proto)); 318 319 if ((task->data_dir != PCI_DMA_NONE) && 320 !sas_protocol_ata(task->task_proto)) { 321 if (task->num_scatter == 0) 322 /* 0 indicates a single dma address */ 323 dma_unmap_single( 324 &pdev->dev, 325 request->zero_scatter_daddr, 326 task->total_xfer_len, 327 task->data_dir 328 ); 329 330 else /* unmap the sgl dma addresses */ 331 dma_unmap_sg( 332 &pdev->dev, 333 task->scatter, 334 request->num_sg_entries, 335 task->data_dir 336 ); 337 } 338 } 339 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 u32 isci_request_io_request_get_transfer_length( 347 struct isci_request *request); 348 349 SCI_IO_REQUEST_DATA_DIRECTION isci_request_io_request_get_data_direction( 350 struct isci_request *request); 351 352 /** 353 * isci_request_io_request_get_next_sge() - This function is called by the sci 354 * core to retrieve the next sge for a given request. 355 * @request: This parameter is the isci_request object. 356 * @current_sge_address: This parameter is the last sge retrieved by the sci 357 * core for this request. 358 * 359 * pointer to the next sge for specified request. 360 */ 361 static inline void *isci_request_io_request_get_next_sge( 362 struct isci_request *request, 363 void *current_sge_address) 364 { 365 struct sas_task *task = isci_request_access_task(request); 366 void *ret = NULL; 367 368 dev_dbg(&request->isci_host->pdev->dev, 369 "%s: request = %p, " 370 "current_sge_address = %p, " 371 "num_scatter = %d\n", 372 __func__, 373 request, 374 current_sge_address, 375 task->num_scatter); 376 377 if (!current_sge_address) /* First time through.. */ 378 ret = task->scatter; /* always task->scatter */ 379 else if (task->num_scatter == 0) /* Next element, if num_scatter == 0 */ 380 ret = NULL; /* there is only one element. */ 381 else 382 ret = sg_next(current_sge_address); /* sg_next returns NULL 383 * for the last element 384 */ 385 386 dev_dbg(&request->isci_host->pdev->dev, 387 "%s: next sge address = %p\n", 388 __func__, 389 ret); 390 391 return ret; 392 } 393 394 dma_addr_t isci_request_sge_get_address_field( 395 struct isci_request *request, 396 void *sge_address); 397 398 u32 isci_request_sge_get_length_field( 399 struct isci_request *request, 400 void *sge_address); 401 402 void *isci_request_ssp_io_request_get_cdb_address( 403 struct isci_request *request); 404 405 u32 isci_request_ssp_io_request_get_cdb_length( 406 struct isci_request *request); 407 408 u32 isci_request_ssp_io_request_get_lun( 409 struct isci_request *request); 410 411 u32 isci_request_ssp_io_request_get_task_attribute( 412 struct isci_request *request); 413 414 u32 isci_request_ssp_io_request_get_command_priority( 415 struct isci_request *request); 416 417 418 419 420 421 void isci_terminate_pending_requests( 422 struct isci_host *isci_host, 423 struct isci_remote_device *isci_device, 424 enum isci_request_status new_request_state); 425 426 427 428 429 #endif /* !defined(_ISCI_REQUEST_H_) */ 430