aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Hancock <hancockr@shaw.ca>2007-02-19 19:03:08 -0600
committerJeff Garzik <jeff@garzik.org>2007-02-21 04:58:19 -0500
commit721449bf0d51213fe3abf0ac3e3561ef9ea7827a (patch)
tree7f2180d3f8454216e6a2c1ce9aa8602bfb5b1d61
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>
-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)
if (status & (NV_ADMA_STAT_DONE |
NV_ADMA_STAT_CPBERR)) {
+ u32 check_commands = notifier | notifier_error;
+ int pos, error = 0;
/** Check CPBs for completed commands */
-
- if (ata_tag_valid(ap->active_tag)) {
- /* Non-NCQ command */
- nv_adma_check_cpb(ap, ap->active_tag,
- notifier_error & (1 << ap->active_tag));
- } else {
- int pos, error = 0;
- u32 active = ap->sactive;
-
- while ((pos = ffs(active)) && !error) {
- pos--;
- error = nv_adma_check_cpb(ap, pos,
- notifier_error & (1 << pos) );
- active &= ~(1 << pos );
- }
+ while ((pos = ffs(check_commands)) && !error) {
+ pos--;
+ error = nv_adma_check_cpb(ap, pos,
+ notifier_error & (1 << pos) );
+ check_commands &= ~(1 << pos );
}
}
}