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 #ifndef _ISCI_REQUEST_H_ 57 #define _ISCI_REQUEST_H_ 58 59 #include "isci.h" 60 #include "host.h" 61 #include "scic_sds_request.h" 62 63 /** 64 * struct isci_request_status - This enum defines the possible states of an I/O 65 * request. 66 * 67 * 68 */ 69 enum isci_request_status { 70 unallocated = 0x00, 71 allocated = 0x01, 72 started = 0x02, 73 completed = 0x03, 74 aborting = 0x04, 75 aborted = 0x05, 76 terminating = 0x06, 77 dead = 0x07 78 }; 79 80 enum task_type { 81 io_task = 0, 82 tmf_task = 1 83 }; 84 85 struct isci_request { 86 enum isci_request_status status; 87 enum task_type ttype; 88 unsigned short io_tag; 89 bool complete_in_target; 90 bool terminated; 91 92 union ttype_ptr_union { 93 struct sas_task *io_task_ptr; /* When ttype==io_task */ 94 struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */ 95 } ttype_ptr; 96 struct isci_host *isci_host; 97 struct isci_remote_device *isci_device; 98 /* For use in the requests_to_{complete|abort} lists: */ 99 struct list_head completed_node; 100 /* For use in the reqs_in_process list: */ 101 struct list_head dev_node; 102 spinlock_t state_lock; 103 dma_addr_t request_daddr; 104 dma_addr_t zero_scatter_daddr; 105 106 unsigned int num_sg_entries; /* returned by pci_alloc_sg */ 107 108 /** Note: "io_request_completion" is completed in two different ways 109 * depending on whether this is a TMF or regular request. 110 * - TMF requests are completed in the thread that started them; 111 * - regular requests are completed in the request completion callback 112 * function. 113 * This difference in operation allows the aborter of a TMF request 114 * to be sure that once the TMF request completes, the I/O that the 115 * TMF was aborting is guaranteed to have completed. 116 */ 117 struct completion *io_request_completion; 118 struct scic_sds_request sci; 119 }; 120 121 static inline struct isci_request *sci_req_to_ireq(struct scic_sds_request *sci_req) 122 { 123 struct isci_request *ireq = container_of(sci_req, typeof(*ireq), sci); 124 125 return ireq; 126 } 127 128 /** 129 * This function gets the status of the request object. 130 * @request: This parameter points to the isci_request object 131 * 132 * status of the object as a isci_request_status enum. 133 */ 134 static inline 135 enum isci_request_status isci_request_get_state( 136 struct isci_request *isci_request) 137 { 138 BUG_ON(isci_request == NULL); 139 140 /*probably a bad sign... */ 141 if (isci_request->status == unallocated) 142 dev_warn(&isci_request->isci_host->pdev->dev, 143 "%s: isci_request->status == unallocated\n", 144 __func__); 145 146 return isci_request->status; 147 } 148 149 150 /** 151 * isci_request_change_state() - This function sets the status of the request 152 * object. 153 * @request: This parameter points to the isci_request object 154 * @status: This Parameter is the new status of the object 155 * 156 */ 157 static inline enum isci_request_status isci_request_change_state( 158 struct isci_request *isci_request, 159 enum isci_request_status status) 160 { 161 enum isci_request_status old_state; 162 unsigned long flags; 163 164 dev_dbg(&isci_request->isci_host->pdev->dev, 165 "%s: isci_request = %p, state = 0x%x\n", 166 __func__, 167 isci_request, 168 status); 169 170 BUG_ON(isci_request == NULL); 171 172 spin_lock_irqsave(&isci_request->state_lock, flags); 173 old_state = isci_request->status; 174 isci_request->status = status; 175 spin_unlock_irqrestore(&isci_request->state_lock, flags); 176 177 return old_state; 178 } 179 180 /** 181 * isci_request_change_started_to_newstate() - This function sets the status of 182 * the request object. 183 * @request: This parameter points to the isci_request object 184 * @status: This Parameter is the new status of the object 185 * 186 * state previous to any change. 187 */ 188 static inline enum isci_request_status isci_request_change_started_to_newstate( 189 struct isci_request *isci_request, 190 struct completion *completion_ptr, 191 enum isci_request_status newstate) 192 { 193 enum isci_request_status old_state; 194 unsigned long flags; 195 196 spin_lock_irqsave(&isci_request->state_lock, flags); 197 198 old_state = isci_request->status; 199 200 if (old_state == started || old_state == aborting) { 201 BUG_ON(isci_request->io_request_completion != NULL); 202 203 isci_request->io_request_completion = completion_ptr; 204 isci_request->status = newstate; 205 } 206 spin_unlock_irqrestore(&isci_request->state_lock, flags); 207 208 dev_dbg(&isci_request->isci_host->pdev->dev, 209 "%s: isci_request = %p, old_state = 0x%x\n", 210 __func__, 211 isci_request, 212 old_state); 213 214 return old_state; 215 } 216 217 /** 218 * isci_request_change_started_to_aborted() - This function sets the status of 219 * the request object. 220 * @request: This parameter points to the isci_request object 221 * @completion_ptr: This parameter is saved as the kernel completion structure 222 * signalled when the old request completes. 223 * 224 * state previous to any change. 225 */ 226 static inline enum isci_request_status isci_request_change_started_to_aborted( 227 struct isci_request *isci_request, 228 struct completion *completion_ptr) 229 { 230 return isci_request_change_started_to_newstate( 231 isci_request, completion_ptr, aborted 232 ); 233 } 234 /** 235 * isci_request_free() - This function frees the request object. 236 * @isci_host: This parameter specifies the ISCI host object 237 * @isci_request: This parameter points to the isci_request object 238 * 239 */ 240 static inline void isci_request_free( 241 struct isci_host *isci_host, 242 struct isci_request *isci_request) 243 { 244 if (!isci_request) 245 return; 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 /** 347 * 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. 349 * @request: This parameter is the isci_request object. 350 * @current_sge_address: This parameter is the last sge retrieved by the sci 351 * core for this request. 352 * 353 * pointer to the next sge for specified request. 354 */ 355 static inline void *isci_request_io_request_get_next_sge( 356 struct isci_request *request, 357 void *current_sge_address) 358 { 359 struct sas_task *task = isci_request_access_task(request); 360 void *ret = NULL; 361 362 dev_dbg(&request->isci_host->pdev->dev, 363 "%s: request = %p, " 364 "current_sge_address = %p, " 365 "num_scatter = %d\n", 366 __func__, 367 request, 368 current_sge_address, 369 task->num_scatter); 370 371 if (!current_sge_address) /* First time through.. */ 372 ret = task->scatter; /* always task->scatter */ 373 else if (task->num_scatter == 0) /* Next element, if num_scatter == 0 */ 374 ret = NULL; /* there is only one element. */ 375 else 376 ret = sg_next(current_sge_address); /* sg_next returns NULL 377 * for the last element 378 */ 379 380 dev_dbg(&request->isci_host->pdev->dev, 381 "%s: next sge address = %p\n", 382 __func__, 383 ret); 384 385 return ret; 386 } 387 388 389 void isci_terminate_pending_requests( 390 struct isci_host *isci_host, 391 struct isci_remote_device *isci_device, 392 enum isci_request_status new_request_state); 393 394 395 396 397 #endif /* !defined(_ISCI_REQUEST_H_) */ 398