diff options
author | Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com> | 2017-02-02 15:53:29 -0800 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-02-03 10:35:03 -0500 |
commit | 423400e64d377c0d8a2459795420681177e51e74 (patch) | |
tree | b7a0804cd17798df455cf297843283d7c28ec48b /drivers/scsi/aacraid/dpcsup.c | |
parent | 6223a39fe6fbbeef0877a56dc427a6351f22ef6c (diff) | |
download | linux-423400e64d377c0d8a2459795420681177e51e74.tar.bz2 |
scsi: aacraid: Include HBA direct interface
Added support to send direct pasthru srb commands from management utilty
to the controller.
Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/aacraid/dpcsup.c')
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 136 |
1 files changed, 90 insertions, 46 deletions
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index 8077dbad984e..c426ea2864ae 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -346,7 +346,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif, (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. @@ -364,60 +364,104 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif, 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); } } |