-
- if (!(port[num].dev_mask)) {
- printf ("no devices on port%d\n", num);
- return 1;
- }
-
- dev_select (&port[num].ioaddr, dev);
-
- port[num].ctl_reg = 0x08; /*Default value of control reg */
- sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
- udelay (10);
- sata_outb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr);
- udelay (10);
- sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
-
- /* spec mandates ">= 2ms" before checking status.
- * We wait 150ms, because that was the magic delay used for
- * ATAPI devices in Hale Landis's ATADRVR, for the period of time
- * between when the ATA command register is written, and then
- * status is checked. Because waiting for "a while" before
- * checking status is fine, post SRST, we perform this magic
- * delay here as well.
- */
- msleep (150);
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300);
- while ((status & ATA_BUSY)) {
- msleep (100);
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3);
- }
-
- if (status & ATA_BUSY)
- printf ("ata%u is slow to respond,plz be patient\n", port);
-
- while ((status & ATA_BUSY)) {
- msleep (100);
- status = sata_chk_status (&port[num].ioaddr);
- }
-
- if (status & ATA_BUSY) {
- printf ("ata%u failed to respond : ", port);
- printf ("bus reset failed\n");
- return 1;
- }
- return 0;
-}
-
-void
-sata_identify (int num, int dev)
-{
- u8 cmd = 0, status = 0, devno = num * CFG_SATA_DEVS_PER_BUS + dev;
- u16 iobuf[ATA_SECT_SIZE];
- u64 n_sectors = 0;
- u8 mask = 0;
-
- memset (iobuf, 0, sizeof (iobuf));
- hd_driveid_t *iop = (hd_driveid_t *) iobuf;
-
- if (dev == 0)
- mask = 0x01;
- else
- mask = 0x02;
-
- if (!(port[num].dev_mask & mask)) {
- printf ("dev%d is not present on port#%d\n", dev, num);
- return;
- }
-
- printf ("port=%d dev=%d\n", num, dev);
-
- dev_select (&port[num].ioaddr, dev);
-
- status = 0;
- cmd = ATA_CMD_IDENT; /*Device Identify Command */
- sata_outb (cmd, port[num].ioaddr.command_addr);
- sata_inb (port[num].ioaddr.altstatus_addr);
- udelay (10);
-
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000);
- if (status & ATA_ERR) {
- printf ("\ndevice not responding\n");
- port[num].dev_mask &= ~mask;
- return;
- }
-
- input_data (&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS);
-
- PRINTF ("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x"
- "86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49],
- iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86],
- iobuf[87], iobuf[88]);
-
- /* we require LBA and DMA support (bits 8 & 9 of word 49) */
- if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) {
- PRINTF ("ata%u: no dma/lba\n", num);
- }
- ata_dump_id (iobuf);
-
- if (ata_id_has_lba48 (iobuf)) {
- n_sectors = ata_id_u64 (iobuf, 100);
- } else {
- n_sectors = ata_id_u32 (iobuf, 60);
- }
- PRINTF ("no. of sectors %u\n", ata_id_u64 (iobuf, 100));
- PRINTF ("no. of sectors %u\n", ata_id_u32 (iobuf, 60));
-
- if (n_sectors == 0) {
- port[num].dev_mask &= ~mask;
- return;
- }
-
- sata_cpy (sata_dev_desc[devno].revision, iop->fw_rev,
- sizeof (sata_dev_desc[devno].revision));
- sata_cpy (sata_dev_desc[devno].vendor, iop->model,
- sizeof (sata_dev_desc[devno].vendor));
- sata_cpy (sata_dev_desc[devno].product, iop->serial_no,
- sizeof (sata_dev_desc[devno].product));
- strswab (sata_dev_desc[devno].revision);
- strswab (sata_dev_desc[devno].vendor);
-
- if ((iop->config & 0x0080) == 0x0080) {
- sata_dev_desc[devno].removable = 1;
- } else {
- sata_dev_desc[devno].removable = 0;
- }
-
- sata_dev_desc[devno].lba = iop->lba_capacity;
- PRINTF ("lba=0x%x", sata_dev_desc[devno].lba);
-
-#ifdef CONFIG_LBA48
- if (iop->command_set_2 & 0x0400) {
- sata_dev_desc[devno].lba48 = 1;
- lba = (unsigned long long) iop->lba48_capacity[0] |
- ((unsigned long long) iop->lba48_capacity[1] << 16) |
- ((unsigned long long) iop->lba48_capacity[2] << 32) |
- ((unsigned long long) iop->lba48_capacity[3] << 48);
- } else {
- sata_dev_desc[devno].lba48 = 0;
- }
-#endif
-
- /* assuming HD */
- sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
- sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
- sata_dev_desc[devno].lun = 0; /* just to fill something in... */
-}
-
-void
-set_Feature_cmd (int num, int dev)
-{
- u8 mask = 0x00, status = 0;
-
- if (dev == 0)
- mask = 0x01;
- else
- mask = 0x02;
-
- if (!(port[num].dev_mask & mask)) {
- PRINTF ("dev%d is not present on port#%d\n", dev, num);
- return;
- }
-
- dev_select (&port[num].ioaddr, dev);
-
- sata_outb (SETFEATURES_XFER, port[num].ioaddr.feature_addr);
- sata_outb (XFER_PIO_4, port[num].ioaddr.nsect_addr);
- sata_outb (0, port[num].ioaddr.lbal_addr);
- sata_outb (0, port[num].ioaddr.lbam_addr);
- sata_outb (0, port[num].ioaddr.lbah_addr);
-
- sata_outb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
- sata_outb (ATA_CMD_SETF, port[num].ioaddr.command_addr);
-
- udelay (50);
- msleep (150);
-
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000);
- if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) {
- printf ("Error : status 0x%02x\n", status);
- port[num].dev_mask &= ~mask;
- }
-}
-
-void
-sata_port (struct sata_ioports *ioport)
-{
- ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA;
- ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR;
- ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE;
- ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT;
- ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL;
- ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM;
- ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH;
- ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE;
- ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS;
- ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD;
-}
-
-int
-sata_devchk (struct sata_ioports *ioaddr, int dev)
-{
- u8 nsect, lbal;
-
- dev_select (ioaddr, dev);
-
- sata_outb (0x55, ioaddr->nsect_addr);
- sata_outb (0xaa, ioaddr->lbal_addr);
-
- sata_outb (0xaa, ioaddr->nsect_addr);
- sata_outb (0x55, ioaddr->lbal_addr);
-
- sata_outb (0x55, ioaddr->nsect_addr);
- sata_outb (0xaa, ioaddr->lbal_addr);
-
- nsect = sata_inb (ioaddr->nsect_addr);
- lbal = sata_inb (ioaddr->lbal_addr);
-
- if ((nsect == 0x55) && (lbal == 0xaa))
- return 1; /* we found a device */
- else
- return 0; /* nothing found */
-}
-
-void
-dev_select (struct sata_ioports *ioaddr, int dev)
-{
- u8 tmp = 0;
-
- if (dev == 0)
- tmp = ATA_DEVICE_OBS;
- else
- tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
- sata_outb (tmp, ioaddr->device_addr);
- sata_inb (ioaddr->altstatus_addr);
- udelay (5);