Merge branch 'upstream'
authorJeff Garzik <jgarzik@pobox.com>
Tue, 17 Jan 2006 15:29:06 +0000 (10:29 -0500)
committerJeff Garzik <jgarzik@pobox.com>
Tue, 17 Jan 2006 15:29:06 +0000 (10:29 -0500)
1  2 
drivers/scsi/libata-core.c
drivers/scsi/sata_mv.c
drivers/scsi/sata_nv.c
drivers/scsi/sata_promise.c
drivers/scsi/sata_sx4.c
drivers/scsi/sata_vsc.c
include/linux/ata.h
include/linux/libata.h

@@@ -74,7 -74,6 +74,7 @@@ static int ata_choose_xfer_mode(const s
                                u8 *xfer_mode_out,
                                unsigned int *xfer_shift_out);
  static void __ata_qc_complete(struct ata_queued_cmd *qc);
 +static void ata_pio_error(struct ata_port *ap);
  
  static unsigned int ata_unique_id = 1;
  static struct workqueue_struct *ata_wq;
@@@ -563,16 -562,28 +563,28 @@@ static const u8 ata_rw_cmds[] = 
        ATA_CMD_WRITE_MULTI,
        ATA_CMD_READ_MULTI_EXT,
        ATA_CMD_WRITE_MULTI_EXT,
+       0,
+       0,
+       0,
+       ATA_CMD_WRITE_MULTI_FUA_EXT,
        /* pio */
        ATA_CMD_PIO_READ,
        ATA_CMD_PIO_WRITE,
        ATA_CMD_PIO_READ_EXT,
        ATA_CMD_PIO_WRITE_EXT,
+       0,
+       0,
+       0,
+       0,
        /* dma */
        ATA_CMD_READ,
        ATA_CMD_WRITE,
        ATA_CMD_READ_EXT,
-       ATA_CMD_WRITE_EXT
+       ATA_CMD_WRITE_EXT,
+       0,
+       0,
+       0,
+       ATA_CMD_WRITE_FUA_EXT
  };
  
  /**
   *    LOCKING:
   *    caller.
   */
void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
  {
        struct ata_taskfile *tf = &qc->tf;
        struct ata_device *dev = qc->dev;
+       u8 cmd;
  
-       int index, lba48, write;
+       int index, fua, lba48, write;
   
+       fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0;
        lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
        write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
  
        if (dev->flags & ATA_DFLAG_PIO) {
                tf->protocol = ATA_PROT_PIO;
-               index = dev->multi_count ? 0 : 4;
+               index = dev->multi_count ? 0 : 8;
        } else {
                tf->protocol = ATA_PROT_DMA;
-               index = 8;
+               index = 16;
        }
  
-       tf->command = ata_rw_cmds[index + lba48 + write];
+       cmd = ata_rw_cmds[index + fua + lba48 + write];
+       if (cmd) {
+               tf->command = cmd;
+               return 0;
+       }
+       return -1;
  }
  
  static const char * const xfer_mode_str[] = {
@@@ -1033,18 -1051,22 +1052,22 @@@ static unsigned int ata_pio_modes(cons
  {
        u16 modes;
  
-       /* Usual case. Word 53 indicates word 88 is valid */
-       if (adev->id[ATA_ID_FIELD_VALID] & (1 << 2)) {
+       /* Usual case. Word 53 indicates word 64 is valid */
+       if (adev->id[ATA_ID_FIELD_VALID] & (1 << 1)) {
                modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
                modes <<= 3;
                modes |= 0x7;
                return modes;
        }
  
-       /* If word 88 isn't valid then Word 51 holds the PIO timing number
-          for the maximum. Turn it into a mask and return it */
-       modes = (2 << (adev->id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+       /* If word 64 isn't valid then Word 51 high byte holds the PIO timing
+          number for the maximum. Turn it into a mask and return it */
+       modes = (2 << ((adev->id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF)) - 1 ;
        return modes;
+       /* But wait.. there's more. Design your standards by committee and
+          you too can get a free iordy field to process. However its the 
+          speeds not the modes that are supported... Note drivers using the
+          timing API will get this right anyway */
  }
  
  struct ata_exec_internal_arg {
@@@ -1146,6 -1168,39 +1169,39 @@@ ata_exec_internal(struct ata_port *ap, 
        return AC_ERR_OTHER;
  }
  
+ /**
+  *    ata_pio_need_iordy      -       check if iordy needed
+  *    @adev: ATA device
+  *
+  *    Check if the current speed of the device requires IORDY. Used
+  *    by various controllers for chip configuration.
+  */
+ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
+ {
+       int pio;
+       int speed = adev->pio_mode - XFER_PIO_0;
+       if (speed < 2)
+               return 0;
+       if (speed > 2)
+               return 1;
+               
+       /* If we have no drive specific rule, then PIO 2 is non IORDY */
+       if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */
+               pio = adev->id[ATA_ID_EIDE_PIO];
+               /* Is the speed faster than the drive allows non IORDY ? */
+               if (pio) {
+                       /* This is cycle times not frequency - watch the logic! */
+                       if (pio > 240)  /* PIO2 is 240nS per cycle */
+                               return 1;
+                       return 0;
+               }
+       }
+       return 0;
+ }
  /**
   *    ata_dev_identify - obtain IDENTIFY x DEVICE page
   *    @ap: port on which device we wish to probe resides
@@@ -1340,12 -1395,6 +1396,12 @@@ retry
  
                }
  
 +              if (dev->id[59] & 0x100) {
 +                      dev->multi_count = dev->id[59] & 0xff;
 +                      DPRINTK("ata%u: dev %u multi count %u\n",
 +                              ap->id, device, dev->multi_count);
 +              }
 +
                ap->host->max_cmd_len = 16;
        }
  
                ap->cdb_len = (unsigned int) rc;
                ap->host->max_cmd_len = (unsigned char) ap->cdb_len;
  
 +              if (ata_id_cdb_intr(dev->id))
 +                      dev->flags |= ATA_DFLAG_CDB_INTR;
 +
                /* print device info to dmesg */
                printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
                       ap->id, device,
@@@ -1738,7 -1784,7 +1794,7 @@@ static const struct 
        { ATA_SHIFT_PIO,        XFER_PIO_0 },
  };
  
- static inline u8 base_from_shift(unsigned int shift)
+ static u8 base_from_shift(unsigned int shift)
  {
        int i;
  
@@@ -2812,6 -2858,7 +2868,6 @@@ 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);
@@@ -2877,8 -2924,7 +2933,8 @@@ static unsigned long ata_pio_poll(struc
   *    None.  (executing in kernel thread context)
   *
   *    RETURNS:
 - *    Non-zero if qc completed, zero otherwise.
 + *    Zero if qc completed.
 + *    Non-zero if has next.
   */
  
  static int ata_pio_complete (struct ata_port *ap)
         * 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.
 +       * HSM_ST_LAST_POLL state.
         */
        drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
        if (drv_stat & ATA_BUSY) {
                if (drv_stat & ATA_BUSY) {
                        ap->hsm_task_state = HSM_ST_LAST_POLL;
                        ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
 -                      return 0;
 +                      return 1;
                }
        }
  
        if (!ata_ok(drv_stat)) {
                qc->err_mask |= __ac_err_mask(drv_stat);
                ap->hsm_task_state = HSM_ST_ERR;
 -              return 0;
 +              return 1;
        }
  
        ap->hsm_task_state = HSM_ST_IDLE;
  
        /* another command may start at this point */
  
 -      return 1;
 +      return 0;
  }
  
  
@@@ -3082,23 -3128,7 +3138,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;
 +
 +              assert(qc->dev->multi_count);
 +
 +              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");
 +      assert(ap->cdb_len >= 12);
  
 -      /* do the actual data transfer */
 -      do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
 -      ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
 +      ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
 +      ata_altstatus(ap); /* flush */
  
 -      kunmap(page);
 +      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;
 +      }
 +}
 +
 +/**
 + *    ata_pio_first_block - Write first data block to hardware
 + *    @ap: Port to which ATA/ATAPI device is attached.
 + *
 + *    When device has indicated its readiness to accept
 + *    the data, this function sends out the CDB or 
 + *    the first data block by PIO.
 + *    After this, 
 + *      - If polling, ata_pio_task() handles the rest.
 + *      - Otherwise, interrupt handler takes over.
 + *
 + *    LOCKING:
 + *    Kernel thread context (may sleep)
 + *
 + *    RETURNS:
 + *    Zero if irq handler takes over
 + *    Non-zero if has next (polling).
 + */
 +
 +static int ata_pio_first_block(struct ata_port *ap)
 +{
 +      struct ata_queued_cmd *qc;
 +      u8 status;
 +      unsigned long flags;
 +      int has_next;
 +
 +      qc = ata_qc_from_tag(ap, ap->active_tag);
 +      assert(qc != NULL);
 +      assert(qc->flags & ATA_QCFLAG_ACTIVE);
 +
 +      /* if polling, we will stay in the work queue after sending the data.
 +       * otherwise, interrupt handler takes over after sending the data.
 +       */
 +      has_next = (qc->tf.flags & ATA_TFLAG_POLLING);
 +
 +      /* sleep-wait for BSY to clear */
 +      DPRINTK("busy wait\n");
 +      if (ata_busy_sleep(ap, ATA_TMOUT_DATAOUT_QUICK, ATA_TMOUT_DATAOUT)) {
 +              ap->hsm_task_state = HSM_ST_TMOUT;
 +              goto err_out;
 +      }
 +
 +      /* make sure DRQ is set */
 +      status = ata_chk_status(ap);
 +      if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
 +              /* device status error */
 +              ap->hsm_task_state = HSM_ST_ERR;
 +              goto err_out;
 +      }
 +
 +      /* 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.
 +       */
 +      spin_lock_irqsave(&ap->host_set->lock, flags);
 +
 +      if (qc->tf.protocol == ATA_PROT_PIO) {
 +              /* PIO data out protocol.
 +               * send first data block.
 +               */
 +
 +              /* 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);
 +
 +      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 +
 +      /* if polling, ata_pio_task() handles the rest.
 +       * otherwise, interrupt handler takes over from here.
 +       */
 +      return has_next;
 +
 +err_out:
 +      return 1; /* has next */
  }
  
  /**
@@@ -3317,23 -3210,7 +3373,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;
  }
@@@ -3380,8 -3264,6 +3436,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;
@@@ -3452,10 -3334,8 +3508,10 @@@ static void ata_pio_block(struct ata_po
                        return;
                }
  
 -              ata_pio_sector(qc);
 +              ata_pio_sectors(qc);
        }
 +
 +      ata_altstatus(ap); /* flush */
  }
  
  static void ata_pio_error(struct ata_port *ap)
@@@ -3481,23 -3361,22 +3537,23 @@@ static void ata_pio_task(void *_data
  {
        struct ata_port *ap = _data;
        unsigned long timeout;
 -      int qc_completed;
 +      int has_next;
  
  fsm_start:
        timeout = 0;
 -      qc_completed = 0;
 +      has_next = 1;
  
        switch (ap->hsm_task_state) {
 -      case HSM_ST_IDLE:
 -              return;
 +      case HSM_ST_FIRST:
 +              has_next = ata_pio_first_block(ap);
 +              break;
  
        case HSM_ST:
                ata_pio_block(ap);
                break;
  
        case HSM_ST_LAST:
 -              qc_completed = ata_pio_complete(ap);
 +              has_next = ata_pio_complete(ap);
                break;
  
        case HSM_ST_POLL:
        case HSM_ST_ERR:
                ata_pio_error(ap);
                return;
 +
 +      default:
 +              BUG();
 +              return;
        }
  
        if (timeout)
                queue_delayed_work(ata_wq, &ap->pio_task, timeout);
 -      else if (!qc_completed)
 +      else if (has_next)
                goto fsm_start;
  }
  
@@@ -3580,8 -3455,6 +3636,8 @@@ 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);
                ata_qc_complete(qc);
@@@ -3847,103 -3720,43 +3903,103 @@@ 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(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:
 +              assert(!(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;
 -              queue_work(ata_wq, &ap->pio_task);
 -              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);
 -              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->pio_task);
 +
 +                      /* 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)
 +                              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(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->pio_task);
                break;
  
        case ATA_PROT_ATAPI_DMA:
 -              ap->flags |= ATA_FLAG_NOINTR;
 +              assert(!(qc->tf.flags & ATA_TFLAG_POLLING));
 +
                ap->ops->tf_load(ap, &qc->tf);   /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
 -              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))
 +                      queue_work(ata_wq, &ap->pio_task);
                break;
  
        default:
@@@ -4204,144 -4017,48 +4260,144 @@@ void ata_bmdma_stop(struct ata_queued_c
  inline unsigned int ata_host_intr (struct ata_port *ap,
                                   struct ata_queued_cmd *qc)
  {
 -      u8 status, host_stat;
 +      u8 status, host_stat = 0;
  
 -      switch (qc->tf.protocol) {
 +      VPRINTK("ata%u: protocol %d task_state %d\n",
 +              ap->id, qc->tf.protocol, ap->hsm_task_state);
  
 -      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);
 -
 -              /* if it's not our irq... */
 -              if (!(host_stat & ATA_DMA_INTR))
 +      /* Check whether we are expecting interrupt in this state */
 +      switch (ap->hsm_task_state) {
 +      case HSM_ST_FIRST:
 +              /* 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;
 +              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);
 +              }
 +              break;
 +      case HSM_ST:
 +              break;
 +      default:
 +              goto idle_irq;
 +      }
  
 -              /* before we do anything else, clear DMA-Start bit */
 -              ap->ops->bmdma_stop(qc);
 +      /* check altstatus */
 +      status = ata_altstatus(ap);
 +      if (status & ATA_BUSY)
 +              goto idle_irq;
  
 -              /* fall through */
 +      /* check main status, clearing INTRQ */
 +      status = ata_chk_status(ap);
 +      if (unlikely(status & ATA_BUSY))
 +              goto idle_irq;
  
 -      case ATA_PROT_ATAPI_NODATA:
 -      case ATA_PROT_NODATA:
 -              /* check altstatus */
 -              status = ata_altstatus(ap);
 -              if (status & ATA_BUSY)
 -                      goto idle_irq;
 +      DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n",
 +              ap->id, qc->tf.protocol, ap->hsm_task_state, status);
  
 -              /* check main status, clearing INTRQ */
 -              status = ata_chk_status(ap);
 -              if (unlikely(status & ATA_BUSY))
 -                      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);
  
 -              /* ack bmdma irq events */
 -              ap->ops->irq_clear(ap);
 +      /* check error */
 +      if (unlikely((status & ATA_ERR) || (host_stat & ATA_DMA_ERR)))
 +              ap->hsm_task_state = HSM_ST_ERR;
 +
 +fsm_start:
 +      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 device status */
 +              if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
 +                      /* Wrong status. Let EH handle this */
 +                      ap->hsm_task_state = HSM_ST_ERR;
 +                      goto fsm_start;
 +              }
 +
 +              atapi_send_cdb(ap, qc);
 +
 +              break;
 +
 +      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;
 +                      }
 +                      
 +                      atapi_pio_bytes(qc);
 +
 +                      if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
 +                              /* bad ireason reported by device */
 +                              goto fsm_start;
 +
 +              } else {
 +                      /* ATA PIO protocol */
 +                      if (unlikely((status & ATA_DRQ) == 0)) {
 +                              /* handle BSY=0, DRQ=0 as error */
 +                              ap->hsm_task_state = HSM_ST_ERR;
 +                              goto fsm_start;
 +                      }
 +
 +                      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_chk_status(ap);
 +                              goto fsm_start;
 +                      }
 +              }
 +
 +              ata_altstatus(ap); /* flush */
 +              break;
 +
 +      case HSM_ST_LAST:
 +              if (unlikely(status & ATA_DRQ)) {
 +                      /* handle DRQ=1 as error */
 +                      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);
 +
 +              ap->hsm_task_state = HSM_ST_IDLE;
  
                /* complete taskfile transaction */
                qc->err_mask |= ac_err_mask(status);
                ata_qc_complete(qc);
                break;
  
 +      case HSM_ST_ERR:
 +              printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n",
 +                     ap->id, status, host_stat);
 +
 +              ap->hsm_task_state = HSM_ST_IDLE;
 +              qc->err_mask |= __ac_err_mask(status);
 +              ata_qc_complete(qc);
 +              break;
        default:
                goto idle_irq;
        }
@@@ -4392,11 -4109,11 +4448,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);
                }
        return IRQ_RETVAL(handled);
  }
  
 -/**
 - *    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)
 -{
 -      struct ata_port *ap = _data;
 -      struct ata_queued_cmd *qc;
 -      u8 status;
 -
 -      qc = ata_qc_from_tag(ap, ap->active_tag);
 -      assert(qc != NULL);
 -      assert(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_ATA_BUS;
 -              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_ATA_BUS;
 -              goto err_out;
 -      }
 -
 -      /* send SCSI cdb */
 -      DPRINTK("send cdb\n");
 -      assert(ap->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, ap->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, ap->cdb_len, 1);
 -
 -              /* PIO commands are handled by polling */
 -              ap->hsm_task_state = HSM_ST;
 -              queue_work(ata_wq, &ap->pio_task);
 -      }
 -
 -      return;
 -
 -err_out:
 -      ata_poll_qc_complete(qc);
 -}
 -
 -
  /**
   *    ata_port_start - Set port up for dma.
   *    @ap: Port to initialize
   *    Inherited from caller.
   */
  
+ /*
+  * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
+  * without filling any other registers
+  */
+ static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
+                            u8 cmd)
+ {
+       struct ata_taskfile tf;
+       int err;
+       ata_tf_init(ap, &tf, dev->devno);
+       tf.command = cmd;
+       tf.flags |= ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+       if (err)
+               printk(KERN_ERR "%s: ata command failed: %d\n",
+                               __FUNCTION__, err);
+       return err;
+ }
+ static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
+ {
+       u8 cmd;
+       if (!ata_try_flush_cache(dev))
+               return 0;
+       if (ata_id_has_flush_ext(dev->id))
+               cmd = ATA_CMD_FLUSH_EXT;
+       else
+               cmd = ATA_CMD_FLUSH;
+       return ata_do_simple_cmd(ap, dev, cmd);
+ }
+ static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
+ {
+       return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
+ }
+ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
+ {
+       return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
+ }
+ /**
+  *    ata_device_resume - wakeup a previously suspended devices
+  *
+  *    Kick the drive back into action, by sending it an idle immediate
+  *    command and making sure its transfer mode matches between drive
+  *    and host.
+  *
+  */
+ int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
+ {
+       if (ap->flags & ATA_FLAG_SUSPENDED) {
+               ap->flags &= ~ATA_FLAG_SUSPENDED;
+               ata_set_mode(ap);
+       }
+       if (!ata_dev_present(dev))
+               return 0;
+       if (dev->class == ATA_DEV_ATA)
+               ata_start_drive(ap, dev);
+       return 0;
+ }
+ /**
+  *    ata_device_suspend - prepare a device for suspend
+  *
+  *    Flush the cache on the drive, if appropriate, then issue a
+  *    standbynow command.
+  *
+  */
+ int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
+ {
+       if (!ata_dev_present(dev))
+               return 0;
+       if (dev->class == ATA_DEV_ATA)
+               ata_flush_cache(ap, dev);
+       ata_standby_drive(ap, dev);
+       ap->flags |= ATA_FLAG_SUSPENDED;
+       return 0;
+ }
  int ata_port_start (struct ata_port *ap)
  {
        struct device *dev = ap->host_set->dev;
@@@ -4533,6 -4413,7 +4679,6 @@@ static void ata_host_init(struct ata_po
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
  
 -      INIT_WORK(&ap->packet_task, atapi_packet_task, ap);
        INIT_WORK(&ap->pio_task, ata_pio_task, ap);
  
        for (i = 0; i < ATA_MAX_DEVICES; i++)
@@@ -5167,6 -5048,23 +5313,23 @@@ int pci_test_config_bits(struct pci_de
  
        return (tmp == bits->val) ? 1 : 0;
  }
+ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+       return 0;
+ }
+ int ata_pci_device_resume(struct pci_dev *pdev)
+ {
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       pci_enable_device(pdev);
+       pci_set_master(pdev);
+       return 0;
+ }
  #endif /* CONFIG_PCI */
  
  
@@@ -5261,6 -5159,7 +5424,7 @@@ EXPORT_SYMBOL_GPL(ata_dev_id_string)
  EXPORT_SYMBOL_GPL(ata_dev_config);
  EXPORT_SYMBOL_GPL(ata_scsi_simulate);
  
+ EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
  EXPORT_SYMBOL_GPL(ata_timing_compute);
  EXPORT_SYMBOL_GPL(ata_timing_merge);
  
@@@ -5270,4 -5169,11 +5434,11 @@@ EXPORT_SYMBOL_GPL(ata_pci_host_stop)
  EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
  EXPORT_SYMBOL_GPL(ata_pci_init_one);
  EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+ EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
+ EXPORT_SYMBOL_GPL(ata_pci_device_resume);
  #endif /* CONFIG_PCI */
+ EXPORT_SYMBOL_GPL(ata_device_suspend);
+ EXPORT_SYMBOL_GPL(ata_device_resume);
+ EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
+ EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
diff --combined drivers/scsi/sata_mv.c
@@@ -87,7 -87,7 +87,7 @@@ enum 
        MV_FLAG_IRQ_COALESCE    = (1 << 29),  /* IRQ coalescing capability */
        MV_COMMON_FLAGS         = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
 -                                 ATA_FLAG_NO_ATAPI),
 +                                 ATA_FLAG_PIO_POLLING),
        MV_6XXX_FLAGS           = MV_FLAG_IRQ_COALESCE,
  
        CRQB_FLAG_READ          = (1 << 0),
@@@ -374,7 -374,6 +374,6 @@@ static struct scsi_host_template mv_sh
        .dma_boundary           = MV_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-       .ordered_flush          = 1,
  };
  
  static const struct ata_port_operations mv5_ops = {
@@@ -1221,7 -1220,8 +1220,7 @@@ static void mv_host_intr(struct ata_hos
                        handled++;
                }
  
 -              if (ap &&
 -                  (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))
 +              if (ap && (ap->flags & ATA_FLAG_PORT_DISABLED))
                        continue;
  
                err_mask = ac_err_mask(ata_status);
                                VPRINTK("port %u IRQ found for qc, "
                                        "ata_status 0x%x\n", port,ata_status);
                                /* mark qc status appropriately */
 -                              if (!(qc->tf.ctl & ATA_NIEN)) {
 +                              if (!(qc->tf.flags & ATA_TFLAG_POLLING)) {
                                        qc->err_mask |= err_mask;
                                        ata_qc_complete(qc);
                                }
diff --combined drivers/scsi/sata_nv.c
   *  NV-specific details such as register offsets, SATA phy location,
   *  hotplug info, etc.
   *
+  *  0.10
+  *     - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB
+  *       drive.  Also made the check_hotplug() callbacks return whether there
+  *       was a hotplug interrupt or not.  This was not the source of the
+  *       spurious interrupts, but is the right thing to do anyway.
+  *
   *  0.09
   *     - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
   *
@@@ -124,10 -130,10 +130,10 @@@ static void nv_scr_write (struct ata_po
  static void nv_host_stop (struct ata_host_set *host_set);
  static void nv_enable_hotplug(struct ata_probe_ent *probe_ent);
  static void nv_disable_hotplug(struct ata_host_set *host_set);
- static void nv_check_hotplug(struct ata_host_set *host_set);
+ static int nv_check_hotplug(struct ata_host_set *host_set);
  static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent);
  static void nv_disable_hotplug_ck804(struct ata_host_set *host_set);
- static void nv_check_hotplug_ck804(struct ata_host_set *host_set);
+ static int nv_check_hotplug_ck804(struct ata_host_set *host_set);
  
  enum nv_host_type
  {
@@@ -176,7 -182,7 +182,7 @@@ struct nv_host_des
        enum nv_host_type       host_type;
        void                    (*enable_hotplug)(struct ata_probe_ent *probe_ent);
        void                    (*disable_hotplug)(struct ata_host_set *host_set);
-       void                    (*check_hotplug)(struct ata_host_set *host_set);
+       int                     (*check_hotplug)(struct ata_host_set *host_set);
  
  };
  static struct nv_host_desc nv_device_tbl[] = {
@@@ -235,7 -241,6 +241,6 @@@ static struct scsi_host_template nv_sh
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-       .ordered_flush          = 1,
  };
  
  static const struct ata_port_operations nv_ops = {
@@@ -304,18 -309,22 +309,22 @@@ static irqreturn_t nv_interrupt (int ir
  
                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)))
                                handled += ata_host_intr(ap, qc);
+                       else
+                               // No request pending?  Clear interrupt status
+                               // anyway, in case there's one pending.
+                               ap->ops->check_status(ap);
                }
  
        }
  
        if (host->host_desc->check_hotplug)
-               host->host_desc->check_hotplug(host_set);
+               handled += host->host_desc->check_hotplug(host_set);
  
        spin_unlock_irqrestore(&host_set->lock, flags);
  
@@@ -498,7 -507,7 +507,7 @@@ static void nv_disable_hotplug(struct a
        outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
  }
  
- static void nv_check_hotplug(struct ata_host_set *host_set)
+ static int nv_check_hotplug(struct ata_host_set *host_set)
  {
        u8 intr_status;
  
                if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
                        printk(KERN_WARNING "nv_sata: "
                                "Secondary device removed\n");
+               return 1;
        }
+       return 0;
  }
  
  static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
@@@ -561,7 -574,7 +574,7 @@@ static void nv_disable_hotplug_ck804(st
        pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
  }
  
- static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
+ static int nv_check_hotplug_ck804(struct ata_host_set *host_set)
  {
        u8 intr_status;
  
                if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
                        printk(KERN_WARNING "nv_sata: "
                                "Secondary device removed\n");
+               return 1;
        }
+       return 0;
  }
  
  static int __init nv_init(void)
@@@ -66,14 -66,14 +66,15 @@@ enum 
        board_2037x             = 0,    /* FastTrak S150 TX2plus */
        board_20319             = 1,    /* FastTrak S150 TX4 */
        board_20619             = 2,    /* FastTrak TX4000 */
+       board_20771             = 3,    /* FastTrak TX2300 */
  
        PDC_HAS_PATA            = (1 << 1), /* PDC20375 has PATA */
  
        PDC_RESET               = (1 << 11), /* HDMA reset */
  
        PDC_COMMON_FLAGS        = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
 -                                ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI,
 +                                ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
 +                                ATA_FLAG_PIO_POLLING,
  };
  
  
@@@ -115,7 -115,6 +116,6 @@@ static struct scsi_host_template pdc_at
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-       .ordered_flush          = 1,
  };
  
  static const struct ata_port_operations pdc_sata_ops = {
@@@ -192,6 -191,16 +192,16 @@@ static const struct ata_port_info pdc_p
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &pdc_pata_ops,
        },
+       /* board_20771 */
+       {
+               .sht            = &pdc_ata_sht,
+               .host_flags     = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .port_ops       = &pdc_sata_ops,
+       },
  };
  
  static const struct pci_device_id pdc_ata_pci_tbl[] = {
        { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_20619 },
  
+       { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         board_20771 },
        { }     /* terminate list */
  };
  
@@@ -499,11 -510,11 +511,11 @@@ static irqreturn_t pdc_interrupt (int i
                ap = host_set->ports[i];
                tmp = mask & (1 << (i + 1));
                if (tmp && 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)))
                                handled += pdc_host_intr(ap, qc);
                }
        }
@@@ -708,6 -719,9 +720,9 @@@ static int pdc_ata_init_one (struct pci
        case board_2037x:
                probe_ent->n_ports = 2;
                break;
+       case board_20771:
+               probe_ent->n_ports = 2;
+               break;
        case board_20619:
                probe_ent->n_ports = 4;
  
diff --combined drivers/scsi/sata_sx4.c
@@@ -194,7 -194,6 +194,6 @@@ static struct scsi_host_template pdc_sa
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-       .ordered_flush          = 1,
  };
  
  static const struct ata_port_operations pdc_20621_ops = {
@@@ -221,7 -220,7 +220,7 @@@ static const struct ata_port_info pdc_p
                .sht            = &pdc_sata_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_SRST | ATA_FLAG_MMIO |
 -                                ATA_FLAG_NO_ATAPI,
 +                                ATA_FLAG_PIO_POLLING,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
@@@ -836,11 -835,11 +835,11 @@@ static irqreturn_t pdc20621_interrupt (
                tmp = mask & (1 << i);
                VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp);
                if (tmp && 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)))
                                handled += pdc20621_host_intr(ap, qc, (i > 4),
                                                              mmio_base);
                }
diff --combined drivers/scsi/sata_vsc.c
@@@ -201,12 -201,12 +201,12 @@@ static irqreturn_t vsc_sata_interrupt (
                        struct ata_port *ap;
  
                        ap = host_set->ports[i];
 -                      if (ap && !(ap->flags &
 -                                  (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) {
 +                      if (ap &&
 +                          !(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)))
                                        handled += ata_host_intr(ap, qc);
                        }
                }
@@@ -235,7 -235,6 +235,6 @@@ static struct scsi_host_template vsc_sa
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-       .ordered_flush          = 1,
  };
  
  
diff --combined include/linux/ata.h
@@@ -129,6 -129,7 +129,7 @@@ enum 
        ATA_CMD_READ_EXT        = 0x25,
        ATA_CMD_WRITE           = 0xCA,
        ATA_CMD_WRITE_EXT       = 0x35,
+       ATA_CMD_WRITE_FUA_EXT   = 0x3D,
        ATA_CMD_PIO_READ        = 0x20,
        ATA_CMD_PIO_READ_EXT    = 0x24,
        ATA_CMD_PIO_WRITE       = 0x30,
        ATA_CMD_READ_MULTI_EXT  = 0x29,
        ATA_CMD_WRITE_MULTI     = 0xC5,
        ATA_CMD_WRITE_MULTI_EXT = 0x39,
+       ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
        ATA_CMD_SET_FEATURES    = 0xEF,
        ATA_CMD_PACKET          = 0xA0,
        ATA_CMD_VERIFY          = 0x40,
        ATA_CMD_VERIFY_EXT      = 0x42,
+       ATA_CMD_STANDBYNOW1     = 0xE0,
+       ATA_CMD_IDLEIMMEDIATE   = 0xE1,
        ATA_CMD_INIT_DEV_PARAMS = 0x91,
  
        /* SETFEATURES stuff */
        ATA_TFLAG_DEVICE        = (1 << 2), /* enable r/w to device reg */
        ATA_TFLAG_WRITE         = (1 << 3), /* data dir: host->dev==1 (write) */
        ATA_TFLAG_LBA           = (1 << 4), /* enable LBA */
-       ATA_TFLAG_POLLING       = (1 << 5), /* set nIEN to 1 and use polling */
+       ATA_TFLAG_FUA           = (1 << 5), /* enable FUA */
++      ATA_TFLAG_POLLING       = (1 << 6), /* set nIEN to 1 and use polling */
  };
  
  enum ata_tf_protocols {
@@@ -246,7 -250,8 +251,8 @@@ struct ata_taskfile 
  #define ata_id_is_sata(id)    ((id)[93] == 0)
  #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
  #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
- #define ata_id_has_flush(id) ((id)[83] & (1 << 12))
+ #define ata_id_has_fua(id)    ((id)[84] & (1 << 6))
+ #define ata_id_has_flush(id)  ((id)[83] & (1 << 12))
  #define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
  #define ata_id_has_lba48(id)  ((id)[83] & (1 << 10))
  #define ata_id_has_wcache(id) ((id)[82] & (1 << 5))
          ((u64) (id)[(n) + 1] << 16) | \
          ((u64) (id)[(n) + 0]) )
  
 +#define ata_id_cdb_intr(id)   (((id)[0] & 0x60) == 0x20)
 +
  static inline int ata_id_current_chs_valid(const u16 *id)
  {
        /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command 
@@@ -293,14 -296,6 +299,14 @@@ static inline int is_atapi_taskfile(con
               (tf->protocol == ATA_PROT_ATAPI_DMA);
  }
  
 +static inline int is_multi_taskfile(struct ata_taskfile *tf)
 +{
 +      return (tf->command == ATA_CMD_READ_MULTI) ||
 +             (tf->command == ATA_CMD_WRITE_MULTI) ||
 +             (tf->command == ATA_CMD_READ_MULTI_EXT) ||
 +             (tf->command == ATA_CMD_WRITE_MULTI_EXT);
 +}
 +
  static inline int ata_ok(u8 status)
  {
        return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))
diff --combined include/linux/libata.h
@@@ -101,7 -101,6 +101,7 @@@ enum 
        ATA_DFLAG_PIO           = (1 << 1), /* device currently in PIO mode */
        ATA_DFLAG_LOCK_SECTORS  = (1 << 2), /* don't adjust max_sectors */
        ATA_DFLAG_LBA           = (1 << 3), /* device supports LBA */
 +      ATA_DFLAG_CDB_INTR      = (1 << 4), /* device asserts INTRQ when ready for CDB */
  
        ATA_DEV_UNKNOWN         = 0,    /* unknown device */
        ATA_DEV_ATA             = 1,    /* ATA device */
        ATA_FLAG_MMIO           = (1 << 6), /* use MMIO, not PIO */
        ATA_FLAG_SATA_RESET     = (1 << 7), /* use COMRESET */
        ATA_FLAG_PIO_DMA        = (1 << 8), /* PIO cmds via DMA */
 -      ATA_FLAG_NOINTR         = (1 << 9), /* FIXME: Remove this once
 -                                           * proper HSM is in place. */
 +      ATA_FLAG_PIO_POLLING    = (1 << 9), /* use polling PIO if LLD
 +                                           * doesn't handle PIO interrupts */
        ATA_FLAG_DEBUGMSG       = (1 << 10),
        ATA_FLAG_NO_ATAPI       = (1 << 11), /* No ATAPI support */
  
+       ATA_FLAG_SUSPENDED      = (1 << 12), /* port is suspended */
        ATA_QCFLAG_ACTIVE       = (1 << 1), /* cmd not yet ack'd to scsi lyer */
        ATA_QCFLAG_SG           = (1 << 3), /* have s/g table? */
        ATA_QCFLAG_SINGLE       = (1 << 4), /* no s/g, just a single buffer */
        ATA_TMOUT_PIO           = 30 * HZ,
        ATA_TMOUT_BOOT          = 30 * HZ,      /* hueristic */
        ATA_TMOUT_BOOT_QUICK    = 7 * HZ,       /* hueristic */
 +      ATA_TMOUT_DATAOUT       = 30 * HZ,
 +      ATA_TMOUT_DATAOUT_QUICK = 5 * HZ,
        ATA_TMOUT_CDB           = 30 * HZ,
        ATA_TMOUT_CDB_QUICK     = 5 * HZ,
        ATA_TMOUT_INTERNAL      = 30 * HZ,
  };
  
  enum hsm_task_states {
 -      HSM_ST_UNKNOWN,
 -      HSM_ST_IDLE,
 -      HSM_ST_POLL,
 -      HSM_ST_TMOUT,
 -      HSM_ST,
 -      HSM_ST_LAST,
 -      HSM_ST_LAST_POLL,
 -      HSM_ST_ERR,
 +      HSM_ST_UNKNOWN,         /* state unknown */
 +      HSM_ST_IDLE,            /* no command on going */
 +      HSM_ST_POLL,            /* same as HSM_ST, waits longer */
 +      HSM_ST_TMOUT,           /* timeout */
 +      HSM_ST,                 /* (waiting the device to) transfer data */
 +      HSM_ST_LAST,            /* (waiting the device to) complete command */
 +      HSM_ST_LAST_POLL,       /* same as HSM_ST_LAST, waits longer */
 +      HSM_ST_ERR,             /* error */
 +      HSM_ST_FIRST,           /* (waiting the device to)
 +                                 write CDB or first data block */
  };
  
  enum ata_completion_errors {
@@@ -353,6 -350,8 +355,6 @@@ struct ata_port 
        struct ata_host_stats   stats;
        struct ata_host_set     *host_set;
  
 -      struct work_struct      packet_task;
 -
        struct work_struct      pio_task;
        unsigned int            hsm_task_state;
        unsigned long           pio_task_timeout;
@@@ -439,6 -438,8 +441,8 @@@ extern void ata_std_ports(struct ata_io
  extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                             unsigned int n_ports);
  extern void ata_pci_remove_one (struct pci_dev *pdev);
+ extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
+ extern int ata_pci_device_resume(struct pci_dev *pdev);
  #endif /* CONFIG_PCI */
  extern int ata_device_add(const struct ata_probe_ent *ent);
  extern void ata_host_set_remove(struct ata_host_set *host_set);
@@@ -448,6 -449,10 +452,10 @@@ extern int ata_scsi_queuecmd(struct scs
  extern int ata_scsi_error(struct Scsi_Host *host);
  extern int ata_scsi_release(struct Scsi_Host *host);
  extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+ extern int ata_scsi_device_resume(struct scsi_device *);
+ extern int ata_scsi_device_suspend(struct scsi_device *);
+ extern int ata_device_resume(struct ata_port *, struct ata_device *);
+ extern int ata_device_suspend(struct ata_port *, struct ata_device *);
  extern int ata_ratelimit(void);
  
  /*
@@@ -483,7 -488,8 +491,8 @@@ extern u8   ata_bmdma_status(struct ata
  extern void ata_bmdma_irq_clear(struct ata_port *ap);
  extern void ata_qc_complete(struct ata_queued_cmd *qc);
  extern void ata_eng_timeout(struct ata_port *ap);
- extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
+ extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
+                             struct scsi_cmnd *cmd,
                              void (*done)(struct scsi_cmnd *));
  extern int ata_std_bios_param(struct scsi_device *sdev,
                              struct block_device *bdev,
@@@ -493,6 -499,8 +502,8 @@@ extern int ata_scsi_slave_config(struc
  /*
   * Timing helpers
   */
+ extern unsigned int ata_pio_need_iordy(const struct ata_device *);
  extern int ata_timing_compute(struct ata_device *, unsigned short,
                              struct ata_timing *, int, int);
  extern void ata_timing_merge(const struct ata_timing *,