]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'master'
authorJeff Garzik <jeff@garzik.org>
Wed, 1 Mar 2006 19:45:47 +0000 (14:45 -0500)
committerJeff Garzik <jeff@garzik.org>
Wed, 1 Mar 2006 19:45:47 +0000 (14:45 -0500)
1  2 
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c
drivers/scsi/libata.h
drivers/scsi/scsi_error.c

index ab3257a6b8606672aee71793a120bba6d63a27a6,4f91b0dc572bb5b1aea66a6aed56df874808eac8..17c1df435cc8ab89b0a6f0c79c824de07dc3edd5
  
  #include "libata.h"
  
 -static unsigned int ata_busy_sleep (struct ata_port *ap,
 -                                  unsigned long tmout_pat,
 -                                  unsigned long tmout);
 -static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev);
 -static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
 +static unsigned int ata_dev_init_params(struct ata_port *ap,
 +                                      struct ata_device *dev);
  static void ata_set_mode(struct ata_port *ap);
  static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
  static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift);
@@@ -70,6 -73,7 +70,6 @@@ 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_qc_complete(struct ata_queued_cmd *qc);
  
  static unsigned int ata_unique_id = 1;
  static struct workqueue_struct *ata_wq;
@@@ -78,11 -82,412 +78,15 @@@ int atapi_enabled = 0
  module_param(atapi_enabled, int, 0444);
  MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
  
+ int libata_fua = 0;
+ module_param_named(fua, libata_fua, int, 0444);
+ MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
  MODULE_AUTHOR("Jeff Garzik");
  MODULE_DESCRIPTION("Library module for ATA devices");
  MODULE_LICENSE("GPL");
  MODULE_VERSION(DRV_VERSION);
  
 -/**
 - *    ata_tf_load_pio - send taskfile registers to host controller
 - *    @ap: Port to which output is sent
 - *    @tf: ATA taskfile register set
 - *
 - *    Outputs ATA taskfile to standard ATA host controller.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -
 -static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
 -{
 -      struct ata_ioports *ioaddr = &ap->ioaddr;
 -      unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
 -
 -      if (tf->ctl != ap->last_ctl) {
 -              outb(tf->ctl, ioaddr->ctl_addr);
 -              ap->last_ctl = tf->ctl;
 -              ata_wait_idle(ap);
 -      }
 -
 -      if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
 -              outb(tf->hob_feature, ioaddr->feature_addr);
 -              outb(tf->hob_nsect, ioaddr->nsect_addr);
 -              outb(tf->hob_lbal, ioaddr->lbal_addr);
 -              outb(tf->hob_lbam, ioaddr->lbam_addr);
 -              outb(tf->hob_lbah, ioaddr->lbah_addr);
 -              VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
 -                      tf->hob_feature,
 -                      tf->hob_nsect,
 -                      tf->hob_lbal,
 -                      tf->hob_lbam,
 -                      tf->hob_lbah);
 -      }
 -
 -      if (is_addr) {
 -              outb(tf->feature, ioaddr->feature_addr);
 -              outb(tf->nsect, ioaddr->nsect_addr);
 -              outb(tf->lbal, ioaddr->lbal_addr);
 -              outb(tf->lbam, ioaddr->lbam_addr);
 -              outb(tf->lbah, ioaddr->lbah_addr);
 -              VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
 -                      tf->feature,
 -                      tf->nsect,
 -                      tf->lbal,
 -                      tf->lbam,
 -                      tf->lbah);
 -      }
 -
 -      if (tf->flags & ATA_TFLAG_DEVICE) {
 -              outb(tf->device, ioaddr->device_addr);
 -              VPRINTK("device 0x%X\n", tf->device);
 -      }
 -
 -      ata_wait_idle(ap);
 -}
 -
 -/**
 - *    ata_tf_load_mmio - send taskfile registers to host controller
 - *    @ap: Port to which output is sent
 - *    @tf: ATA taskfile register set
 - *
 - *    Outputs ATA taskfile to standard ATA host controller using MMIO.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -
 -static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 -{
 -      struct ata_ioports *ioaddr = &ap->ioaddr;
 -      unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
 -
 -      if (tf->ctl != ap->last_ctl) {
 -              writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
 -              ap->last_ctl = tf->ctl;
 -              ata_wait_idle(ap);
 -      }
 -
 -      if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
 -              writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr);
 -              writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr);
 -              writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr);
 -              writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr);
 -              writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr);
 -              VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
 -                      tf->hob_feature,
 -                      tf->hob_nsect,
 -                      tf->hob_lbal,
 -                      tf->hob_lbam,
 -                      tf->hob_lbah);
 -      }
 -
 -      if (is_addr) {
 -              writeb(tf->feature, (void __iomem *) ioaddr->feature_addr);
 -              writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
 -              writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
 -              writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
 -              writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
 -              VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
 -                      tf->feature,
 -                      tf->nsect,
 -                      tf->lbal,
 -                      tf->lbam,
 -                      tf->lbah);
 -      }
 -
 -      if (tf->flags & ATA_TFLAG_DEVICE) {
 -              writeb(tf->device, (void __iomem *) ioaddr->device_addr);
 -              VPRINTK("device 0x%X\n", tf->device);
 -      }
 -
 -      ata_wait_idle(ap);
 -}
 -
 -
 -/**
 - *    ata_tf_load - send taskfile registers to host controller
 - *    @ap: Port to which output is sent
 - *    @tf: ATA taskfile register set
 - *
 - *    Outputs ATA taskfile to standard ATA host controller using MMIO
 - *    or PIO as indicated by the ATA_FLAG_MMIO flag.
 - *    Writes the control, feature, nsect, lbal, lbam, and lbah registers.
 - *    Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
 - *    hob_lbal, hob_lbam, and hob_lbah.
 - *
 - *    This function waits for idle (!BUSY and !DRQ) after writing
 - *    registers.  If the control register has a new value, this
 - *    function also waits for idle after writing control and before
 - *    writing the remaining registers.
 - *
 - *    May be used as the tf_load() entry in ata_port_operations.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
 -{
 -      if (ap->flags & ATA_FLAG_MMIO)
 -              ata_tf_load_mmio(ap, tf);
 -      else
 -              ata_tf_load_pio(ap, tf);
 -}
 -
 -/**
 - *    ata_exec_command_pio - issue ATA command to host controller
 - *    @ap: port to which command is being issued
 - *    @tf: ATA taskfile register set
 - *
 - *    Issues PIO write to ATA command register, with proper
 - *    synchronization with interrupt handler / other threads.
 - *
 - *    LOCKING:
 - *    spin_lock_irqsave(host_set lock)
 - */
 -
 -static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
 -{
 -      DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
 -
 -              outb(tf->command, ap->ioaddr.command_addr);
 -      ata_pause(ap);
 -}
 -
 -
 -/**
 - *    ata_exec_command_mmio - issue ATA command to host controller
 - *    @ap: port to which command is being issued
 - *    @tf: ATA taskfile register set
 - *
 - *    Issues MMIO write to ATA command register, with proper
 - *    synchronization with interrupt handler / other threads.
 - *
 - *    LOCKING:
 - *    spin_lock_irqsave(host_set lock)
 - */
 -
 -static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 -{
 -      DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
 -
 -              writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr);
 -      ata_pause(ap);
 -}
 -
 -
 -/**
 - *    ata_exec_command - issue ATA command to host controller
 - *    @ap: port to which command is being issued
 - *    @tf: ATA taskfile register set
 - *
 - *    Issues PIO/MMIO write to ATA command register, with proper
 - *    synchronization with interrupt handler / other threads.
 - *
 - *    LOCKING:
 - *    spin_lock_irqsave(host_set lock)
 - */
 -void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
 -{
 -      if (ap->flags & ATA_FLAG_MMIO)
 -              ata_exec_command_mmio(ap, tf);
 -      else
 -              ata_exec_command_pio(ap, tf);
 -}
 -
 -/**
 - *    ata_tf_to_host - issue ATA taskfile to host controller
 - *    @ap: port to which command is being issued
 - *    @tf: ATA taskfile register set
 - *
 - *    Issues ATA taskfile register set to ATA host controller,
 - *    with proper synchronization with interrupt handler and
 - *    other threads.
 - *
 - *    LOCKING:
 - *    spin_lock_irqsave(host_set lock)
 - */
 -
 -static inline void ata_tf_to_host(struct ata_port *ap,
 -                                const struct ata_taskfile *tf)
 -{
 -      ap->ops->tf_load(ap, tf);
 -      ap->ops->exec_command(ap, tf);
 -}
 -
 -/**
 - *    ata_tf_read_pio - input device's ATA taskfile shadow registers
 - *    @ap: Port from which input is read
 - *    @tf: ATA taskfile register set for storing input
 - *
 - *    Reads ATA taskfile registers for currently-selected device
 - *    into @tf.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -
 -static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
 -{
 -      struct ata_ioports *ioaddr = &ap->ioaddr;
 -
 -      tf->command = ata_check_status(ap);
 -      tf->feature = inb(ioaddr->error_addr);
 -      tf->nsect = inb(ioaddr->nsect_addr);
 -      tf->lbal = inb(ioaddr->lbal_addr);
 -      tf->lbam = inb(ioaddr->lbam_addr);
 -      tf->lbah = inb(ioaddr->lbah_addr);
 -      tf->device = inb(ioaddr->device_addr);
 -
 -      if (tf->flags & ATA_TFLAG_LBA48) {
 -              outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
 -              tf->hob_feature = inb(ioaddr->error_addr);
 -              tf->hob_nsect = inb(ioaddr->nsect_addr);
 -              tf->hob_lbal = inb(ioaddr->lbal_addr);
 -              tf->hob_lbam = inb(ioaddr->lbam_addr);
 -              tf->hob_lbah = inb(ioaddr->lbah_addr);
 -      }
 -}
 -
 -/**
 - *    ata_tf_read_mmio - input device's ATA taskfile shadow registers
 - *    @ap: Port from which input is read
 - *    @tf: ATA taskfile register set for storing input
 - *
 - *    Reads ATA taskfile registers for currently-selected device
 - *    into @tf via MMIO.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -
 -static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
 -{
 -      struct ata_ioports *ioaddr = &ap->ioaddr;
 -
 -      tf->command = ata_check_status(ap);
 -      tf->feature = readb((void __iomem *)ioaddr->error_addr);
 -      tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
 -      tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
 -      tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
 -      tf->lbah = readb((void __iomem *)ioaddr->lbah_addr);
 -      tf->device = readb((void __iomem *)ioaddr->device_addr);
 -
 -      if (tf->flags & ATA_TFLAG_LBA48) {
 -              writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr);
 -              tf->hob_feature = readb((void __iomem *)ioaddr->error_addr);
 -              tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr);
 -              tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr);
 -              tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr);
 -              tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr);
 -      }
 -}
 -
 -
 -/**
 - *    ata_tf_read - input device's ATA taskfile shadow registers
 - *    @ap: Port from which input is read
 - *    @tf: ATA taskfile register set for storing input
 - *
 - *    Reads ATA taskfile registers for currently-selected device
 - *    into @tf.
 - *
 - *    Reads nsect, lbal, lbam, lbah, and device.  If ATA_TFLAG_LBA48
 - *    is set, also reads the hob registers.
 - *
 - *    May be used as the tf_read() entry in ata_port_operations.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
 -{
 -      if (ap->flags & ATA_FLAG_MMIO)
 -              ata_tf_read_mmio(ap, tf);
 -      else
 -              ata_tf_read_pio(ap, tf);
 -}
 -
 -/**
 - *    ata_check_status_pio - Read device status reg & clear interrupt
 - *    @ap: port where the device is
 - *
 - *    Reads ATA taskfile status register for currently-selected device
 - *    and return its value. This also clears pending interrupts
 - *      from this device
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -static u8 ata_check_status_pio(struct ata_port *ap)
 -{
 -      return inb(ap->ioaddr.status_addr);
 -}
 -
 -/**
 - *    ata_check_status_mmio - Read device status reg & clear interrupt
 - *    @ap: port where the device is
 - *
 - *    Reads ATA taskfile status register for currently-selected device
 - *    via MMIO and return its value. This also clears pending interrupts
 - *      from this device
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -static u8 ata_check_status_mmio(struct ata_port *ap)
 -{
 -              return readb((void __iomem *) ap->ioaddr.status_addr);
 -}
 -
 -
 -/**
 - *    ata_check_status - Read device status reg & clear interrupt
 - *    @ap: port where the device is
 - *
 - *    Reads ATA taskfile status register for currently-selected device
 - *    and return its value. This also clears pending interrupts
 - *      from this device
 - *
 - *    May be used as the check_status() entry in ata_port_operations.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -u8 ata_check_status(struct ata_port *ap)
 -{
 -      if (ap->flags & ATA_FLAG_MMIO)
 -              return ata_check_status_mmio(ap);
 -      return ata_check_status_pio(ap);
 -}
 -
 -
 -/**
 - *    ata_altstatus - Read device alternate status reg
 - *    @ap: port where the device is
 - *
 - *    Reads ATA taskfile alternate status register for
 - *    currently-selected device and return its value.
 - *
 - *    Note: may NOT be used as the check_altstatus() entry in
 - *    ata_port_operations.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -u8 ata_altstatus(struct ata_port *ap)
 -{
 -      if (ap->ops->check_altstatus)
 -              return ap->ops->check_altstatus(ap);
 -
 -      if (ap->flags & ATA_FLAG_MMIO)
 -              return readb((void __iomem *)ap->ioaddr.altstatus_addr);
 -      return inb(ap->ioaddr.altstatus_addr);
 -}
 -
  
  /**
   *    ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
@@@ -433,7 -838,6 +437,7 @@@ unsigned int ata_dev_classify(const str
   *    ata_dev_try_classify - Parse returned ATA device signature
   *    @ap: ATA channel to examine
   *    @device: Device to examine (starting at zero)
 + *    @r_err: Value of error register on completion
   *
   *    After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
   *    an ATA/ATAPI-defined set of values is placed in the ATA
   *
   *    LOCKING:
   *    caller.
 + *
 + *    RETURNS:
 + *    Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE.
   */
  
 -static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
 +static unsigned int
 +ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err)
  {
 -      struct ata_device *dev = &ap->device[device];
        struct ata_taskfile tf;
        unsigned int class;
        u8 err;
  
        ap->ops->tf_read(ap, &tf);
        err = tf.feature;
 -
 -      dev->class = ATA_DEV_NONE;
 +      if (r_err)
 +              *r_err = err;
  
        /* see if device passed diags */
        if (err == 1)
        else if ((device == 0) && (err == 0x81))
                /* do nothing */ ;
        else
 -              return err;
 +              return ATA_DEV_NONE;
  
 -      /* determine if device if ATA or ATAPI */
 +      /* determine if device is ATA or ATAPI */
        class = ata_dev_classify(&tf);
 +
        if (class == ATA_DEV_UNKNOWN)
 -              return err;
 +              return ATA_DEV_NONE;
        if ((class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0))
 -              return err;
 -
 -      dev->class = class;
 -
 -      return err;
 +              return ATA_DEV_NONE;
 +      return class;
  }
  
  /**
 - *    ata_dev_id_string - Convert IDENTIFY DEVICE page into string
 + *    ata_id_string - Convert IDENTIFY DEVICE page into string
   *    @id: IDENTIFY DEVICE results we will examine
   *    @s: string into which data is output
   *    @ofs: offset into identify device page
   *    caller.
   */
  
 -void ata_dev_id_string(const u16 *id, unsigned char *s,
 -                     unsigned int ofs, unsigned int len)
 +void ata_id_string(const u16 *id, unsigned char *s,
 +                 unsigned int ofs, unsigned int len)
  {
        unsigned int c;
  
        }
  }
  
 +/**
 + *    ata_id_c_string - Convert IDENTIFY DEVICE page into C string
 + *    @id: IDENTIFY DEVICE results we will examine
 + *    @s: string into which data is output
 + *    @ofs: offset into identify device page
 + *    @len: length of string to return. must be an odd number.
 + *
 + *    This function is identical to ata_id_string except that it
 + *    trims trailing spaces and terminates the resulting string with
 + *    null.  @len must be actual maximum length (even number) + 1.
 + *
 + *    LOCKING:
 + *    caller.
 + */
 +void ata_id_c_string(const u16 *id, unsigned char *s,
 +                   unsigned int ofs, unsigned int len)
 +{
 +      unsigned char *p;
 +
 +      WARN_ON(!(len & 1));
 +
 +      ata_id_string(id, s, ofs, len - 1);
 +
 +      p = s + strnlen(s, len - 1);
 +      while (p > s && p[-1] == ' ')
 +              p--;
 +      *p = '\0';
 +}
 +
 +static u64 ata_id_n_sectors(const u16 *id)
 +{
 +      if (ata_id_has_lba(id)) {
 +              if (ata_id_has_lba48(id))
 +                      return ata_id_u64(id, 100);
 +              else
 +                      return ata_id_u32(id, 60);
 +      } else {
 +              if (ata_id_current_chs_valid(id))
 +                      return ata_id_u32(id, 57);
 +              else
 +                      return id[1] * id[3] * id[6];
 +      }
 +}
  
  /**
   *    ata_noop_dev_select - Select device 0/1 on ATA bus
@@@ -651,41 -1011,41 +655,41 @@@ void ata_dev_select(struct ata_port *ap
  
  /**
   *    ata_dump_id - IDENTIFY DEVICE info debugging output
 - *    @dev: Device whose IDENTIFY DEVICE page we will dump
 + *    @id: IDENTIFY DEVICE page to dump
   *
 - *    Dump selected 16-bit words from a detected device's
 - *    IDENTIFY PAGE page.
 + *    Dump selected 16-bit words from the given IDENTIFY DEVICE
 + *    page.
   *
   *    LOCKING:
   *    caller.
   */
  
 -static inline void ata_dump_id(const struct ata_device *dev)
 +static inline void ata_dump_id(const u16 *id)
  {
        DPRINTK("49==0x%04x  "
                "53==0x%04x  "
                "63==0x%04x  "
                "64==0x%04x  "
                "75==0x%04x  \n",
 -              dev->id[49],
 -              dev->id[53],
 -              dev->id[63],
 -              dev->id[64],
 -              dev->id[75]);
 +              id[49],
 +              id[53],
 +              id[63],
 +              id[64],
 +              id[75]);
        DPRINTK("80==0x%04x  "
                "81==0x%04x  "
                "82==0x%04x  "
                "83==0x%04x  "
                "84==0x%04x  \n",
 -              dev->id[80],
 -              dev->id[81],
 -              dev->id[82],
 -              dev->id[83],
 -              dev->id[84]);
 +              id[80],
 +              id[81],
 +              id[82],
 +              id[83],
 +              id[84]);
        DPRINTK("88==0x%04x  "
                "93==0x%04x\n",
 -              dev->id[88],
 -              dev->id[93]);
 +              id[88],
 +              id[93]);
  }
  
  /*
@@@ -717,77 -1077,24 +721,77 @@@ static unsigned int ata_pio_modes(cons
           timing API will get this right anyway */
  }
  
 -struct ata_exec_internal_arg {
 -      unsigned int err_mask;
 -      struct ata_taskfile *tf;
 -      struct completion *waiting;
 -};
 +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);
 +}
  
 -int ata_qc_complete_internal(struct ata_queued_cmd *qc)
 +static inline void
 +ata_queue_pio_task(struct ata_port *ap)
  {
 -      struct ata_exec_internal_arg *arg = qc->private_data;
 -      struct completion *waiting = arg->waiting;
 +      if (!(ap->flags & ATA_FLAG_FLUSH_PIO_TASK))
 +              queue_work(ata_wq, &ap->pio_task);
 +}
  
 -      if (!(qc->err_mask & ~AC_ERR_DEV))
 -              qc->ap->ops->tf_read(qc->ap, arg->tf);
 -      arg->err_mask = qc->err_mask;
 -      arg->waiting = NULL;
 -      complete(waiting);
 +static inline void
 +ata_queue_delayed_pio_task(struct ata_port *ap, unsigned long delay)
 +{
 +      if (!(ap->flags & ATA_FLAG_FLUSH_PIO_TASK))
 +              queue_delayed_work(ata_wq, &ap->pio_task, delay);
 +}
  
 -      return 0;
 +/**
 + *    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)
 +{
 +      struct completion *waiting = qc->private_data;
 +
 +      qc->ap->ops->tf_read(qc->ap, &qc->tf);
 +      complete(waiting);
  }
  
  /**
@@@ -818,7 -1125,7 +822,7 @@@ ata_exec_internal(struct ata_port *ap, 
        struct ata_queued_cmd *qc;
        DECLARE_COMPLETION(wait);
        unsigned long flags;
 -      struct ata_exec_internal_arg arg;
 +      unsigned int err_mask;
  
        spin_lock_irqsave(&ap->host_set->lock, flags);
  
                qc->nsect = buflen / ATA_SECT_SIZE;
        }
  
 -      arg.waiting = &wait;
 -      arg.tf = tf;
 -      qc->private_data = &arg;
 +      qc->private_data = &wait;
        qc->complete_fn = ata_qc_complete_internal;
  
 -      if (ata_qc_issue(qc))
 -              goto issue_fail;
 +      qc->err_mask = ata_qc_issue(qc);
 +      if (qc->err_mask)
 +              ata_qc_complete(qc);
  
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
  
                 * before the caller cleans up, it will result in a
                 * spurious interrupt.  We can live with that.
                 */
 -              if (arg.waiting) {
 -                      qc->err_mask = AC_ERR_OTHER;
 +              if (qc->flags & ATA_QCFLAG_ACTIVE) {
 +                      qc->err_mask = AC_ERR_TIMEOUT;
                        ata_qc_complete(qc);
                        printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
                               ap->id, command);
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        }
  
 -      return arg.err_mask;
 +      *tf = qc->tf;
 +      err_mask = qc->err_mask;
  
 - issue_fail:
        ata_qc_free(qc);
 -      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 -      return AC_ERR_OTHER;
 +
 +      return err_mask;
  }
  
  /**
@@@ -902,70 -1210,73 +906,70 @@@ unsigned int ata_pio_need_iordy(const s
  }
  
  /**
 - *    ata_dev_identify - obtain IDENTIFY x DEVICE page
 - *    @ap: port on which device we wish to probe resides
 - *    @device: device bus address, starting at zero
 - *
 - *    Following bus reset, we issue the IDENTIFY [PACKET] DEVICE
 - *    command, and read back the 512-byte device information page.
 - *    The device information page is fed to us via the standard
 - *    PIO-IN protocol, but we hand-code it here. (TODO: investigate
 - *    using standard PIO-IN paths)
 - *
 - *    After reading the device information page, we use several
 - *    bits of information from it to initialize data structures
 - *    that will be used during the lifetime of the ata_device.
 - *    Other data from the info page is used to disqualify certain
 - *    older ATA devices we do not wish to support.
 + *    ata_dev_read_id - Read ID data from the specified device
 + *    @ap: port on which target device resides
 + *    @dev: target device
 + *    @p_class: pointer to class of the target device (may be changed)
 + *    @post_reset: is this read ID post-reset?
 + *    @id: buffer to fill IDENTIFY page into
 + *
 + *    Read ID data from the specified device.  ATA_CMD_ID_ATA is
 + *    performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
 + *    devices.  This function also takes care of EDD signature
 + *    misreporting (to be removed once EDD support is gone) and
 + *    issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives.
   *
   *    LOCKING:
 - *    Inherited from caller.  Some functions called by this function
 - *    obtain the host_set lock.
 + *    Kernel thread context (may sleep)
 + *
 + *    RETURNS:
 + *    0 on success, -errno otherwise.
   */
 -
 -static void ata_dev_identify(struct ata_port *ap, unsigned int device)
 +static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 +                         unsigned int *p_class, int post_reset, u16 *id)
  {
 -      struct ata_device *dev = &ap->device[device];
 -      unsigned int major_version;
 -      u16 tmp;
 -      unsigned long xfer_modes;
 +      unsigned int class = *p_class;
        unsigned int using_edd;
        struct ata_taskfile tf;
 -      unsigned int err_mask;
 +      unsigned int err_mask = 0;
 +      const char *reason;
        int rc;
  
 -      if (!ata_dev_present(dev)) {
 -              DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
 -                      ap->id, device);
 -              return;
 -      }
 +      DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
  
 -      if (ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET))
 +      if (ap->ops->probe_reset ||
 +          ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET))
                using_edd = 0;
        else
                using_edd = 1;
  
 -      DPRINTK("ENTER, host %u, dev %u\n", ap->id, device);
 -
 -      assert (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ATAPI ||
 -              dev->class == ATA_DEV_NONE);
 -
 -      ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
 +      ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
  
 -retry:
 -      ata_tf_init(ap, &tf, device);
 + retry:
 +      ata_tf_init(ap, &tf, dev->devno);
  
 -      if (dev->class == ATA_DEV_ATA) {
 +      switch (class) {
 +      case ATA_DEV_ATA:
                tf.command = ATA_CMD_ID_ATA;
 -              DPRINTK("do ATA identify\n");
 -      } else {
 +              break;
 +      case ATA_DEV_ATAPI:
                tf.command = ATA_CMD_ID_ATAPI;
 -              DPRINTK("do ATAPI identify\n");
 +              break;
 +      default:
 +              rc = -ENODEV;
 +              reason = "unsupported class";
 +              goto err_out;
        }
  
        tf.protocol = ATA_PROT_PIO;
  
        err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
 -                                   dev->id, sizeof(dev->id));
 +                                   id, sizeof(id[0]) * ATA_ID_WORDS);
  
        if (err_mask) {
 +              rc = -EIO;
 +              reason = "I/O error";
 +
                if (err_mask & ~AC_ERR_DEV)
                        goto err_out;
  
                 * ATA software reset (SRST, the default) does not appear
                 * to have this problem.
                 */
 -              if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
 +              if ((using_edd) && (class == ATA_DEV_ATA)) {
                        u8 err = tf.feature;
                        if (err & ATA_ABORTED) {
 -                              dev->class = ATA_DEV_ATAPI;
 +                              class = ATA_DEV_ATAPI;
                                goto retry;
                        }
                }
                goto err_out;
        }
  
 -      swap_buf_le16(dev->id, ATA_ID_WORDS);
 +      swap_buf_le16(id, ATA_ID_WORDS);
  
        /* print device capabilities */
        printk(KERN_DEBUG "ata%u: dev %u cfg "
               "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
 -             ap->id, device, dev->id[49],
 -             dev->id[82], dev->id[83], dev->id[84],
 -             dev->id[85], dev->id[86], dev->id[87],
 -             dev->id[88]);
 +             ap->id, dev->devno,
 +             id[49], id[82], id[83], id[84], id[85], id[86], id[87], id[88]);
 +
 +      /* sanity check */
 +      if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) {
 +              rc = -EINVAL;
 +              reason = "device reports illegal type";
 +              goto err_out;
 +      }
 +
 +      if (post_reset && class == ATA_DEV_ATA) {
 +              /*
 +               * The exact sequence expected by certain pre-ATA4 drives is:
 +               * SRST RESET
 +               * IDENTIFY
 +               * INITIALIZE DEVICE PARAMETERS
 +               * anything else..
 +               * Some drives were very specific about that exact sequence.
 +               */
 +              if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
 +                      err_mask = ata_dev_init_params(ap, dev);
 +                      if (err_mask) {
 +                              rc = -EIO;
 +                              reason = "INIT_DEV_PARAMS failed";
 +                              goto err_out;
 +                      }
 +
 +                      /* current CHS translation info (id[53-58]) might be
 +                       * changed. reread the identify device info.
 +                       */
 +                      post_reset = 0;
 +                      goto retry;
 +              }
 +      }
 +
 +      *p_class = class;
 +      return 0;
 +
 + err_out:
 +      printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n",
 +             ap->id, dev->devno, reason);
 +      kfree(id);
 +      return rc;
 +}
 +
 +/**
 + *    ata_dev_identify - obtain IDENTIFY x DEVICE page
 + *    @ap: port on which device we wish to probe resides
 + *    @device: device bus address, starting at zero
 + *
 + *    Following bus reset, we issue the IDENTIFY [PACKET] DEVICE
 + *    command, and read back the 512-byte device information page.
 + *    The device information page is fed to us via the standard
 + *    PIO-IN protocol, but we hand-code it here. (TODO: investigate
 + *    using standard PIO-IN paths)
 + *
 + *    After reading the device information page, we use several
 + *    bits of information from it to initialize data structures
 + *    that will be used during the lifetime of the ata_device.
 + *    Other data from the info page is used to disqualify certain
 + *    older ATA devices we do not wish to support.
 + *
 + *    LOCKING:
 + *    Inherited from caller.  Some functions called by this function
 + *    obtain the host_set lock.
 + */
 +
 +static void ata_dev_identify(struct ata_port *ap, unsigned int device)
 +{
 +      struct ata_device *dev = &ap->device[device];
 +      unsigned long xfer_modes;
 +      int i, rc;
 +
 +      if (!ata_dev_present(dev)) {
 +              DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
 +                      ap->id, device);
 +              return;
 +      }
 +
 +      DPRINTK("ENTER, host %u, dev %u\n", ap->id, device);
 +
 +      rc = ata_dev_read_id(ap, dev, &dev->class, 1, dev->id);
 +      if (rc)
 +              goto err_out;
  
        /*
         * common ATA, ATAPI feature tests
        if (!xfer_modes)
                xfer_modes = ata_pio_modes(dev);
  
 -      ata_dump_id(dev);
 -
 -      /* ATA-specific feature tests */
 -      if (dev->class == ATA_DEV_ATA) {
 -              if (!ata_id_is_ata(dev->id))    /* sanity check */
 -                      goto err_out_nosup;
 -
 -              /* get major version */
 -              tmp = dev->id[ATA_ID_MAJOR_VER];
 -              for (major_version = 14; major_version >= 1; major_version--)
 -                      if (tmp & (1 << major_version))
 -                              break;
 -
 -              /*
 -               * The exact sequence expected by certain pre-ATA4 drives is:
 -               * SRST RESET
 -               * IDENTIFY
 -               * INITIALIZE DEVICE PARAMETERS
 -               * anything else..
 -               * Some drives were very specific about that exact sequence.
 -               */
 -              if (major_version < 4 || (!ata_id_has_lba(dev->id))) {
 -                      ata_dev_init_params(ap, dev);
 +      ata_dump_id(dev->id);
  
 -                      /* current CHS translation info (id[53-58]) might be
 -                       * changed. reread the identify device info.
 -                       */
 -                      ata_dev_reread_id(ap, dev);
 -              }
 +      /* ATA-specific feature tests */
 +      if (dev->class == ATA_DEV_ATA) {
 +              dev->n_sectors = ata_id_n_sectors(dev->id);
  
                if (ata_id_has_lba(dev->id)) {
                        dev->flags |= ATA_DFLAG_LBA;
  
 -                      if (ata_id_has_lba48(dev->id)) {
 +                      if (ata_id_has_lba48(dev->id))
                                dev->flags |= ATA_DFLAG_LBA48;
 -                              dev->n_sectors = ata_id_u64(dev->id, 100);
 -                      } else {
 -                              dev->n_sectors = ata_id_u32(dev->id, 60);
 -                      }
  
                        /* print device info to dmesg */
                        printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
                               ap->id, device,
 -                             major_version,
 +                             ata_id_major_version(dev->id),
                               ata_mode_string(xfer_modes),
                               (unsigned long long)dev->n_sectors,
                               dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
                        dev->cylinders  = dev->id[1];
                        dev->heads      = dev->id[3];
                        dev->sectors    = dev->id[6];
 -                      dev->n_sectors  = dev->cylinders * dev->heads * dev->sectors;
  
                        if (ata_id_current_chs_valid(dev->id)) {
                                /* Current CHS translation is valid. */
                                dev->cylinders = dev->id[54];
                                dev->heads     = dev->id[55];
                                dev->sectors   = dev->id[56];
 -                              
 -                              dev->n_sectors = ata_id_u32(dev->id, 57);
                        }
  
                        /* print device info to dmesg */
                        printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
                               ap->id, device,
 -                             major_version,
 +                             ata_id_major_version(dev->id),
                               ata_mode_string(xfer_modes),
                               (unsigned long long)dev->n_sectors,
                               (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
  
                }
  
 -              ap->host->max_cmd_len = 16;
 +              dev->cdb_len = 16;
        }
  
        /* ATAPI-specific feature tests */
        else if (dev->class == ATA_DEV_ATAPI) {
 -              if (ata_id_is_ata(dev->id))             /* sanity check */
 -                      goto err_out_nosup;
 -
                rc = atapi_cdb_len(dev->id);
                if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
                        printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
                        goto err_out_nosup;
                }
 -              ap->cdb_len = (unsigned int) rc;
 -              ap->host->max_cmd_len = (unsigned char) ap->cdb_len;
 +              dev->cdb_len = (unsigned int) rc;
  
                /* print device info to dmesg */
                printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
                       ata_mode_string(xfer_modes));
        }
  
 +      ap->host->max_cmd_len = 0;
 +      for (i = 0; i < ATA_MAX_DEVICES; i++)
 +              ap->host->max_cmd_len = max_t(unsigned int,
 +                                            ap->host->max_cmd_len,
 +                                            ap->device[i].cdb_len);
 +
        DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
        return;
  
@@@ -1177,28 -1437,30 +1181,28 @@@ err_out
  }
  
  
 -static inline u8 ata_dev_knobble(const struct ata_port *ap)
 +static inline u8 ata_dev_knobble(const struct ata_port *ap,
 +                               struct ata_device *dev)
  {
 -      return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
 +      return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
  }
  
  /**
 - *    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)
  {
        /* limit bridge transfers to udma5, 200 sectors */
 -      if (ata_dev_knobble(ap)) {
 +      if (ata_dev_knobble(ap, &ap->device[i])) {
                printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
 -                      ap->id, ap->device->devno);
 +                     ap->id, i);
                ap->udma_mask &= ATA_UDMA5;
 -              ap->host->max_sectors = ATA_MAX_SECTORS;
 -              ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
 -              ap->device[i].flags |= ATA_DFLAG_LOCK_SECTORS;
 +              ap->device[i].max_sectors = ATA_MAX_SECTORS;
        }
  
        if (ap->ops->dev_config)
@@@ -1224,27 -1486,7 +1228,27 @@@ static int ata_bus_probe(struct ata_por
  {
        unsigned int i, found = 0;
  
 -      ap->ops->phy_reset(ap);
 +      if (ap->ops->probe_reset) {
 +              unsigned int classes[ATA_MAX_DEVICES];
 +              int rc;
 +
 +              ata_port_probe(ap);
 +
 +              rc = ap->ops->probe_reset(ap, classes);
 +              if (rc == 0) {
 +                      for (i = 0; i < ATA_MAX_DEVICES; i++) {
 +                              if (classes[i] == ATA_DEV_UNKNOWN)
 +                                      classes[i] = ATA_DEV_NONE;
 +                              ap->device[i].class = classes[i];
 +                      }
 +              } else {
 +                      printk(KERN_ERR "ata%u: probe reset failed, "
 +                             "disabling port\n", ap->id);
 +                      ata_port_disable(ap);
 +              }
 +      } else
 +              ap->ops->phy_reset(ap);
 +
        if (ap->flags & ATA_FLAG_PORT_DISABLED)
                goto err_out;
  
@@@ -1287,41 -1529,6 +1291,41 @@@ void ata_port_probe(struct ata_port *ap
        ap->flags &= ~ATA_FLAG_PORT_DISABLED;
  }
  
 +/**
 + *    sata_print_link_status - Print SATA link status
 + *    @ap: SATA port to printk link status about
 + *
 + *    This function prints link speed and status of a SATA link.
 + *
 + *    LOCKING:
 + *    None.
 + */
 +static void sata_print_link_status(struct ata_port *ap)
 +{
 +      u32 sstatus, tmp;
 +      const char *speed;
 +
 +      if (!ap->ops->scr_read)
 +              return;
 +
 +      sstatus = scr_read(ap, SCR_STATUS);
 +
 +      if (sata_dev_present(ap)) {
 +              tmp = (sstatus >> 4) & 0xf;
 +              if (tmp & (1 << 0))
 +                      speed = "1.5";
 +              else if (tmp & (1 << 1))
 +                      speed = "3.0";
 +              else
 +                      speed = "<unknown>";
 +              printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
 +                     ap->id, speed, sstatus);
 +      } else {
 +              printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
 +                     ap->id, sstatus);
 +      }
 +}
 +
  /**
   *    __sata_phy_reset - Wake/reset a low-level SATA PHY
   *    @ap: SATA port associated with target SATA PHY.
@@@ -1356,14 -1563,27 +1360,14 @@@ void __sata_phy_reset(struct ata_port *
                        break;
        } while (time_before(jiffies, timeout));
  
 -      /* TODO: phy layer with polling, timeouts, etc. */
 -      sstatus = scr_read(ap, SCR_STATUS);
 -      if (sata_dev_present(ap)) {
 -              const char *speed;
 -              u32 tmp;
 +      /* print link status */
 +      sata_print_link_status(ap);
  
 -              tmp = (sstatus >> 4) & 0xf;
 -              if (tmp & (1 << 0))
 -                      speed = "1.5";
 -              else if (tmp & (1 << 1))
 -                      speed = "3.0";
 -              else
 -                      speed = "<unknown>";
 -              printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
 -                     ap->id, speed, sstatus);
 +      /* TODO: phy layer with polling, timeouts, etc. */
 +      if (sata_dev_present(ap))
                ata_port_probe(ap);
 -      } else {
 -              printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
 -                     ap->id, sstatus);
 +      else
                ata_port_disable(ap);
 -      }
  
        if (ap->flags & ATA_FLAG_PORT_DISABLED)
                return;
@@@ -1536,9 -1756,9 +1540,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) {
@@@ -1666,6 -1886,7 +1670,6 @@@ static void ata_host_set_dma(struct ata
   *
   *    LOCKING:
   *    PCI/etc. bus probe sem.
 - *
   */
  static void ata_set_mode(struct ata_port *ap)
  {
@@@ -1704,26 -1925,6 +1708,26 @@@ err_out
        ata_port_disable(ap);
  }
  
 +/**
 + *    ata_tf_to_host - issue ATA taskfile to host controller
 + *    @ap: port to which command is being issued
 + *    @tf: ATA taskfile register set
 + *
 + *    Issues ATA taskfile register set to ATA host controller,
 + *    with proper synchronization with interrupt handler and
 + *    other threads.
 + *
 + *    LOCKING:
 + *    spin_lock_irqsave(host_set lock)
 + */
 +
 +static inline void ata_tf_to_host(struct ata_port *ap,
 +                                const struct ata_taskfile *tf)
 +{
 +      ap->ops->tf_load(ap, tf);
 +      ap->ops->exec_command(ap, tf);
 +}
 +
  /**
   *    ata_busy_sleep - sleep until BSY clears, or timeout
   *    @ap: port containing status register to be polled
   *    or a timeout occurs.
   *
   *    LOCKING: None.
 - *
   */
  
 -static unsigned int ata_busy_sleep (struct ata_port *ap,
 -                                  unsigned long tmout_pat,
 -                                  unsigned long tmout)
 +unsigned int ata_busy_sleep (struct ata_port *ap,
 +                           unsigned long tmout_pat, unsigned long tmout)
  {
        unsigned long timer_start, timeout;
        u8 status;
@@@ -1956,9 -2159,9 +1960,9 @@@ void ata_bus_reset(struct ata_port *ap
        /*
         * determine by signature whether we have ATA or ATAPI devices
         */
 -      err = ata_dev_try_classify(ap, 0);
 +      ap->device[0].class = ata_dev_try_classify(ap, 0, &err);
        if ((slave_possible) && (err != 0x81))
 -              ata_dev_try_classify(ap, 1);
 +              ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
  
        /* re-enable interrupts */
        if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
        if (ap->device[0].class != ATA_DEV_NONE)
                ap->ops->dev_select(ap, 0);
  
 -      /* if no devices were detected, disable this port */
 -      if ((ap->device[0].class == ATA_DEV_NONE) &&
 -          (ap->device[1].class == ATA_DEV_NONE))
 -              goto err_out;
 +      /* if no devices were detected, disable this port */
 +      if ((ap->device[0].class == ATA_DEV_NONE) &&
 +          (ap->device[1].class == ATA_DEV_NONE))
 +              goto err_out;
 +
 +      if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
 +              /* set up device control for ATA_FLAG_SATA_RESET */
 +              if (ap->flags & ATA_FLAG_MMIO)
 +                      writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
 +              else
 +                      outb(ap->ctl, ioaddr->ctl_addr);
 +      }
 +
 +      DPRINTK("EXIT\n");
 +      return;
 +
 +err_out:
 +      printk(KERN_ERR "ata%u: disabling port\n", ap->id);
 +      ap->ops->port_disable(ap);
 +
 +      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().
 + *
 + *    NOTE!!! Do not use this function as probeinit if a low level
 + *    driver implements only hardreset.  Just pass NULL as probeinit
 + *    in that case.  Using this function is probably okay but doing
 + *    so makes reset sequence different from the original
 + *    ->phy_reset implementation and Jeff nervous.  :-P
 + */
 +extern void ata_std_probeinit(struct ata_port *ap)
 +{
 +      if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) {
 +              sata_phy_resume(ap);
 +              if (sata_dev_present(ap))
 +                      ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
 +      }
 +}
 +
 +/**
 + *    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");
 +
 +      if (ap->ops->scr_read && !sata_dev_present(ap)) {
 +              classes[0] = ATA_DEV_NONE;
 +              goto out;
 +      }
 +
 +      /* 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);
 +
 +      /* 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);
 +
 + out:
 +      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)
 +{
 +      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);
 +
 +      /* 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;
 +      }
 +
 +      ap->ops->dev_select(ap, 0);     /* probably unnecessary */
 +
 +      *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.
 + *
 + *    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 it isn't already set */
 +      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);
 +
 +      /* re-enable interrupts */
 +      if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
 +              ata_irq_on(ap);
 +
 +      /* 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);
 +
 +      /* bail out if no device is present */
 +      if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
 +              DPRINTK("EXIT, no device\n");
 +              return;
 +      }
 +
 +      /* set up device control */
 +      if (ap->ioaddr.ctl_addr) {
 +              if (ap->flags & ATA_FLAG_MMIO)
 +                      writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
 +              else
 +                      outb(ap->ctl, ap->ioaddr.ctl_addr);
 +      }
 +
 +      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 (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
 -              /* set up device control for ATA_FLAG_SATA_RESET */
 -              if (ap->flags & ATA_FLAG_MMIO)
 -                      writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
 -              else
 -                      outb(ap->ctl, ioaddr->ctl_addr);
 +      if (probeinit)
 +              probeinit(ap);
 +
 +      if (softreset) {
 +              rc = do_probe_reset(ap, softreset, postreset, classes);
 +              if (rc == 0)
 +                      return 0;
        }
  
 -      DPRINTK("EXIT\n");
 -      return;
 +      if (!hardreset)
 +              return rc;
  
 -err_out:
 -      printk(KERN_ERR "ata%u: disabling port\n", ap->id);
 -      ap->ops->port_disable(ap);
 +      rc = do_probe_reset(ap, hardreset, postreset, classes);
 +      if (rc == 0 || rc != -ENODEV)
 +              return rc;
  
 -      DPRINTK("EXIT\n");
 +      if (softreset)
 +              rc = do_probe_reset(ap, softreset, postreset, classes);
 +
 +      return rc;
  }
  
  static void ata_pr_blacklisted(const struct ata_port *ap,
@@@ -2362,13 -2237,24 +2366,13 @@@ static const char * const ata_dma_black
  
  static int ata_dma_blacklisted(const struct ata_device *dev)
  {
 -      unsigned char model_num[40];
 -      char *s;
 -      unsigned int len;
 +      unsigned char model_num[41];
        int i;
  
 -      ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
 -                        sizeof(model_num));
 -      s = &model_num[0];
 -      len = strnlen(s, sizeof(model_num));
 -
 -      /* ATAPI specifies that empty space is blank-filled; remove blanks */
 -      while ((len > 0) && (s[len - 1] == ' ')) {
 -              len--;
 -              s[len] = 0;
 -      }
 +      ata_id_c_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
  
        for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++)
 -              if (!strncmp(ata_dma_blacklist[i], s, len))
 +              if (!strcmp(ata_dma_blacklist[i], model_num))
                        return 1;
  
        return 0;
@@@ -2382,7 -2268,7 +2386,7 @@@ static unsigned int ata_get_mode_mask(c
        master = &ap->device[0];
        slave = &ap->device[1];
  
 -      assert (ata_dev_present(master) || ata_dev_present(slave));
 +      WARN_ON(!ata_dev_present(master) && !ata_dev_present(slave));
  
        if (shift == ATA_SHIFT_UDMA) {
                mask = ap->udma_mask;
@@@ -2533,29 -2419,64 +2537,29 @@@ static void ata_dev_set_xfermode(struc
        DPRINTK("EXIT\n");
  }
  
 -/**
 - *    ata_dev_reread_id - Reread the device identify device info
 - *    @ap: port where the device is
 - *    @dev: device to reread the identify device info
 - *
 - *    LOCKING:
 - */
 -
 -static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
 -{
 -      struct ata_taskfile tf;
 -
 -      ata_tf_init(ap, &tf, dev->devno);
 -
 -      if (dev->class == ATA_DEV_ATA) {
 -              tf.command = ATA_CMD_ID_ATA;
 -              DPRINTK("do ATA identify\n");
 -      } else {
 -              tf.command = ATA_CMD_ID_ATAPI;
 -              DPRINTK("do ATAPI identify\n");
 -      }
 -
 -      tf.flags |= ATA_TFLAG_DEVICE;
 -      tf.protocol = ATA_PROT_PIO;
 -
 -      if (ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
 -                            dev->id, sizeof(dev->id)))
 -              goto err_out;
 -
 -      swap_buf_le16(dev->id, ATA_ID_WORDS);
 -
 -      ata_dump_id(dev);
 -
 -      DPRINTK("EXIT\n");
 -
 -      return;
 -err_out:
 -      printk(KERN_ERR "ata%u: failed to reread ID, disabled\n", ap->id);
 -      ata_port_disable(ap);
 -}
 -
  /**
   *    ata_dev_init_params - Issue INIT DEV PARAMS command
   *    @ap: Port associated with device @dev
   *    @dev: Device to which command will be sent
   *
   *    LOCKING:
 + *    Kernel thread context (may sleep)
 + *
 + *    RETURNS:
 + *    0 on success, AC_ERR_* mask otherwise.
   */
  
 -static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 +static unsigned int ata_dev_init_params(struct ata_port *ap,
 +                                      struct ata_device *dev)
  {
        struct ata_taskfile tf;
 +      unsigned int err_mask;
        u16 sectors = dev->id[6];
        u16 heads   = dev->id[3];
  
        /* Number of sectors per track 1-255. Number of heads 1-16 */
        if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
 -              return;
 +              return 0;
  
        /* set up init dev params taskfile */
        DPRINTK("init dev params \n");
        tf.nsect = sectors;
        tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
  
 -      if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
 -              printk(KERN_ERR "ata%u: failed to init parameters, disabled\n",
 -                     ap->id);
 -              ata_port_disable(ap);
 -      }
 +      err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
  
 -      DPRINTK("EXIT\n");
 +      DPRINTK("EXIT, err_mask=%x\n", err_mask);
 +      return err_mask;
  }
  
  /**
@@@ -2590,11 -2514,11 +2594,11 @@@ static void ata_sg_clean(struct ata_que
        int dir = qc->dma_dir;
        void *pad_buf = NULL;
  
 -      assert(qc->flags & ATA_QCFLAG_DMAMAP);
 -      assert(sg != NULL);
 +      WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP));
 +      WARN_ON(sg == NULL);
  
        if (qc->flags & ATA_QCFLAG_SINGLE)
 -              assert(qc->n_elem <= 1);
 +              WARN_ON(qc->n_elem > 1);
  
        VPRINTK("unmapping %u sg elements\n", qc->n_elem);
  
@@@ -2649,8 -2573,8 +2653,8 @@@ static void ata_fill_sg(struct ata_queu
        struct scatterlist *sg;
        unsigned int idx;
  
 -      assert(qc->__sg != NULL);
 -      assert(qc->n_elem > 0 || qc->pad_len > 0);
 +      WARN_ON(qc->__sg == NULL);
 +      WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
  
        idx = 0;
        ata_for_each_sg(sg, qc) {
@@@ -2803,7 -2727,7 +2807,7 @@@ static int ata_sg_setup_one(struct ata_
                void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
                struct scatterlist *psg = &qc->pad_sgent;
  
 -              assert(qc->dev->class == ATA_DEV_ATAPI);
 +              WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
  
                memset(pad_buf, 0, ATA_DMA_PAD_SZ);
  
@@@ -2867,7 -2791,7 +2871,7 @@@ static int ata_sg_setup(struct ata_queu
        int n_elem, pre_n_elem, dir, trim_sg = 0;
  
        VPRINTK("ENTER, ata%u\n", ap->id);
 -      assert(qc->flags & ATA_QCFLAG_SG);
 +      WARN_ON(!(qc->flags & ATA_QCFLAG_SG));
  
        /* we must lengthen transfers to end on a 32-bit boundary */
        qc->pad_len = lsg->length & 3;
                struct scatterlist *psg = &qc->pad_sgent;
                unsigned int offset;
  
 -              assert(qc->dev->class == ATA_DEV_ATAPI);
 +              WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
  
                memset(pad_buf, 0, ATA_DMA_PAD_SZ);
  
@@@ -2952,7 -2876,7 +2956,7 @@@ void ata_poll_qc_complete(struct ata_qu
  }
  
  /**
 - *    ata_pio_poll -
 + *    ata_pio_poll - poll using PIO, depending on current state
   *    @ap: the target ata_port
   *
   *    LOCKING:
@@@ -2970,7 -2894,7 +2974,7 @@@ static unsigned long ata_pio_poll(struc
        unsigned int reg_state = HSM_ST_UNKNOWN;
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
 -      assert(qc != NULL);
 +      WARN_ON(qc == NULL);
  
        switch (ap->hsm_task_state) {
        case HSM_ST:
        status = ata_chk_status(ap);
        if (status & ATA_BUSY) {
                if (time_after(jiffies, ap->pio_task_timeout)) {
 -                      qc->err_mask |= AC_ERR_ATA_BUS;
 +                      qc->err_mask |= AC_ERR_TIMEOUT;
                        ap->hsm_task_state = HSM_ST_TMOUT;
                        return 0;
                }
@@@ -3038,7 -2962,7 +3042,7 @@@ static int ata_pio_complete (struct ata
        }
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
 -      assert(qc != NULL);
 +      WARN_ON(qc == NULL);
  
        drv_stat = ata_wait_idle(ap);
        if (!ata_ok(drv_stat)) {
  
        ap->hsm_task_state = HSM_ST_IDLE;
  
 -      assert(qc->err_mask == 0);
 +      WARN_ON(qc->err_mask);
        ata_poll_qc_complete(qc);
  
        /* another command may start at this point */
  
  
  /**
 - *    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.
   *
@@@ -3369,7 -3293,7 +3373,7 @@@ static void atapi_pio_bytes(struct ata_
  err_out:
        printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
              ap->id, dev->devno);
 -      qc->err_mask |= AC_ERR_ATA_BUS;
 +      qc->err_mask |= AC_ERR_HSM;
        ap->hsm_task_state = HSM_ST_ERR;
  }
  
@@@ -3406,7 -3330,7 +3410,7 @@@ static void ata_pio_block(struct ata_po
        }
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
 -      assert(qc != NULL);
 +      WARN_ON(qc == NULL);
  
        /* check error */
        if (status & (ATA_ERR | ATA_DF)) {
        } else {
                /* handle BSY=0, DRQ=0 as error */
                if ((status & ATA_DRQ) == 0) {
 -                      qc->err_mask |= AC_ERR_ATA_BUS;
 +                      qc->err_mask |= AC_ERR_HSM;
                        ap->hsm_task_state = HSM_ST_ERR;
                        return;
                }
@@@ -3441,7 -3365,7 +3445,7 @@@ static void ata_pio_error(struct ata_po
        struct ata_queued_cmd *qc;
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
 -      assert(qc != NULL);
 +      WARN_ON(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
         */
 -      assert(qc->err_mask);
 +      WARN_ON(qc->err_mask == 0);
  
        ap->hsm_task_state = HSM_ST_IDLE;
  
@@@ -3490,7 -3414,7 +3494,7 @@@ fsm_start
        }
  
        if (timeout)
 -              queue_delayed_work(ata_wq, &ap->pio_task, timeout);
 +              ata_queue_delayed_pio_task(ap, timeout);
        else if (!qc_completed)
                goto fsm_start;
  }
@@@ -3523,10 -3447,15 +3527,10 @@@ static void ata_qc_timeout(struct ata_q
  
        DPRINTK("ENTER\n");
  
 -      spin_lock_irqsave(&host_set->lock, flags);
 +      ata_flush_pio_tasks(ap);
 +      ap->hsm_task_state = HSM_ST_IDLE;
  
 -      /* hack alert!  We cannot use the supplied completion
 -       * function from inside the ->eh_strategy_handler() thread.
 -       * libata is the only user of ->eh_strategy_handler() in
 -       * any kernel, so the default scsi_done() assumes it is
 -       * not being called from the SCSI EH.
 -       */
 -      qc->scsidone = scsi_finish_command;
 +      spin_lock_irqsave(&host_set->lock, flags);
  
        switch (qc->tf.protocol) {
  
  
                /* complete taskfile transaction */
                qc->err_mask |= ac_err_mask(drv_stat);
 -              ata_qc_complete(qc);
                break;
        }
  
        spin_unlock_irqrestore(&host_set->lock, flags);
  
 +      ata_eh_qc_complete(qc);
 +
        DPRINTK("EXIT\n");
  }
  
  
  void ata_eng_timeout(struct ata_port *ap)
  {
 -      struct ata_queued_cmd *qc;
 -
        DPRINTK("ENTER\n");
  
 -      qc = ata_qc_from_tag(ap, ap->active_tag);
 -      if (qc)
 -              ata_qc_timeout(qc);
 -      else {
 -              printk(KERN_ERR "ata%u: BUG: timeout without command\n",
 -                     ap->id);
 -              goto out;
 -      }
 +      ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag));
  
 -out:
        DPRINTK("EXIT\n");
  }
  
@@@ -3641,6 -3579,21 +3645,6 @@@ struct ata_queued_cmd *ata_qc_new_init(
        return qc;
  }
  
 -static void __ata_qc_complete(struct ata_queued_cmd *qc)
 -{
 -      struct ata_port *ap = qc->ap;
 -      unsigned int tag;
 -
 -      qc->flags = 0;
 -      tag = qc->tag;
 -      if (likely(ata_tag_valid(tag))) {
 -              if (tag == ap->active_tag)
 -                      ap->active_tag = ATA_TAG_POISON;
 -              qc->tag = ATA_TAG_POISON;
 -              clear_bit(tag, &ap->qactive);
 -      }
 -}
 -
  /**
   *    ata_qc_free - free unused ata_queued_cmd
   *    @qc: Command to complete
   */
  void ata_qc_free(struct ata_queued_cmd *qc)
  {
 -      assert(qc != NULL);     /* ata_qc_from_tag _might_ return NULL */
 +      struct ata_port *ap = qc->ap;
 +      unsigned int tag;
  
 -      __ata_qc_complete(qc);
 -}
 +      WARN_ON(qc == NULL);    /* ata_qc_from_tag _might_ return NULL */
  
 -/**
 - *    ata_qc_complete - Complete an active ATA command
 - *    @qc: Command to complete
 - *    @err_mask: ATA Status register contents
 - *
 - *    Indicate to the mid and upper layers that an ATA
 - *    command has completed, with either an ok or not-ok status.
 - *
 - *    LOCKING:
 - *    spin_lock_irqsave(host_set lock)
 - */
 +      qc->flags = 0;
 +      tag = qc->tag;
 +      if (likely(ata_tag_valid(tag))) {
 +              if (tag == ap->active_tag)
 +                      ap->active_tag = ATA_TAG_POISON;
 +              qc->tag = ATA_TAG_POISON;
 +              clear_bit(tag, &ap->qactive);
 +      }
 +}
  
 -void ata_qc_complete(struct ata_queued_cmd *qc)
 +void __ata_qc_complete(struct ata_queued_cmd *qc)
  {
 -      int rc;
 -
 -      assert(qc != NULL);     /* ata_qc_from_tag _might_ return NULL */
 -      assert(qc->flags & ATA_QCFLAG_ACTIVE);
 +      WARN_ON(qc == NULL);    /* ata_qc_from_tag _might_ return NULL */
 +      WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
  
        if (likely(qc->flags & ATA_QCFLAG_DMAMAP))
                ata_sg_clean(qc);
        qc->flags &= ~ATA_QCFLAG_ACTIVE;
  
        /* call completion callback */
 -      rc = qc->complete_fn(qc);
 -
 -      /* if callback indicates not to complete command (non-zero),
 -       * return immediately
 -       */
 -      if (rc != 0)
 -              return;
 -
 -      __ata_qc_complete(qc);
 -
 -      VPRINTK("EXIT\n");
 +      qc->complete_fn(qc);
  }
  
  static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
   *    spin_lock_irqsave(host_set lock)
   *
   *    RETURNS:
 - *    Zero on success, negative on error.
 + *    Zero on success, AC_ERR_* mask on failure
   */
  
 -int ata_qc_issue(struct ata_queued_cmd *qc)
 +unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
  {
        struct ata_port *ap = qc->ap;
  
        if (ata_should_dma_map(qc)) {
                if (qc->flags & ATA_QCFLAG_SG) {
                        if (ata_sg_setup(qc))
 -                              goto err_out;
 +                              goto sg_err;
                } else if (qc->flags & ATA_QCFLAG_SINGLE) {
                        if (ata_sg_setup_one(qc))
 -                              goto err_out;
 +                              goto sg_err;
                }
        } else {
                qc->flags &= ~ATA_QCFLAG_DMAMAP;
  
        return ap->ops->qc_issue(qc);
  
 -err_out:
 -      return -1;
 +sg_err:
 +      qc->flags &= ~ATA_QCFLAG_DMAMAP;
 +      return AC_ERR_SYSTEM;
  }
  
  
   *    spin_lock_irqsave(host_set lock)
   *
   *    RETURNS:
 - *    Zero on success, negative on error.
 + *    Zero on success, AC_ERR_* mask on failure
   */
  
 -int ata_qc_issue_prot(struct ata_queued_cmd *qc)
 +unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
  {
        struct ata_port *ap = qc->ap;
  
                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);
 +              ata_queue_pio_task(ap);
                break;
  
        case ATA_PROT_ATAPI:
                ata_qc_set_polling(qc);
                ata_tf_to_host(ap, &qc->tf);
 -              queue_work(ata_wq, &ap->packet_task);
 +              ata_queue_packet_task(ap);
                break;
  
        case ATA_PROT_ATAPI_NODATA:
                ap->flags |= ATA_FLAG_NOINTR;
                ata_tf_to_host(ap, &qc->tf);
 -              queue_work(ata_wq, &ap->packet_task);
 +              ata_queue_packet_task(ap);
                break;
  
        case ATA_PROT_ATAPI_DMA:
                ap->flags |= ATA_FLAG_NOINTR;
                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);
 +              ata_queue_packet_task(ap);
                break;
  
        default:
                WARN_ON(1);
 -              return -1;
 +              return AC_ERR_SYSTEM;
        }
  
        return 0;
@@@ -4202,26 -4168,26 +4206,26 @@@ static void atapi_packet_task(void *_da
        u8 status;
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
 -      assert(qc != NULL);
 -      assert(qc->flags & ATA_QCFLAG_ACTIVE);
 +      WARN_ON(qc == NULL);
 +      WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
  
        /* sleep-wait for BSY to clear */
        DPRINTK("busy wait\n");
        if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
 -              qc->err_mask |= AC_ERR_ATA_BUS;
 +              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_ATA_BUS;
 +              qc->err_mask |= AC_ERR_HSM;
                goto err_out;
        }
  
        /* send SCSI cdb */
        DPRINTK("send cdb\n");
 -      assert(ap->cdb_len >= 12);
 +      WARN_ON(qc->dev->cdb_len < 12);
  
        if (qc->tf.protocol == ATA_PROT_ATAPI_DMA ||
            qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
                 */
                spin_lock_irqsave(&ap->host_set->lock, flags);
                ap->flags &= ~ATA_FLAG_NOINTR;
 -              ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
 +              ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
                if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
                        ap->ops->bmdma_start(qc);       /* initiate bmdma */
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        } else {
 -              ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
 +              ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
  
                /* PIO commands are handled by polling */
                ap->hsm_task_state = HSM_ST;
 -              queue_work(ata_wq, &ap->pio_task);
 +              ata_queue_pio_task(ap);
        }
  
        return;
@@@ -4254,6 -4220,19 +4258,6 @@@ err_out
  }
  
  
 -/**
 - *    ata_port_start - Set port up for dma.
 - *    @ap: Port to initialize
 - *
 - *    Called just after data structures for each port are
 - *    initialized.  Allocates space for PRD table.
 - *
 - *    May be used as the port_start() entry in ata_port_operations.
 - *
 - *    LOCKING:
 - *    Inherited from caller.
 - */
 -
  /*
   * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
   * without filling any other registers
@@@ -4305,8 -4284,6 +4309,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
@@@ -4329,11 -4306,10 +4333,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)
  {
        return 0;
  }
  
 +/**
 + *    ata_port_start - Set port up for dma.
 + *    @ap: Port to initialize
 + *
 + *    Called just after data structures for each port are
 + *    initialized.  Allocates space for PRD table.
 + *
 + *    May be used as the port_start() entry in ata_port_operations.
 + *
 + *    LOCKING:
 + *    Inherited from caller.
 + */
 +
  int ata_port_start (struct ata_port *ap)
  {
        struct device *dev = ap->host_set->dev;
@@@ -4475,7 -4438,6 +4479,7 @@@ static void ata_host_init(struct ata_po
  
        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);
  
        for (i = 0; i < ATA_MAX_DEVICES; i++)
                ap->device[i].devno = i;
@@@ -4617,9 -4579,9 +4621,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];
  
@@@ -4765,6 -4727,32 +4769,6 @@@ void ata_std_ports(struct ata_ioports *
        ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
  }
  
 -static struct ata_probe_ent *
 -ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
 -{
 -      struct ata_probe_ent *probe_ent;
 -
 -      probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
 -      if (!probe_ent) {
 -              printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
 -                     kobject_name(&(dev->kobj)));
 -              return NULL;
 -      }
 -
 -      INIT_LIST_HEAD(&probe_ent->node);
 -      probe_ent->dev = dev;
 -
 -      probe_ent->sht = port->sht;
 -      probe_ent->host_flags = port->host_flags;
 -      probe_ent->pio_mask = port->pio_mask;
 -      probe_ent->mwdma_mask = port->mwdma_mask;
 -      probe_ent->udma_mask = port->udma_mask;
 -      probe_ent->port_ops = port->port_ops;
 -
 -      return probe_ent;
 -}
 -
 -
  
  #ifdef CONFIG_PCI
  
@@@ -4775,6 -4763,256 +4779,6 @@@ void ata_pci_host_stop (struct ata_host
        pci_iounmap(pdev, host_set->mmio_base);
  }
  
 -/**
 - *    ata_pci_init_native_mode - Initialize native-mode driver
 - *    @pdev:  pci device to be initialized
 - *    @port:  array[2] of pointers to port info structures.
 - *    @ports: bitmap of ports present
 - *
 - *    Utility function which allocates and initializes an
 - *    ata_probe_ent structure for a standard dual-port
 - *    PIO-based IDE controller.  The returned ata_probe_ent
 - *    structure can be passed to ata_device_add().  The returned
 - *    ata_probe_ent structure should then be freed with kfree().
 - *
 - *    The caller need only pass the address of the primary port, the
 - *    secondary will be deduced automatically. If the device has non
 - *    standard secondary port mappings this function can be called twice,
 - *    once for each interface.
 - */
 -
 -struct ata_probe_ent *
 -ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
 -{
 -      struct ata_probe_ent *probe_ent =
 -              ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
 -      int p = 0;
 -
 -      if (!probe_ent)
 -              return NULL;
 -
 -      probe_ent->irq = pdev->irq;
 -      probe_ent->irq_flags = SA_SHIRQ;
 -      probe_ent->private_data = port[0]->private_data;
 -
 -      if (ports & ATA_PORT_PRIMARY) {
 -              probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
 -              probe_ent->port[p].altstatus_addr =
 -              probe_ent->port[p].ctl_addr =
 -                      pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
 -              probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
 -              ata_std_ports(&probe_ent->port[p]);
 -              p++;
 -      }
 -
 -      if (ports & ATA_PORT_SECONDARY) {
 -              probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
 -              probe_ent->port[p].altstatus_addr =
 -              probe_ent->port[p].ctl_addr =
 -                      pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
 -              probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
 -              ata_std_ports(&probe_ent->port[p]);
 -              p++;
 -      }
 -
 -      probe_ent->n_ports = p;
 -      return probe_ent;
 -}
 -
 -static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num)
 -{
 -      struct ata_probe_ent *probe_ent;
 -
 -      probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
 -      if (!probe_ent)
 -              return NULL;
 -
 -      probe_ent->legacy_mode = 1;
 -      probe_ent->n_ports = 1;
 -      probe_ent->hard_port_no = port_num;
 -      probe_ent->private_data = port->private_data;
 -
 -      switch(port_num)
 -      {
 -              case 0:
 -                      probe_ent->irq = 14;
 -                      probe_ent->port[0].cmd_addr = 0x1f0;
 -                      probe_ent->port[0].altstatus_addr =
 -                      probe_ent->port[0].ctl_addr = 0x3f6;
 -                      break;
 -              case 1:
 -                      probe_ent->irq = 15;
 -                      probe_ent->port[0].cmd_addr = 0x170;
 -                      probe_ent->port[0].altstatus_addr =
 -                      probe_ent->port[0].ctl_addr = 0x376;
 -                      break;
 -      }
 -      probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num;
 -      ata_std_ports(&probe_ent->port[0]);
 -      return probe_ent;
 -}
 -
 -/**
 - *    ata_pci_init_one - Initialize/register PCI IDE host controller
 - *    @pdev: Controller to be initialized
 - *    @port_info: Information from low-level host driver
 - *    @n_ports: Number of ports attached to host controller
 - *
 - *    This is a helper function which can be called from a driver's
 - *    xxx_init_one() probe function if the hardware uses traditional
 - *    IDE taskfile registers.
 - *
 - *    This function calls pci_enable_device(), reserves its register
 - *    regions, sets the dma mask, enables bus master mode, and calls
 - *    ata_device_add()
 - *
 - *    LOCKING:
 - *    Inherited from PCI layer (may sleep).
 - *
 - *    RETURNS:
 - *    Zero on success, negative on errno-based value on error.
 - */
 -
 -int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 -                    unsigned int n_ports)
 -{
 -      struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
 -      struct ata_port_info *port[2];
 -      u8 tmp8, mask;
 -      unsigned int legacy_mode = 0;
 -      int disable_dev_on_err = 1;
 -      int rc;
 -
 -      DPRINTK("ENTER\n");
 -
 -      port[0] = port_info[0];
 -      if (n_ports > 1)
 -              port[1] = port_info[1];
 -      else
 -              port[1] = port[0];
 -
 -      if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
 -          && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 -              /* TODO: What if one channel is in native mode ... */
 -              pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
 -              mask = (1 << 2) | (1 << 0);
 -              if ((tmp8 & mask) != mask)
 -                      legacy_mode = (1 << 3);
 -      }
 -
 -      /* FIXME... */
 -      if ((!legacy_mode) && (n_ports > 2)) {
 -              printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
 -              n_ports = 2;
 -              /* For now */
 -      }
 -
 -      /* FIXME: Really for ATA it isn't safe because the device may be
 -         multi-purpose and we want to leave it alone if it was already
 -         enabled. Secondly for shared use as Arjan says we want refcounting
 -         
 -         Checking dev->is_enabled is insufficient as this is not set at
 -         boot for the primary video which is BIOS enabled
 -         */
 -         
 -      rc = pci_enable_device(pdev);
 -      if (rc)
 -              return rc;
 -
 -      rc = pci_request_regions(pdev, DRV_NAME);
 -      if (rc) {
 -              disable_dev_on_err = 0;
 -              goto err_out;
 -      }
 -
 -      /* FIXME: Should use platform specific mappers for legacy port ranges */
 -      if (legacy_mode) {
 -              if (!request_region(0x1f0, 8, "libata")) {
 -                      struct resource *conflict, res;
 -                      res.start = 0x1f0;
 -                      res.end = 0x1f0 + 8 - 1;
 -                      conflict = ____request_resource(&ioport_resource, &res);
 -                      if (!strcmp(conflict->name, "libata"))
 -                              legacy_mode |= (1 << 0);
 -                      else {
 -                              disable_dev_on_err = 0;
 -                              printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
 -                      }
 -              } else
 -                      legacy_mode |= (1 << 0);
 -
 -              if (!request_region(0x170, 8, "libata")) {
 -                      struct resource *conflict, res;
 -                      res.start = 0x170;
 -                      res.end = 0x170 + 8 - 1;
 -                      conflict = ____request_resource(&ioport_resource, &res);
 -                      if (!strcmp(conflict->name, "libata"))
 -                              legacy_mode |= (1 << 1);
 -                      else {
 -                              disable_dev_on_err = 0;
 -                              printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
 -                      }
 -              } else
 -                      legacy_mode |= (1 << 1);
 -      }
 -
 -      /* we have legacy mode, but all ports are unavailable */
 -      if (legacy_mode == (1 << 3)) {
 -              rc = -EBUSY;
 -              goto err_out_regions;
 -      }
 -
 -      rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 -      if (rc)
 -              goto err_out_regions;
 -      rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
 -      if (rc)
 -              goto err_out_regions;
 -
 -      if (legacy_mode) {
 -              if (legacy_mode & (1 << 0))
 -                      probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
 -              if (legacy_mode & (1 << 1))
 -                      probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
 -      } else {
 -              if (n_ports == 2)
 -                      probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
 -              else
 -                      probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
 -      }
 -      if (!probe_ent && !probe_ent2) {
 -              rc = -ENOMEM;
 -              goto err_out_regions;
 -      }
 -
 -      pci_set_master(pdev);
 -
 -      /* FIXME: check ata_device_add return */
 -      if (legacy_mode) {
 -              if (legacy_mode & (1 << 0))
 -                      ata_device_add(probe_ent);
 -              if (legacy_mode & (1 << 1))
 -                      ata_device_add(probe_ent2);
 -      } else
 -              ata_device_add(probe_ent);
 -
 -      kfree(probe_ent);
 -      kfree(probe_ent2);
 -
 -      return 0;
 -
 -err_out_regions:
 -      if (legacy_mode & (1 << 0))
 -              release_region(0x1f0, 8);
 -      if (legacy_mode & (1 << 1))
 -              release_region(0x170, 8);
 -      pci_release_regions(pdev);
 -err_out:
 -      if (disable_dev_on_err)
 -              pci_disable_device(pdev);
 -      return rc;
 -}
 -
  /**
   *    ata_pci_remove_one - PCI layer callback for device removal
   *    @pdev: PCI device that was removed
@@@ -4905,7 -5143,7 +4909,7 @@@ EXPORT_SYMBOL_GPL(ata_device_add)
  EXPORT_SYMBOL_GPL(ata_host_set_remove);
  EXPORT_SYMBOL_GPL(ata_sg_init);
  EXPORT_SYMBOL_GPL(ata_sg_init_one);
 -EXPORT_SYMBOL_GPL(ata_qc_complete);
 +EXPORT_SYMBOL_GPL(__ata_qc_complete);
  EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
  EXPORT_SYMBOL_GPL(ata_eng_timeout);
  EXPORT_SYMBOL_GPL(ata_tf_load);
@@@ -4931,29 -5169,18 +4935,29 @@@ 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);
  EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
  EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
 +EXPORT_SYMBOL_GPL(ata_scsi_timed_out);
  EXPORT_SYMBOL_GPL(ata_scsi_error);
  EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
  EXPORT_SYMBOL_GPL(ata_scsi_release);
  EXPORT_SYMBOL_GPL(ata_host_intr);
  EXPORT_SYMBOL_GPL(ata_dev_classify);
 -EXPORT_SYMBOL_GPL(ata_dev_id_string);
 +EXPORT_SYMBOL_GPL(ata_id_string);
 +EXPORT_SYMBOL_GPL(ata_id_c_string);
  EXPORT_SYMBOL_GPL(ata_dev_config);
  EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 +EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 +EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
  
  EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
  EXPORT_SYMBOL_GPL(ata_timing_compute);
index 538784e65cdc02977f9c424edd19011935dbb9f9,59503c9ccac9ff794a66d29c358f4d98c4b33ed0..d0bd94abb41308a58957f1d45218c38e9da260c2
@@@ -151,7 -151,7 +151,7 @@@ int ata_cmd_ioctl(struct scsi_device *s
        struct scsi_sense_hdr sshdr;
        enum dma_data_direction data_dir;
  
 -      if (NULL == (void *)arg)
 +      if (arg == NULL)
                return -EINVAL;
  
        if (copy_from_user(args, arg, sizeof(args)))
        /* Need code to retrieve data from check condition? */
  
        if ((argbuf)
 -       && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
 +       && copy_to_user(arg + sizeof(args), argbuf, argsize))
                rc = -EFAULT;
  error:
        if (argbuf)
@@@ -228,7 -228,7 +228,7 @@@ int ata_task_ioctl(struct scsi_device *
        u8 args[7];
        struct scsi_sense_hdr sshdr;
  
 -      if (NULL == (void *)arg)
 +      if (arg == NULL)
                return -EINVAL;
  
        if (copy_from_user(args, arg, sizeof(args)))
@@@ -553,7 -553,7 +553,7 @@@ void ata_gen_ata_desc_sense(struct ata_
        /*
         * Read the controller registers.
         */
 -      assert(NULL != qc->ap->ops->tf_read);
 +      WARN_ON(qc->ap->ops->tf_read == NULL);
        qc->ap->ops->tf_read(qc->ap, tf);
  
        /*
@@@ -628,7 -628,7 +628,7 @@@ void ata_gen_fixed_sense(struct ata_que
        /*
         * Read the controller registers.
         */
 -      assert(NULL != qc->ap->ops->tf_read);
 +      WARN_ON(qc->ap->ops->tf_read == NULL);
        qc->ap->ops->tf_read(qc->ap, tf);
  
        /*
@@@ -684,23 -684,23 +684,23 @@@ int ata_scsi_slave_config(struct scsi_d
        if (sdev->id < ATA_MAX_DEVICES) {
                struct ata_port *ap;
                struct ata_device *dev;
 +              unsigned int max_sectors;
  
                ap = (struct ata_port *) &sdev->host->hostdata[0];
                dev = &ap->device[sdev->id];
  
 -              /* TODO: 1024 is an arbitrary number, not the
 +              /* TODO: 2048 is an arbitrary number, not the
                 * hardware maximum.  This should be increased to
                 * 65534 when Jens Axboe's patch for dynamically
                 * determining max_sectors is merged.
                 */
 -              if ((dev->flags & ATA_DFLAG_LBA48) &&
 -                  ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
 -                      /*
 -                       * do not overwrite sdev->host->max_sectors, since
 -                       * other drives on this host may not support LBA48
 -                       */
 -                      blk_queue_max_sectors(sdev->request_queue, 2048);
 -              }
 +              max_sectors = ATA_MAX_SECTORS;
 +              if (dev->flags & ATA_DFLAG_LBA48)
 +                      max_sectors = 2048;
 +              if (dev->max_sectors)
 +                      max_sectors = dev->max_sectors;
 +
 +              blk_queue_max_sectors(sdev->request_queue, max_sectors);
  
                /*
                 * SATA DMA transfers must be multiples of 4 byte, so
        return 0;       /* scsi layer doesn't check return value, sigh */
  }
  
 +/**
 + *    ata_scsi_timed_out - SCSI layer time out callback
 + *    @cmd: timed out SCSI command
 + *
 + *    Handles SCSI layer timeout.  We race with normal completion of
 + *    the qc for @cmd.  If the qc is already gone, we lose and let
 + *    the scsi command finish (EH_HANDLED).  Otherwise, the qc has
 + *    timed out and EH should be invoked.  Prevent ata_qc_complete()
 + *    from finishing it by setting EH_SCHEDULED and return
 + *    EH_NOT_HANDLED.
 + *
 + *    LOCKING:
 + *    Called from timer context
 + *
 + *    RETURNS:
 + *    EH_HANDLED or EH_NOT_HANDLED
 + */
 +enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
 +{
 +      struct Scsi_Host *host = cmd->device->host;
 +      struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
 +      unsigned long flags;
 +      struct ata_queued_cmd *qc;
 +      enum scsi_eh_timer_return ret = EH_HANDLED;
 +
 +      DPRINTK("ENTER\n");
 +
 +      spin_lock_irqsave(&ap->host_set->lock, flags);
 +      qc = ata_qc_from_tag(ap, ap->active_tag);
 +      if (qc) {
 +              WARN_ON(qc->scsicmd != cmd);
 +              qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
 +              qc->err_mask |= AC_ERR_TIMEOUT;
 +              ret = EH_NOT_HANDLED;
 +      }
 +      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 +
 +      DPRINTK("EXIT, ret=%d\n", ret);
 +      return ret;
 +}
 +
  /**
   *    ata_scsi_error - SCSI layer error handler callback
   *    @host: SCSI host on which error occurred
  int ata_scsi_error(struct Scsi_Host *host)
  {
        struct ata_port *ap;
 +      unsigned long flags;
  
        DPRINTK("ENTER\n");
  
        ap = (struct ata_port *) &host->hostdata[0];
 +
 +      spin_lock_irqsave(&ap->host_set->lock, flags);
 +      WARN_ON(ap->flags & ATA_FLAG_IN_EH);
 +      ap->flags |= ATA_FLAG_IN_EH;
 +      WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL);
 +      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 +
        ap->ops->eng_timeout(ap);
  
 -      /* TODO: this is per-command; when queueing is supported
 -       * this code will either change or move to a more
 -       * appropriate place
 -       */
 -      host->host_failed--;
 -      INIT_LIST_HEAD(&host->eh_cmd_q);
 +      WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
 +
 +      scsi_eh_flush_done_q(&ap->eh_done_q);
 +
 +      spin_lock_irqsave(&ap->host_set->lock, flags);
 +      ap->flags &= ~ATA_FLAG_IN_EH;
 +      spin_unlock_irqrestore(&ap->host_set->lock, flags);
  
        DPRINTK("EXIT\n");
        return 0;
  }
  
 +static void ata_eh_scsidone(struct scsi_cmnd *scmd)
 +{
 +      /* nada */
 +}
 +
 +static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
 +{
 +      struct ata_port *ap = qc->ap;
 +      struct scsi_cmnd *scmd = qc->scsicmd;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&ap->host_set->lock, flags);
 +      qc->scsidone = ata_eh_scsidone;
 +      __ata_qc_complete(qc);
 +      WARN_ON(ata_tag_valid(qc->tag));
 +      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 +
 +      scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
 +}
 +
 +/**
 + *    ata_eh_qc_complete - Complete an active ATA command from EH
 + *    @qc: Command to complete
 + *
 + *    Indicate to the mid and upper layers that an ATA command has
 + *    completed.  To be used from EH.
 + */
 +void ata_eh_qc_complete(struct ata_queued_cmd *qc)
 +{
 +      struct scsi_cmnd *scmd = qc->scsicmd;
 +      scmd->retries = scmd->allowed;
 +      __ata_eh_qc_complete(qc);
 +}
 +
 +/**
 + *    ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
 + *    @qc: Command to retry
 + *
 + *    Indicate to the mid and upper layers that an ATA command
 + *    should be retried.  To be used from EH.
 + *
 + *    SCSI midlayer limits the number of retries to scmd->allowed.
 + *    This function might need to adjust scmd->retries for commands
 + *    which get retried due to unrelated NCQ failures.
 + */
 +void ata_eh_qc_retry(struct ata_queued_cmd *qc)
 +{
 +      __ata_eh_qc_complete(qc);
 +}
 +
  /**
   *    ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
   *    @qc: Storage for translated ATA taskfile
@@@ -1085,13 -985,9 +1085,13 @@@ static unsigned int ata_scsi_verify_xla
        if (dev->flags & ATA_DFLAG_LBA) {
                tf->flags |= ATA_TFLAG_LBA;
  
 -              if (dev->flags & ATA_DFLAG_LBA48) {
 -                      if (n_block > (64 * 1024))
 -                              goto invalid_fld;
 +              if (lba_28_ok(block, n_block)) {
 +                      /* use LBA28 */
 +                      tf->command = ATA_CMD_VERIFY;
 +                      tf->device |= (block >> 24) & 0xf;
 +              } else if (lba_48_ok(block, n_block)) {
 +                      if (!(dev->flags & ATA_DFLAG_LBA48))
 +                              goto out_of_range;
  
                        /* use LBA48 */
                        tf->flags |= ATA_TFLAG_LBA48;
                        tf->hob_lbah = (block >> 40) & 0xff;
                        tf->hob_lbam = (block >> 32) & 0xff;
                        tf->hob_lbal = (block >> 24) & 0xff;
 -              } else {
 -                      if (n_block > 256)
 -                              goto invalid_fld;
 -
 -                      /* use LBA28 */
 -                      tf->command = ATA_CMD_VERIFY;
 -
 -                      tf->device |= (block >> 24) & 0xf;
 -              }
 +              } else
 +                      /* request too large even for LBA48 */
 +                      goto out_of_range;
  
                tf->nsect = n_block & 0xff;
  
                /* CHS */
                u32 sect, head, cyl, track;
  
 -              if (n_block > 256)
 -                      goto invalid_fld;
 +              if (!lba_28_ok(block, n_block))
 +                      goto out_of_range;
  
                /* Convert LBA to CHS */
                track = (u32)block / dev->sectors;
@@@ -1237,11 -1139,9 +1237,11 @@@ static unsigned int ata_scsi_rw_xlat(st
        if (dev->flags & ATA_DFLAG_LBA) {
                tf->flags |= ATA_TFLAG_LBA;
  
 -              if (dev->flags & ATA_DFLAG_LBA48) {
 -                      /* The request -may- be too large for LBA48. */
 -                      if ((block >> 48) || (n_block > 65536))
 +              if (lba_28_ok(block, n_block)) {
 +                      /* use LBA28 */
 +                      tf->device |= (block >> 24) & 0xf;
 +              } else if (lba_48_ok(block, n_block)) {
 +                      if (!(dev->flags & ATA_DFLAG_LBA48))
                                goto out_of_range;
  
                        /* use LBA48 */
                        tf->hob_lbah = (block >> 40) & 0xff;
                        tf->hob_lbam = (block >> 32) & 0xff;
                        tf->hob_lbal = (block >> 24) & 0xff;
 -              } else { 
 -                      /* use LBA28 */
 -
 -                      /* The request -may- be too large for LBA28. */
 -                      if ((block >> 28) || (n_block > 256))
 -                              goto out_of_range;
 -
 -                      tf->device |= (block >> 24) & 0xf;
 -              }
 +              } else
 +                      /* request too large even for LBA48 */
 +                      goto out_of_range;
  
                if (unlikely(ata_rwcmd_protocol(qc) < 0))
                        goto invalid_fld;
                u32 sect, head, cyl, track;
  
                /* The request -may- be too large for CHS addressing. */
 -              if ((block >> 28) || (n_block > 256))
 +              if (!lba_28_ok(block, n_block))
                        goto out_of_range;
  
                if (unlikely(ata_rwcmd_protocol(qc) < 0))
@@@ -1319,7 -1225,7 +1319,7 @@@ nothing_to_do
        return 1;
  }
  
 -static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 +static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
  {
        struct scsi_cmnd *cmd = qc->scsicmd;
        u8 *cdb = cmd->cmnd;
  
        qc->scsidone(cmd);
  
 -      return 0;
 +      ata_qc_free(qc);
  }
  
  /**
@@@ -1422,9 -1328,8 +1422,9 @@@ static void ata_scsi_translate(struct a
                goto early_finish;
  
        /* select device, send command to hardware */
 -      if (ata_qc_issue(qc))
 -              goto err_did;
 +      qc->err_mask = ata_qc_issue(qc);
 +      if (qc->err_mask)
 +              ata_qc_complete(qc);
  
        VPRINTK("EXIT\n");
        return;
@@@ -1567,8 -1472,8 +1567,8 @@@ unsigned int ata_scsiop_inq_std(struct 
  
        if (buflen > 35) {
                memcpy(&rbuf[8], "ATA     ", 8);
 -              ata_dev_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
 -              ata_dev_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
 +              ata_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
 +              ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
                if (rbuf[32] == 0 || rbuf[32] == ' ')
                        memcpy(&rbuf[32], "n/a ", 4);
        }
@@@ -1642,8 -1547,8 +1642,8 @@@ unsigned int ata_scsiop_inq_80(struct a
        memcpy(rbuf, hdr, sizeof(hdr));
  
        if (buflen > (ATA_SERNO_LEN + 4 - 1))
 -              ata_dev_id_string(args->id, (unsigned char *) &rbuf[4],
 -                                ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
 +              ata_id_string(args->id, (unsigned char *) &rbuf[4],
 +                            ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
  
        return 0;
  }
@@@ -1803,15 -1708,20 +1803,17 @@@ static int ata_dev_supports_fua(u16 *id
  {
        unsigned char model[41], fw[9];
  
+       if (!libata_fua)
+               return 0;
        if (!ata_id_has_fua(id))
                return 0;
  
 -      model[40] = '\0';
 -      fw[8] = '\0';
 -
 -      ata_dev_id_string(id, model, ATA_ID_PROD_OFS, sizeof(model) - 1);
 -      ata_dev_id_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw) - 1);
 +      ata_id_c_string(id, model, ATA_ID_PROD_OFS, sizeof(model));
 +      ata_id_c_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw));
  
 -      if (strncmp(model, "Maxtor", 6))
 +      if (strcmp(model, "Maxtor"))
                return 1;
 -      if (strncmp(fw, "BANC1G10", 8))
 +      if (strcmp(fw, "BANC1G10"))
                return 1;
  
        return 0; /* blacklisted */
@@@ -2105,7 -2015,7 +2107,7 @@@ void ata_scsi_badcmd(struct scsi_cmnd *
        done(cmd);
  }
  
 -static int atapi_sense_complete(struct ata_queued_cmd *qc)
 +static void atapi_sense_complete(struct ata_queued_cmd *qc)
  {
        if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
                /* FIXME: not quite right; we don't want the
                ata_gen_ata_desc_sense(qc);
  
        qc->scsidone(qc->scsicmd);
 -      return 0;
 +      ata_qc_free(qc);
  }
  
  /* is it pointless to prefer PIO for "safety reasons"? */
@@@ -2146,7 -2056,7 +2148,7 @@@ static void atapi_request_sense(struct 
        ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
        qc->dma_dir = DMA_FROM_DEVICE;
  
 -      memset(&qc->cdb, 0, ap->cdb_len);
 +      memset(&qc->cdb, 0, qc->dev->cdb_len);
        qc->cdb[0] = REQUEST_SENSE;
        qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
  
  
        qc->complete_fn = atapi_sense_complete;
  
 -      if (ata_qc_issue(qc)) {
 -              qc->err_mask |= AC_ERR_OTHER;
 +      qc->err_mask = ata_qc_issue(qc);
 +      if (qc->err_mask)
                ata_qc_complete(qc);
 -      }
  
        DPRINTK("EXIT\n");
  }
  
 -static int atapi_qc_complete(struct ata_queued_cmd *qc)
 +static void atapi_qc_complete(struct ata_queued_cmd *qc)
  {
        struct scsi_cmnd *cmd = qc->scsicmd;
        unsigned int err_mask = qc->err_mask;
        if (unlikely(err_mask & AC_ERR_DEV)) {
                cmd->result = SAM_STAT_CHECK_CONDITION;
                atapi_request_sense(qc);
 -              return 1;
 +              return;
        }
  
        else if (unlikely(err_mask))
        }
  
        qc->scsidone(cmd);
 -      return 0;
 +      ata_qc_free(qc);
  }
  /**
   *    atapi_xlat - Initialize PACKET taskfile
@@@ -2248,7 -2159,7 +2250,7 @@@ static unsigned int atapi_xlat(struct a
                if (ata_check_atapi_dma(qc))
                        using_pio = 1;
  
 -      memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len);
 +      memcpy(&qc->cdb, scsicmd, dev->cdb_len);
  
        qc->complete_fn = atapi_qc_complete;
  
@@@ -2608,8 -2519,7 +2610,8 @@@ out_unlock
  
  /**
   *    ata_scsi_simulate - simulate SCSI command on ATA device
 - *    @id: current IDENTIFY data for target device.
 + *    @ap: port the device is connected to
 + *    @dev: the target device
   *    @cmd: SCSI command being sent to device.
   *    @done: SCSI command completion function.
   *
diff --combined drivers/scsi/libata.h
index 9d76923a22536eeb850427757fed3d794b0c270a,fddaf479a5440ff08c12d6e22c49f9e373814731..d822eba05f3c20a91edcace48990f407fdda7869
@@@ -41,11 -41,12 +41,12 @@@ struct ata_scsi_args 
  
  /* libata-core.c */
  extern int atapi_enabled;
+ extern int libata_fua;
  extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
                                      struct ata_device *dev);
  extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
  extern void ata_qc_free(struct ata_queued_cmd *qc);
 -extern int ata_qc_issue(struct ata_queued_cmd *qc);
 +extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc);
  extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
  extern void ata_dev_select(struct ata_port *ap, unsigned int device,
                             unsigned int wait, unsigned int can_sleep);
index 50f8057be75de1b5aae4b0eba0a5a7c565b1e385,ff82ccfbb106b528539e112168a1aba8d250294c..5d169a2881b98dd2accf752cc784551c7f598473
@@@ -584,7 -584,8 +584,7 @@@ static int scsi_request_sense(struct sc
   *    keep a list of pending commands for final completion, and once we
   *    are ready to leave error handling we handle completion for real.
   **/
 -static void scsi_eh_finish_cmd(struct scsi_cmnd *scmd,
 -                             struct list_head *done_q)
 +void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
  {
        scmd->device->host->host_failed--;
        scmd->eh_eflags = 0;
        scsi_setup_cmd_retry(scmd);
        list_move_tail(&scmd->eh_entry, done_q);
  }
 +EXPORT_SYMBOL(scsi_eh_finish_cmd);
  
  /**
   * scsi_eh_get_sense - Get device sense data.
@@@ -1308,7 -1308,7 +1308,7 @@@ int scsi_decide_disposition(struct scsi
         * the request was not marked fast fail.  Note that above,
         * even if the request is marked fast fail, we still requeue
         * for queue congestion conditions (QUEUE_FULL or BUSY) */
-       if ((++scmd->retries) < scmd->allowed 
+       if ((++scmd->retries) <= scmd->allowed
            && !blk_noretry_request(scmd->request)) {
                return NEEDS_RETRY;
        } else {
@@@ -1425,7 -1425,7 +1425,7 @@@ static void scsi_eh_ready_devs(struct S
   * @done_q:   list_head of processed commands.
   *
   **/
 -static void scsi_eh_flush_done_q(struct list_head *done_q)
 +void scsi_eh_flush_done_q(struct list_head *done_q)
  {
        struct scsi_cmnd *scmd, *next;
  
                list_del_init(&scmd->eh_entry);
                if (scsi_device_online(scmd->device) &&
                    !blk_noretry_request(scmd->request) &&
-                   (++scmd->retries < scmd->allowed)) {
+                   (++scmd->retries <= scmd->allowed)) {
                        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush"
                                                          " retry cmd: %p\n",
                                                          current->comm,
                }
        }
  }
 +EXPORT_SYMBOL(scsi_eh_flush_done_q);
  
  /**
   * scsi_unjam_host - Attempt to fix a host which has a cmd that failed.