aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/task.c')
-rw-r--r--drivers/scsi/isci/task.c136
1 files changed, 50 insertions, 86 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 01032dc2c116..ded81cd1a781 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -146,7 +146,6 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
146int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) 146int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
147{ 147{
148 struct isci_host *ihost = dev_to_ihost(task->dev); 148 struct isci_host *ihost = dev_to_ihost(task->dev);
149 struct isci_request *request = NULL;
150 struct isci_remote_device *device; 149 struct isci_remote_device *device;
151 unsigned long flags; 150 unsigned long flags;
152 int ret; 151 int ret;
@@ -226,8 +225,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
226 spin_unlock_irqrestore(&task->task_state_lock, flags); 225 spin_unlock_irqrestore(&task->task_state_lock, flags);
227 226
228 /* build and send the request. */ 227 /* build and send the request. */
229 status = isci_request_execute(ihost, task, &request, 228 status = isci_request_execute(ihost, task, gfp_flags);
230 gfp_flags);
231 229
232 if (status != SCI_SUCCESS) { 230 if (status != SCI_SUCCESS) {
233 231
@@ -254,54 +252,34 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
254 return 0; 252 return 0;
255} 253}
256 254
257 255static struct isci_request *isci_task_request_build(struct isci_host *ihost,
258 256 struct isci_tmf *isci_tmf)
259/**
260 * isci_task_request_build() - This function builds the task request object.
261 * @isci_host: This parameter specifies the ISCI host object
262 * @request: This parameter points to the isci_request object allocated in the
263 * request construct function.
264 * @tmf: This parameter is the task management struct to be built
265 *
266 * SCI_SUCCESS on successfull completion, or specific failure code.
267 */
268static enum sci_status isci_task_request_build(
269 struct isci_host *isci_host,
270 struct isci_request **isci_request,
271 struct isci_tmf *isci_tmf)
272{ 257{
273 struct scic_sds_remote_device *sci_device; 258 struct scic_sds_remote_device *sci_dev;
274 enum sci_status status = SCI_FAILURE; 259 enum sci_status status = SCI_FAILURE;
275 struct isci_request *request = NULL; 260 struct isci_request *ireq = NULL;
276 struct isci_remote_device *isci_device; 261 struct isci_remote_device *idev;
277 struct domain_device *dev; 262 struct domain_device *dev;
278 263
279 dev_dbg(&isci_host->pdev->dev, 264 dev_dbg(&ihost->pdev->dev,
280 "%s: isci_tmf = %p\n", __func__, isci_tmf); 265 "%s: isci_tmf = %p\n", __func__, isci_tmf);
281 266
282 isci_device = isci_tmf->device; 267 idev = isci_tmf->device;
283 sci_device = &isci_device->sci; 268 sci_dev = &idev->sci;
284 dev = isci_device->domain_dev; 269 dev = idev->domain_dev;
285 270
286 /* do common allocation and init of request object. */ 271 /* do common allocation and init of request object. */
287 status = isci_request_alloc_tmf( 272 ireq = isci_request_alloc_tmf(ihost, isci_tmf, idev, GFP_ATOMIC);
288 isci_host, 273 if (!ireq)
289 isci_tmf, 274 return NULL;
290 &request,
291 isci_device,
292 GFP_ATOMIC
293 );
294
295 if (status != SCI_SUCCESS)
296 goto out;
297 275
298 /* let the core do it's construct. */ 276 /* let the core do it's construct. */
299 status = scic_task_request_construct(&isci_host->sci, sci_device, 277 status = scic_task_request_construct(&ihost->sci, sci_dev,
300 SCI_CONTROLLER_INVALID_IO_TAG, 278 SCI_CONTROLLER_INVALID_IO_TAG,
301 &request->sci); 279 &ireq->sci);
302 280
303 if (status != SCI_SUCCESS) { 281 if (status != SCI_SUCCESS) {
304 dev_warn(&isci_host->pdev->dev, 282 dev_warn(&ihost->pdev->dev,
305 "%s: scic_task_request_construct failed - " 283 "%s: scic_task_request_construct failed - "
306 "status = 0x%x\n", 284 "status = 0x%x\n",
307 __func__, 285 __func__,
@@ -312,30 +290,23 @@ static enum sci_status isci_task_request_build(
312 /* XXX convert to get this from task->tproto like other drivers */ 290 /* XXX convert to get this from task->tproto like other drivers */
313 if (dev->dev_type == SAS_END_DEV) { 291 if (dev->dev_type == SAS_END_DEV) {
314 isci_tmf->proto = SAS_PROTOCOL_SSP; 292 isci_tmf->proto = SAS_PROTOCOL_SSP;
315 status = scic_task_request_construct_ssp(&request->sci); 293 status = scic_task_request_construct_ssp(&ireq->sci);
316 if (status != SCI_SUCCESS) 294 if (status != SCI_SUCCESS)
317 goto errout; 295 goto errout;
318 } 296 }
319 297
320 if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { 298 if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
321 isci_tmf->proto = SAS_PROTOCOL_SATA; 299 isci_tmf->proto = SAS_PROTOCOL_SATA;
322 status = isci_sata_management_task_request_build(request); 300 status = isci_sata_management_task_request_build(ireq);
323 301
324 if (status != SCI_SUCCESS) 302 if (status != SCI_SUCCESS)
325 goto errout; 303 goto errout;
326 } 304 }
327 305 return ireq;
328 goto out;
329
330 errout: 306 errout:
331 307 isci_request_free(ihost, ireq);
332 /* release the dma memory if we fail. */ 308 ireq = NULL;
333 isci_request_free(isci_host, request); 309 return ireq;
334 request = NULL;
335
336 out:
337 *isci_request = request;
338 return status;
339} 310}
340 311
341/** 312/**
@@ -350,16 +321,14 @@ static enum sci_status isci_task_request_build(
350 * TMF_RESP_FUNC_COMPLETE on successful completion of the TMF (this includes 321 * TMF_RESP_FUNC_COMPLETE on successful completion of the TMF (this includes
351 * error conditions reported in the IU status), or TMF_RESP_FUNC_FAILED. 322 * error conditions reported in the IU status), or TMF_RESP_FUNC_FAILED.
352 */ 323 */
353int isci_task_execute_tmf( 324int isci_task_execute_tmf(struct isci_host *ihost, struct isci_tmf *tmf,
354 struct isci_host *isci_host, 325 unsigned long timeout_ms)
355 struct isci_tmf *tmf,
356 unsigned long timeout_ms)
357{ 326{
358 DECLARE_COMPLETION_ONSTACK(completion); 327 DECLARE_COMPLETION_ONSTACK(completion);
359 enum sci_task_status status = SCI_TASK_FAILURE; 328 enum sci_task_status status = SCI_TASK_FAILURE;
360 struct scic_sds_remote_device *sci_device; 329 struct scic_sds_remote_device *sci_device;
361 struct isci_remote_device *isci_device = tmf->device; 330 struct isci_remote_device *isci_device = tmf->device;
362 struct isci_request *request; 331 struct isci_request *ireq;
363 int ret = TMF_RESP_FUNC_FAILED; 332 int ret = TMF_RESP_FUNC_FAILED;
364 unsigned long flags; 333 unsigned long flags;
365 unsigned long timeleft; 334 unsigned long timeleft;
@@ -368,13 +337,13 @@ int isci_task_execute_tmf(
368 * if the device is not there and ready. 337 * if the device is not there and ready.
369 */ 338 */
370 if (!isci_device || isci_device->status != isci_ready_for_io) { 339 if (!isci_device || isci_device->status != isci_ready_for_io) {
371 dev_dbg(&isci_host->pdev->dev, 340 dev_dbg(&ihost->pdev->dev,
372 "%s: isci_device = %p not ready (%d)\n", 341 "%s: isci_device = %p not ready (%d)\n",
373 __func__, 342 __func__,
374 isci_device, isci_device->status); 343 isci_device, isci_device->status);
375 return TMF_RESP_FUNC_FAILED; 344 return TMF_RESP_FUNC_FAILED;
376 } else 345 } else
377 dev_dbg(&isci_host->pdev->dev, 346 dev_dbg(&ihost->pdev->dev,
378 "%s: isci_device = %p\n", 347 "%s: isci_device = %p\n",
379 __func__, isci_device); 348 __func__, isci_device);
380 349
@@ -383,64 +352,59 @@ int isci_task_execute_tmf(
383 /* Assign the pointer to the TMF's completion kernel wait structure. */ 352 /* Assign the pointer to the TMF's completion kernel wait structure. */
384 tmf->complete = &completion; 353 tmf->complete = &completion;
385 354
386 isci_task_request_build( 355 ireq = isci_task_request_build(ihost, tmf);
387 isci_host, 356 if (!ireq) {
388 &request, 357 dev_warn(&ihost->pdev->dev,
389 tmf
390 );
391
392 if (!request) {
393 dev_warn(&isci_host->pdev->dev,
394 "%s: isci_task_request_build failed\n", 358 "%s: isci_task_request_build failed\n",
395 __func__); 359 __func__);
396 return TMF_RESP_FUNC_FAILED; 360 return TMF_RESP_FUNC_FAILED;
397 } 361 }
398 362
399 spin_lock_irqsave(&isci_host->scic_lock, flags); 363 spin_lock_irqsave(&ihost->scic_lock, flags);
400 364
401 /* start the TMF io. */ 365 /* start the TMF io. */
402 status = scic_controller_start_task( 366 status = scic_controller_start_task(
403 &isci_host->sci, 367 &ihost->sci,
404 sci_device, 368 sci_device,
405 &request->sci, 369 &ireq->sci,
406 SCI_CONTROLLER_INVALID_IO_TAG); 370 SCI_CONTROLLER_INVALID_IO_TAG);
407 371
408 if (status != SCI_TASK_SUCCESS) { 372 if (status != SCI_TASK_SUCCESS) {
409 dev_warn(&isci_host->pdev->dev, 373 dev_warn(&ihost->pdev->dev,
410 "%s: start_io failed - status = 0x%x, request = %p\n", 374 "%s: start_io failed - status = 0x%x, request = %p\n",
411 __func__, 375 __func__,
412 status, 376 status,
413 request); 377 ireq);
414 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 378 spin_unlock_irqrestore(&ihost->scic_lock, flags);
415 goto cleanup_request; 379 goto cleanup_request;
416 } 380 }
417 381
418 if (tmf->cb_state_func != NULL) 382 if (tmf->cb_state_func != NULL)
419 tmf->cb_state_func(isci_tmf_started, tmf, tmf->cb_data); 383 tmf->cb_state_func(isci_tmf_started, tmf, tmf->cb_data);
420 384
421 isci_request_change_state(request, started); 385 isci_request_change_state(ireq, started);
422 386
423 /* add the request to the remote device request list. */ 387 /* add the request to the remote device request list. */
424 list_add(&request->dev_node, &isci_device->reqs_in_process); 388 list_add(&ireq->dev_node, &isci_device->reqs_in_process);
425 389
426 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 390 spin_unlock_irqrestore(&ihost->scic_lock, flags);
427 391
428 /* Wait for the TMF to complete, or a timeout. */ 392 /* Wait for the TMF to complete, or a timeout. */
429 timeleft = wait_for_completion_timeout(&completion, 393 timeleft = wait_for_completion_timeout(&completion,
430 jiffies + msecs_to_jiffies(timeout_ms)); 394 jiffies + msecs_to_jiffies(timeout_ms));
431 395
432 if (timeleft == 0) { 396 if (timeleft == 0) {
433 spin_lock_irqsave(&isci_host->scic_lock, flags); 397 spin_lock_irqsave(&ihost->scic_lock, flags);
434 398
435 if (tmf->cb_state_func != NULL) 399 if (tmf->cb_state_func != NULL)
436 tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data); 400 tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data);
437 401
438 status = scic_controller_terminate_request( 402 status = scic_controller_terminate_request(
439 &request->isci_host->sci, 403 &ireq->isci_host->sci,
440 &request->isci_device->sci, 404 &ireq->isci_device->sci,
441 &request->sci); 405 &ireq->sci);
442 406
443 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 407 spin_unlock_irqrestore(&ihost->scic_lock, flags);
444 } 408 }
445 409
446 isci_print_tmf(tmf); 410 isci_print_tmf(tmf);
@@ -448,7 +412,7 @@ int isci_task_execute_tmf(
448 if (tmf->status == SCI_SUCCESS) 412 if (tmf->status == SCI_SUCCESS)
449 ret = TMF_RESP_FUNC_COMPLETE; 413 ret = TMF_RESP_FUNC_COMPLETE;
450 else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) { 414 else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) {
451 dev_dbg(&isci_host->pdev->dev, 415 dev_dbg(&ihost->pdev->dev,
452 "%s: tmf.status == " 416 "%s: tmf.status == "
453 "SCI_FAILURE_IO_RESPONSE_VALID\n", 417 "SCI_FAILURE_IO_RESPONSE_VALID\n",
454 __func__); 418 __func__);
@@ -456,18 +420,18 @@ int isci_task_execute_tmf(
456 } 420 }
457 /* Else - leave the default "failed" status alone. */ 421 /* Else - leave the default "failed" status alone. */
458 422
459 dev_dbg(&isci_host->pdev->dev, 423 dev_dbg(&ihost->pdev->dev,
460 "%s: completed request = %p\n", 424 "%s: completed request = %p\n",
461 __func__, 425 __func__,
462 request); 426 ireq);
463 427
464 if (request->io_request_completion != NULL) { 428 if (ireq->io_request_completion != NULL) {
465 /* A thread is waiting for this TMF to finish. */ 429 /* A thread is waiting for this TMF to finish. */
466 complete(request->io_request_completion); 430 complete(ireq->io_request_completion);
467 } 431 }
468 432
469 cleanup_request: 433 cleanup_request:
470 isci_request_free(isci_host, request); 434 isci_request_free(ihost, ireq);
471 return ret; 435 return ret;
472} 436}
473 437