]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'upstream'
authorJeff Garzik <jgarzik@pobox.com>
Mon, 31 Oct 2005 04:35:23 +0000 (23:35 -0500)
committerJeff Garzik <jgarzik@pobox.com>
Mon, 31 Oct 2005 04:35:23 +0000 (23:35 -0500)
1  2 
drivers/scsi/libata-core.c

index b1011f4b995ca733440bce2aa98b6656c0ccd00a,ff18fa7044c593ebe61ebd184cc45ffbbc91b771..85081a1e1b102a76740b1834085d7eee4c198a48
@@@ -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:
-               ata_tf_to_host_nolock(ap, &qc->tf);
 +              if (qc->tf.flags & ATA_TFLAG_POLLING)
 +                      ata_qc_set_polling(qc);
 +
+               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:
                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: