aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-04-06 15:04:33 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 14:45:24 -0400
commit49198b371e2da20548d1408a7d3a8dea2f91263c (patch)
treeb04993f74b2798bbf9e18f952ec6d1fd18cb0db6 /drivers/scsi/lpfc/lpfc_sli.c
parent6c8eea54ec62c1a3fdb21de583639c49dcdc8811 (diff)
[SCSI] lpfc 8.3.12: Critical fixes
- Move the code to increase the sg seg count for LP21000 adapters. - Check pcmd on command completion before dereferencing it. - Clear queue memory when creating firmware queues to prevent stale entries. - Replace the use of PAGE_SIZE in many areas that assumed it was always 4k. - Add an else clause to a conditional that needed to unlock the hba_lock. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 2c88999b7095..73259bca1d14 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4296,7 +4296,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
4296 "2570 Failed to read FCoE parameters\n"); 4296 "2570 Failed to read FCoE parameters\n");
4297 4297
4298 /* Issue READ_REV to collect vpd and FW information. */ 4298 /* Issue READ_REV to collect vpd and FW information. */
4299 vpd_size = PAGE_SIZE; 4299 vpd_size = SLI4_PAGE_SIZE;
4300 vpd = kzalloc(vpd_size, GFP_KERNEL); 4300 vpd = kzalloc(vpd_size, GFP_KERNEL);
4301 if (!vpd) { 4301 if (!vpd) {
4302 rc = -ENOMEM; 4302 rc = -ENOMEM;
@@ -7136,13 +7136,11 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
7136 */ 7136 */
7137 list_del_init(&abort_iocb->list); 7137 list_del_init(&abort_iocb->list);
7138 pring->txcmplq_cnt--; 7138 pring->txcmplq_cnt--;
7139 spin_unlock_irq(&phba->hbalock);
7140 7139
7141 /* Firmware could still be in progress of DMAing 7140 /* Firmware could still be in progress of DMAing
7142 * payload, so don't free data buffer till after 7141 * payload, so don't free data buffer till after
7143 * a hbeat. 7142 * a hbeat.
7144 */ 7143 */
7145 spin_lock_irq(&phba->hbalock);
7146 abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE; 7144 abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE;
7147 abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; 7145 abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED;
7148 spin_unlock_irq(&phba->hbalock); 7146 spin_unlock_irq(&phba->hbalock);
@@ -7150,7 +7148,8 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
7150 abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; 7148 abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT;
7151 abort_iocb->iocb.un.ulpWord[4] = IOERR_ABORT_REQUESTED; 7149 abort_iocb->iocb.un.ulpWord[4] = IOERR_ABORT_REQUESTED;
7152 (abort_iocb->iocb_cmpl)(phba, abort_iocb, abort_iocb); 7150 (abort_iocb->iocb_cmpl)(phba, abort_iocb, abort_iocb);
7153 } 7151 } else
7152 spin_unlock_irq(&phba->hbalock);
7154 } 7153 }
7155 7154
7156 lpfc_sli_release_iocbq(phba, cmdiocb); 7155 lpfc_sli_release_iocbq(phba, cmdiocb);
@@ -9544,7 +9543,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue)
9544 while (!list_empty(&queue->page_list)) { 9543 while (!list_empty(&queue->page_list)) {
9545 list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf, 9544 list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf,
9546 list); 9545 list);
9547 dma_free_coherent(&queue->phba->pcidev->dev, PAGE_SIZE, 9546 dma_free_coherent(&queue->phba->pcidev->dev, SLI4_PAGE_SIZE,
9548 dmabuf->virt, dmabuf->phys); 9547 dmabuf->virt, dmabuf->phys);
9549 kfree(dmabuf); 9548 kfree(dmabuf);
9550 } 9549 }
@@ -9572,7 +9571,6 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size,
9572 void *dma_pointer; 9571 void *dma_pointer;
9573 uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; 9572 uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
9574 9573
9575
9576 if (!phba->sli4_hba.pc_sli4_params.supported) 9574 if (!phba->sli4_hba.pc_sli4_params.supported)
9577 hw_page_size = SLI4_PAGE_SIZE; 9575 hw_page_size = SLI4_PAGE_SIZE;
9578 9576
@@ -9647,6 +9645,10 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax)
9647 uint32_t shdr_status, shdr_add_status; 9645 uint32_t shdr_status, shdr_add_status;
9648 union lpfc_sli4_cfg_shdr *shdr; 9646 union lpfc_sli4_cfg_shdr *shdr;
9649 uint16_t dmult; 9647 uint16_t dmult;
9648 uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
9649
9650 if (!phba->sli4_hba.pc_sli4_params.supported)
9651 hw_page_size = SLI4_PAGE_SIZE;
9650 9652
9651 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 9653 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
9652 if (!mbox) 9654 if (!mbox)
@@ -9696,6 +9698,7 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax)
9696 break; 9698 break;
9697 } 9699 }
9698 list_for_each_entry(dmabuf, &eq->page_list, list) { 9700 list_for_each_entry(dmabuf, &eq->page_list, list) {
9701 memset(dmabuf->virt, 0, hw_page_size);
9699 eq_create->u.request.page[dmabuf->buffer_tag].addr_lo = 9702 eq_create->u.request.page[dmabuf->buffer_tag].addr_lo =
9700 putPaddrLow(dmabuf->phys); 9703 putPaddrLow(dmabuf->phys);
9701 eq_create->u.request.page[dmabuf->buffer_tag].addr_hi = 9704 eq_create->u.request.page[dmabuf->buffer_tag].addr_hi =
@@ -9758,6 +9761,11 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
9758 int rc, length, status = 0; 9761 int rc, length, status = 0;
9759 uint32_t shdr_status, shdr_add_status; 9762 uint32_t shdr_status, shdr_add_status;
9760 union lpfc_sli4_cfg_shdr *shdr; 9763 union lpfc_sli4_cfg_shdr *shdr;
9764 uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
9765
9766 if (!phba->sli4_hba.pc_sli4_params.supported)
9767 hw_page_size = SLI4_PAGE_SIZE;
9768
9761 9769
9762 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 9770 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
9763 if (!mbox) 9771 if (!mbox)
@@ -9795,6 +9803,7 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
9795 break; 9803 break;
9796 } 9804 }
9797 list_for_each_entry(dmabuf, &cq->page_list, list) { 9805 list_for_each_entry(dmabuf, &cq->page_list, list) {
9806 memset(dmabuf->virt, 0, hw_page_size);
9798 cq_create->u.request.page[dmabuf->buffer_tag].addr_lo = 9807 cq_create->u.request.page[dmabuf->buffer_tag].addr_lo =
9799 putPaddrLow(dmabuf->phys); 9808 putPaddrLow(dmabuf->phys);
9800 cq_create->u.request.page[dmabuf->buffer_tag].addr_hi = 9809 cq_create->u.request.page[dmabuf->buffer_tag].addr_hi =
@@ -9924,7 +9933,10 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
9924 int rc, length, status = 0; 9933 int rc, length, status = 0;
9925 uint32_t shdr_status, shdr_add_status; 9934 uint32_t shdr_status, shdr_add_status;
9926 union lpfc_sli4_cfg_shdr *shdr; 9935 union lpfc_sli4_cfg_shdr *shdr;
9936 uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
9927 9937
9938 if (!phba->sli4_hba.pc_sli4_params.supported)
9939 hw_page_size = SLI4_PAGE_SIZE;
9928 9940
9929 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 9941 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
9930 if (!mbox) 9942 if (!mbox)
@@ -9973,6 +9985,7 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
9973 break; 9985 break;
9974 } 9986 }
9975 list_for_each_entry(dmabuf, &mq->page_list, list) { 9987 list_for_each_entry(dmabuf, &mq->page_list, list) {
9988 memset(dmabuf->virt, 0, hw_page_size);
9976 mq_create_ext->u.request.page[dmabuf->buffer_tag].addr_lo = 9989 mq_create_ext->u.request.page[dmabuf->buffer_tag].addr_lo =
9977 putPaddrLow(dmabuf->phys); 9990 putPaddrLow(dmabuf->phys);
9978 mq_create_ext->u.request.page[dmabuf->buffer_tag].addr_hi = 9991 mq_create_ext->u.request.page[dmabuf->buffer_tag].addr_hi =
@@ -10054,6 +10067,10 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
10054 int rc, length, status = 0; 10067 int rc, length, status = 0;
10055 uint32_t shdr_status, shdr_add_status; 10068 uint32_t shdr_status, shdr_add_status;
10056 union lpfc_sli4_cfg_shdr *shdr; 10069 union lpfc_sli4_cfg_shdr *shdr;
10070 uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
10071
10072 if (!phba->sli4_hba.pc_sli4_params.supported)
10073 hw_page_size = SLI4_PAGE_SIZE;
10057 10074
10058 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 10075 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
10059 if (!mbox) 10076 if (!mbox)
@@ -10069,6 +10086,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
10069 bf_set(lpfc_mbx_wq_create_cq_id, &wq_create->u.request, 10086 bf_set(lpfc_mbx_wq_create_cq_id, &wq_create->u.request,
10070 cq->queue_id); 10087 cq->queue_id);
10071 list_for_each_entry(dmabuf, &wq->page_list, list) { 10088 list_for_each_entry(dmabuf, &wq->page_list, list) {
10089 memset(dmabuf->virt, 0, hw_page_size);
10072 wq_create->u.request.page[dmabuf->buffer_tag].addr_lo = 10090 wq_create->u.request.page[dmabuf->buffer_tag].addr_lo =
10073 putPaddrLow(dmabuf->phys); 10091 putPaddrLow(dmabuf->phys);
10074 wq_create->u.request.page[dmabuf->buffer_tag].addr_hi = 10092 wq_create->u.request.page[dmabuf->buffer_tag].addr_hi =
@@ -10137,6 +10155,10 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
10137 int rc, length, status = 0; 10155 int rc, length, status = 0;
10138 uint32_t shdr_status, shdr_add_status; 10156 uint32_t shdr_status, shdr_add_status;
10139 union lpfc_sli4_cfg_shdr *shdr; 10157 union lpfc_sli4_cfg_shdr *shdr;
10158 uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
10159
10160 if (!phba->sli4_hba.pc_sli4_params.supported)
10161 hw_page_size = SLI4_PAGE_SIZE;
10140 10162
10141 if (hrq->entry_count != drq->entry_count) 10163 if (hrq->entry_count != drq->entry_count)
10142 return -EINVAL; 10164 return -EINVAL;
@@ -10181,6 +10203,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
10181 bf_set(lpfc_rq_context_buf_size, &rq_create->u.request.context, 10203 bf_set(lpfc_rq_context_buf_size, &rq_create->u.request.context,
10182 LPFC_HDR_BUF_SIZE); 10204 LPFC_HDR_BUF_SIZE);
10183 list_for_each_entry(dmabuf, &hrq->page_list, list) { 10205 list_for_each_entry(dmabuf, &hrq->page_list, list) {
10206 memset(dmabuf->virt, 0, hw_page_size);
10184 rq_create->u.request.page[dmabuf->buffer_tag].addr_lo = 10207 rq_create->u.request.page[dmabuf->buffer_tag].addr_lo =
10185 putPaddrLow(dmabuf->phys); 10208 putPaddrLow(dmabuf->phys);
10186 rq_create->u.request.page[dmabuf->buffer_tag].addr_hi = 10209 rq_create->u.request.page[dmabuf->buffer_tag].addr_hi =
@@ -10753,7 +10776,7 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba)
10753 10776
10754 reqlen = els_xri_cnt * sizeof(struct sgl_page_pairs) + 10777 reqlen = els_xri_cnt * sizeof(struct sgl_page_pairs) +
10755 sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); 10778 sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t);
10756 if (reqlen > PAGE_SIZE) { 10779 if (reqlen > SLI4_PAGE_SIZE) {
10757 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 10780 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
10758 "2559 Block sgl registration required DMA " 10781 "2559 Block sgl registration required DMA "
10759 "size (%d) great than a page\n", reqlen); 10782 "size (%d) great than a page\n", reqlen);
@@ -10859,7 +10882,7 @@ lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, struct list_head *sblist,
10859 /* Calculate the requested length of the dma memory */ 10882 /* Calculate the requested length of the dma memory */
10860 reqlen = cnt * sizeof(struct sgl_page_pairs) + 10883 reqlen = cnt * sizeof(struct sgl_page_pairs) +
10861 sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); 10884 sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t);
10862 if (reqlen > PAGE_SIZE) { 10885 if (reqlen > SLI4_PAGE_SIZE) {
10863 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 10886 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
10864 "0217 Block sgl registration required DMA " 10887 "0217 Block sgl registration required DMA "
10865 "size (%d) great than a page\n", reqlen); 10888 "size (%d) great than a page\n", reqlen);
@@ -11695,8 +11718,8 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
11695 * 11718 *
11696 * This routine is invoked to post rpi header templates to the 11719 * This routine is invoked to post rpi header templates to the
11697 * HBA consistent with the SLI-4 interface spec. This routine 11720 * HBA consistent with the SLI-4 interface spec. This routine
11698 * posts a PAGE_SIZE memory region to the port to hold up to 11721 * posts a SLI4_PAGE_SIZE memory region to the port to hold up to
11699 * PAGE_SIZE modulo 64 rpi context headers. 11722 * SLI4_PAGE_SIZE modulo 64 rpi context headers.
11700 * 11723 *
11701 * This routine does not require any locks. It's usage is expected 11724 * This routine does not require any locks. It's usage is expected
11702 * to be driver load or reset recovery when the driver is 11725 * to be driver load or reset recovery when the driver is
@@ -11799,8 +11822,8 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page)
11799 * 11822 *
11800 * This routine is invoked to post rpi header templates to the 11823 * This routine is invoked to post rpi header templates to the
11801 * HBA consistent with the SLI-4 interface spec. This routine 11824 * HBA consistent with the SLI-4 interface spec. This routine
11802 * posts a PAGE_SIZE memory region to the port to hold up to 11825 * posts a SLI4_PAGE_SIZE memory region to the port to hold up to
11803 * PAGE_SIZE modulo 64 rpi context headers. 11826 * SLI4_PAGE_SIZE modulo 64 rpi context headers.
11804 * 11827 *
11805 * Returns 11828 * Returns
11806 * A nonzero rpi defined as rpi_base <= rpi < max_rpi if successful 11829 * A nonzero rpi defined as rpi_base <= rpi < max_rpi if successful