From: Jeff Garzik Date: Mon, 31 Oct 2005 04:35:23 +0000 (-0500) Subject: Merge branch 'upstream' X-Git-Tag: v2.6.18-rc1~1079^2~98^2~13^2~86 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=cd8200e6d4f9f05e6ea48f7c000be890337396ac;p=linux.git Merge branch 'upstream' --- cd8200e6d4f9f05e6ea48f7c000be890337396ac diff --cc drivers/scsi/libata-core.c index b1011f4b995c,ff18fa7044c5..85081a1e1b10 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@@ -3683,40 -3514,11 +3646,40 @@@ int ata_qc_issue_prot(struct ata_queued { struct ata_port *ap = qc->ap; + /* Use polling pio if the LLD doesn't handle + * interrupt driven pio and atapi CDB interrupt. + */ + if (ap->flags & ATA_FLAG_PIO_POLLING) { + switch (qc->tf.protocol) { + case ATA_PROT_PIO: + case ATA_PROT_ATAPI: + case ATA_PROT_ATAPI_NODATA: + qc->tf.flags |= ATA_TFLAG_POLLING; + break; + case ATA_PROT_ATAPI_DMA: + if (qc->dev->flags & ATA_DFLAG_CDB_INTR) + BUG(); + break; + default: + break; + } + } + + /* select the device */ ata_dev_select(ap, qc->dev->devno, 1, 0); + /* start the command */ switch (qc->tf.protocol) { case ATA_PROT_NODATA: + if (qc->tf.flags & ATA_TFLAG_POLLING) + ata_qc_set_polling(qc); + - ata_tf_to_host_nolock(ap, &qc->tf); + ata_tf_to_host(ap, &qc->tf); + ap->hsm_task_state = HSM_ST_LAST; + + if (qc->tf.flags & ATA_TFLAG_POLLING) + queue_work(ata_wq, &ap->pio_task); + break; case ATA_PROT_DMA: @@@ -3725,49 -3525,25 +3688,49 @@@ ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ ap->ops->bmdma_setup(qc); /* set up bmdma */ ap->ops->bmdma_start(qc); /* initiate bmdma */ + ap->hsm_task_state = HSM_ST_LAST; break; - case ATA_PROT_PIO: /* load tf registers, initiate polling pio */ - ata_qc_set_polling(qc); - ata_tf_to_host(ap, &qc->tf); - ap->hsm_task_state = HSM_ST; - queue_work(ata_wq, &ap->pio_task); - break; + case ATA_PROT_PIO: + if (qc->tf.flags & ATA_TFLAG_POLLING) + ata_qc_set_polling(qc); - ata_tf_to_host_nolock(ap, &qc->tf); - case ATA_PROT_ATAPI: - ata_qc_set_polling(qc); + ata_tf_to_host(ap, &qc->tf); - queue_work(ata_wq, &ap->packet_task); + + if (qc->tf.flags & ATA_TFLAG_WRITE) { + /* PIO data out protocol */ + ap->hsm_task_state = HSM_ST_FIRST; + queue_work(ata_wq, &ap->dataout_task); + + /* always send first data block using + * the ata_dataout_task() codepath. + */ + } else { + /* PIO data in protocol */ + ap->hsm_task_state = HSM_ST; + + if (qc->tf.flags & ATA_TFLAG_POLLING) + queue_work(ata_wq, &ap->pio_task); + + /* if polling, ata_pio_task() handles the rest. + * otherwise, interrupt handler takes over from here. + */ + } + break; + case ATA_PROT_ATAPI: case ATA_PROT_ATAPI_NODATA: - ap->flags |= ATA_FLAG_NOINTR; + if (qc->tf.flags & ATA_TFLAG_POLLING) + ata_qc_set_polling(qc); + - ata_tf_to_host_nolock(ap, &qc->tf); + ata_tf_to_host(ap, &qc->tf); - queue_work(ata_wq, &ap->packet_task); + ap->hsm_task_state = HSM_ST_FIRST; + + /* send cdb by polling if no cdb interrupt */ + if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || + (qc->tf.flags & ATA_TFLAG_POLLING)) + queue_work(ata_wq, &ap->dataout_task); break; case ATA_PROT_ATAPI_DMA: