aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_nv.c
diff options
context:
space:
mode:
authorRobert Hancock <hancockr@shaw.ca>2007-02-19 20:03:08 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-21 04:58:19 -0500
commit721449bf0d51213fe3abf0ac3e3561ef9ea7827a (patch)
tree7f2180d3f8454216e6a2c1ce9aa8602bfb5b1d61 /drivers/ata/sata_nv.c
parentac3d6b869f1f2d8ee1bf7b0ba45cd7daed9b9513 (diff)
sata_nv: Use notifier for completion checks
The hardware provides us a notifier register that indicates what command tags have completed. Use this to determine which CPBs to check, rather than blindly checking all active CPBs. This should provide a minor performance win, since if the controller has touched some of these incomplete CPBs, accessing them will likely result in a cache miss. Signed-off-by: Robert Hancock <hancockr@shaw.ca> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_nv.c')
-rw-r--r--drivers/ata/sata_nv.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 57dace43b33..745d85686f5 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -854,22 +854,14 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
854 854
855 if (status & (NV_ADMA_STAT_DONE | 855 if (status & (NV_ADMA_STAT_DONE |
856 NV_ADMA_STAT_CPBERR)) { 856 NV_ADMA_STAT_CPBERR)) {
857 u32 check_commands = notifier | notifier_error;
858 int pos, error = 0;
857 /** Check CPBs for completed commands */ 859 /** Check CPBs for completed commands */
858 860 while ((pos = ffs(check_commands)) && !error) {
859 if (ata_tag_valid(ap->active_tag)) { 861 pos--;
860 /* Non-NCQ command */ 862 error = nv_adma_check_cpb(ap, pos,
861 nv_adma_check_cpb(ap, ap->active_tag, 863 notifier_error & (1 << pos) );
862 notifier_error & (1 << ap->active_tag)); 864 check_commands &= ~(1 << pos );
863 } else {
864 int pos, error = 0;
865 u32 active = ap->sactive;
866
867 while ((pos = ffs(active)) && !error) {
868 pos--;
869 error = nv_adma_check_cpb(ap, pos,
870 notifier_error & (1 << pos) );
871 active &= ~(1 << pos );
872 }
873 } 865 }
874 } 866 }
875 } 867 }