-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);
-}
-
-u8
-sata_busy_wait (struct sata_ioports *ioaddr, int bits, unsigned int max)
-{
- u8 status;
-
- do {
- udelay (1000);
- status = sata_chk_status (ioaddr);
- max--;
- } while ((status & bits) && (max > 0));
-
- return status;
-}
-
-u8
-sata_chk_status (struct sata_ioports * ioaddr)
-{
- return sata_inb (ioaddr->status_addr);
-}
-
-void
-msleep (int count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- udelay (1000);
-}
-
-ulong
-sata_read (int device, ulong blknr,lbaint_t blkcnt, void * buff)
-{
- ulong n = 0, *buffer = (ulong *)buff;
- u8 dev = 0, num = 0, mask = 0, status = 0;
-
-#ifdef CONFIG_LBA48
- unsigned char lba48 = 0;
-
- if (blknr & 0x0000fffff0000000) {
- if (!sata_dev_desc[devno].lba48) {
- printf ("Drive doesn't support 48-bit addressing\n");
- return 0;
- }
- /* more than 28 bits used, use 48bit mode */
- lba48 = 1;
- }
-#endif
- /*Port Number */
- num = device / CFG_SATA_DEVS_PER_BUS;
- /*dev on the port */
- if (device >= CFG_SATA_DEVS_PER_BUS)
- dev = device - CFG_SATA_DEVS_PER_BUS;
- else
- dev = device;
-
- 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 0;
- }
-
- /* Select device */
- dev_select (&port[num].ioaddr, dev);
-
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
- if (status & ATA_BUSY) {
- printf ("ata%u failed to respond\n", port[num].port_no);
- return n;
- }
- while (blkcnt-- > 0) {
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
- if (status & ATA_BUSY) {
- printf ("ata%u failed to respond\n", 0);
- return n;
- }
-#ifdef CONFIG_LBA48
- if (lba48) {
- /* write high bits */
- sata_outb (0, port[num].ioaddr.nsect_addr);
- sata_outb ((blknr >> 24) & 0xFF,
- port[num].ioaddr.lbal_addr);
- sata_outb ((blknr >> 32) & 0xFF,
- port[num].ioaddr.lbam_addr);
- sata_outb ((blknr >> 40) & 0xFF,
- port[num].ioaddr.lbah_addr);
- }
-#endif
- sata_outb (1, port[num].ioaddr.nsect_addr);
- sata_outb (((blknr) >> 0) & 0xFF,
- port[num].ioaddr.lbal_addr);
- sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
- sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
-
-#ifdef CONFIG_LBA48
- if (lba48) {
- sata_outb (ATA_LBA, port[num].ioaddr.device_addr);
- sata_outb (ATA_CMD_READ_EXT,
- port[num].ioaddr.command_addr);
- } else
-#endif
- {
- sata_outb (ATA_LBA | ((blknr >> 24) & 0xF),
- port[num].ioaddr.device_addr);
- sata_outb (ATA_CMD_READ,
- port[num].ioaddr.command_addr);
- }
-
- msleep (50);
- /*may take up to 4 sec */
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000);
-
- if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
- != ATA_STAT_DRQ) {
- u8 err = 0;
-
- printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
- device, (ulong) blknr, status);
- err = sata_inb (port[num].ioaddr.error_addr);
- printf ("Error reg = 0x%x\n", err);
- return (n);
- }
- input_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS);
- sata_inb (port[num].ioaddr.altstatus_addr);
- udelay (50);
-
- ++n;
- ++blknr;
- buffer += ATA_SECTORWORDS;
- }
- return n;
-}
-
-ulong
-sata_write (int device, ulong blknr,lbaint_t blkcnt, void * buff)
-{
- ulong n = 0, *buffer = (ulong *)buff;
- unsigned char status = 0, num = 0, dev = 0, mask = 0;
-
-#ifdef CONFIG_LBA48
- unsigned char lba48 = 0;
-
- if (blknr & 0x0000fffff0000000) {
- if (!sata_dev_desc[devno].lba48) {
- printf ("Drive doesn't support 48-bit addressing\n");
- return 0;
- }
- /* more than 28 bits used, use 48bit mode */
- lba48 = 1;
- }
-#endif
- /*Port Number */
- num = device / CFG_SATA_DEVS_PER_BUS;
- /*dev on the Port */
- if (device >= CFG_SATA_DEVS_PER_BUS)
- dev = device - CFG_SATA_DEVS_PER_BUS;
- else
- dev = device;
-
- if (dev == 0)
- mask = 0x01;
- else
- mask = 0x02;
-
- /* Select device */
- dev_select (&port[num].ioaddr, dev);
-
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
- if (status & ATA_BUSY) {
- printf ("ata%u failed to respond\n", port[num].port_no);
- return n;
- }
-
- while (blkcnt-- > 0) {
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
- if (status & ATA_BUSY) {
- printf ("ata%u failed to respond\n",
- port[num].port_no);
- return n;
- }
-#ifdef CONFIG_LBA48
- if (lba48) {
- /* write high bits */
- sata_outb (0, port[num].ioaddr.nsect_addr);
- sata_outb ((blknr >> 24) & 0xFF,
- port[num].ioaddr.lbal_addr);
- sata_outb ((blknr >> 32) & 0xFF,
- port[num].ioaddr.lbam_addr);
- sata_outb ((blknr >> 40) & 0xFF,
- port[num].ioaddr.lbah_addr);
- }
-#endif
- sata_outb (1, port[num].ioaddr.nsect_addr);
- sata_outb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr);
- sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
- sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
-#ifdef CONFIG_LBA48
- if (lba48) {
- sata_outb (ATA_LBA, port[num].ioaddr.device_addr);
- sata_outb (ATA_CMD_WRITE_EXT,
- port[num].ioaddr.command_addr);
- } else
-#endif
- {
- sata_outb (ATA_LBA | ((blknr >> 24) & 0xF),
- port[num].ioaddr.device_addr);
- sata_outb (ATA_CMD_WRITE,
- port[num].ioaddr.command_addr);
- }
-
- msleep (50);
- /*may take up to 4 sec */
- status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000);
- if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
- != ATA_STAT_DRQ) {
- printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
- device, (ulong) blknr, status);
- return (n);
- }
-
- output_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS);
- sata_inb (port[num].ioaddr.altstatus_addr);
- udelay (50);
-
- ++n;
- ++blknr;
- buffer += ATA_SECTORWORDS;
- }
- return n;
-}
-
-block_dev_desc_t *sata_get_dev (int dev);
-
-block_dev_desc_t *
-sata_get_dev (int dev)
-{
- return ((block_dev_desc_t *) & sata_dev_desc[dev]);
-}
-
-int
-do_sata (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
-{