diff options
author | Tejun Heo <tj@kernel.org> | 2010-05-10 15:41:30 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-05-17 22:49:02 -0400 |
commit | 3e4ec3443f70fbe144799ccf0b1c3797f78d1715 (patch) | |
tree | cfb297e42075baacbbabfb6034e3e7c9a44c73b2 /drivers/ata/sata_qstor.c | |
parent | c7a8209f766961eea4cfc6f22d2d6e06ef63546c (diff) |
libata: kill ATA_FLAG_DISABLED
ATA_FLAG_DISABLED is only used by drivers which don't use
->error_handler framework and is largely broken. Its only meaningful
function is to make irq handlers skip processing if the flag is set,
which is largely useless and even harmful as it makes those ports more
likely to cause IRQ storms.
Kill ATA_FLAG_DISABLED and makes the callers disable attached devices
instead. ata_port_probe() and ata_port_disable() which manipulate the
flag are also killed.
This simplifies condition check in IRQ handlers. While updating IRQ
handlers, remove ap NULL check as libata guarantees consecutive port
allocation (unoccupied ports are initialized with dummies) and
long-obsolete ATA_QCFLAG_ACTIVE check (checked by ata_qc_from_tag()).
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_qstor.c')
-rw-r--r-- | drivers/ata/sata_qstor.c | 79 |
1 files changed, 37 insertions, 42 deletions
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 92ba45e6689b..febc6e748420 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -404,26 +404,24 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host) | |||
404 | u8 sHST = sff1 & 0x3f; /* host status */ | 404 | u8 sHST = sff1 & 0x3f; /* host status */ |
405 | unsigned int port_no = (sff1 >> 8) & 0x03; | 405 | unsigned int port_no = (sff1 >> 8) & 0x03; |
406 | struct ata_port *ap = host->ports[port_no]; | 406 | struct ata_port *ap = host->ports[port_no]; |
407 | struct qs_port_priv *pp = ap->private_data; | ||
408 | struct ata_queued_cmd *qc; | ||
407 | 409 | ||
408 | DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", | 410 | DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", |
409 | sff1, sff0, port_no, sHST, sDST); | 411 | sff1, sff0, port_no, sHST, sDST); |
410 | handled = 1; | 412 | handled = 1; |
411 | if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { | 413 | if (!pp || pp->state != qs_state_pkt) |
412 | struct ata_queued_cmd *qc; | 414 | continue; |
413 | struct qs_port_priv *pp = ap->private_data; | 415 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
414 | if (!pp || pp->state != qs_state_pkt) | 416 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { |
415 | continue; | 417 | switch (sHST) { |
416 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 418 | case 0: /* successful CPB */ |
417 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { | 419 | case 3: /* device error */ |
418 | switch (sHST) { | 420 | qs_enter_reg_mode(qc->ap); |
419 | case 0: /* successful CPB */ | 421 | qs_do_or_die(qc, sDST); |
420 | case 3: /* device error */ | 422 | break; |
421 | qs_enter_reg_mode(qc->ap); | 423 | default: |
422 | qs_do_or_die(qc, sDST); | 424 | break; |
423 | break; | ||
424 | default: | ||
425 | break; | ||
426 | } | ||
427 | } | 425 | } |
428 | } | 426 | } |
429 | } | 427 | } |
@@ -436,33 +434,30 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) | |||
436 | unsigned int handled = 0, port_no; | 434 | unsigned int handled = 0, port_no; |
437 | 435 | ||
438 | for (port_no = 0; port_no < host->n_ports; ++port_no) { | 436 | for (port_no = 0; port_no < host->n_ports; ++port_no) { |
439 | struct ata_port *ap; | 437 | struct ata_port *ap = host->ports[port_no]; |
440 | ap = host->ports[port_no]; | 438 | struct qs_port_priv *pp = ap->private_data; |
441 | if (ap && | 439 | struct ata_queued_cmd *qc; |
442 | !(ap->flags & ATA_FLAG_DISABLED)) { | 440 | |
443 | struct ata_queued_cmd *qc; | 441 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
444 | struct qs_port_priv *pp; | 442 | if (!qc) { |
445 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 443 | /* |
446 | if (!qc || !(qc->flags & ATA_QCFLAG_ACTIVE)) { | 444 | * The qstor hardware generates spurious |
447 | /* | 445 | * interrupts from time to time when switching |
448 | * The qstor hardware generates spurious | 446 | * in and out of packet mode. There's no |
449 | * interrupts from time to time when switching | 447 | * obvious way to know if we're here now due |
450 | * in and out of packet mode. | 448 | * to that, so just ack the irq and pretend we |
451 | * There's no obvious way to know if we're | 449 | * knew it was ours.. (ugh). This does not |
452 | * here now due to that, so just ack the irq | 450 | * affect packet mode. |
453 | * and pretend we knew it was ours.. (ugh). | 451 | */ |
454 | * This does not affect packet mode. | 452 | ata_sff_check_status(ap); |
455 | */ | 453 | handled = 1; |
456 | ata_sff_check_status(ap); | 454 | continue; |
457 | handled = 1; | ||
458 | continue; | ||
459 | } | ||
460 | pp = ap->private_data; | ||
461 | if (!pp || pp->state != qs_state_mmio) | ||
462 | continue; | ||
463 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) | ||
464 | handled |= ata_sff_host_intr(ap, qc); | ||
465 | } | 455 | } |
456 | |||
457 | if (!pp || pp->state != qs_state_mmio) | ||
458 | continue; | ||
459 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) | ||
460 | handled |= ata_sff_host_intr(ap, qc); | ||
466 | } | 461 | } |
467 | return handled; | 462 | return handled; |
468 | } | 463 | } |