aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-06-17 13:40:43 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:51 -0400
commitddcc7e347a891937be65358b43f40b7f81185f8f (patch)
tree35492d904678bb36560efa05dd1a474e9ee78b36 /drivers/scsi
parent5edc33480c1c363ab361a881f2957b9fba5185cf (diff)
isci: fix dma_unmap_sg usage
One bug and a cleanup: 1/ Fix cases where we were unmapping invalid addresses (smp requests were being unmapped) [ 604.662770] ------------[ cut here ]------------ [ 604.668026] WARNING: at lib/dma-debug.c:800 check_unmap+0x418/0x740() [ 604.675315] Hardware name: SandyBridge Platform [ 604.680465] isci 0000:03:00.0: DMA-API: device driver tries to free an invalid DMA memory address 2/ The unmap routine is too large to be an inline function, and isci_request_io_request_get_next_sge is unused. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/isci/request.c17
-rw-r--r--drivers/scsi/isci/request.h91
2 files changed, 18 insertions, 90 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index f4fbca7b1fa3..395084955150 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -2930,7 +2930,22 @@ static void isci_request_io_request_complete(struct isci_host *isci_host,
2930 break; 2930 break;
2931 } 2931 }
2932 2932
2933 isci_request_unmap_sgl(request, isci_host->pdev); 2933 switch (task->task_proto) {
2934 case SAS_PROTOCOL_SSP:
2935 if (task->data_dir == DMA_NONE)
2936 break;
2937 if (task->num_scatter == 0)
2938 /* 0 indicates a single dma address */
2939 dma_unmap_single(&isci_host->pdev->dev,
2940 request->zero_scatter_daddr,
2941 task->total_xfer_len, task->data_dir);
2942 else /* unmap the sgl dma addresses */
2943 dma_unmap_sg(&isci_host->pdev->dev, task->scatter,
2944 request->num_sg_entries, task->data_dir);
2945 break;
2946 default:
2947 break;
2948 }
2934 2949
2935 /* Put the completed request on the correct list */ 2950 /* Put the completed request on the correct list */
2936 isci_task_save_for_upper_layer_completion(isci_host, request, response, 2951 isci_task_save_for_upper_layer_completion(isci_host, request, response,
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h
index a91d1d6060ce..324fb7b3ab42 100644
--- a/drivers/scsi/isci/request.h
+++ b/drivers/scsi/isci/request.h
@@ -672,97 +672,10 @@ static inline void isci_request_free(struct isci_host *isci_host,
672struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, 672struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost,
673 struct isci_tmf *isci_tmf, 673 struct isci_tmf *isci_tmf,
674 gfp_t gfp_flags); 674 gfp_t gfp_flags);
675
676int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, 675int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev,
677 struct sas_task *task, gfp_t gfp_flags); 676 struct sas_task *task, gfp_t gfp_flags);
678 677void isci_terminate_pending_requests(struct isci_host *ihost,
679/** 678 struct isci_remote_device *idev);
680 * isci_request_unmap_sgl() - This function unmaps the DMA address of a given
681 * sgl
682 * @request: This parameter points to the isci_request object
683 * @*pdev: This Parameter is the pci_device struct for the controller
684 *
685 */
686static inline void
687isci_request_unmap_sgl(struct isci_request *request, struct pci_dev *pdev)
688{
689 struct sas_task *task = isci_request_access_task(request);
690
691 dev_dbg(&request->isci_host->pdev->dev,
692 "%s: request = %p, task = %p,\n"
693 "task->data_dir = %d, is_sata = %d\n ",
694 __func__,
695 request,
696 task,
697 task->data_dir,
698 sas_protocol_ata(task->task_proto));
699
700 if ((task->data_dir != PCI_DMA_NONE) &&
701 !sas_protocol_ata(task->task_proto)) {
702 if (task->num_scatter == 0)
703 /* 0 indicates a single dma address */
704 dma_unmap_single(
705 &pdev->dev,
706 request->zero_scatter_daddr,
707 task->total_xfer_len,
708 task->data_dir
709 );
710
711 else /* unmap the sgl dma addresses */
712 dma_unmap_sg(
713 &pdev->dev,
714 task->scatter,
715 request->num_sg_entries,
716 task->data_dir
717 );
718 }
719}
720
721/**
722 * isci_request_io_request_get_next_sge() - This function is called by the sci
723 * core to retrieve the next sge for a given request.
724 * @request: This parameter is the isci_request object.
725 * @current_sge_address: This parameter is the last sge retrieved by the sci
726 * core for this request.
727 *
728 * pointer to the next sge for specified request.
729 */
730static inline void *
731isci_request_io_request_get_next_sge(struct isci_request *request,
732 void *current_sge_address)
733{
734 struct sas_task *task = isci_request_access_task(request);
735 void *ret = NULL;
736
737 dev_dbg(&request->isci_host->pdev->dev,
738 "%s: request = %p, "
739 "current_sge_address = %p, "
740 "num_scatter = %d\n",
741 __func__,
742 request,
743 current_sge_address,
744 task->num_scatter);
745
746 if (!current_sge_address) /* First time through.. */
747 ret = task->scatter; /* always task->scatter */
748 else if (task->num_scatter == 0) /* Next element, if num_scatter == 0 */
749 ret = NULL; /* there is only one element. */
750 else
751 ret = sg_next(current_sge_address); /* sg_next returns NULL
752 * for the last element
753 */
754
755 dev_dbg(&request->isci_host->pdev->dev,
756 "%s: next sge address = %p\n",
757 __func__,
758 ret);
759
760 return ret;
761}
762
763void
764isci_terminate_pending_requests(struct isci_host *ihost,
765 struct isci_remote_device *idev);
766enum sci_status 679enum sci_status
767scic_task_request_construct(struct scic_sds_controller *scic, 680scic_task_request_construct(struct scic_sds_controller *scic,
768 struct scic_sds_remote_device *sci_dev, 681 struct scic_sds_remote_device *sci_dev,