aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2005-09-27 05:39:50 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-28 12:07:13 -0400
commite50362eccd8809a224cda5f71714a088ba37b2ab (patch)
tree762b753691ef8c4645efaa677b32c57fd33ecbc0
parent312f7da2824c82800ee78d6190f12854456957af (diff)
[PATCH] libata: interrupt driven pio for LLD
libata.h: libata-core: Add ATA_FLAG_PIO_POLLING flag for LLDs that expect interrupt for command completion only. sata_nv.c: sata_vsc.c: irq handler is wrapper around ata_host_intr(), can handle PIO interrupts. sata_promise.c: sata_sx4.c: sata_qstor.c: sata_mv.c: Private irq handler. Polling mode ATA_FLAG_PIO_POLLING used for compatibility. Signed-off-by: Albert Lee <albertcc@tw.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/scsi/libata-core.c19
-rw-r--r--drivers/scsi/sata_mv.c7
-rw-r--r--drivers/scsi/sata_nv.c4
-rw-r--r--drivers/scsi/sata_promise.c13
-rw-r--r--drivers/scsi/sata_qstor.c11
-rw-r--r--drivers/scsi/sata_sx4.c7
-rw-r--r--drivers/scsi/sata_vsc.c6
-rw-r--r--include/linux/libata.h2
8 files changed, 48 insertions, 21 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index cc2d1308826e..f8a590e59f10 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -3356,6 +3356,25 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
3356{ 3356{
3357 struct ata_port *ap = qc->ap; 3357 struct ata_port *ap = qc->ap;
3358 3358
3359 /* Use polling pio if the LLD doesn't handle
3360 * interrupt driven pio and atapi CDB interrupt.
3361 */
3362 if (ap->flags & ATA_FLAG_PIO_POLLING) {
3363 switch (qc->tf.protocol) {
3364 case ATA_PROT_PIO:
3365 case ATA_PROT_ATAPI:
3366 case ATA_PROT_ATAPI_NODATA:
3367 qc->tf.flags |= ATA_TFLAG_POLLING;
3368 break;
3369 case ATA_PROT_ATAPI_DMA:
3370 if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
3371 BUG();
3372 break;
3373 default:
3374 break;
3375 }
3376 }
3377
3359 /* select the device */ 3378 /* select the device */
3360 ata_dev_select(ap, qc->dev->devno, 1, 0); 3379 ata_dev_select(ap, qc->dev->devno, 1, 0);
3361 3380
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index ea76fe44585e..b8f1f6963179 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -241,7 +241,8 @@ static struct ata_port_info mv_port_info[] = {
241 { /* chip_504x */ 241 { /* chip_504x */
242 .sht = &mv_sht, 242 .sht = &mv_sht,
243 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 243 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
244 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO), 244 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
245 ATA_FLAG_PIO_POLLING),
245 .pio_mask = 0x1f, /* pio4-0 */ 246 .pio_mask = 0x1f, /* pio4-0 */
246 .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */ 247 .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
247 .port_ops = &mv_ops, 248 .port_ops = &mv_ops,
@@ -250,7 +251,7 @@ static struct ata_port_info mv_port_info[] = {
250 .sht = &mv_sht, 251 .sht = &mv_sht,
251 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 252 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
252 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 253 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
253 MV_FLAG_DUAL_HC), 254 ATA_FLAG_PIO_POLLING | MV_FLAG_DUAL_HC),
254 .pio_mask = 0x1f, /* pio4-0 */ 255 .pio_mask = 0x1f, /* pio4-0 */
255 .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */ 256 .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
256 .port_ops = &mv_ops, 257 .port_ops = &mv_ops,
@@ -259,6 +260,7 @@ static struct ata_port_info mv_port_info[] = {
259 .sht = &mv_sht, 260 .sht = &mv_sht,
260 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 261 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
261 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 262 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
263 ATA_FLAG_PIO_POLLING |
262 MV_FLAG_IRQ_COALESCE | MV_FLAG_BDMA), 264 MV_FLAG_IRQ_COALESCE | MV_FLAG_BDMA),
263 .pio_mask = 0x1f, /* pio4-0 */ 265 .pio_mask = 0x1f, /* pio4-0 */
264 .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */ 266 .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
@@ -268,6 +270,7 @@ static struct ata_port_info mv_port_info[] = {
268 .sht = &mv_sht, 270 .sht = &mv_sht,
269 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 271 .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
270 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 272 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
273 ATA_FLAG_PIO_POLLING |
271 MV_FLAG_IRQ_COALESCE | MV_FLAG_DUAL_HC | 274 MV_FLAG_IRQ_COALESCE | MV_FLAG_DUAL_HC |
272 MV_FLAG_BDMA), 275 MV_FLAG_BDMA),
273 .pio_mask = 0x1f, /* pio4-0 */ 276 .pio_mask = 0x1f, /* pio4-0 */
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index c05653c7779d..8b7e871ea0bf 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -304,11 +304,11 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance,
304 304
305 ap = host_set->ports[i]; 305 ap = host_set->ports[i];
306 if (ap && 306 if (ap &&
307 !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { 307 !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
308 struct ata_queued_cmd *qc; 308 struct ata_queued_cmd *qc;
309 309
310 qc = ata_qc_from_tag(ap, ap->active_tag); 310 qc = ata_qc_from_tag(ap, ap->active_tag);
311 if (qc && (!(qc->tf.ctl & ATA_NIEN))) 311 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
312 handled += ata_host_intr(ap, qc); 312 handled += ata_host_intr(ap, qc);
313 } 313 }
314 314
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index def7e0d9dacb..f67deb0a55c9 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -162,7 +162,8 @@ static struct ata_port_info pdc_port_info[] = {
162 { 162 {
163 .sht = &pdc_ata_sht, 163 .sht = &pdc_ata_sht,
164 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 164 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
165 ATA_FLAG_SRST | ATA_FLAG_MMIO, 165 ATA_FLAG_SRST | ATA_FLAG_MMIO |
166 ATA_FLAG_PIO_POLLING,
166 .pio_mask = 0x1f, /* pio0-4 */ 167 .pio_mask = 0x1f, /* pio0-4 */
167 .mwdma_mask = 0x07, /* mwdma0-2 */ 168 .mwdma_mask = 0x07, /* mwdma0-2 */
168 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 169 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -173,7 +174,8 @@ static struct ata_port_info pdc_port_info[] = {
173 { 174 {
174 .sht = &pdc_ata_sht, 175 .sht = &pdc_ata_sht,
175 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 176 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
176 ATA_FLAG_SRST | ATA_FLAG_MMIO, 177 ATA_FLAG_SRST | ATA_FLAG_MMIO |
178 ATA_FLAG_PIO_POLLING,
177 .pio_mask = 0x1f, /* pio0-4 */ 179 .pio_mask = 0x1f, /* pio0-4 */
178 .mwdma_mask = 0x07, /* mwdma0-2 */ 180 .mwdma_mask = 0x07, /* mwdma0-2 */
179 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 181 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -184,7 +186,8 @@ static struct ata_port_info pdc_port_info[] = {
184 { 186 {
185 .sht = &pdc_ata_sht, 187 .sht = &pdc_ata_sht,
186 .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | 188 .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
187 ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS, 189 ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS |
190 ATA_FLAG_PIO_POLLING,
188 .pio_mask = 0x1f, /* pio0-4 */ 191 .pio_mask = 0x1f, /* pio0-4 */
189 .mwdma_mask = 0x07, /* mwdma0-2 */ 192 .mwdma_mask = 0x07, /* mwdma0-2 */
190 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 193 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -493,11 +496,11 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
493 ap = host_set->ports[i]; 496 ap = host_set->ports[i];
494 tmp = mask & (1 << (i + 1)); 497 tmp = mask & (1 << (i + 1));
495 if (tmp && ap && 498 if (tmp && ap &&
496 !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { 499 !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
497 struct ata_queued_cmd *qc; 500 struct ata_queued_cmd *qc;
498 501
499 qc = ata_qc_from_tag(ap, ap->active_tag); 502 qc = ata_qc_from_tag(ap, ap->active_tag);
500 if (qc && (!(qc->tf.ctl & ATA_NIEN))) 503 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
501 handled += pdc_host_intr(ap, qc); 504 handled += pdc_host_intr(ap, qc);
502 } 505 }
503 } 506 }
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index ffcdeb68641c..a604afafaecc 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -175,7 +175,7 @@ static struct ata_port_info qs_port_info[] = {
175 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 175 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
176 ATA_FLAG_SATA_RESET | 176 ATA_FLAG_SATA_RESET |
177 //FIXME ATA_FLAG_SRST | 177 //FIXME ATA_FLAG_SRST |
178 ATA_FLAG_MMIO, 178 ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
179 .pio_mask = 0x10, /* pio4 */ 179 .pio_mask = 0x10, /* pio4 */
180 .udma_mask = 0x7f, /* udma0-6 */ 180 .udma_mask = 0x7f, /* udma0-6 */
181 .port_ops = &qs_ata_ops, 181 .port_ops = &qs_ata_ops,
@@ -389,14 +389,13 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
389 DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", 389 DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n",
390 sff1, sff0, port_no, sHST, sDST); 390 sff1, sff0, port_no, sHST, sDST);
391 handled = 1; 391 handled = 1;
392 if (ap && !(ap->flags & 392 if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
393 (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) {
394 struct ata_queued_cmd *qc; 393 struct ata_queued_cmd *qc;
395 struct qs_port_priv *pp = ap->private_data; 394 struct qs_port_priv *pp = ap->private_data;
396 if (!pp || pp->state != qs_state_pkt) 395 if (!pp || pp->state != qs_state_pkt)
397 continue; 396 continue;
398 qc = ata_qc_from_tag(ap, ap->active_tag); 397 qc = ata_qc_from_tag(ap, ap->active_tag);
399 if (qc && (!(qc->tf.ctl & ATA_NIEN))) { 398 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
400 switch (sHST) { 399 switch (sHST) {
401 case 0: /* sucessful CPB */ 400 case 0: /* sucessful CPB */
402 case 3: /* device error */ 401 case 3: /* device error */
@@ -422,13 +421,13 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
422 struct ata_port *ap; 421 struct ata_port *ap;
423 ap = host_set->ports[port_no]; 422 ap = host_set->ports[port_no];
424 if (ap && 423 if (ap &&
425 !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { 424 !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
426 struct ata_queued_cmd *qc; 425 struct ata_queued_cmd *qc;
427 struct qs_port_priv *pp = ap->private_data; 426 struct qs_port_priv *pp = ap->private_data;
428 if (!pp || pp->state != qs_state_mmio) 427 if (!pp || pp->state != qs_state_mmio)
429 continue; 428 continue;
430 qc = ata_qc_from_tag(ap, ap->active_tag); 429 qc = ata_qc_from_tag(ap, ap->active_tag);
431 if (qc && (!(qc->tf.ctl & ATA_NIEN))) { 430 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
432 431
433 /* check main status, clearing INTRQ */ 432 /* check main status, clearing INTRQ */
434 u8 status = ata_chk_status(ap); 433 u8 status = ata_chk_status(ap);
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 540a85191172..a9f9f7685a59 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -219,7 +219,8 @@ static struct ata_port_info pdc_port_info[] = {
219 { 219 {
220 .sht = &pdc_sata_sht, 220 .sht = &pdc_sata_sht,
221 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 221 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
222 ATA_FLAG_SRST | ATA_FLAG_MMIO, 222 ATA_FLAG_SRST | ATA_FLAG_MMIO |
223 ATA_FLAG_PIO_POLLING,
223 .pio_mask = 0x1f, /* pio0-4 */ 224 .pio_mask = 0x1f, /* pio0-4 */
224 .mwdma_mask = 0x07, /* mwdma0-2 */ 225 .mwdma_mask = 0x07, /* mwdma0-2 */
225 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 226 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -832,11 +833,11 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
832 tmp = mask & (1 << i); 833 tmp = mask & (1 << i);
833 VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); 834 VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp);
834 if (tmp && ap && 835 if (tmp && ap &&
835 !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { 836 !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
836 struct ata_queued_cmd *qc; 837 struct ata_queued_cmd *qc;
837 838
838 qc = ata_qc_from_tag(ap, ap->active_tag); 839 qc = ata_qc_from_tag(ap, ap->active_tag);
839 if (qc && (!(qc->tf.ctl & ATA_NIEN))) 840 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
840 handled += pdc20621_host_intr(ap, qc, (i > 4), 841 handled += pdc20621_host_intr(ap, qc, (i > 4),
841 mmio_base); 842 mmio_base);
842 } 843 }
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index cf94e0158a8d..92378d768c86 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -193,12 +193,12 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
193 struct ata_port *ap; 193 struct ata_port *ap;
194 194
195 ap = host_set->ports[i]; 195 ap = host_set->ports[i];
196 if (ap && !(ap->flags & 196 if (ap &&
197 (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { 197 !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
198 struct ata_queued_cmd *qc; 198 struct ata_queued_cmd *qc;
199 199
200 qc = ata_qc_from_tag(ap, ap->active_tag); 200 qc = ata_qc_from_tag(ap, ap->active_tag);
201 if (qc && (!(qc->tf.ctl & ATA_NIEN))) 201 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
202 handled += ata_host_intr(ap, qc); 202 handled += ata_host_intr(ap, qc);
203 } 203 }
204 } 204 }
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 9ac2b69df3c1..ea8ab29aa92e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -116,6 +116,8 @@ enum {
116 ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ 116 ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */
117 ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ 117 ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */
118 ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ 118 ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */
119 ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD
120 * doesn't handle PIO interrupts */
119 121
120 ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ 122 ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
121 ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ 123 ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */