Merge branch 'scsi-scan'
authorJeff Garzik <jgarzik@pobox.com>
Tue, 4 Oct 2005 18:24:04 +0000 (14:24 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Tue, 4 Oct 2005 18:24:04 +0000 (14:24 -0400)
1  2 
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c

index 82ec7f30bf3f0b146e5e9c01f13a4c3f29af7193,902c76364af7fb01e6265318cc69b92a62def2ff..f0894bfa908b3953401e4ffb8456f33211d95dc1
@@@ -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
@@@ -2511,20 -2425,20 +2511,20 @@@ void ata_poll_qc_complete(struct ata_qu
  static unsigned long ata_pio_poll(struct ata_port *ap)
  {
        u8 status;
 -      unsigned int poll_state = PIO_ST_UNKNOWN;
 -      unsigned int reg_state = PIO_ST_UNKNOWN;
 -      const unsigned int tmout_state = PIO_ST_TMOUT;
 -
 -      switch (ap->pio_task_state) {
 -      case PIO_ST:
 -      case PIO_ST_POLL:
 -              poll_state = PIO_ST_POLL;
 -              reg_state = PIO_ST;
 +      unsigned int poll_state = HSM_ST_UNKNOWN;
 +      unsigned int reg_state = HSM_ST_UNKNOWN;
 +      const unsigned int tmout_state = HSM_ST_TMOUT;
 +
 +      switch (ap->hsm_task_state) {
 +      case HSM_ST:
 +      case HSM_ST_POLL:
 +              poll_state = HSM_ST_POLL;
 +              reg_state = HSM_ST;
                break;
 -      case PIO_ST_LAST:
 -      case PIO_ST_LAST_POLL:
 -              poll_state = PIO_ST_LAST_POLL;
 -              reg_state = PIO_ST_LAST;
 +      case HSM_ST_LAST:
 +      case HSM_ST_LAST_POLL:
 +              poll_state = HSM_ST_LAST_POLL;
 +              reg_state = HSM_ST_LAST;
                break;
        default:
                BUG();
        status = ata_chk_status(ap);
        if (status & ATA_BUSY) {
                if (time_after(jiffies, ap->pio_task_timeout)) {
 -                      ap->pio_task_state = tmout_state;
 +                      ap->hsm_task_state = tmout_state;
                        return 0;
                }
 -              ap->pio_task_state = poll_state;
 +              ap->hsm_task_state = poll_state;
                return ATA_SHORT_PAUSE;
        }
  
 -      ap->pio_task_state = reg_state;
 +      ap->hsm_task_state = reg_state;
        return 0;
  }
  
@@@ -2566,14 -2480,14 +2566,14 @@@ static int ata_pio_complete (struct ata
         * we enter, BSY will be cleared in a chk-status or two.  If not,
         * the drive is probably seeking or something.  Snooze for a couple
         * msecs, then chk-status again.  If still busy, fall back to
 -       * PIO_ST_POLL state.
 +       * HSM_ST_POLL state.
         */
        drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
        if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
                msleep(2);
                drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
                if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
 -                      ap->pio_task_state = PIO_ST_LAST_POLL;
 +                      ap->hsm_task_state = HSM_ST_LAST_POLL;
                        ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
                        return 0;
                }
  
        drv_stat = ata_wait_idle(ap);
        if (!ata_ok(drv_stat)) {
 -              ap->pio_task_state = PIO_ST_ERR;
 +              ap->hsm_task_state = HSM_ST_ERR;
                return 0;
        }
  
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
  
 -      ap->pio_task_state = PIO_ST_IDLE;
 +      ap->hsm_task_state = HSM_ST_IDLE;
  
        ata_poll_qc_complete(qc, drv_stat);
  
@@@ -2748,7 -2662,7 +2748,7 @@@ static void ata_pio_sector(struct ata_q
        unsigned char *buf;
  
        if (qc->cursect == (qc->nsect - 1))
 -              ap->pio_task_state = PIO_ST_LAST;
 +              ap->hsm_task_state = HSM_ST_LAST;
  
        page = sg[qc->cursg].page;
        offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
@@@ -2798,7 -2712,7 +2798,7 @@@ static void __atapi_pio_bytes(struct at
        unsigned int offset, count;
  
        if (qc->curbytes + bytes >= qc->nbytes)
 -              ap->pio_task_state = PIO_ST_LAST;
 +              ap->hsm_task_state = HSM_ST_LAST;
  
  next_sg:
        if (unlikely(qc->cursg >= qc->n_elem)) {
                for (i = 0; i < words; i++)
                        ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write);
  
 -              ap->pio_task_state = PIO_ST_LAST;
 +              ap->hsm_task_state = HSM_ST_LAST;
                return;
        }
  
@@@ -2901,7 -2815,7 +2901,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);
 -      ap->pio_task_state = PIO_ST_ERR;
 +      ap->hsm_task_state = HSM_ST_ERR;
  }
  
  /**
@@@ -2923,14 -2837,14 +2923,14 @@@ static void ata_pio_block(struct ata_po
         * a chk-status or two.  If not, the drive is probably seeking
         * or something.  Snooze for a couple msecs, then
         * chk-status again.  If still busy, fall back to
 -       * PIO_ST_POLL state.
 +       * HSM_ST_POLL state.
         */
        status = ata_busy_wait(ap, ATA_BUSY, 5);
        if (status & ATA_BUSY) {
                msleep(2);
                status = ata_busy_wait(ap, ATA_BUSY, 10);
                if (status & ATA_BUSY) {
 -                      ap->pio_task_state = PIO_ST_POLL;
 +                      ap->hsm_task_state = HSM_ST_POLL;
                        ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
                        return;
                }
        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_LAST;
 +                      ap->hsm_task_state = HSM_ST_LAST;
                        return;
                }
  
        } else {
                /* handle BSY=0, DRQ=0 as error */
                if ((status & ATA_DRQ) == 0) {
 -                      ap->pio_task_state = PIO_ST_ERR;
 +                      ap->hsm_task_state = HSM_ST_ERR;
                        return;
                }
  
@@@ -2970,7 -2884,7 +2970,7 @@@ static void ata_pio_error(struct ata_po
        printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
               ap->id, drv_stat);
  
 -      ap->pio_task_state = PIO_ST_IDLE;
 +      ap->hsm_task_state = HSM_ST_IDLE;
  
        ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
  }
@@@ -2985,25 -2899,25 +2985,25 @@@ fsm_start
        timeout = 0;
        qc_completed = 0;
  
 -      switch (ap->pio_task_state) {
 -      case PIO_ST_IDLE:
 +      switch (ap->hsm_task_state) {
 +      case HSM_ST_IDLE:
                return;
  
 -      case PIO_ST:
 +      case HSM_ST:
                ata_pio_block(ap);
                break;
  
 -      case PIO_ST_LAST:
 +      case HSM_ST_LAST:
                qc_completed = ata_pio_complete(ap);
                break;
  
 -      case PIO_ST_POLL:
 -      case PIO_ST_LAST_POLL:
 +      case HSM_ST_POLL:
 +      case HSM_ST_LAST_POLL:
                timeout = ata_pio_poll(ap);
                break;
  
 -      case PIO_ST_TMOUT:
 -      case PIO_ST_ERR:
 +      case HSM_ST_TMOUT:
 +      case HSM_ST_ERR:
                ata_pio_error(ap);
                return;
        }
@@@ -3242,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;
@@@ -3450,7 -3360,7 +3450,7 @@@ int ata_qc_issue_prot(struct ata_queued
        case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
                ata_qc_set_polling(qc);
                ata_tf_to_host_nolock(ap, &qc->tf);
 -              ap->pio_task_state = PIO_ST;
 +              ap->hsm_task_state = HSM_ST;
                queue_work(ata_wq, &ap->pio_task);
                break;
  
@@@ -3676,7 -3586,7 +3676,7 @@@ u8 ata_bmdma_status(struct ata_port *ap
                void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
                host_stat = readb(mmio + ATA_DMA_STATUS);
        } else
 -      host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
 +              host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
        return host_stat;
  }
  
@@@ -3896,7 -3806,7 +3896,7 @@@ static void atapi_packet_task(void *_da
                ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
  
                /* PIO commands are handled by polling */
 -              ap->pio_task_state = PIO_ST;
 +              ap->hsm_task_state = HSM_ST;
                queue_work(ata_wq, &ap->pio_task);
        }
  
@@@ -4203,7 -4113,7 +4203,7 @@@ int ata_device_add(struct ata_probe_en
        for (i = 0; i < count; i++) {
                struct ata_port *ap = host_set->ports[i];
  
-               scsi_scan_host(ap->host);
+               ata_scsi_scan_host(ap);
        }
  
        dev_set_drvdata(dev, host_set);
@@@ -4363,87 -4273,85 +4363,87 @@@ void ata_pci_host_stop (struct ata_host
   *    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)
 +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->n_ports = 2;
        probe_ent->irq = pdev->irq;
        probe_ent->irq_flags = SA_SHIRQ;
  
 -      probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
 -      probe_ent->port[0].altstatus_addr =
 -      probe_ent->port[0].ctl_addr =
 -              pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
 -      probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
 -
 -      probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
 -      probe_ent->port[1].altstatus_addr =
 -      probe_ent->port[1].ctl_addr =
 -              pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
 -      probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
 +      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++;
 +      }
  
 -      ata_std_ports(&probe_ent->port[0]);
 -      ata_std_ports(&probe_ent->port[1]);
 +      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_mode(struct pci_dev *pdev, struct ata_port_info **port,
 -    struct ata_probe_ent **ppe2)
 +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_ent2;
 +      struct ata_probe_ent *probe_ent;
  
        probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
        if (!probe_ent)
                return NULL;
 -      probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
 -      if (!probe_ent2) {
 -              kfree(probe_ent);
 -              return NULL;
 -      }
 -
 -      probe_ent->n_ports = 1;
 -      probe_ent->irq = 14;
  
 -      probe_ent->hard_port_no = 0;
 +      
        probe_ent->legacy_mode = 1;
 -
 -      probe_ent2->n_ports = 1;
 -      probe_ent2->irq = 15;
 -
 -      probe_ent2->hard_port_no = 1;
 -      probe_ent2->legacy_mode = 1;
 -
 -      probe_ent->port[0].cmd_addr = 0x1f0;
 -      probe_ent->port[0].altstatus_addr =
 -      probe_ent->port[0].ctl_addr = 0x3f6;
 -      probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
 -
 -      probe_ent2->port[0].cmd_addr = 0x170;
 -      probe_ent2->port[0].altstatus_addr =
 -      probe_ent2->port[0].ctl_addr = 0x376;
 -      probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
 -
 +      probe_ent->n_ports = 1;
 +      probe_ent->hard_port_no = port_num;
 +
 +      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]);
 -      ata_std_ports(&probe_ent2->port[0]);
 -
 -      *ppe2 = probe_ent2;
        return probe_ent;
  }
  
  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, *probe_ent2 = NULL;
 +      struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
        struct ata_port_info *port[2];
        u8 tmp8, mask;
        unsigned int legacy_mode = 0;
  
        if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
            && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 -              /* TODO: support transitioning to native mode? */
 +              /* 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)
        }
  
        /* FIXME... */
 -      if ((!legacy_mode) && (n_ports > 1)) {
 -              printk(KERN_ERR "ata: BUG: native mode, n_ports > 1\n");
 -              return -EINVAL;
 +      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;
                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;
                goto err_out_regions;
  
        if (legacy_mode) {
 -              probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
 -      } else
 -              probe_ent = ata_pci_init_native_mode(pdev, port);
 -      if (!probe_ent) {
 +              if (legacy_mode & (1 << 0))
 +                      probe_ent = ata_pci_init_legacy_port(pdev, port, 0);
 +              if (legacy_mode & (1 << 1))
 +                      probe_ent2 = ata_pci_init_legacy_port(pdev, port, 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;
        }
index 4982e6eff7004f7a7a7a078aa6d8eb07bc4c08e1,8295a656e521f65af1a6058097866e85167dfcdd..45ebe9fd52eaaccf38d9b96a0b90b39879a58d60
@@@ -435,21 -435,10 +435,21 @@@ static unsigned int ata_scsi_start_stop
                return 1;       /* power conditions not supported */
        if (scsicmd[4] & 0x1) {
                tf->nsect = 1;  /* 1 sector, lba=0 */
 -              tf->lbah = 0x0;
 -              tf->lbam = 0x0;
 -              tf->lbal = 0x0;
 -              tf->device |= ATA_LBA;
 +
 +              if (qc->dev->flags & ATA_DFLAG_LBA) {
 +                      qc->tf.flags |= ATA_TFLAG_LBA;
 +
 +                      tf->lbah = 0x0;
 +                      tf->lbam = 0x0;
 +                      tf->lbal = 0x0;
 +                      tf->device |= ATA_LBA;
 +              } else {
 +                      /* CHS */
 +                      tf->lbal = 0x1; /* sect */
 +                      tf->lbam = 0x0; /* cyl low */
 +                      tf->lbah = 0x0; /* cyl high */
 +              }
 +
                tf->command = ATA_CMD_VERIFY;   /* READ VERIFY */
        } else {
                tf->nsect = 0;  /* time period value (0 implies now) */
@@@ -498,99 -487,6 +498,99 @@@ static unsigned int ata_scsi_flush_xlat
        return 0;
  }
  
 +/**
 + *    scsi_6_lba_len - Get LBA and transfer length
 + *    @scsicmd: SCSI command to translate
 + *
 + *    Calculate LBA and transfer length for 6-byte commands.
 + *
 + *    RETURNS:
 + *    @plba: the LBA
 + *    @plen: the transfer length
 + */
 +
 +static void scsi_6_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
 +{
 +      u64 lba = 0;
 +      u32 len = 0;
 +
 +      VPRINTK("six-byte command\n");
 +
 +      lba |= ((u64)scsicmd[2]) << 8;
 +      lba |= ((u64)scsicmd[3]);
 +
 +      len |= ((u32)scsicmd[4]);
 +
 +      *plba = lba;
 +      *plen = len;
 +}
 +
 +/**
 + *    scsi_10_lba_len - Get LBA and transfer length
 + *    @scsicmd: SCSI command to translate
 + *
 + *    Calculate LBA and transfer length for 10-byte commands.
 + *
 + *    RETURNS:
 + *    @plba: the LBA
 + *    @plen: the transfer length
 + */
 +
 +static void scsi_10_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
 +{
 +      u64 lba = 0;
 +      u32 len = 0;
 +
 +      VPRINTK("ten-byte command\n");
 +
 +      lba |= ((u64)scsicmd[2]) << 24;
 +      lba |= ((u64)scsicmd[3]) << 16;
 +      lba |= ((u64)scsicmd[4]) << 8;
 +      lba |= ((u64)scsicmd[5]);
 +
 +      len |= ((u32)scsicmd[7]) << 8;
 +      len |= ((u32)scsicmd[8]);
 +
 +      *plba = lba;
 +      *plen = len;
 +}
 +
 +/**
 + *    scsi_16_lba_len - Get LBA and transfer length
 + *    @scsicmd: SCSI command to translate
 + *
 + *    Calculate LBA and transfer length for 16-byte commands.
 + *
 + *    RETURNS:
 + *    @plba: the LBA
 + *    @plen: the transfer length
 + */
 +
 +static void scsi_16_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
 +{
 +      u64 lba = 0;
 +      u32 len = 0;
 +
 +      VPRINTK("sixteen-byte command\n");
 +
 +      lba |= ((u64)scsicmd[2]) << 56;
 +      lba |= ((u64)scsicmd[3]) << 48;
 +      lba |= ((u64)scsicmd[4]) << 40;
 +      lba |= ((u64)scsicmd[5]) << 32;
 +      lba |= ((u64)scsicmd[6]) << 24;
 +      lba |= ((u64)scsicmd[7]) << 16;
 +      lba |= ((u64)scsicmd[8]) << 8;
 +      lba |= ((u64)scsicmd[9]);
 +
 +      len |= ((u32)scsicmd[10]) << 24;
 +      len |= ((u32)scsicmd[11]) << 16;
 +      len |= ((u32)scsicmd[12]) << 8;
 +      len |= ((u32)scsicmd[13]);
 +
 +      *plba = lba;
 +      *plen = len;
 +}
 +
  /**
   *    ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
   *    @qc: Storage for translated ATA taskfile
  static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
  {
        struct ata_taskfile *tf = &qc->tf;
 +      struct ata_device *dev = qc->dev;
 +      unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
        unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
        u64 dev_sectors = qc->dev->n_sectors;
 -      u64 sect = 0;
 -      u32 n_sect = 0;
 +      u64 block;
 +      u32 n_block;
  
        tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf->protocol = ATA_PROT_NODATA;
 -      tf->device |= ATA_LBA;
 -
 -      if (scsicmd[0] == VERIFY) {
 -              sect |= ((u64)scsicmd[2]) << 24;
 -              sect |= ((u64)scsicmd[3]) << 16;
 -              sect |= ((u64)scsicmd[4]) << 8;
 -              sect |= ((u64)scsicmd[5]);
 -
 -              n_sect |= ((u32)scsicmd[7]) << 8;
 -              n_sect |= ((u32)scsicmd[8]);
 -      }
 -
 -      else if (scsicmd[0] == VERIFY_16) {
 -              sect |= ((u64)scsicmd[2]) << 56;
 -              sect |= ((u64)scsicmd[3]) << 48;
 -              sect |= ((u64)scsicmd[4]) << 40;
 -              sect |= ((u64)scsicmd[5]) << 32;
 -              sect |= ((u64)scsicmd[6]) << 24;
 -              sect |= ((u64)scsicmd[7]) << 16;
 -              sect |= ((u64)scsicmd[8]) << 8;
 -              sect |= ((u64)scsicmd[9]);
 -
 -              n_sect |= ((u32)scsicmd[10]) << 24;
 -              n_sect |= ((u32)scsicmd[11]) << 16;
 -              n_sect |= ((u32)scsicmd[12]) << 8;
 -              n_sect |= ((u32)scsicmd[13]);
 -      }
  
 +      if (scsicmd[0] == VERIFY)
 +              scsi_10_lba_len(scsicmd, &block, &n_block);
 +      else if (scsicmd[0] == VERIFY_16)
 +              scsi_16_lba_len(scsicmd, &block, &n_block);
        else
                return 1;
  
 -      if (!n_sect)
 +      if (!n_block)
                return 1;
 -      if (sect >= dev_sectors)
 +      if (block >= dev_sectors)
                return 1;
 -      if ((sect + n_sect) > dev_sectors)
 +      if ((block + n_block) > dev_sectors)
                return 1;
        if (lba48) {
 -              if (n_sect > (64 * 1024))
 +              if (n_block > (64 * 1024))
                        return 1;
        } else {
 -              if (n_sect > 256)
 +              if (n_block > 256)
                        return 1;
        }
  
 -      if (lba48) {
 -              tf->command = ATA_CMD_VERIFY_EXT;
 +      if (lba) {
 +              if (lba48) {
 +                      tf->command = ATA_CMD_VERIFY_EXT;
  
 -              tf->hob_nsect = (n_sect >> 8) & 0xff;
 +                      tf->hob_nsect = (n_block >> 8) & 0xff;
  
 -              tf->hob_lbah = (sect >> 40) & 0xff;
 -              tf->hob_lbam = (sect >> 32) & 0xff;
 -              tf->hob_lbal = (sect >> 24) & 0xff;
 -      } else {
 -              tf->command = ATA_CMD_VERIFY;
 +                      tf->hob_lbah = (block >> 40) & 0xff;
 +                      tf->hob_lbam = (block >> 32) & 0xff;
 +                      tf->hob_lbal = (block >> 24) & 0xff;
 +              } else {
 +                      tf->command = ATA_CMD_VERIFY;
  
 -              tf->device |= (sect >> 24) & 0xf;
 -      }
 +                      tf->device |= (block >> 24) & 0xf;
 +              }
  
 -      tf->nsect = n_sect & 0xff;
 +              tf->nsect = n_block & 0xff;
  
 -      tf->lbah = (sect >> 16) & 0xff;
 -      tf->lbam = (sect >> 8) & 0xff;
 -      tf->lbal = sect & 0xff;
 +              tf->lbah = (block >> 16) & 0xff;
 +              tf->lbam = (block >> 8) & 0xff;
 +              tf->lbal = block & 0xff;
 +
 +              tf->device |= ATA_LBA;
 +      } else {
 +              /* CHS */
 +              u32 sect, head, cyl, track;
 +
 +              /* Convert LBA to CHS */
 +              track = (u32)block / dev->sectors;
 +              cyl   = track / dev->heads;
 +              head  = track % dev->heads;
 +              sect  = (u32)block % dev->sectors + 1;
 +
 +              DPRINTK("block %u track %u cyl %u head %u sect %u\n",
 +                      (u32)block, track, cyl, head, sect);
 +              
 +              /* Check whether the converted CHS can fit. 
 +                 Cylinder: 0-65535 
 +                 Head: 0-15
 +                 Sector: 1-255*/
 +              if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) 
 +                      return 1;
 +              
 +              tf->command = ATA_CMD_VERIFY;
 +              tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
 +              tf->lbal = sect;
 +              tf->lbam = cyl;
 +              tf->lbah = cyl >> 8;
 +              tf->device |= head;
 +      }
  
        return 0;
  }
  static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
  {
        struct ata_taskfile *tf = &qc->tf;
 +      struct ata_device *dev = qc->dev;
 +      unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
        unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
 +      u64 block;
 +      u32 n_block;
  
        tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf->protocol = qc->dev->xfer_protocol;
 -      tf->device |= ATA_LBA;
  
        if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
            scsicmd[0] == READ_16) {
                tf->flags |= ATA_TFLAG_WRITE;
        }
  
 -      if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
 -              if (lba48) {
 -                      tf->hob_nsect = scsicmd[7];
 -                      tf->hob_lbal = scsicmd[2];
 -
 -                      qc->nsect = ((unsigned int)scsicmd[7] << 8) |
 -                                      scsicmd[8];
 -              } else {
 -                      /* if we don't support LBA48 addressing, the request
 -                       * -may- be too large. */
 -                      if ((scsicmd[2] & 0xf0) || scsicmd[7])
 -                              return 1;
 +      /* Calculate the SCSI LBA and transfer length. */
 +      switch (scsicmd[0]) {
 +      case READ_10:
 +      case WRITE_10:
 +              scsi_10_lba_len(scsicmd, &block, &n_block);
 +              break;
 +      case READ_6:
 +      case WRITE_6:
 +              scsi_6_lba_len(scsicmd, &block, &n_block);
  
 -                      /* stores LBA27:24 in lower 4 bits of device reg */
 -                      tf->device |= scsicmd[2];
 +              /* for 6-byte r/w commands, transfer length 0
 +               * means 256 blocks of data, not 0 block.
 +               */
 +              if (!n_block)
 +                      n_block = 256;
 +              break;
 +      case READ_16:
 +      case WRITE_16:
 +              scsi_16_lba_len(scsicmd, &block, &n_block);
 +              break;
 +      default:
 +              DPRINTK("no-byte command\n");
 +              return 1;
 +      }
  
 -                      qc->nsect = scsicmd[8];
 -              }
 +      /* Check and compose ATA command */
 +      if (!n_block)
 +              /* For 10-byte and 16-byte SCSI R/W commands, transfer
 +               * length 0 means transfer 0 block of data.
 +               * However, for ATA R/W commands, sector count 0 means
 +               * 256 or 65536 sectors, not 0 sectors as in SCSI.
 +               */
 +              return 1;
  
 -              tf->nsect = scsicmd[8];
 -              tf->lbal = scsicmd[5];
 -              tf->lbam = scsicmd[4];
 -              tf->lbah = scsicmd[3];
 +      if (lba) {
 +              if (lba48) {
 +                      /* The request -may- be too large for LBA48. */
 +                      if ((block >> 48) || (n_block > 65536))
 +                              return 1;
  
 -              VPRINTK("ten-byte command\n");
 -              if (qc->nsect == 0) /* we don't support length==0 cmds */
 -                      return 1;
 -              return 0;
 -      }
 +                      tf->hob_nsect = (n_block >> 8) & 0xff;
  
 -      if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
 -              qc->nsect = tf->nsect = scsicmd[4];
 -              if (!qc->nsect) {
 -                      qc->nsect = 256;
 -                      if (lba48)
 -                              tf->hob_nsect = 1;
 -              }
 +                      tf->hob_lbah = (block >> 40) & 0xff;
 +                      tf->hob_lbam = (block >> 32) & 0xff;
 +                      tf->hob_lbal = (block >> 24) & 0xff;
 +              } else { 
 +                      /* LBA28 */
  
 -              tf->lbal = scsicmd[3];
 -              tf->lbam = scsicmd[2];
 -              tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
 +                      /* The request -may- be too large for LBA28. */
 +                      if ((block >> 28) || (n_block > 256))
 +                              return 1;
  
 -              VPRINTK("six-byte command\n");
 -              return 0;
 -      }
 +                      tf->device |= (block >> 24) & 0xf;
 +              }
  
 -      if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
 -              /* rule out impossible LBAs and sector counts */
 -              if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
 -                      return 1;
 +              qc->nsect = n_block;
 +              tf->nsect = n_block & 0xff;
  
 -              if (lba48) {
 -                      tf->hob_nsect = scsicmd[12];
 -                      tf->hob_lbal = scsicmd[6];
 -                      tf->hob_lbam = scsicmd[5];
 -                      tf->hob_lbah = scsicmd[4];
 +              tf->lbah = (block >> 16) & 0xff;
 +              tf->lbam = (block >> 8) & 0xff;
 +              tf->lbal = block & 0xff;
  
 -                      qc->nsect = ((unsigned int)scsicmd[12] << 8) |
 -                                      scsicmd[13];
 -              } else {
 -                      /* once again, filter out impossible non-zero values */
 -                      if (scsicmd[4] || scsicmd[5] || scsicmd[12] ||
 -                          (scsicmd[6] & 0xf0))
 -                              return 1;
 +              tf->device |= ATA_LBA;
 +      } else { 
 +              /* CHS */
 +              u32 sect, head, cyl, track;
  
 -                      /* stores LBA27:24 in lower 4 bits of device reg */
 -                      tf->device |= scsicmd[6];
 +              /* The request -may- be too large for CHS addressing. */
 +              if ((block >> 28) || (n_block > 256))
 +                      return 1;
  
 -                      qc->nsect = scsicmd[13];
 -              }
 +              /* Convert LBA to CHS */
 +              track = (u32)block / dev->sectors;
 +              cyl   = track / dev->heads;
 +              head  = track % dev->heads;
 +              sect  = (u32)block % dev->sectors + 1;
  
 -              tf->nsect = scsicmd[13];
 -              tf->lbal = scsicmd[9];
 -              tf->lbam = scsicmd[8];
 -              tf->lbah = scsicmd[7];
 +              DPRINTK("block %u track %u cyl %u head %u sect %u\n",
 +                      (u32)block, track, cyl, head, sect);
  
 -              VPRINTK("sixteen-byte command\n");
 -              if (qc->nsect == 0) /* we don't support length==0 cmds */
 +              /* Check whether the converted CHS can fit. 
 +                 Cylinder: 0-65535 
 +                 Head: 0-15
 +                 Sector: 1-255*/
 +              if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
                        return 1;
 -              return 0;
 +
 +              qc->nsect = n_block;
 +              tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
 +              tf->lbal = sect;
 +              tf->lbam = cyl;
 +              tf->lbah = cyl >> 8;
 +              tf->device |= head;
        }
  
 -      DPRINTK("no-byte command\n");
 -      return 1;
 +      return 0;
  }
  
  static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
@@@ -1374,20 -1246,10 +1374,20 @@@ unsigned int ata_scsiop_read_cap(struc
  
        VPRINTK("ENTER\n");
  
 -      if (ata_id_has_lba48(args->id))
 -              n_sectors = ata_id_u64(args->id, 100);
 -      else
 -              n_sectors = ata_id_u32(args->id, 60);
 +      if (ata_id_has_lba(args->id)) {
 +              if (ata_id_has_lba48(args->id))
 +                      n_sectors = ata_id_u64(args->id, 100);
 +              else
 +                      n_sectors = ata_id_u32(args->id, 60);
 +      } else {
 +              /* CHS default translation */
 +              n_sectors = args->id[1] * args->id[3] * args->id[6];
 +
 +              if (ata_id_current_chs_valid(args->id))
 +                      /* CHS current translation */
 +                      n_sectors = ata_id_u32(args->id, 57);
 +      }
 +
        n_sectors--;            /* ATA TotalUserSectors - 1 */
  
        if (args->cmd->cmnd[0] == READ_CAPACITY) {
@@@ -1816,3 -1678,19 +1816,19 @@@ void ata_scsi_simulate(u16 *id
        }
  }
  
+ void ata_scsi_scan_host(struct ata_port *ap)
+ {
+       struct ata_device *dev;
+       unsigned int i;
+       if (ap->flags & ATA_FLAG_PORT_DISABLED)
+               return;
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               dev = &ap->device[i];
+               if (ata_dev_present(dev))
+                       scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
+       }
+ }
This page took 0.16495 seconds and 5 git commands to generate.