Merge branch 'upstream'
authorJeff Garzik <jeff@garzik.org>
Wed, 29 Mar 2006 22:24:55 +0000 (17:24 -0500)
committerJeff Garzik <jeff@garzik.org>
Wed, 29 Mar 2006 22:24:55 +0000 (17:24 -0500)
1  2 
drivers/scsi/libata-core.c

index 5fdc3143ed15694fd0d5c96c321ee8b29fd6aee7,86310562da8b37f3e5e8e682b545b27b798f7973..83c92b19e7f44385d03bee25e9ccb10760b2fb6c
@@@ -1292,12 -1292,6 +1292,12 @@@ static int ata_dev_configure(struct ata
                                       dev->cylinders, dev->heads, dev->sectors);
                }
  
 +              if (dev->id[59] & 0x100) {
 +                      dev->multi_count = dev->id[59] & 0xff;
 +                      DPRINTK("ata%u: dev %u multi count %u\n",
 +                              ap->id, dev->devno, dev->multi_count);
 +              }
 +
                dev->cdb_len = 16;
        }
  
                }
                dev->cdb_len = (unsigned int) rc;
  
 +              if (ata_id_cdb_intr(dev->id))
 +                      dev->flags |= ATA_DFLAG_CDB_INTR;
 +
                /* print device info to dmesg */
                if (print_info)
                        printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
@@@ -2017,13 -2008,12 +2017,12 @@@ static unsigned int ata_bus_softreset(s
         */
        msleep(150);
  
        /* Before we perform post reset processing we want to see if
-          the bus shows 0xFF because the odd clown forgets the D7 pulldown
-          resistor */
+        * the bus shows 0xFF because the odd clown forgets the D7
+        * pulldown resistor.
+        */
        if (ata_check_status(ap) == 0xFF)
-               return 1;       /* Positive is failure for some reason */
+               return AC_ERR_OTHER;
  
        ata_bus_post_reset(ap, devmask);
  
@@@ -2643,6 -2633,10 +2642,10 @@@ static int ata_dma_blacklisted(const st
   *    known limits including host controller limits, device
   *    blacklist, etc...
   *
+  *    FIXME: The current implementation limits all transfer modes to
+  *    the fastest of the lowested device on the port.  This is not
+  *    required on most controllers.
+  *
   *    LOCKING:
   *    None.
   */
@@@ -2883,15 -2877,6 +2886,15 @@@ int ata_check_atapi_dma(struct ata_queu
        if (ap->ops->check_atapi_dma)
                rc = ap->ops->check_atapi_dma(qc);
  
 +      /* We don't support polling DMA.
 +       * Use PIO if the LLDD handles only interrupts in
 +       * the HSM_ST_LAST state and the ATAPI device
 +       * generates CDB interrupts.
 +       */
 +      if ((ap->flags & ATA_FLAG_PIO_POLLING) &&
 +          (qc->dev->flags & ATA_DFLAG_CDB_INTR))
 +              rc = 1;
 +
        return rc;
  }
  /**
@@@ -3134,11 -3119,119 +3137,11 @@@ void ata_poll_qc_complete(struct ata_qu
        unsigned long flags;
  
        spin_lock_irqsave(&ap->host_set->lock, flags);
 -      ap->flags &= ~ATA_FLAG_NOINTR;
        ata_irq_on(ap);
        ata_qc_complete(qc);
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
  }
  
 -/**
 - *    ata_pio_poll - poll using PIO, depending on current state
 - *    @ap: the target ata_port
 - *
 - *    LOCKING:
 - *    None.  (executing in kernel thread context)
 - *
 - *    RETURNS:
 - *    timeout value to use
 - */
 -
 -static unsigned long ata_pio_poll(struct ata_port *ap)
 -{
 -      struct ata_queued_cmd *qc;
 -      u8 status;
 -      unsigned int poll_state = HSM_ST_UNKNOWN;
 -      unsigned int reg_state = HSM_ST_UNKNOWN;
 -
 -      qc = ata_qc_from_tag(ap, ap->active_tag);
 -      WARN_ON(qc == NULL);
 -
 -      switch (ap->hsm_task_state) {
 -      case HSM_ST:
 -      case HSM_ST_POLL:
 -              poll_state = HSM_ST_POLL;
 -              reg_state = HSM_ST;
 -              break;
 -      case HSM_ST_LAST:
 -      case HSM_ST_LAST_POLL:
 -              poll_state = HSM_ST_LAST_POLL;
 -              reg_state = HSM_ST_LAST;
 -              break;
 -      default:
 -              BUG();
 -              break;
 -      }
 -
 -      status = ata_chk_status(ap);
 -      if (status & ATA_BUSY) {
 -              if (time_after(jiffies, ap->pio_task_timeout)) {
 -                      qc->err_mask |= AC_ERR_TIMEOUT;
 -                      ap->hsm_task_state = HSM_ST_TMOUT;
 -                      return 0;
 -              }
 -              ap->hsm_task_state = poll_state;
 -              return ATA_SHORT_PAUSE;
 -      }
 -
 -      ap->hsm_task_state = reg_state;
 -      return 0;
 -}
 -
 -/**
 - *    ata_pio_complete - check if drive is busy or idle
 - *    @ap: the target ata_port
 - *
 - *    LOCKING:
 - *    None.  (executing in kernel thread context)
 - *
 - *    RETURNS:
 - *    Non-zero if qc completed, zero otherwise.
 - */
 -
 -static int ata_pio_complete (struct ata_port *ap)
 -{
 -      struct ata_queued_cmd *qc;
 -      u8 drv_stat;
 -
 -      /*
 -       * This is purely heuristic.  This is a fast path.  Sometimes when
 -       * we enter, BSY will be cleared in a chk-status or two.  If not,
 -       * the drive is probably seeking or something.  Snooze for a couple
 -       * msecs, then chk-status again.  If still busy, fall back to
 -       * HSM_ST_POLL state.
 -       */
 -      drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
 -      if (drv_stat & ATA_BUSY) {
 -              msleep(2);
 -              drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
 -              if (drv_stat & ATA_BUSY) {
 -                      ap->hsm_task_state = HSM_ST_LAST_POLL;
 -                      ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
 -                      return 0;
 -              }
 -      }
 -
 -      qc = ata_qc_from_tag(ap, ap->active_tag);
 -      WARN_ON(qc == NULL);
 -
 -      drv_stat = ata_wait_idle(ap);
 -      if (!ata_ok(drv_stat)) {
 -              qc->err_mask |= __ac_err_mask(drv_stat);
 -              ap->hsm_task_state = HSM_ST_ERR;
 -              return 0;
 -      }
 -
 -      ap->hsm_task_state = HSM_ST_IDLE;
 -
 -      WARN_ON(qc->err_mask);
 -      ata_poll_qc_complete(qc);
 -
 -      /* another command may start at this point */
 -
 -      return 1;
 -}
 -
 -
  /**
   *    swap_buf_le16 - swap halves of 16-bit words in place
   *    @buf:  Buffer to swap
@@@ -3307,23 -3400,7 +3310,23 @@@ static void ata_pio_sector(struct ata_q
        page = nth_page(page, (offset >> PAGE_SHIFT));
        offset %= PAGE_SIZE;
  
 -      buf = kmap(page) + offset;
 +      DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
 +
 +      if (PageHighMem(page)) {
 +              unsigned long flags;
 +
 +              local_irq_save(flags);
 +              buf = kmap_atomic(page, KM_IRQ0);
 +
 +              /* do the actual data transfer */
 +              ata_data_xfer(ap, buf + offset, ATA_SECT_SIZE, do_write);
 +
 +              kunmap_atomic(buf, KM_IRQ0);
 +              local_irq_restore(flags);
 +      } else {
 +              buf = page_address(page);
 +              ata_data_xfer(ap, buf + offset, ATA_SECT_SIZE, do_write);
 +      }
  
        qc->cursect++;
        qc->cursg_ofs++;
                qc->cursg++;
                qc->cursg_ofs = 0;
        }
 +}
  
 -      DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
 +/**
 + *    ata_pio_sectors - Transfer one or many 512-byte sectors.
 + *    @qc: Command on going
 + *
 + *    Transfer one or many ATA_SECT_SIZE of data from/to the 
 + *    ATA device for the DRQ request.
 + *
 + *    LOCKING:
 + *    Inherited from caller.
 + */
 +
 +static void ata_pio_sectors(struct ata_queued_cmd *qc)
 +{
 +      if (is_multi_taskfile(&qc->tf)) {
 +              /* READ/WRITE MULTIPLE */
 +              unsigned int nsect;
  
 -      /* do the actual data transfer */
 -      do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
 -      ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
 +              WARN_ON(qc->dev->multi_count == 0);
  
 -      kunmap(page);
 +              nsect = min(qc->nsect - qc->cursect, qc->dev->multi_count);
 +              while (nsect--)
 +                      ata_pio_sector(qc);
 +      } else
 +              ata_pio_sector(qc);
 +}
 +
 +/**
 + *    atapi_send_cdb - Write CDB bytes to hardware
 + *    @ap: Port to which ATAPI device is attached.
 + *    @qc: Taskfile currently active
 + *
 + *    When device has indicated its readiness to accept
 + *    a CDB, this function is called.  Send the CDB.
 + *
 + *    LOCKING:
 + *    caller.
 + */
 +
 +static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
 +{
 +      /* send SCSI cdb */
 +      DPRINTK("send cdb\n");
 +      WARN_ON(qc->dev->cdb_len < 12);
 +
 +      ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
 +      ata_altstatus(ap); /* flush */
 +
 +      switch (qc->tf.protocol) {
 +      case ATA_PROT_ATAPI:
 +              ap->hsm_task_state = HSM_ST;
 +              break;
 +      case ATA_PROT_ATAPI_NODATA:
 +              ap->hsm_task_state = HSM_ST_LAST;
 +              break;
 +      case ATA_PROT_ATAPI_DMA:
 +              ap->hsm_task_state = HSM_ST_LAST;
 +              /* initiate bmdma */
 +              ap->ops->bmdma_start(qc);
 +              break;
 +      }
  }
  
  /**
@@@ -3459,23 -3482,7 +3462,23 @@@ next_sg
        /* don't cross page boundaries */
        count = min(count, (unsigned int)PAGE_SIZE - offset);
  
 -      buf = kmap(page) + offset;
 +      DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
 +
 +      if (PageHighMem(page)) {
 +              unsigned long flags;
 +
 +              local_irq_save(flags);
 +              buf = kmap_atomic(page, KM_IRQ0);
 +
 +              /* do the actual data transfer */
 +              ata_data_xfer(ap, buf + offset, count, do_write);
 +
 +              kunmap_atomic(buf, KM_IRQ0);
 +              local_irq_restore(flags);
 +      } else {
 +              buf = page_address(page);
 +              ata_data_xfer(ap, buf + offset, count, do_write);
 +      }
  
        bytes -= count;
        qc->curbytes += count;
                qc->cursg_ofs = 0;
        }
  
 -      DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
 -
 -      /* do the actual data transfer */
 -      ata_data_xfer(ap, buf, count, do_write);
 -
 -      kunmap(page);
 -
        if (bytes)
                goto next_sg;
  }
@@@ -3522,8 -3536,6 +3525,8 @@@ static void atapi_pio_bytes(struct ata_
        if (do_write != i_write)
                goto err_out;
  
 +      VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes);
 +
        __atapi_pio_bytes(qc, bytes);
  
        return;
@@@ -3536,279 -3548,197 +3539,279 @@@ err_out
  }
  
  /**
 - *    ata_pio_block - start PIO on a block
 + *    ata_hsm_ok_in_wq - Check if the qc can be handled in the workqueue.
   *    @ap: the target ata_port
 + *    @qc: qc on going
   *
 - *    LOCKING:
 - *    None.  (executing in kernel thread context)
 + *    RETURNS:
 + *    1 if ok in workqueue, 0 otherwise.
   */
  
 -static void ata_pio_block(struct ata_port *ap)
 +static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
  {
 -      struct ata_queued_cmd *qc;
 -      u8 status;
 +      if (qc->tf.flags & ATA_TFLAG_POLLING)
 +              return 1;
  
 -      /*
 -       * This is purely heuristic.  This is a fast path.
 -       * Sometimes when we enter, BSY will be cleared in
 -       * a chk-status or two.  If not, the drive is probably seeking
 -       * or something.  Snooze for a couple msecs, then
 -       * chk-status again.  If still busy, fall back to
 -       * HSM_ST_POLL state.
 -       */
 -      status = ata_busy_wait(ap, ATA_BUSY, 5);
 -      if (status & ATA_BUSY) {
 -              msleep(2);
 -              status = ata_busy_wait(ap, ATA_BUSY, 10);
 -              if (status & ATA_BUSY) {
 -                      ap->hsm_task_state = HSM_ST_POLL;
 -                      ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
 -                      return;
 -              }
 +      if (ap->hsm_task_state == HSM_ST_FIRST) {
 +              if (qc->tf.protocol == ATA_PROT_PIO &&
 +                  (qc->tf.flags & ATA_TFLAG_WRITE))
 +                  return 1;
 +
 +              if (is_atapi_taskfile(&qc->tf) &&
 +                  !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
 +                      return 1;
        }
  
 -      qc = ata_qc_from_tag(ap, ap->active_tag);
 -      WARN_ON(qc == NULL);
 +      return 0;
 +}
  
 -      /* check error */
 -      if (status & (ATA_ERR | ATA_DF)) {
 -              qc->err_mask |= AC_ERR_DEV;
 -              ap->hsm_task_state = HSM_ST_ERR;
 -              return;
 -      }
 +/**
 + *    ata_hsm_move - move the HSM to the next state.
 + *    @ap: the target ata_port
 + *    @qc: qc on going
 + *    @status: current device status
 + *    @in_wq: 1 if called from workqueue, 0 otherwise
 + *
 + *    RETURNS:
 + *    1 when poll next status needed, 0 otherwise.
 + */
  
 -      /* transfer data if any */
 -      if (is_atapi_taskfile(&qc->tf)) {
 -              /* DRQ=0 means no more data to transfer */
 -              if ((status & ATA_DRQ) == 0) {
 -                      ap->hsm_task_state = HSM_ST_LAST;
 -                      return;
 -              }
 +static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
 +                       u8 status, int in_wq)
 +{
 +      unsigned long flags = 0;
 +      int poll_next;
  
 -              atapi_pio_bytes(qc);
 -      } else {
 -              /* handle BSY=0, DRQ=0 as error */
 -              if ((status & ATA_DRQ) == 0) {
 +      WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
 +
 +      /* Make sure ata_qc_issue_prot() does not throw things
 +       * like DMA polling into the workqueue. Notice that
 +       * in_wq is not equivalent to (qc->tf.flags & ATA_TFLAG_POLLING).
 +       */
 +      WARN_ON(in_wq != ata_hsm_ok_in_wq(ap, qc));
 +
 +fsm_start:
 +      DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n",
 +              ap->id, qc->tf.protocol, ap->hsm_task_state, status);
 +
 +      switch (ap->hsm_task_state) {
 +      case HSM_ST_FIRST:
 +              /* Send first data block or PACKET CDB */
 +
 +              /* If polling, we will stay in the work queue after
 +               * sending the data. Otherwise, interrupt handler
 +               * takes over after sending the data.
 +               */
 +              poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
 +
 +              /* check device status */
 +              if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
 +                      /* Wrong status. Let EH handle this */
                        qc->err_mask |= AC_ERR_HSM;
                        ap->hsm_task_state = HSM_ST_ERR;
 -                      return;
 +                      goto fsm_start;
                }
  
 -              ata_pio_sector(qc);
 -      }
 -}
 +              /* Device should not ask for data transfer (DRQ=1)
 +               * when it finds something wrong.
 +               * Anyway, we respect DRQ here and let HSM go on
 +               * without changing hsm_task_state to HSM_ST_ERR.
 +               */
 +              if (unlikely(status & (ATA_ERR | ATA_DF))) {
 +                      printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
 +                             ap->id, status);
 +                      qc->err_mask |= AC_ERR_DEV;
 +              }
  
 -static void ata_pio_error(struct ata_port *ap)
 -{
 -      struct ata_queued_cmd *qc;
 +              /* Send the CDB (atapi) or the first data block (ata pio out).
 +               * During the state transition, interrupt handler shouldn't
 +               * be invoked before the data transfer is complete and
 +               * hsm_task_state is changed. Hence, the following locking.
 +               */
 +              if (in_wq)
 +                      spin_lock_irqsave(&ap->host_set->lock, flags);
  
 -      qc = ata_qc_from_tag(ap, ap->active_tag);
 -      WARN_ON(qc == NULL);
 +              if (qc->tf.protocol == ATA_PROT_PIO) {
 +                      /* PIO data out protocol.
 +                       * send first data block.
 +                       */
  
 -      if (qc->tf.command != ATA_CMD_PACKET)
 -              printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
 +                      /* ata_pio_sectors() might change the state
 +                       * to HSM_ST_LAST. so, the state is changed here
 +                       * before ata_pio_sectors().
 +                       */
 +                      ap->hsm_task_state = HSM_ST;
 +                      ata_pio_sectors(qc);
 +                      ata_altstatus(ap); /* flush */
 +              } else
 +                      /* send CDB */
 +                      atapi_send_cdb(ap, qc);
 +
 +              if (in_wq)
 +                      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 +
 +              /* if polling, ata_pio_task() handles the rest.
 +               * otherwise, interrupt handler takes over from here.
 +               */
 +              break;
  
 -      /* make sure qc->err_mask is available to
 -       * know what's wrong and recover
 -       */
 -      WARN_ON(qc->err_mask == 0);
 +      case HSM_ST:
 +              /* complete command or read/write the data register */
 +              if (qc->tf.protocol == ATA_PROT_ATAPI) {
 +                      /* ATAPI PIO protocol */
 +                      if ((status & ATA_DRQ) == 0) {
 +                              /* no more data to transfer */
 +                              ap->hsm_task_state = HSM_ST_LAST;
 +                              goto fsm_start;
 +                      }
  
 -      ap->hsm_task_state = HSM_ST_IDLE;
 +                      /* Device should not ask for data transfer (DRQ=1)
 +                       * when it finds something wrong.
 +                       * Anyway, we respect DRQ here and let HSM go on
 +                       * without changing hsm_task_state to HSM_ST_ERR.
 +                       */
 +                      if (unlikely(status & (ATA_ERR | ATA_DF))) {
 +                              printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
 +                                     ap->id, status);
 +                              qc->err_mask |= AC_ERR_DEV;
 +                      }
  
 -      ata_poll_qc_complete(qc);
 -}
 +                      atapi_pio_bytes(qc);
  
 -static void ata_pio_task(void *_data)
 -{
 -      struct ata_port *ap = _data;
 -      unsigned long timeout;
 -      int qc_completed;
 +                      if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
 +                              /* bad ireason reported by device */
 +                              goto fsm_start;
  
 -fsm_start:
 -      timeout = 0;
 -      qc_completed = 0;
 +              } else {
 +                      /* ATA PIO protocol */
 +                      if (unlikely((status & ATA_DRQ) == 0)) {
 +                              /* handle BSY=0, DRQ=0 as error */
 +                              qc->err_mask |= AC_ERR_HSM;
 +                              ap->hsm_task_state = HSM_ST_ERR;
 +                              goto fsm_start;
 +                      }
  
 -      switch (ap->hsm_task_state) {
 -      case HSM_ST_IDLE:
 -              return;
 +                      /* Some devices may ask for data transfer (DRQ=1)
 +                       * alone with ERR=1 for PIO reads.
 +                       * We respect DRQ here and let HSM go on without
 +                       * changing hsm_task_state to HSM_ST_ERR.
 +                       */
 +                      if (unlikely(status & (ATA_ERR | ATA_DF))) {
 +                              /* For writes, ERR=1 DRQ=1 doesn't make
 +                               * sense since the data block has been
 +                               * transferred to the device.
 +                               */
 +                              WARN_ON(qc->tf.flags & ATA_TFLAG_WRITE);
 +
 +                              /* data might be corrputed */
 +                              qc->err_mask |= AC_ERR_DEV;
 +                      }
  
 -      case HSM_ST:
 -              ata_pio_block(ap);
 +                      ata_pio_sectors(qc);
 +
 +                      if (ap->hsm_task_state == HSM_ST_LAST &&
 +                          (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
 +                              /* all data read */
 +                              ata_altstatus(ap);
 +                              status = ata_wait_idle(ap);
 +                              goto fsm_start;
 +                      }
 +              }
 +
 +              ata_altstatus(ap); /* flush */
 +              poll_next = 1;
                break;
  
        case HSM_ST_LAST:
 -              qc_completed = ata_pio_complete(ap);
 -              break;
 +              if (unlikely(!ata_ok(status))) {
 +                      qc->err_mask |= __ac_err_mask(status);
 +                      ap->hsm_task_state = HSM_ST_ERR;
 +                      goto fsm_start;
 +              }
 +
 +              /* no more data to transfer */
 +              DPRINTK("ata%u: command complete, drv_stat 0x%x\n",
 +                      ap->id, status);
  
 -      case HSM_ST_POLL:
 -      case HSM_ST_LAST_POLL:
 -              timeout = ata_pio_poll(ap);
 +              WARN_ON(qc->err_mask);
 +
 +              ap->hsm_task_state = HSM_ST_IDLE;
 +
 +              /* complete taskfile transaction */
 +              if (in_wq)
 +                      ata_poll_qc_complete(qc);
 +              else
 +                      ata_qc_complete(qc);
 +
 +              poll_next = 0;
                break;
  
 -      case HSM_ST_TMOUT:
        case HSM_ST_ERR:
 -              ata_pio_error(ap);
 -              return;
 +              if (qc->tf.command != ATA_CMD_PACKET)
 +                      printk(KERN_ERR "ata%u: command error, drv_stat 0x%x\n",
 +                             ap->id, status);
 +
 +              /* make sure qc->err_mask is available to
 +               * know what's wrong and recover
 +               */
 +              WARN_ON(qc->err_mask == 0);
 +
 +              ap->hsm_task_state = HSM_ST_IDLE;
 +
 +              /* complete taskfile transaction */
 +              if (in_wq)
 +                      ata_poll_qc_complete(qc);
 +              else
 +                      ata_qc_complete(qc);
 +
 +              poll_next = 0;
 +              break;
 +      default:
 +              poll_next = 0;
 +              BUG();
        }
  
 -      if (timeout)
 -              ata_port_queue_task(ap, ata_pio_task, ap, timeout);
 -      else if (!qc_completed)
 -              goto fsm_start;
 +      return poll_next;
  }
  
 -/**
 - *    atapi_packet_task - Write CDB bytes to hardware
 - *    @_data: Port to which ATAPI device is attached.
 - *
 - *    When device has indicated its readiness to accept
 - *    a CDB, this function is called.  Send the CDB.
 - *    If DMA is to be performed, exit immediately.
 - *    Otherwise, we are in polling mode, so poll
 - *    status under operation succeeds or fails.
 - *
 - *    LOCKING:
 - *    Kernel thread context (may sleep)
 - */
 -
 -static void atapi_packet_task(void *_data)
 +static void ata_pio_task(void *_data)
  {
        struct ata_port *ap = _data;
        struct ata_queued_cmd *qc;
        u8 status;
 +      int poll_next;
 +
 +fsm_start:
 +      WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
        WARN_ON(qc == NULL);
 -      WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
 -
 -      /* sleep-wait for BSY to clear */
 -      DPRINTK("busy wait\n");
 -      if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
 -              qc->err_mask |= AC_ERR_TIMEOUT;
 -              goto err_out;
 -      }
 -
 -      /* make sure DRQ is set */
 -      status = ata_chk_status(ap);
 -      if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
 -              qc->err_mask |= AC_ERR_HSM;
 -              goto err_out;
 -      }
  
 -      /* send SCSI cdb */
 -      DPRINTK("send cdb\n");
 -      WARN_ON(qc->dev->cdb_len < 12);
 -
 -      if (qc->tf.protocol == ATA_PROT_ATAPI_DMA ||
 -          qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
 -              unsigned long flags;
 -
 -              /* Once we're done issuing command and kicking bmdma,
 -               * irq handler takes over.  To not lose irq, we need
 -               * to clear NOINTR flag before sending cdb, but
 -               * interrupt handler shouldn't be invoked before we're
 -               * finished.  Hence, the following locking.
 -               */
 -              spin_lock_irqsave(&ap->host_set->lock, flags);
 -              ap->flags &= ~ATA_FLAG_NOINTR;
 -              ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
 -              if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
 -                      ap->ops->bmdma_start(qc);       /* initiate bmdma */
 -              spin_unlock_irqrestore(&ap->host_set->lock, flags);
 -      } else {
 -              ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
 -
 -              /* PIO commands are handled by polling */
 -              ap->hsm_task_state = HSM_ST;
 -              ata_port_queue_task(ap, ata_pio_task, ap, 0);
 +      /*
 +       * This is purely heuristic.  This is a fast path.
 +       * Sometimes when we enter, BSY will be cleared in
 +       * a chk-status or two.  If not, the drive is probably seeking
 +       * or something.  Snooze for a couple msecs, then
 +       * chk-status again.  If still busy, queue delayed work.
 +       */
 +      status = ata_busy_wait(ap, ATA_BUSY, 5);
 +      if (status & ATA_BUSY) {
 +              msleep(2);
 +              status = ata_busy_wait(ap, ATA_BUSY, 10);
 +              if (status & ATA_BUSY) {
 +                      ata_port_queue_task(ap, ata_pio_task, ap, ATA_SHORT_PAUSE);
 +                      return;
 +              }
        }
  
 -      return;
 +      /* move the HSM */
 +      poll_next = ata_hsm_move(ap, qc, status, 1);
  
 -err_out:
 -      ata_poll_qc_complete(qc);
 +      /* another command or interrupt handler
 +       * may be running at this point.
 +       */
 +      if (poll_next)
 +              goto fsm_start;
  }
  
  /**
@@@ -3864,10 -3794,8 +3867,10 @@@ static void ata_qc_timeout(struct ata_q
                printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
                       ap->id, qc->tf.command, drv_stat, host_stat);
  
 +              ap->hsm_task_state = HSM_ST_IDLE;
 +
                /* complete taskfile transaction */
 -              qc->err_mask |= ac_err_mask(drv_stat);
 +              qc->err_mask |= AC_ERR_TIMEOUT;
                break;
        }
  
@@@ -4093,105 -4021,43 +4096,105 @@@ unsigned int ata_qc_issue_prot(struct a
  {
        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)
 +                              /* see ata_check_atapi_dma() */
 +                              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(ap, &qc->tf);
 +              ap->hsm_task_state = HSM_ST_LAST;
 +
 +              if (qc->tf.flags & ATA_TFLAG_POLLING)
 +                      ata_port_queue_task(ap, ata_pio_task, ap, 0);
 +
                break;
  
        case ATA_PROT_DMA:
 +              WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
 +
                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;
 -              ata_port_queue_task(ap, ata_pio_task, ap, 0);
 -              break;
 +      case ATA_PROT_PIO:
 +              if (qc->tf.flags & ATA_TFLAG_POLLING)
 +                      ata_qc_set_polling(qc);
  
 -      case ATA_PROT_ATAPI:
 -              ata_qc_set_polling(qc);
                ata_tf_to_host(ap, &qc->tf);
 -              ata_port_queue_task(ap, atapi_packet_task, ap, 0);
 +
 +              if (qc->tf.flags & ATA_TFLAG_WRITE) {
 +                      /* PIO data out protocol */
 +                      ap->hsm_task_state = HSM_ST_FIRST;
 +                      ata_port_queue_task(ap, ata_pio_task, ap, 0);
 +
 +                      /* always send first data block using
 +                       * the ata_pio_task() codepath.
 +                       */
 +              } else {
 +                      /* PIO data in protocol */
 +                      ap->hsm_task_state = HSM_ST;
 +
 +                      if (qc->tf.flags & ATA_TFLAG_POLLING)
 +                              ata_port_queue_task(ap, ata_pio_task, ap, 0);
 +
 +                      /* 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(ap, &qc->tf);
 -              ata_port_queue_task(ap, atapi_packet_task, ap, 0);
 +
 +              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))
 +                      ata_port_queue_task(ap, ata_pio_task, ap, 0);
                break;
  
        case ATA_PROT_ATAPI_DMA:
 -              ap->flags |= ATA_FLAG_NOINTR;
 +              WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
 +
                ap->ops->tf_load(ap, &qc->tf);   /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
 -              ata_port_queue_task(ap, atapi_packet_task, ap, 0);
 +              ap->hsm_task_state = HSM_ST_FIRST;
 +
 +              /* send cdb by polling if no cdb interrupt */
 +              if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
 +                      ata_port_queue_task(ap, ata_pio_task, ap, 0);
                break;
  
        default:
  inline unsigned int ata_host_intr (struct ata_port *ap,
                                   struct ata_queued_cmd *qc)
  {
 -      u8 status, host_stat;
 -
 -      switch (qc->tf.protocol) {
 +      u8 status, host_stat = 0;
  
 -      case ATA_PROT_DMA:
 -      case ATA_PROT_ATAPI_DMA:
 -      case ATA_PROT_ATAPI:
 -              /* check status of DMA engine */
 -              host_stat = ap->ops->bmdma_status(ap);
 -              VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
 +      VPRINTK("ata%u: protocol %d task_state %d\n",
 +              ap->id, qc->tf.protocol, ap->hsm_task_state);
  
 -              /* if it's not our irq... */
 -              if (!(host_stat & ATA_DMA_INTR))
 -                      goto idle_irq;
 -
 -              /* before we do anything else, clear DMA-Start bit */
 -              ap->ops->bmdma_stop(qc);
 -
 -              /* fall through */
 -
 -      case ATA_PROT_ATAPI_NODATA:
 -      case ATA_PROT_NODATA:
 -              /* check altstatus */
 -              status = ata_altstatus(ap);
 -              if (status & ATA_BUSY)
 -                      goto idle_irq;
 +      /* Check whether we are expecting interrupt in this state */
 +      switch (ap->hsm_task_state) {
 +      case HSM_ST_FIRST:
 +              /* Some pre-ATAPI-4 devices assert INTRQ
 +               * at this state when ready to receive CDB.
 +               */
  
 -              /* check main status, clearing INTRQ */
 -              status = ata_chk_status(ap);
 -              if (unlikely(status & ATA_BUSY))
 +              /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
 +               * The flag was turned on only for atapi devices.
 +               * No need to check is_atapi_taskfile(&qc->tf) again.
 +               */
 +              if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
                        goto idle_irq;
 -              DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
 -                      ap->id, qc->tf.protocol, status);
 -
 -              /* ack bmdma irq events */
 -              ap->ops->irq_clear(ap);
 -
 -              /* complete taskfile transaction */
 -              qc->err_mask |= ac_err_mask(status);
 -              ata_qc_complete(qc);
                break;
 -
 +      case HSM_ST_LAST:
 +              if (qc->tf.protocol == ATA_PROT_DMA ||
 +                  qc->tf.protocol == ATA_PROT_ATAPI_DMA) {
 +                      /* check status of DMA engine */
 +                      host_stat = ap->ops->bmdma_status(ap);
 +                      VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
 +
 +                      /* if it's not our irq... */
 +                      if (!(host_stat & ATA_DMA_INTR))
 +                              goto idle_irq;
 +
 +                      /* before we do anything else, clear DMA-Start bit */
 +                      ap->ops->bmdma_stop(qc);
 +
 +                      if (unlikely(host_stat & ATA_DMA_ERR)) {
 +                              /* error when transfering data to/from memory */
 +                              qc->err_mask |= AC_ERR_HOST_BUS;
 +                              ap->hsm_task_state = HSM_ST_ERR;
 +                      }
 +              }
 +              break;
 +      case HSM_ST:
 +              break;
        default:
                goto idle_irq;
        }
  
 +      /* check altstatus */
 +      status = ata_altstatus(ap);
 +      if (status & ATA_BUSY)
 +              goto idle_irq;
 +
 +      /* check main status, clearing INTRQ */
 +      status = ata_chk_status(ap);
 +      if (unlikely(status & ATA_BUSY))
 +              goto idle_irq;
 +
 +      /* ack bmdma irq events */
 +      ap->ops->irq_clear(ap);
 +
 +      ata_hsm_move(ap, qc, status, 0);
        return 1;       /* irq handled */
  
  idle_irq:
@@@ -4327,11 -4179,11 +4330,11 @@@ irqreturn_t ata_interrupt (int irq, voi
  
                ap = host_set->ports[i];
                if (ap &&
 -                  !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) {
 +                  !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
                        struct ata_queued_cmd *qc;
  
                        qc = ata_qc_from_tag(ap, ap->active_tag);
 -                      if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
 +                      if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
                            (qc->flags & ATA_QCFLAG_ACTIVE))
                                handled |= ata_host_intr(ap, qc);
                }