Merge branch 'upstream'
authorJeff Garzik <jgarzik@pobox.com>
Thu, 9 Feb 2006 09:28:13 +0000 (04:28 -0500)
committerJeff Garzik <jgarzik@pobox.com>
Thu, 9 Feb 2006 09:28:13 +0000 (04:28 -0500)
1  2 
drivers/scsi/libata-core.c
drivers/scsi/sata_mv.c
drivers/scsi/sata_promise.c
include/linux/libata.h

index ff31b0b6a6b3fb7c61a7c0f68264bf5ff3d7257c,14cdbb336dd501990cdf6b0e8ed2882988d51c3c..c93bb1bd333253c977a16ea50420484ff2dfa7f8
@@@ -70,7 -70,6 +70,7 @@@ static int fgb(u32 bitmap)
  static int ata_choose_xfer_mode(const struct ata_port *ap,
                                u8 *xfer_mode_out,
                                unsigned int *xfer_shift_out);
 +static void ata_pio_error(struct ata_port *ap);
  
  static unsigned int ata_unique_id = 1;
  static struct workqueue_struct *ata_wq;
@@@ -611,7 -610,7 +611,7 @@@ int ata_rwcmd_protocol(struct ata_queue
        } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) {
                /* Unable to use DMA due to host limitation */
                tf->protocol = ATA_PROT_PIO;
 -              index = dev->multi_count ? 0 : 4;
 +              index = dev->multi_count ? 0 : 8;
        } else {
                tf->protocol = ATA_PROT_DMA;
                index = 16;
@@@ -1072,16 -1071,69 +1072,62 @@@ static unsigned int ata_pio_modes(cons
           timing API will get this right anyway */
  }
  
 -static inline void
 -ata_queue_packet_task(struct ata_port *ap)
 -{
 -      if (!(ap->flags & ATA_FLAG_FLUSH_PIO_TASK))
 -              queue_work(ata_wq, &ap->packet_task);
 -}
 -
  static inline void
  ata_queue_pio_task(struct ata_port *ap)
  {
-       queue_work(ata_wq, &ap->pio_task);
+       if (!(ap->flags & ATA_FLAG_FLUSH_PIO_TASK))
+               queue_work(ata_wq, &ap->pio_task);
  }
  
  static inline void
  ata_queue_delayed_pio_task(struct ata_port *ap, unsigned long delay)
  {
-       queue_delayed_work(ata_wq, &ap->pio_task, delay);
+       if (!(ap->flags & ATA_FLAG_FLUSH_PIO_TASK))
+               queue_delayed_work(ata_wq, &ap->pio_task, delay);
+ }
+ /**
+  *    ata_flush_pio_tasks - Flush pio_task and packet_task
+  *    @ap: the target ata_port
+  *
+  *    After this function completes, pio_task and packet_task are
+  *    guranteed not to be running or scheduled.
+  *
+  *    LOCKING:
+  *    Kernel thread context (may sleep)
+  */
+ static void ata_flush_pio_tasks(struct ata_port *ap)
+ {
+       int tmp = 0;
+       unsigned long flags;
+       DPRINTK("ENTER\n");
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->flags |= ATA_FLAG_FLUSH_PIO_TASK;
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       DPRINTK("flush #1\n");
+       flush_workqueue(ata_wq);
+       /*
+        * At this point, if a task is running, it's guaranteed to see
+        * the FLUSH flag; thus, it will never queue pio tasks again.
+        * Cancel and flush.
+        */
+       tmp |= cancel_delayed_work(&ap->pio_task);
+       tmp |= cancel_delayed_work(&ap->packet_task);
+       if (!tmp) {
+               DPRINTK("flush #2\n");
+               flush_workqueue(ata_wq);
+       }
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->flags &= ~ATA_FLAG_FLUSH_PIO_TASK;
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       DPRINTK("EXIT\n");
  }
  
  void ata_qc_complete_internal(struct ata_queued_cmd *qc)
@@@ -1397,12 -1449,6 +1443,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,
@@@ -1446,12 -1489,11 +1492,11 @@@ static inline u8 ata_dev_knobble(const 
  }
  
  /**
-  *    ata_dev_config - Run device specific handlers and check for
-  *                     SATA->PATA bridges
-  *    @ap: Bus
-  *    @i:  Device
+  * ata_dev_config - Run device specific handlers & check for SATA->PATA bridges
+  * @ap: Bus
+  * @i:  Device
   *
-  *    LOCKING:
+  * LOCKING:
   */
  
  void ata_dev_config(struct ata_port *ap, unsigned int i)
@@@ -1798,9 -1840,9 +1843,9 @@@ int ata_timing_compute(struct ata_devic
        ata_timing_quantize(t, t, T, UT);
  
        /*
-        * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
-        * and some other commands. We have to ensure that the DMA cycle timing is
-        * slower/equal than the fastest PIO timing.
+        * Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
+        * S.M.A.R.T * and some other commands. We have to ensure that the
+        * DMA cycle timing is slower/equal than the fastest PIO timing.
         */
  
        if (speed > XFER_PIO_4) {
        }
  
        /*
-        * Lenghten active & recovery time so that cycle time is correct.
+        * Lengthen active & recovery time so that cycle time is correct.
         */
  
        if (t->act8b + t->rec8b < t->cyc8b) {
@@@ -1928,7 -1970,6 +1973,6 @@@ static void ata_host_set_dma(struct ata
   *
   *    LOCKING:
   *    PCI/etc. bus probe sem.
-  *
   */
  static void ata_set_mode(struct ata_port *ap)
  {
@@@ -1977,7 -2018,6 +2021,6 @@@ err_out
   *    or a timeout occurs.
   *
   *    LOCKING: None.
-  *
   */
  
  unsigned int ata_busy_sleep (struct ata_port *ap,
@@@ -2237,6 -2277,324 +2280,324 @@@ err_out
        DPRINTK("EXIT\n");
  }
  
+ static int sata_phy_resume(struct ata_port *ap)
+ {
+       unsigned long timeout = jiffies + (HZ * 5);
+       u32 sstatus;
+       scr_write_flush(ap, SCR_CONTROL, 0x300);
+       /* Wait for phy to become ready, if necessary. */
+       do {
+               msleep(200);
+               sstatus = scr_read(ap, SCR_STATUS);
+               if ((sstatus & 0xf) != 1)
+                       return 0;
+       } while (time_before(jiffies, timeout));
+       return -1;
+ }
+ /**
+  *    ata_std_probeinit - initialize probing
+  *    @ap: port to be probed
+  *
+  *    @ap is about to be probed.  Initialize it.  This function is
+  *    to be used as standard callback for ata_drive_probe_reset().
+  */
+ extern void ata_std_probeinit(struct ata_port *ap)
+ {
+       if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read)
+               sata_phy_resume(ap);
+ }
+ /**
+  *    ata_std_softreset - reset host port via ATA SRST
+  *    @ap: port to reset
+  *    @verbose: fail verbosely
+  *    @classes: resulting classes of attached devices
+  *
+  *    Reset host port using ATA SRST.  This function is to be used
+  *    as standard callback for ata_drive_*_reset() functions.
+  *
+  *    LOCKING:
+  *    Kernel thread context (may sleep)
+  *
+  *    RETURNS:
+  *    0 on success, -errno otherwise.
+  */
+ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
+ {
+       unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+       unsigned int devmask = 0, err_mask;
+       u8 err;
+       DPRINTK("ENTER\n");
+       /* determine if device 0/1 are present */
+       if (ata_devchk(ap, 0))
+               devmask |= (1 << 0);
+       if (slave_possible && ata_devchk(ap, 1))
+               devmask |= (1 << 1);
+       /* devchk reports device presence without actual device on
+        * most SATA controllers.  Check SStatus and turn devmask off
+        * if link is offline.  Note that we should continue resetting
+        * even when it seems like there's no device.
+        */
+       if (ap->ops->scr_read && !sata_dev_present(ap))
+               devmask = 0;
+       /* select device 0 again */
+       ap->ops->dev_select(ap, 0);
+       /* issue bus reset */
+       DPRINTK("about to softreset, devmask=%x\n", devmask);
+       err_mask = ata_bus_softreset(ap, devmask);
+       if (err_mask) {
+               if (verbose)
+                       printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
+                              ap->id, err_mask);
+               else
+                       DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n",
+                               err_mask);
+               return -EIO;
+       }
+       /* determine by signature whether we have ATA or ATAPI devices */
+       classes[0] = ata_dev_try_classify(ap, 0, &err);
+       if (slave_possible && err != 0x81)
+               classes[1] = ata_dev_try_classify(ap, 1, &err);
+       DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
+       return 0;
+ }
+ /**
+  *    sata_std_hardreset - reset host port via SATA phy reset
+  *    @ap: port to reset
+  *    @verbose: fail verbosely
+  *    @class: resulting class of attached device
+  *
+  *    SATA phy-reset host port using DET bits of SControl register.
+  *    This function is to be used as standard callback for
+  *    ata_drive_*_reset().
+  *
+  *    LOCKING:
+  *    Kernel thread context (may sleep)
+  *
+  *    RETURNS:
+  *    0 on success, -errno otherwise.
+  */
+ int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+ {
+       u32 serror;
+       DPRINTK("ENTER\n");
+       /* Issue phy wake/reset */
+       scr_write_flush(ap, SCR_CONTROL, 0x301);
+       /*
+        * Couldn't find anything in SATA I/II specs, but AHCI-1.1
+        * 10.4.2 says at least 1 ms.
+        */
+       msleep(1);
+       /* Bring phy back */
+       sata_phy_resume(ap);
+       /* Clear SError */
+       serror = scr_read(ap, SCR_ERROR);
+       scr_write(ap, SCR_ERROR, serror);
+       /* TODO: phy layer with polling, timeouts, etc. */
+       if (!sata_dev_present(ap)) {
+               *class = ATA_DEV_NONE;
+               DPRINTK("EXIT, link offline\n");
+               return 0;
+       }
+       if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+               if (verbose)
+                       printk(KERN_ERR "ata%u: COMRESET failed "
+                              "(device not ready)\n", ap->id);
+               else
+                       DPRINTK("EXIT, device not ready\n");
+               return -EIO;
+       }
+       *class = ata_dev_try_classify(ap, 0, NULL);
+       DPRINTK("EXIT, class=%u\n", *class);
+       return 0;
+ }
+ /**
+  *    ata_std_postreset - standard postreset callback
+  *    @ap: the target ata_port
+  *    @classes: classes of attached devices
+  *
+  *    This function is invoked after a successful reset.  Note that
+  *    the device might have been reset more than once using
+  *    different reset methods before postreset is invoked.
+  *    postreset is also reponsible for setting cable type.
+  *
+  *    This function is to be used as standard callback for
+  *    ata_drive_*_reset().
+  *
+  *    LOCKING:
+  *    Kernel thread context (may sleep)
+  */
+ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
+ {
+       DPRINTK("ENTER\n");
+       /* set cable type */
+       if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA)
+               ap->cbl = ATA_CBL_SATA;
+       /* print link status */
+       if (ap->cbl == ATA_CBL_SATA)
+               sata_print_link_status(ap);
+       /* bail out if no device is present */
+       if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+               DPRINTK("EXIT, no device\n");
+               return;
+       }
+       /* is double-select really necessary? */
+       if (classes[0] != ATA_DEV_NONE)
+               ap->ops->dev_select(ap, 1);
+       if (classes[1] != ATA_DEV_NONE)
+               ap->ops->dev_select(ap, 0);
+       /* re-enable interrupts & set up device control */
+       if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
+               ata_irq_on(ap);
+       DPRINTK("EXIT\n");
+ }
+ /**
+  *    ata_std_probe_reset - standard probe reset method
+  *    @ap: prot to perform probe-reset
+  *    @classes: resulting classes of attached devices
+  *
+  *    The stock off-the-shelf ->probe_reset method.
+  *
+  *    LOCKING:
+  *    Kernel thread context (may sleep)
+  *
+  *    RETURNS:
+  *    0 on success, -errno otherwise.
+  */
+ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
+ {
+       ata_reset_fn_t hardreset;
+       hardreset = NULL;
+       if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read)
+               hardreset = sata_std_hardreset;
+       return ata_drive_probe_reset(ap, ata_std_probeinit,
+                                    ata_std_softreset, hardreset,
+                                    ata_std_postreset, classes);
+ }
+ static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
+                         ata_postreset_fn_t postreset,
+                         unsigned int *classes)
+ {
+       int i, rc;
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               classes[i] = ATA_DEV_UNKNOWN;
+       rc = reset(ap, 0, classes);
+       if (rc)
+               return rc;
+       /* If any class isn't ATA_DEV_UNKNOWN, consider classification
+        * is complete and convert all ATA_DEV_UNKNOWN to
+        * ATA_DEV_NONE.
+        */
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               if (classes[i] != ATA_DEV_UNKNOWN)
+                       break;
+       if (i < ATA_MAX_DEVICES)
+               for (i = 0; i < ATA_MAX_DEVICES; i++)
+                       if (classes[i] == ATA_DEV_UNKNOWN)
+                               classes[i] = ATA_DEV_NONE;
+       if (postreset)
+               postreset(ap, classes);
+       return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV;
+ }
+ /**
+  *    ata_drive_probe_reset - Perform probe reset with given methods
+  *    @ap: port to reset
+  *    @probeinit: probeinit method (can be NULL)
+  *    @softreset: softreset method (can be NULL)
+  *    @hardreset: hardreset method (can be NULL)
+  *    @postreset: postreset method (can be NULL)
+  *    @classes: resulting classes of attached devices
+  *
+  *    Reset the specified port and classify attached devices using
+  *    given methods.  This function prefers softreset but tries all
+  *    possible reset sequences to reset and classify devices.  This
+  *    function is intended to be used for constructing ->probe_reset
+  *    callback by low level drivers.
+  *
+  *    Reset methods should follow the following rules.
+  *
+  *    - Return 0 on sucess, -errno on failure.
+  *    - If classification is supported, fill classes[] with
+  *      recognized class codes.
+  *    - If classification is not supported, leave classes[] alone.
+  *    - If verbose is non-zero, print error message on failure;
+  *      otherwise, shut up.
+  *
+  *    LOCKING:
+  *    Kernel thread context (may sleep)
+  *
+  *    RETURNS:
+  *    0 on success, -EINVAL if no reset method is avaliable, -ENODEV
+  *    if classification fails, and any error code from reset
+  *    methods.
+  */
+ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
+                         ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+                         ata_postreset_fn_t postreset, unsigned int *classes)
+ {
+       int rc = -EINVAL;
+       if (probeinit)
+               probeinit(ap);
+       if (softreset) {
+               rc = do_probe_reset(ap, softreset, postreset, classes);
+               if (rc == 0)
+                       return 0;
+       }
+       if (!hardreset)
+               return rc;
+       rc = do_probe_reset(ap, hardreset, postreset, classes);
+       if (rc == 0 || rc != -ENODEV)
+               return rc;
+       if (softreset)
+               rc = do_probe_reset(ap, softreset, postreset, classes);
+       return rc;
+ }
  static void ata_pr_blacklisted(const struct ata_port *ap,
                               const struct ata_device *dev)
  {
@@@ -2907,13 -3265,14 +3268,13 @@@ 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 -
+  *    ata_pio_poll - poll using PIO, depending on current state
   *    @ap: the target ata_port
   *
   *    LOCKING:
@@@ -2972,8 -3331,7 +3333,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;
  }
  
  
  /**
-  *    swap_buf_le16 - swap halves of 16-words in place
+  *    swap_buf_le16 - swap halves of 16-bit words in place
   *    @buf:  Buffer to swap
   *    @buf_words:  Number of 16-bit words in buffer.
   *
@@@ -3188,23 -3546,7 +3549,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);
 +
 +      ata_data_xfer(ap, qc->cdb, ap->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;
 +      }
 +}
 +
 +/**
 + *    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)) {
 +              qc->err_mask |= AC_ERR_TIMEOUT;
 +              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 */
 +              qc->err_mask |= AC_ERR_HSM;
 +              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);
  
 -      /* do the actual data transfer */
 -      do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
 -      ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
 +      /* if polling, ata_pio_task() handles the rest.
 +       * otherwise, interrupt handler takes over from here.
 +       */
 +      return has_next;
  
 -      kunmap(page);
 +err_out:
 +      return 1; /* has next */
  }
  
  /**
@@@ -3425,23 -3628,7 +3786,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;
  }
@@@ -3488,8 -3682,6 +3849,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;
@@@ -3560,22 -3752,19 +3921,22 @@@ 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)
  {
        struct ata_queued_cmd *qc;
  
 -      printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
 -
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
  
 +      if (qc->tf.command != ATA_CMD_PACKET)
 +              printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
 +
        /* make sure qc->err_mask is available to 
         * know what's wrong and recover
         */
@@@ -3590,23 -3779,22 +3951,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)
                ata_queue_delayed_pio_task(ap, timeout);
 -      else if (!qc_completed)
 +      else if (has_next)
                goto fsm_start;
  }
  
@@@ -3658,6 -3842,9 +4019,9 @@@ static void ata_qc_timeout(struct ata_q
  
        DPRINTK("ENTER\n");
  
+       ata_flush_pio_tasks(ap);
+       ap->hsm_task_state = HSM_ST_IDLE;
        spin_lock_irqsave(&host_set->lock, flags);
  
        switch (qc->tf.protocol) {
                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;
        }
  
@@@ -3933,104 -4118,43 +4297,104 @@@ 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)
 +                              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_queue_pio_task(ap);
 +
                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;
 -              ata_queue_pio_task(ap);
 -              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_queue_packet_task(ap);
 +
 +              if (qc->tf.flags & ATA_TFLAG_WRITE) {
 +                      /* PIO data out protocol */
 +                      ap->hsm_task_state = HSM_ST_FIRST;
 +                      ata_queue_pio_task(ap);
 +
 +                      /* 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_queue_pio_task(ap);
 +
 +                      /* 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_queue_packet_task(ap);
 +
 +              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_queue_pio_task(ap);
                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 */
 -              ata_queue_packet_task(ap);
 +              ap->hsm_task_state = HSM_ST_FIRST;
 +
 +              /* send cdb by polling if no cdb interrupt */
 +              if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
 +                      ata_queue_pio_task(ap);
                break;
  
        default:
@@@ -4291,160 -4415,48 +4655,160 @@@ 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);
 +
 +                      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;
 +      }
  
 -              /* 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 | ATA_DF))) {
 +              qc->err_mask |= AC_ERR_DEV;
 +              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 */
 +                      qc->err_mask |= AC_ERR_HSM;
 +                      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 */
 +                              qc->err_mask |= AC_ERR_HSM;
 +                              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 */
 +                      qc->err_mask |= AC_ERR_HSM;
 +                      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:
 +              if (qc->tf.command != ATA_CMD_PACKET)
 +                      printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n",
 +                             ap->id, status, host_stat);
 +
 +              /* make sure qc->err_mask is available to 
 +               * know what's wrong and recover
 +               */
 +              assert(qc->err_mask);
 +
 +              ap->hsm_task_state = HSM_ST_IDLE;
 +              ata_qc_complete(qc);
 +              break;
        default:
                goto idle_irq;
        }
@@@ -4495,11 -4507,11 +4859,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_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");
 -      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;
 -              ata_queue_pio_task(ap);
 -      }
 -
 -      return;
 -
 -err_out:
 -      ata_poll_qc_complete(qc);
 -}
 -
 -
  /*
   * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
   * without filling any other registers
@@@ -4561,6 -4646,8 +4925,8 @@@ static int ata_start_drive(struct ata_p
  
  /**
   *    ata_device_resume - wakeup a previously suspended devices
+  *    @ap: port the device is connected to
+  *    @dev: the device to resume
   *
   *    Kick the drive back into action, by sending it an idle immediate
   *    command and making sure its transfer mode matches between drive
@@@ -4583,10 -4670,11 +4949,11 @@@ int ata_device_resume(struct ata_port *
  
  /**
   *    ata_device_suspend - prepare a device for suspend
+  *    @ap: port the device is connected to
+  *    @dev: the device to 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)
  {
@@@ -4726,6 -4814,7 +5093,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);
        INIT_LIST_HEAD(&ap->eh_done_q);
  
@@@ -4869,9 -4958,9 +5236,9 @@@ int ata_device_add(const struct ata_pro
  
                ap = host_set->ports[i];
  
-               DPRINTK("ata%u: probe begin\n", ap->id);
+               DPRINTK("ata%u: bus probe begin\n", ap->id);
                rc = ata_bus_probe(ap);
-               DPRINTK("ata%u: probe end\n", ap->id);
+               DPRINTK("ata%u: bus probe end\n", ap->id);
  
                if (rc) {
                        /* FIXME: do something useful here?
        }
  
        /* probes are done, now scan each port's disk(s) */
-       DPRINTK("probe begin\n");
+       DPRINTK("host probe begin\n");
        for (i = 0; i < count; i++) {
                struct ata_port *ap = host_set->ports[i];
  
@@@ -5459,6 -5548,12 +5826,12 @@@ EXPORT_SYMBOL_GPL(ata_port_probe)
  EXPORT_SYMBOL_GPL(sata_phy_reset);
  EXPORT_SYMBOL_GPL(__sata_phy_reset);
  EXPORT_SYMBOL_GPL(ata_bus_reset);
+ EXPORT_SYMBOL_GPL(ata_std_probeinit);
+ EXPORT_SYMBOL_GPL(ata_std_softreset);
+ EXPORT_SYMBOL_GPL(sata_std_hardreset);
+ EXPORT_SYMBOL_GPL(ata_std_postreset);
+ EXPORT_SYMBOL_GPL(ata_std_probe_reset);
+ EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
  EXPORT_SYMBOL_GPL(ata_port_disable);
  EXPORT_SYMBOL_GPL(ata_ratelimit);
  EXPORT_SYMBOL_GPL(ata_busy_sleep);
diff --combined drivers/scsi/sata_mv.c
index 0042c7840d809a36882ea45cda548e879857aead,3e916327ae3738421efce50ae3508b418fd9c617..5b36a23455dec97620d8e7fba14240933b958c08
@@@ -37,7 -37,7 +37,7 @@@
  #include <asm/io.h>
  
  #define DRV_NAME      "sata_mv"
- #define DRV_VERSION   "0.5"
+ #define DRV_VERSION   "0.6"
  
  enum {
        /* BAR's are enumerated in terms of pci_resource_start() terms */
@@@ -87,7 -87,7 +87,7 @@@
        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),
        MV_HP_ERRATA_50XXB2     = (1 << 2),
        MV_HP_ERRATA_60X1B2     = (1 << 3),
        MV_HP_ERRATA_60X1C0     = (1 << 4),
-       MV_HP_50XX              = (1 << 5),
+       MV_HP_ERRATA_XX42A0     = (1 << 5),
+       MV_HP_50XX              = (1 << 6),
+       MV_HP_GEN_IIE           = (1 << 7),
  
        /* Port private flags (pp_flags) */
        MV_PP_FLAG_EDMA_EN      = (1 << 0),
  
  #define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
  #define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0)
+ #define IS_GEN_I(hpriv) IS_50XX(hpriv)
+ #define IS_GEN_II(hpriv) IS_60XX(hpriv)
+ #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
  
  enum {
        /* Our DMA boundary is determined by an ePRD being unable to handle
@@@ -255,6 -260,8 +260,8 @@@ enum chip_type 
        chip_5080,
        chip_604x,
        chip_608x,
+       chip_6042,
+       chip_7042,
  };
  
  /* Command ReQuest Block: 32B */
@@@ -265,6 -272,14 +272,14 @@@ struct mv_crqb 
        u16                     ata_cmd[11];
  };
  
+ struct mv_crqb_iie {
+       u32                     addr;
+       u32                     addr_hi;
+       u32                     flags;
+       u32                     len;
+       u32                     ata_cmd[4];
+ };
  /* Command ResPonse Block: 8B */
  struct mv_crpb {
        u16                     id;
@@@ -328,6 -343,7 +343,7 @@@ static void mv_host_stop(struct ata_hos
  static int mv_port_start(struct ata_port *ap);
  static void mv_port_stop(struct ata_port *ap);
  static void mv_qc_prep(struct ata_queued_cmd *qc);
+ static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
  static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
  static irqreturn_t mv_interrupt(int irq, void *dev_instance,
                                struct pt_regs *regs);
@@@ -430,6 -446,33 +446,33 @@@ static const struct ata_port_operation
        .host_stop              = mv_host_stop,
  };
  
+ static const struct ata_port_operations mv_iie_ops = {
+       .port_disable           = ata_port_disable,
+       .tf_load                = ata_tf_load,
+       .tf_read                = ata_tf_read,
+       .check_status           = ata_check_status,
+       .exec_command           = ata_exec_command,
+       .dev_select             = ata_std_dev_select,
+       .phy_reset              = mv_phy_reset,
+       .qc_prep                = mv_qc_prep_iie,
+       .qc_issue               = mv_qc_issue,
+       .eng_timeout            = mv_eng_timeout,
+       .irq_handler            = mv_interrupt,
+       .irq_clear              = mv_irq_clear,
+       .scr_read               = mv_scr_read,
+       .scr_write              = mv_scr_write,
+       .port_start             = mv_port_start,
+       .port_stop              = mv_port_stop,
+       .host_stop              = mv_host_stop,
+ };
  static const struct ata_port_info mv_port_info[] = {
        {  /* chip_504x */
                .sht            = &mv_sht,
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv6_ops,
        },
+       {  /* chip_6042 */
+               .sht            = &mv_sht,
+               .host_flags     = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &mv_iie_ops,
+       },
+       {  /* chip_7042 */
+               .sht            = &mv_sht,
+               .host_flags     = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+                                  MV_FLAG_DUAL_HC),
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &mv_iie_ops,
+       },
  };
  
  static const struct pci_device_id mv_pci_tbl[] = {
  
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x},
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x},
+       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6042), 0, 0, chip_6042},
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x},
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x},
  
@@@ -509,6 -568,12 +568,12 @@@ static const struct mv_hw_ops mv6xxx_op
        .reset_bus              = mv_reset_pci_bus,
  };
  
+ /*
+  * module options
+  */
+ static int msi;             /* Use PCI msi; either zero (off, default) or non-zero */
  /*
   * Functions
   */
@@@ -767,6 -832,33 +832,33 @@@ static inline void mv_priv_free(struct 
        dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
  }
  
+ static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
+ {
+       u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
+       /* set up non-NCQ EDMA configuration */
+       cfg &= ~0x1f;           /* clear queue depth */
+       cfg &= ~EDMA_CFG_NCQ;   /* clear NCQ mode */
+       cfg &= ~(1 << 9);       /* disable equeue */
+       if (IS_GEN_I(hpriv))
+               cfg |= (1 << 8);        /* enab config burst size mask */
+       else if (IS_GEN_II(hpriv))
+               cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN;
+       else if (IS_GEN_IIE(hpriv)) {
+               cfg |= (1 << 23);       /* dis RX PM port mask */
+               cfg &= ~(1 << 16);      /* dis FIS-based switching (for now) */
+               cfg &= ~(1 << 19);      /* dis 128-entry queue (for now?) */
+               cfg |= (1 << 18);       /* enab early completion */
+               cfg |= (1 << 17);       /* enab host q cache */
+               cfg |= (1 << 22);       /* enab cutthrough */
+       }
+       writelfl(cfg, port_mmio + EDMA_CFG_OFS);
+ }
  /**
   *      mv_port_start - Port specific init/start routine.
   *      @ap: ATA channel to manipulate
  static int mv_port_start(struct ata_port *ap)
  {
        struct device *dev = ap->host_set->dev;
+       struct mv_host_priv *hpriv = ap->host_set->private_data;
        struct mv_port_priv *pp;
        void __iomem *port_mmio = mv_ap_base(ap);
        void *mem;
        pp->sg_tbl = mem;
        pp->sg_tbl_dma = mem_dma;
  
-       writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT |
-                EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS);
+       mv_edma_cfg(hpriv, port_mmio);
  
        writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
        writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
                 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
  
-       writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
-       writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+               writelfl(pp->crqb_dma & 0xffffffff,
+                        port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+       else
+               writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
  
        writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
+       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+               writelfl(pp->crpb_dma & 0xffffffff,
+                        port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+       else
+               writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
        writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
                 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
  
@@@ -954,9 -1056,8 +1056,8 @@@ static void mv_qc_prep(struct ata_queue
        struct ata_taskfile *tf;
        u16 flags = 0;
  
-       if (ATA_PROT_DMA != qc->tf.protocol) {
+       if (ATA_PROT_DMA != qc->tf.protocol)
                return;
-       }
  
        /* the req producer index should be the same as we remember it */
        assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
  
        /* Fill in command request block
         */
-       if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
+       if (!(qc->tf.flags & ATA_TFLAG_WRITE))
                flags |= CRQB_FLAG_READ;
-       }
        assert(MV_MAX_Q_DEPTH > qc->tag);
        flags |= qc->tag << CRQB_TAG_SHIFT;
  
        mv_crqb_pack_cmd(cw++, tf->device, ATA_REG_DEVICE, 0);
        mv_crqb_pack_cmd(cw++, tf->command, ATA_REG_CMD, 1);    /* last */
  
-       if (!(qc->flags & ATA_QCFLAG_DMAMAP)) {
+       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+               return;
+       mv_fill_sg(qc);
+ }
+ /**
+  *      mv_qc_prep_iie - Host specific command preparation.
+  *      @qc: queued command to prepare
+  *
+  *      This routine simply redirects to the general purpose routine
+  *      if command is not DMA.  Else, it handles prep of the CRQB
+  *      (command request block), does some sanity checking, and calls
+  *      the SG load routine.
+  *
+  *      LOCKING:
+  *      Inherited from caller.
+  */
+ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
+ {
+       struct ata_port *ap = qc->ap;
+       struct mv_port_priv *pp = ap->private_data;
+       struct mv_crqb_iie *crqb;
+       struct ata_taskfile *tf;
+       u32 flags = 0;
+       if (ATA_PROT_DMA != qc->tf.protocol)
+               return;
+       /* the req producer index should be the same as we remember it */
+       assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
+                EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+              pp->req_producer);
+       /* Fill in Gen IIE command request block
+        */
+       if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+               flags |= CRQB_FLAG_READ;
+       assert(MV_MAX_Q_DEPTH > qc->tag);
+       flags |= qc->tag << CRQB_TAG_SHIFT;
+       crqb = (struct mv_crqb_iie *) &pp->crqb[pp->req_producer];
+       crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
+       crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
+       crqb->flags = cpu_to_le32(flags);
+       tf = &qc->tf;
+       crqb->ata_cmd[0] = cpu_to_le32(
+                       (tf->command << 16) |
+                       (tf->feature << 24)
+               );
+       crqb->ata_cmd[1] = cpu_to_le32(
+                       (tf->lbal << 0) |
+                       (tf->lbam << 8) |
+                       (tf->lbah << 16) |
+                       (tf->device << 24)
+               );
+       crqb->ata_cmd[2] = cpu_to_le32(
+                       (tf->hob_lbal << 0) |
+                       (tf->hob_lbam << 8) |
+                       (tf->hob_lbah << 16) |
+                       (tf->hob_feature << 24)
+               );
+       crqb->ata_cmd[3] = cpu_to_le32(
+                       (tf->nsect << 0) |
+                       (tf->hob_nsect << 8)
+               );
+       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
                return;
-       }
        mv_fill_sg(qc);
  }
  
@@@ -1220,7 -1387,8 +1387,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);
                                }
@@@ -1673,6 -1841,12 +1840,12 @@@ static void mv6_phy_errata(struct mv_ho
        m2 |= hpriv->signal[port].pre;
        m2 &= ~(1 << 16);
  
+       /* according to mvSata 3.6.1, some IIE values are fixed */
+       if (IS_GEN_IIE(hpriv)) {
+               m2 &= ~0xC30FF01F;
+               m2 |= 0x0000900F;
+       }
        writel(m2, port_mmio + PHY_MODE2);
  }
  
@@@ -1977,6 -2151,27 +2150,27 @@@ static int mv_chip_id(struct pci_dev *p
                }
                break;
  
+       case chip_7042:
+       case chip_6042:
+               hpriv->ops = &mv6xxx_ops;
+               hp_flags |= MV_HP_GEN_IIE;
+               switch (rev_id) {
+               case 0x0:
+                       hp_flags |= MV_HP_ERRATA_XX42A0;
+                       break;
+               case 0x1:
+                       hp_flags |= MV_HP_ERRATA_60X1C0;
+                       break;
+               default:
+                       dev_printk(KERN_WARNING, &pdev->dev,
+                          "Applying 60X1C0 workarounds to unknown rev\n");
+                       hp_flags |= MV_HP_ERRATA_60X1C0;
+                       break;
+               }
+               break;
        default:
                printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx);
                return 1;
@@@ -2180,7 -2375,7 +2374,7 @@@ static int mv_init_one(struct pci_dev *
        }
  
        /* Enable interrupts */
-       if (pci_enable_msi(pdev) == 0) {
+       if (msi && pci_enable_msi(pdev) == 0) {
                hpriv->hp_flags |= MV_HP_FLAG_MSI;
        } else {
                pci_intx(pdev, 1);
@@@ -2235,5 -2430,8 +2429,8 @@@ MODULE_LICENSE("GPL")
  MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
  MODULE_VERSION(DRV_VERSION);
  
+ module_param(msi, int, 0444);
+ MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
  module_init(mv_init);
  module_exit(mv_exit);
index 760c56f71632d506664d6e6d8b57802a3617f09d,0950a8e4581477d3c88e9d9989afe3d1e11e90fe..dcd1667f4144a120588d4367c3a44556884ca355
@@@ -46,7 -46,7 +46,7 @@@
  #include "sata_promise.h"
  
  #define DRV_NAME      "sata_promise"
- #define DRV_VERSION   "1.03"
+ #define DRV_VERSION   "1.04"
  
  
  enum {
@@@ -58,6 -58,7 +58,7 @@@
        PDC_GLOBAL_CTL          = 0x48, /* Global control/status (per port) */
        PDC_CTLSTAT             = 0x60, /* IDE control and status (per port) */
        PDC_SATA_PLUG_CSR       = 0x6C, /* SATA Plug control/status reg */
+       PDC2_SATA_PLUG_CSR      = 0x60, /* SATAII Plug control/status reg */
        PDC_SLEW_CTL            = 0x470, /* slew rate control reg */
  
        PDC_ERR_MASK            = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
        board_20319             = 1,    /* FastTrak S150 TX4 */
        board_20619             = 2,    /* FastTrak TX4000 */
        board_20771             = 3,    /* FastTrak TX2300 */
+       board_2057x             = 4,    /* SATAII150 Tx2plus */
+       board_40518             = 5,    /* SATAII150 Tx4 */
  
-       PDC_HAS_PATA            = (1 << 1), /* PDC20375 has PATA */
+       PDC_HAS_PATA            = (1 << 1), /* PDC20375/20575 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,
  };
  
  
@@@ -83,6 -85,10 +86,10 @@@ struct pdc_port_priv 
        dma_addr_t              pkt_dma;
  };
  
+ struct pdc_host_priv {
+       int                     hotplug_offset;
+ };
  static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
  static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
  static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
@@@ -97,6 -103,7 +104,7 @@@ static void pdc_tf_load_mmio(struct ata
  static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
  static void pdc_irq_clear(struct ata_port *ap);
  static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
+ static void pdc_host_stop(struct ata_host_set *host_set);
  
  
  static struct scsi_host_template pdc_ata_sht = {
@@@ -138,7 -145,7 +146,7 @@@ static const struct ata_port_operation
        .scr_write              = pdc_sata_scr_write,
        .port_start             = pdc_port_start,
        .port_stop              = pdc_port_stop,
-       .host_stop              = ata_pci_host_stop,
+       .host_stop              = pdc_host_stop,
  };
  
  static const struct ata_port_operations pdc_pata_ops = {
  
        .port_start             = pdc_port_start,
        .port_stop              = pdc_port_stop,
-       .host_stop              = ata_pci_host_stop,
+       .host_stop              = pdc_host_stop,
  };
  
  static const struct ata_port_info pdc_port_info[] = {
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &pdc_sata_ops,
        },
+       /* board_2057x */
+       {
+               .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,
+       },
+       /* board_40518 */
+       {
+               .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, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_2037x },
        { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
+         board_2057x },
        { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
+         board_2057x },
        { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_2037x },
  
        { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_20319 },
        { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20319 },
+         board_40518 },
  
        { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_20619 },
@@@ -262,12 -289,11 +290,11 @@@ static int pdc_port_start(struct ata_po
        if (rc)
                return rc;
  
-       pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+       pp = kzalloc(sizeof(*pp), GFP_KERNEL);
        if (!pp) {
                rc = -ENOMEM;
                goto err_out;
        }
-       memset(pp, 0, sizeof(*pp));
  
        pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
        if (!pp->pkt) {
@@@ -299,6 -325,16 +326,16 @@@ static void pdc_port_stop(struct ata_po
  }
  
  
+ static void pdc_host_stop(struct ata_host_set *host_set)
+ {
+       struct pdc_host_priv *hp = host_set->private_data;
+       ata_pci_host_stop(host_set);
+       kfree(hp);
+ }
  static void pdc_reset_port(struct ata_port *ap)
  {
        void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT;
@@@ -488,14 -524,15 +525,15 @@@ static irqreturn_t pdc_interrupt (int i
                VPRINTK("QUICK EXIT 2\n");
                return IRQ_NONE;
        }
+       spin_lock(&host_set->lock);
        mask &= 0xffff;         /* only 16 tags possible */
        if (!mask) {
                VPRINTK("QUICK EXIT 3\n");
-               return IRQ_NONE;
+               goto done_irq;
        }
  
-       spin_lock(&host_set->lock);
        writel(mask, mmio_base + PDC_INT_SEQMASK);
  
        for (i = 0; i < host_set->n_ports; 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);
                }
        }
  
-         spin_unlock(&host_set->lock);
        VPRINTK("EXIT\n");
  
+ done_irq:
+       spin_unlock(&host_set->lock);
        return IRQ_RETVAL(handled);
  }
  
@@@ -593,6 -630,8 +631,8 @@@ static void pdc_ata_setup_port(struct a
  static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
  {
        void __iomem *mmio = pe->mmio_base;
+       struct pdc_host_priv *hp = pe->private_data;
+       int hotplug_offset = hp->hotplug_offset;
        u32 tmp;
  
        /*
        writel(tmp, mmio + PDC_FLASH_CTL);
  
        /* clear plug/unplug flags for all ports */
-       tmp = readl(mmio + PDC_SATA_PLUG_CSR);
-       writel(tmp | 0xff, mmio + PDC_SATA_PLUG_CSR);
+       tmp = readl(mmio + hotplug_offset);
+       writel(tmp | 0xff, mmio + hotplug_offset);
  
        /* mask plug/unplug ints */
-       tmp = readl(mmio + PDC_SATA_PLUG_CSR);
-       writel(tmp | 0xff0000, mmio + PDC_SATA_PLUG_CSR);
+       tmp = readl(mmio + hotplug_offset);
+       writel(tmp | 0xff0000, mmio + hotplug_offset);
  
        /* reduce TBG clock to 133 Mhz. */
        tmp = readl(mmio + PDC_TBG_MODE);
@@@ -634,6 -673,7 +674,7 @@@ static int pdc_ata_init_one (struct pci
  {
        static int printed_version;
        struct ata_probe_ent *probe_ent = NULL;
+       struct pdc_host_priv *hp;
        unsigned long base;
        void __iomem *mmio_base;
        unsigned int board_idx = (unsigned int) ent->driver_data;
        if (rc)
                goto err_out_regions;
  
-       probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
        if (probe_ent == NULL) {
                rc = -ENOMEM;
                goto err_out_regions;
        }
  
-       memset(probe_ent, 0, sizeof(*probe_ent));
        probe_ent->dev = pci_dev_to_dev(pdev);
        INIT_LIST_HEAD(&probe_ent->node);
  
        }
        base = (unsigned long) mmio_base;
  
+       hp = kzalloc(sizeof(*hp), GFP_KERNEL);
+       if (hp == NULL) {
+               rc = -ENOMEM;
+               goto err_out_free_ent;
+       }
+       /* Set default hotplug offset */
+       hp->hotplug_offset = PDC_SATA_PLUG_CSR;
+       probe_ent->private_data = hp;
        probe_ent->sht          = pdc_port_info[board_idx].sht;
        probe_ent->host_flags   = pdc_port_info[board_idx].host_flags;
        probe_ent->pio_mask     = pdc_port_info[board_idx].pio_mask;
  
        /* notice 4-port boards */
        switch (board_idx) {
+       case board_40518:
+               /* Override hotplug offset for SATAII150 */
+               hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
+               /* Fall through */
        case board_20319:
                        probe_ent->n_ports = 4;
  
                probe_ent->port[2].scr_addr = base + 0x600;
                probe_ent->port[3].scr_addr = base + 0x700;
                break;
+       case board_2057x:
+               /* Override hotplug offset for SATAII150 */
+               hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
+               /* Fall through */
        case board_2037x:
                probe_ent->n_ports = 2;
                break;
        /* initialize adapter */
        pdc_host_init(board_idx, probe_ent);
  
-       /* FIXME: check ata_device_add return value */
-       ata_device_add(probe_ent);
+       /* FIXME: Need any other frees than hp? */
+       if (!ata_device_add(probe_ent))
+               kfree(hp);
        kfree(probe_ent);
  
        return 0;
diff --combined include/linux/libata.h
index f8a04ef5c7c3295768c858e2f71b08fb1993c4be,68b3fe6f9a4da7d23040f44e1ac1005065c801f3..29c78191ab60c23e17e6e1b99d7297dec474167a
@@@ -134,7 -134,6 +134,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), /* (obsolete) 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_PIO_LBA48      = (1 << 13), /* Host DMA engine is LBA28 only */
        ATA_FLAG_IRQ_MASK       = (1 << 14), /* Mask IRQ in PIO xfers */
  
+       ATA_FLAG_FLUSH_PIO_TASK = (1 << 15), /* Flush PIO task */
+       ATA_FLAG_IN_EH          = (1 << 16), /* EH in progress */
        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,      /* heuristic */
        ATA_TMOUT_BOOT_QUICK    = 7 * HZ,       /* heuristic */
 +      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 {
@@@ -246,6 -244,9 +249,9 @@@ struct ata_queued_cmd
  
  /* typedefs */
  typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
+ typedef void (*ata_probeinit_fn_t)(struct ata_port *);
+ typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *);
+ typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *);
  
  struct ata_ioports {
        unsigned long           cmd_addr;
@@@ -396,6 -397,8 +402,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;
@@@ -481,6 -484,16 +487,16 @@@ extern void ata_port_probe(struct ata_p
  extern void __sata_phy_reset(struct ata_port *ap);
  extern void sata_phy_reset(struct ata_port *ap);
  extern void ata_bus_reset(struct ata_port *ap);
+ extern int ata_drive_probe_reset(struct ata_port *ap,
+                       ata_probeinit_fn_t probeinit,
+                       ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+                       ata_postreset_fn_t postreset, unsigned int *classes);
+ extern void ata_std_probeinit(struct ata_port *ap);
+ extern int ata_std_softreset(struct ata_port *ap, int verbose,
+                            unsigned int *classes);
+ extern int sata_std_hardreset(struct ata_port *ap, int verbose,
+                             unsigned int *class);
+ extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
  extern void ata_port_disable(struct ata_port *);
  extern void ata_std_ports(struct ata_ioports *ioaddr);
  #ifdef CONFIG_PCI
@@@ -521,6 -534,7 +537,7 @@@ extern void ata_std_dev_select (struct 
  extern u8 ata_check_status(struct ata_port *ap);
  extern u8 ata_altstatus(struct ata_port *ap);
  extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
+ extern int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes);
  extern int ata_port_start (struct ata_port *ap);
  extern void ata_port_stop (struct ata_port *ap);
  extern void ata_host_stop (struct ata_host_set *host_set);