]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge /spare/repo/linux-2.6/
authorJeff Garzik <jgarzik@pobox.com>
Sat, 24 Sep 2005 04:26:49 +0000 (00:26 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Sat, 24 Sep 2005 04:26:49 +0000 (00:26 -0400)
1  2 
drivers/scsi/libata-core.c
include/linux/libata.h

index 62095bdb173ae67d1f8e1d4e0a6ee929793b5cb8,e5b01997117a9965249cb734b7c00f43b7d9bbd8..9182817612ae053e4af439e1c9f0164f585138ab
@@@ -62,7 -62,6 +62,7 @@@
  static unsigned int ata_busy_sleep (struct ata_port *ap,
                                    unsigned long tmout_pat,
                                    unsigned long tmout);
 +static void 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(struct ata_port *ap, int shift);
@@@ -1132,7 -1131,7 +1132,7 @@@ static inline void ata_dump_id(struct a
  static void ata_dev_identify(struct ata_port *ap, unsigned int device)
  {
        struct ata_device *dev = &ap->device[device];
 -      unsigned int i;
 +      unsigned int major_version;
        u16 tmp;
        unsigned long xfer_modes;
        u8 status;
@@@ -1230,9 -1229,9 +1230,9 @@@ retry
         * common ATA, ATAPI feature tests
         */
  
 -      /* we require LBA and DMA support (bits 8 & 9 of word 49) */
 -      if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
 -              printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
 +      /* we require DMA support (bits 8 of word 49) */
 +      if (!ata_id_has_dma(dev->id)) {
 +              printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
                goto err_out_nosup;
        }
  
                if (!ata_id_is_ata(dev->id))    /* sanity check */
                        goto err_out_nosup;
  
 +              /* get major version */
                tmp = dev->id[ATA_ID_MAJOR_VER];
 -              for (i = 14; i >= 1; i--)
 -                      if (tmp & (1 << i))
 +              for (major_version = 14; major_version >= 1; major_version--)
 +                      if (tmp & (1 << major_version))
                                break;
  
 -              /* we require at least ATA-3 */
 -              if (i < 3) {
 -                      printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id);
 -                      goto err_out_nosup;
 -              }
 +              /*
 +               * 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);
 +
 +              if (ata_id_has_lba(dev->id)) {
 +                      dev->flags |= ATA_DFLAG_LBA;
 +
 +                      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_mode_string(xfer_modes),
 +                             (unsigned long long)dev->n_sectors,
 +                             dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
 +              } else { 
 +                      /* CHS */
 +
 +                      /* Default translation */
 +                      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_mode_string(xfer_modes),
 +                             (unsigned long long)dev->n_sectors,
 +                             (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
  
 -              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);
                }
  
                ap->host->max_cmd_len = 16;
 -
 -              /* print device info to dmesg */
 -              printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
 -                     ap->id, device,
 -                     ata_mode_string(xfer_modes),
 -                     (unsigned long long)dev->n_sectors,
 -                     dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
        }
  
        /* ATAPI-specific feature tests */
@@@ -2181,54 -2143,6 +2181,54 @@@ static void ata_dev_set_xfermode(struc
        DPRINTK("EXIT\n");
  }
  
 +/**
 + *    ata_dev_init_params - Issue INIT DEV PARAMS command
 + *    @ap: Port associated with device @dev
 + *    @dev: Device to which command will be sent
 + *
 + *    LOCKING:
 + */
 +
 +static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 +{
 +      DECLARE_COMPLETION(wait);
 +      struct ata_queued_cmd *qc;
 +      int rc;
 +      unsigned long flags;
 +      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;
 +
 +      /* set up init dev params taskfile */
 +      DPRINTK("init dev params \n");
 +
 +      qc = ata_qc_new_init(ap, dev);
 +      BUG_ON(qc == NULL);
 +
 +      qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
 +      qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 +      qc->tf.protocol = ATA_PROT_NODATA;
 +      qc->tf.nsect = sectors;
 +      qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 +
 +      qc->waiting = &wait;
 +      qc->complete_fn = ata_qc_complete_noop;
 +
 +      spin_lock_irqsave(&ap->host_set->lock, flags);
 +      rc = ata_qc_issue(qc);
 +      spin_unlock_irqrestore(&ap->host_set->lock, flags);
 +
 +      if (rc)
 +              ata_port_disable(ap);
 +      else
 +              wait_for_completion(&wait);
 +
 +      DPRINTK("EXIT\n");
 +}
 +
  /**
   *    ata_sg_clean - Unmap DMA memory associated with command
   *    @qc: Command containing DMA memory to be released
@@@ -2551,9 -2465,12 +2551,12 @@@ static unsigned long ata_pio_poll(struc
   *
   *    LOCKING:
   *    None.  (executing in kernel thread context)
+  *
+  *    RETURNS:
+  *    Non-zero if qc completed, zero otherwise.
   */
  
- static void ata_pio_complete (struct ata_port *ap)
+ static int ata_pio_complete (struct ata_port *ap)
  {
        struct ata_queued_cmd *qc;
        u8 drv_stat;
                if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
                        ap->pio_task_state = PIO_ST_LAST_POLL;
                        ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
-                       return;
+                       return 0;
                }
        }
  
        drv_stat = ata_wait_idle(ap);
        if (!ata_ok(drv_stat)) {
                ap->pio_task_state = PIO_ST_ERR;
-               return;
+               return 0;
        }
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
        ap->pio_task_state = PIO_ST_IDLE;
  
        ata_poll_qc_complete(qc, drv_stat);
+       /* another command may start at this point */
+       return 1;
  }
  
  
@@@ -2795,7 -2716,7 +2802,7 @@@ static void __atapi_pio_bytes(struct at
  
  next_sg:
        if (unlikely(qc->cursg >= qc->n_elem)) {
-               /* 
+               /*
                 * The end of qc->sg is reached and the device expects
                 * more data to transfer. In order not to overrun qc->sg
                 * and fulfill length specified in the byte count register,
                unsigned int i;
  
                if (words) /* warning if bytes > 1 */
-                       printk(KERN_WARNING "ata%u: %u bytes trailing data\n", 
+                       printk(KERN_WARNING "ata%u: %u bytes trailing data\n",
                               ap->id, bytes);
  
                for (i = 0; i < words; i++)
@@@ -2935,9 -2856,7 +2942,7 @@@ static void ata_pio_block(struct ata_po
        if (is_atapi_taskfile(&qc->tf)) {
                /* no more data to transfer or unsupported ATAPI command */
                if ((status & ATA_DRQ) == 0) {
-                       ap->pio_task_state = PIO_ST_IDLE;
-                       ata_poll_qc_complete(qc, status);
+                       ap->pio_task_state = PIO_ST_LAST;
                        return;
                }
  
@@@ -2973,7 -2892,12 +2978,12 @@@ static void ata_pio_error(struct ata_po
  static void ata_pio_task(void *_data)
  {
        struct ata_port *ap = _data;
-       unsigned long timeout = 0;
+       unsigned long timeout;
+       int qc_completed;
+ fsm_start:
+       timeout = 0;
+       qc_completed = 0;
  
        switch (ap->pio_task_state) {
        case PIO_ST_IDLE:
                break;
  
        case PIO_ST_LAST:
-               ata_pio_complete(ap);
+               qc_completed = ata_pio_complete(ap);
                break;
  
        case PIO_ST_POLL:
        }
  
        if (timeout)
-               queue_delayed_work(ata_wq, &ap->pio_task,
-                                  timeout);
-       else
-               queue_work(ata_wq, &ap->pio_task);
+               queue_delayed_work(ata_wq, &ap->pio_task, timeout);
+       else if (!qc_completed)
+               goto fsm_start;
  }
  
  static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
@@@ -3233,12 -3156,8 +3242,12 @@@ struct ata_queued_cmd *ata_qc_new_init(
  
                ata_tf_init(ap, &qc->tf, dev->devno);
  
 -              if (dev->flags & ATA_DFLAG_LBA48)
 -                      qc->tf.flags |= ATA_TFLAG_LBA48;
 +              if (dev->flags & ATA_DFLAG_LBA) {
 +                      qc->tf.flags |= ATA_TFLAG_LBA;
 +
 +                      if (dev->flags & ATA_DFLAG_LBA48)
 +                              qc->tf.flags |= ATA_TFLAG_LBA48;
 +              }
        }
  
        return qc;
@@@ -4212,6 -4131,53 +4221,53 @@@ err_out
        return 0;
  }
  
+ /**
+  *    ata_host_set_remove - PCI layer callback for device removal
+  *    @host_set: ATA host set that was removed
+  *
+  *    Unregister all objects associated with this host set. Free those 
+  *    objects.
+  *
+  *    LOCKING:
+  *    Inherited from calling layer (may sleep).
+  */
+ void ata_host_set_remove(struct ata_host_set *host_set)
+ {
+       struct ata_port *ap;
+       unsigned int i;
+       for (i = 0; i < host_set->n_ports; i++) {
+               ap = host_set->ports[i];
+               scsi_remove_host(ap->host);
+       }
+       free_irq(host_set->irq, host_set);
+       for (i = 0; i < host_set->n_ports; i++) {
+               ap = host_set->ports[i];
+               ata_scsi_release(ap->host);
+               if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
+                       struct ata_ioports *ioaddr = &ap->ioaddr;
+                       if (ioaddr->cmd_addr == 0x1f0)
+                               release_region(0x1f0, 8);
+                       else if (ioaddr->cmd_addr == 0x170)
+                               release_region(0x170, 8);
+               }
+               scsi_host_put(ap->host);
+       }
+       if (host_set->ops->host_stop)
+               host_set->ops->host_stop(host_set);
+       kfree(host_set);
+ }
  /**
   *    ata_scsi_release - SCSI layer callback hook for host unload
   *    @host: libata host to be unloaded
@@@ -4552,39 -4518,8 +4608,8 @@@ void ata_pci_remove_one (struct pci_de
  {
        struct device *dev = pci_dev_to_dev(pdev);
        struct ata_host_set *host_set = dev_get_drvdata(dev);
-       struct ata_port *ap;
-       unsigned int i;
-       for (i = 0; i < host_set->n_ports; i++) {
-               ap = host_set->ports[i];
-               scsi_remove_host(ap->host);
-       }
-       free_irq(host_set->irq, host_set);
-       for (i = 0; i < host_set->n_ports; i++) {
-               ap = host_set->ports[i];
-               ata_scsi_release(ap->host);
-               if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
-                       struct ata_ioports *ioaddr = &ap->ioaddr;
-                       if (ioaddr->cmd_addr == 0x1f0)
-                               release_region(0x1f0, 8);
-                       else if (ioaddr->cmd_addr == 0x170)
-                               release_region(0x170, 8);
-               }
-               scsi_host_put(ap->host);
-       }
-       if (host_set->ops->host_stop)
-               host_set->ops->host_stop(host_set);
-       kfree(host_set);
  
+       ata_host_set_remove(host_set);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        dev_set_drvdata(dev, NULL);
@@@ -4654,6 -4589,7 +4679,7 @@@ module_exit(ata_exit)
  EXPORT_SYMBOL_GPL(ata_std_bios_param);
  EXPORT_SYMBOL_GPL(ata_std_ports);
  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);
diff --combined include/linux/libata.h
index f76f54a223d22b614ada536291dc695a0ae7f7aa,ceee1fc42c600d0aa0d045edb37db8c253fec457..7680b63e345686feb5a11afb0ea19f660a06b63a
@@@ -97,7 -97,6 +97,7 @@@ enum 
        ATA_DFLAG_LBA48         = (1 << 0), /* device supports LBA48 */
        ATA_DFLAG_PIO           = (1 << 1), /* device currently in PIO mode */
        ATA_DFLAG_LOCK_SECTORS  = (1 << 2), /* don't adjust max_sectors */
 +      ATA_DFLAG_LBA           = (1 << 3), /* device supports LBA */
  
        ATA_DEV_UNKNOWN         = 0,    /* unknown device */
        ATA_DEV_ATA             = 1,    /* ATA device */
@@@ -283,11 -282,6 +283,11 @@@ struct ata_device 
        u8                      xfer_protocol;  /* taskfile xfer protocol */
        u8                      read_cmd;       /* opcode to use on read */
        u8                      write_cmd;      /* opcode to use on write */
 +
 +      /* for CHS addressing */
 +      u16                     cylinders;      /* Number of cylinders */
 +      u16                     heads;          /* Number of heads */
 +      u16                     sectors;        /* Number of sectors per track */
  };
  
  struct ata_port {
@@@ -399,6 -393,7 +399,7 @@@ extern int ata_pci_init_one (struct pci
  extern void ata_pci_remove_one (struct pci_dev *pdev);
  #endif /* CONFIG_PCI */
  extern int ata_device_add(struct ata_probe_ent *ent);
+ extern void ata_host_set_remove(struct ata_host_set *host_set);
  extern int ata_scsi_detect(Scsi_Host_Template *sht);
  extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
  extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));