diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-21 20:51:42 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-21 20:51:42 +0100 |
commit | cdc194705d26fdd7fc5446b5d830f2bbe2b22c30 (patch) | |
tree | 91a643f38d490e092855792576a7e903a419cfe1 /drivers/scsi/aacraid/dpcsup.c | |
parent | Merge tag 'for-4.11/linus-merge-signed' of git://git.kernel.dk/linux-block (diff) | |
parent | scsi: megaraid_sas: handle dma_addr_t right on 32-bit (diff) | |
download | linux-cdc194705d26fdd7fc5446b5d830f2bbe2b22c30.tar.xz linux-cdc194705d26fdd7fc5446b5d830f2bbe2b22c30.zip |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This update includes the usual round of major driver updates (ncr5380,
ufs, lpfc, be2iscsi, hisi_sas, storvsc, cxlflash, aacraid,
megaraid_sas, ...).
There's also an assortment of minor fixes and the major update of
switching a bunch of drivers to pci_alloc_irq_vectors from Christoph"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (188 commits)
scsi: megaraid_sas: handle dma_addr_t right on 32-bit
scsi: megaraid_sas: array overflow in megasas_dump_frame()
scsi: snic: switch to pci_irq_alloc_vectors
scsi: megaraid_sas: driver version upgrade
scsi: megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2
scsi: megaraid_sas: Indentation and smatch warning fixes
scsi: megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints
scsi: megaraid_sas: Increase internal command pool
scsi: megaraid_sas: Use synchronize_irq to wait for IRQs to complete
scsi: megaraid_sas: Bail out the driver load if ld_list_query fails
scsi: megaraid_sas: Change build_mpt_mfi_pass_thru to return void
scsi: megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR
scsi: megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool
scsi: megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion
scsi: megaraid_sas: megasas_return_cmd does not memset IO frame to zero
scsi: megaraid_sas: max_fw_cmds are decremented twice, remove duplicate
scsi: megaraid_sas: update can_queue only if the new value is less
scsi: megaraid_sas: Change max_cmd from u32 to u16 in all functions
scsi: megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID
scsi: megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD
...
Diffstat (limited to 'drivers/scsi/aacraid/dpcsup.c')
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 159 |
1 files changed, 103 insertions, 56 deletions
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index 7e836205aef1..417ba349e10e 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -6,7 +6,8 @@ * Adaptec aacraid device driver for Linux. * * Copyright (c) 2000-2010 Adaptec, Inc. - * 2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com) + * 2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com) + * 2016-2017 Microsemi Corp. (aacraid@microsemi.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -122,7 +123,6 @@ unsigned int aac_response_normal(struct aac_queue * q) * NOTE: we cannot touch the fib after this * call, because it may have been deallocated. */ - fib->flags &= FIB_CONTEXT_FLAG_FASTRESP; fib->callback(fib->callback_data, fib); } else { unsigned long flagv; @@ -251,8 +251,9 @@ static void aac_aif_callback(void *context, struct fib * fibptr) BUG_ON(fibptr == NULL); dev = fibptr->dev; - if (fibptr->hw_fib_va->header.XferState & - cpu_to_le32(NoMoreAifDataAvailable)) { + if ((fibptr->hw_fib_va->header.XferState & + cpu_to_le32(NoMoreAifDataAvailable)) || + dev->sa_firmware) { aac_fib_complete(fibptr); aac_fib_free(fibptr); return; @@ -282,8 +283,8 @@ static void aac_aif_callback(void *context, struct fib * fibptr) * know there is a response on our normal priority queue. We will pull off * all QE there are and wake up all the waiters before exiting. */ -unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, - int isAif, int isFastResponse, struct hw_fib *aif_fib) +unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif, + int isFastResponse, struct hw_fib *aif_fib) { unsigned long mflags; dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); @@ -305,12 +306,14 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, kfree (fib); return 1; } - if (aif_fib != NULL) { + if (dev->sa_firmware) { + fib->hbacmd_size = index; /* store event type */ + } else if (aif_fib != NULL) { memcpy(hw_fib, aif_fib, sizeof(struct hw_fib)); } else { - memcpy(hw_fib, - (struct hw_fib *)(((uintptr_t)(dev->regs.sa)) + - index), sizeof(struct hw_fib)); + memcpy(hw_fib, (struct hw_fib *) + (((uintptr_t)(dev->regs.sa)) + index), + sizeof(struct hw_fib)); } INIT_LIST_HEAD(&fib->fiblink); fib->type = FSAFS_NTC_FIB_CONTEXT; @@ -344,7 +347,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, (fib_callback)aac_aif_callback, fibctx); } else { struct fib *fib = &dev->fibs[index]; - struct hw_fib * hwfib = fib->hw_fib_va; + int start_callback = 0; /* * Remove this fib from the Outstanding I/O queue. @@ -362,60 +365,104 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, return 0; } - if (isFastResponse) { - /* - * Doctor the fib - */ - *(__le32 *)hwfib->data = cpu_to_le32(ST_OK); - hwfib->header.XferState |= cpu_to_le32(AdapterProcessed); - fib->flags |= FIB_CONTEXT_FLAG_FASTRESP; - } - FIB_COUNTER_INCREMENT(aac_config.FibRecved); - if (hwfib->header.Command == cpu_to_le16(NuFileSystem)) - { - __le32 *pstatus = (__le32 *)hwfib->data; - if (*pstatus & cpu_to_le32(0xffff0000)) - *pstatus = cpu_to_le32(ST_OK); - } - if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) - { - if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected)) - FIB_COUNTER_INCREMENT(aac_config.NoResponseRecved); - else - FIB_COUNTER_INCREMENT(aac_config.AsyncRecved); - /* - * NOTE: we cannot touch the fib after this - * call, because it may have been deallocated. - */ - if (likely(fib->callback && fib->callback_data)) { - fib->flags &= FIB_CONTEXT_FLAG_FASTRESP; - fib->callback(fib->callback_data, fib); - } else - dev_info(&dev->pdev->dev, - "Invalid callback_fib[%d] (*%p)(%p)\n", - index, fib->callback, fib->callback_data); + if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) { + + if (isFastResponse) + fib->flags |= FIB_CONTEXT_FLAG_FASTRESP; + + if (fib->callback) { + start_callback = 1; + } else { + unsigned long flagv; + int complete = 0; + + dprintk((KERN_INFO "event_wait up\n")); + spin_lock_irqsave(&fib->event_lock, flagv); + if (fib->done == 2) { + fib->done = 1; + complete = 1; + } else { + fib->done = 1; + up(&fib->event_wait); + } + spin_unlock_irqrestore(&fib->event_lock, flagv); + + spin_lock_irqsave(&dev->manage_lock, mflags); + dev->management_fib_count--; + spin_unlock_irqrestore(&dev->manage_lock, + mflags); + + FIB_COUNTER_INCREMENT(aac_config.NativeRecved); + if (complete) + aac_fib_complete(fib); + } } else { - unsigned long flagv; - dprintk((KERN_INFO "event_wait up\n")); - spin_lock_irqsave(&fib->event_lock, flagv); - if (!fib->done) { - fib->done = 1; - up(&fib->event_wait); + struct hw_fib *hwfib = fib->hw_fib_va; + + if (isFastResponse) { + /* Doctor the fib */ + *(__le32 *)hwfib->data = cpu_to_le32(ST_OK); + hwfib->header.XferState |= + cpu_to_le32(AdapterProcessed); + fib->flags |= FIB_CONTEXT_FLAG_FASTRESP; } - spin_unlock_irqrestore(&fib->event_lock, flagv); - spin_lock_irqsave(&dev->manage_lock, mflags); - dev->management_fib_count--; - spin_unlock_irqrestore(&dev->manage_lock, mflags); + if (hwfib->header.Command == + cpu_to_le16(NuFileSystem)) { + __le32 *pstatus = (__le32 *)hwfib->data; - FIB_COUNTER_INCREMENT(aac_config.NormalRecved); - if (fib->done == 2) { + if (*pstatus & cpu_to_le32(0xffff0000)) + *pstatus = cpu_to_le32(ST_OK); + } + if (hwfib->header.XferState & + cpu_to_le32(NoResponseExpected | Async)) { + if (hwfib->header.XferState & cpu_to_le32( + NoResponseExpected)) + FIB_COUNTER_INCREMENT( + aac_config.NoResponseRecved); + else + FIB_COUNTER_INCREMENT( + aac_config.AsyncRecved); + start_callback = 1; + } else { + unsigned long flagv; + int complete = 0; + + dprintk((KERN_INFO "event_wait up\n")); spin_lock_irqsave(&fib->event_lock, flagv); - fib->done = 0; + if (fib->done == 2) { + fib->done = 1; + complete = 1; + } else { + fib->done = 1; + up(&fib->event_wait); + } spin_unlock_irqrestore(&fib->event_lock, flagv); + + spin_lock_irqsave(&dev->manage_lock, mflags); + dev->management_fib_count--; + spin_unlock_irqrestore(&dev->manage_lock, + mflags); + + FIB_COUNTER_INCREMENT(aac_config.NormalRecved); + if (complete) + aac_fib_complete(fib); + } + } + + + if (start_callback) { + /* + * NOTE: we cannot touch the fib after this + * call, because it may have been deallocated. + */ + if (likely(fib->callback && fib->callback_data)) { + fib->callback(fib->callback_data, fib); + } else { aac_fib_complete(fib); + aac_fib_free(fib); } } |