diff options
-rw-r--r-- | drivers/scsi/libata-core.c | 33 | ||||
-rw-r--r-- | drivers/scsi/sata_nv.c | 3 | ||||
-rw-r--r-- | drivers/scsi/sata_promise.c | 3 | ||||
-rw-r--r-- | drivers/scsi/sata_qstor.c | 6 | ||||
-rw-r--r-- | drivers/scsi/sata_sx4.c | 3 | ||||
-rw-r--r-- | drivers/scsi/sata_vsc.c | 3 | ||||
-rw-r--r-- | include/linux/libata.h | 2 |
7 files changed, 36 insertions, 17 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 9a6aacf467b8..c92439fe5dae 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -3350,11 +3350,13 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc) | |||
3350 | break; | 3350 | break; |
3351 | 3351 | ||
3352 | case ATA_PROT_ATAPI_NODATA: | 3352 | case ATA_PROT_ATAPI_NODATA: |
3353 | ap->flags |= ATA_FLAG_NOINTR; | ||
3353 | ata_tf_to_host_nolock(ap, &qc->tf); | 3354 | ata_tf_to_host_nolock(ap, &qc->tf); |
3354 | queue_work(ata_wq, &ap->packet_task); | 3355 | queue_work(ata_wq, &ap->packet_task); |
3355 | break; | 3356 | break; |
3356 | 3357 | ||
3357 | case ATA_PROT_ATAPI_DMA: | 3358 | case ATA_PROT_ATAPI_DMA: |
3359 | ap->flags |= ATA_FLAG_NOINTR; | ||
3358 | ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ | 3360 | ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ |
3359 | ap->ops->bmdma_setup(qc); /* set up bmdma */ | 3361 | ap->ops->bmdma_setup(qc); /* set up bmdma */ |
3360 | queue_work(ata_wq, &ap->packet_task); | 3362 | queue_work(ata_wq, &ap->packet_task); |
@@ -3708,7 +3710,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | |||
3708 | struct ata_port *ap; | 3710 | struct ata_port *ap; |
3709 | 3711 | ||
3710 | ap = host_set->ports[i]; | 3712 | ap = host_set->ports[i]; |
3711 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 3713 | if (ap && |
3714 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
3712 | struct ata_queued_cmd *qc; | 3715 | struct ata_queued_cmd *qc; |
3713 | 3716 | ||
3714 | qc = ata_qc_from_tag(ap, ap->active_tag); | 3717 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -3760,19 +3763,27 @@ static void atapi_packet_task(void *_data) | |||
3760 | /* send SCSI cdb */ | 3763 | /* send SCSI cdb */ |
3761 | DPRINTK("send cdb\n"); | 3764 | DPRINTK("send cdb\n"); |
3762 | assert(ap->cdb_len >= 12); | 3765 | assert(ap->cdb_len >= 12); |
3763 | ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); | ||
3764 | 3766 | ||
3765 | /* if we are DMA'ing, irq handler takes over from here */ | 3767 | if (qc->tf.protocol == ATA_PROT_ATAPI_DMA || |
3766 | if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) | 3768 | qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { |
3767 | ap->ops->bmdma_start(qc); /* initiate bmdma */ | 3769 | unsigned long flags; |
3768 | 3770 | ||
3769 | /* non-data commands are also handled via irq */ | 3771 | /* Once we're done issuing command and kicking bmdma, |
3770 | else if (qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { | 3772 | * irq handler takes over. To not lose irq, we need |
3771 | /* do nothing */ | 3773 | * to clear NOINTR flag before sending cdb, but |
3772 | } | 3774 | * interrupt handler shouldn't be invoked before we're |
3775 | * finished. Hence, the following locking. | ||
3776 | */ | ||
3777 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
3778 | ap->flags &= ~ATA_FLAG_NOINTR; | ||
3779 | ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); | ||
3780 | if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) | ||
3781 | ap->ops->bmdma_start(qc); /* initiate bmdma */ | ||
3782 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
3783 | } else { | ||
3784 | ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); | ||
3773 | 3785 | ||
3774 | /* PIO commands are handled by polling */ | 3786 | /* PIO commands are handled by polling */ |
3775 | else { | ||
3776 | ap->pio_task_state = PIO_ST; | 3787 | ap->pio_task_state = PIO_ST; |
3777 | queue_work(ata_wq, &ap->pio_task); | 3788 | queue_work(ata_wq, &ap->pio_task); |
3778 | } | 3789 | } |
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index 9b9142790bd6..41a3421b02b4 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c | |||
@@ -291,7 +291,8 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance, | |||
291 | struct ata_port *ap; | 291 | struct ata_port *ap; |
292 | 292 | ||
293 | ap = host_set->ports[i]; | 293 | ap = host_set->ports[i]; |
294 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 294 | if (ap && |
295 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
295 | struct ata_queued_cmd *qc; | 296 | struct ata_queued_cmd *qc; |
296 | 297 | ||
297 | qc = ata_qc_from_tag(ap, ap->active_tag); | 298 | qc = ata_qc_from_tag(ap, ap->active_tag); |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index cc613b3c6ce6..6defd7962359 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -445,7 +445,8 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r | |||
445 | VPRINTK("port %u\n", i); | 445 | VPRINTK("port %u\n", i); |
446 | ap = host_set->ports[i]; | 446 | ap = host_set->ports[i]; |
447 | tmp = mask & (1 << (i + 1)); | 447 | tmp = mask & (1 << (i + 1)); |
448 | if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 448 | if (tmp && ap && |
449 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
449 | struct ata_queued_cmd *qc; | 450 | struct ata_queued_cmd *qc; |
450 | 451 | ||
451 | qc = ata_qc_from_tag(ap, ap->active_tag); | 452 | qc = ata_qc_from_tag(ap, ap->active_tag); |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index dca9ed7ac760..08a84042ce09 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -386,7 +386,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) | |||
386 | DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", | 386 | DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", |
387 | sff1, sff0, port_no, sHST, sDST); | 387 | sff1, sff0, port_no, sHST, sDST); |
388 | handled = 1; | 388 | handled = 1; |
389 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 389 | if (ap && !(ap->flags & |
390 | (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { | ||
390 | struct ata_queued_cmd *qc; | 391 | struct ata_queued_cmd *qc; |
391 | struct qs_port_priv *pp = ap->private_data; | 392 | struct qs_port_priv *pp = ap->private_data; |
392 | if (!pp || pp->state != qs_state_pkt) | 393 | if (!pp || pp->state != qs_state_pkt) |
@@ -417,7 +418,8 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) | |||
417 | for (port_no = 0; port_no < host_set->n_ports; ++port_no) { | 418 | for (port_no = 0; port_no < host_set->n_ports; ++port_no) { |
418 | struct ata_port *ap; | 419 | struct ata_port *ap; |
419 | ap = host_set->ports[port_no]; | 420 | ap = host_set->ports[port_no]; |
420 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 421 | if (ap && |
422 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
421 | struct ata_queued_cmd *qc; | 423 | struct ata_queued_cmd *qc; |
422 | struct qs_port_priv *pp = ap->private_data; | 424 | struct qs_port_priv *pp = ap->private_data; |
423 | if (!pp || pp->state != qs_state_mmio) | 425 | if (!pp || pp->state != qs_state_mmio) |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 76644ea62d67..e2db499f22dd 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -825,7 +825,8 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re | |||
825 | ap = host_set->ports[port_no]; | 825 | ap = host_set->ports[port_no]; |
826 | tmp = mask & (1 << i); | 826 | tmp = mask & (1 << i); |
827 | VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); | 827 | VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); |
828 | if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 828 | if (tmp && ap && |
829 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
829 | struct ata_queued_cmd *qc; | 830 | struct ata_queued_cmd *qc; |
830 | 831 | ||
831 | qc = ata_qc_from_tag(ap, ap->active_tag); | 832 | qc = ata_qc_from_tag(ap, ap->active_tag); |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index cb3a6d89cf00..6f2562171be0 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -173,7 +173,8 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, | |||
173 | struct ata_port *ap; | 173 | struct ata_port *ap; |
174 | 174 | ||
175 | ap = host_set->ports[i]; | 175 | ap = host_set->ports[i]; |
176 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 176 | if (ap && !(ap->flags & |
177 | (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { | ||
177 | struct ata_queued_cmd *qc; | 178 | struct ata_queued_cmd *qc; |
178 | 179 | ||
179 | qc = ata_qc_from_tag(ap, ap->active_tag); | 180 | qc = ata_qc_from_tag(ap, ap->active_tag); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 85b0aaee0ef8..724b7d1c18ea 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -113,6 +113,8 @@ enum { | |||
113 | ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ | 113 | ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ |
114 | ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ | 114 | ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ |
115 | ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ | 115 | ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ |
116 | ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once | ||
117 | * proper HSM is in place. */ | ||
116 | 118 | ||
117 | ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ | 119 | ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ |
118 | ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ | 120 | ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ |