aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c33
-rw-r--r--drivers/scsi/sata_nv.c3
-rw-r--r--drivers/scsi/sata_promise.c3
-rw-r--r--drivers/scsi/sata_qstor.c6
-rw-r--r--drivers/scsi/sata_sx4.c3
-rw-r--r--drivers/scsi/sata_vsc.c3
-rw-r--r--include/linux/libata.h2
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? */