summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorRobert Hancock2007-02-20 02:03:08 +0100
committerJeff Garzik2007-02-21 10:58:19 +0100
commit721449bf0d51213fe3abf0ac3e3561ef9ea7827a (patch)
tree7f2180d3f8454216e6a2c1ce9aa8602bfb5b1d61 /drivers/ata
parentsata_nv: Cleanup taskfile setup (diff)
downloadkernel-qcow2-linux-721449bf0d51213fe3abf0ac3e3561ef9ea7827a.tar.gz
kernel-qcow2-linux-721449bf0d51213fe3abf0ac3e3561ef9ea7827a.tar.xz
kernel-qcow2-linux-721449bf0d51213fe3abf0ac3e3561ef9ea7827a.zip
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')
-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 57dace43b337..745d85686f5e 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 );
}
}
}