/* ata.c - ATA disk access.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2007, 2008, 2009  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/ata.h>
#include <grub/dl.h>
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/scsi.h>

GRUB_MOD_LICENSE ("GPLv3+");

static grub_ata_dev_t grub_ata_dev_list;

/* Byteorder has to be changed before strings can be read.  */
static void
grub_ata_strncpy (grub_uint16_t *dst16, grub_uint16_t *src16, grub_size_t len)
{
  unsigned int i;

  for (i = 0; i < len / 2; i++)
    *(dst16++) = grub_swap_bytes16 (*(src16++));
  *dst16 = 0;
}

static void
grub_ata_dumpinfo (struct grub_ata *dev, grub_uint16_t *info)
{
  grub_uint16_t text[21];

  /* The device information was read, dump it for debugging.  */
  grub_ata_strncpy (text, info + 10, 20);
  grub_dprintf ("ata", "Serial: %s\n", (char *) text);
  grub_ata_strncpy (text, info + 23, 8);
  grub_dprintf ("ata", "Firmware: %s\n", (char *) text);
  grub_ata_strncpy (text, info + 27, 40);
  grub_dprintf ("ata", "Model: %s\n", (char *) text);

  if (! dev->atapi)
    {
      grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
      grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size);
      grub_dprintf ("ata", "Sector size: %u\n", 1U << dev->log_sector_size);
    }
}

static grub_err_t
grub_atapi_identify (struct grub_ata *dev)
{
  struct grub_disk_ata_pass_through_parms parms;
  grub_uint16_t *info;
  grub_err_t err;

  info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
  if (! info)
    return grub_errno;

  grub_memset (&parms, 0, sizeof (parms));
  parms.taskfile.disk = 0xE0;
  parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE;
  parms.size = GRUB_DISK_SECTOR_SIZE;
  parms.buffer = info;

  err = dev->dev->readwrite (dev, &parms, *dev->present);
  if (err)
    {
      *dev->present = 0;
      return err;
    }

  if (parms.size != GRUB_DISK_SECTOR_SIZE)
    {
      *dev->present = 0;
      return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
			 "device cannot be identified");
    }

  dev->atapi = 1;

  grub_ata_dumpinfo (dev, info);

  grub_free (info);

  return GRUB_ERR_NONE;
}

static grub_err_t
grub_ata_identify (struct grub_ata *dev)
{
  struct grub_disk_ata_pass_through_parms parms;
  grub_uint64_t *info64;
  grub_uint32_t *info32;
  grub_uint16_t *info16;
  grub_err_t err;

  if (dev->atapi)
    return grub_atapi_identify (dev);

  info64 = grub_malloc (GRUB_DISK_SECTOR_SIZE);
  info32 = (grub_uint32_t *) info64;
  info16 = (grub_uint16_t *) info64;
  if (! info16)
    return grub_errno;

  grub_memset (&parms, 0, sizeof (parms));
  parms.buffer = info16;
  parms.size = GRUB_DISK_SECTOR_SIZE;
  parms.taskfile.disk = 0xE0;

  parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_DEVICE;

  err = dev->dev->readwrite (dev, &parms, *dev->present);

  if (err || parms.size != GRUB_DISK_SECTOR_SIZE)
    {
      grub_uint8_t sts = parms.taskfile.status;
      grub_free (info16);
      grub_errno = GRUB_ERR_NONE;
      if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ
		   | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR
	  && (parms.taskfile.error & 0x04 /* ABRT */))
	/* Device without ATA IDENTIFY, try ATAPI.  */
	return grub_atapi_identify (dev);

      else if (sts == 0x00)
	{
	  *dev->present = 0;
	  /* No device, return error but don't print message.  */
	  return GRUB_ERR_UNKNOWN_DEVICE;
	}
      else
	{
	  *dev->present = 0;
	  /* Other Error.  */
	  return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
			     "device cannot be identified");
	}
    }

  /* Now it is certain that this is not an ATAPI device.  */
  dev->atapi = 0;

  /* CHS is always supported.  */
  dev->addr = GRUB_ATA_CHS;

  /* Check if LBA is supported.  */
  if (info16[49] & grub_cpu_to_le16_compile_time ((1 << 9)))
    {
      /* Check if LBA48 is supported.  */
      if (info16[83] & grub_cpu_to_le16_compile_time ((1 << 10)))
	dev->addr = GRUB_ATA_LBA48;
      else
	dev->addr = GRUB_ATA_LBA;
    }

  /* Determine the amount of sectors.  */
  if (dev->addr != GRUB_ATA_LBA48)
    dev->size = grub_le_to_cpu32 (info32[30]);
  else
    dev->size = grub_le_to_cpu64 (info64[25]);

  if (info16[106] & grub_cpu_to_le16_compile_time ((1 << 12)))
    {
      grub_uint32_t secsize;
      secsize = grub_le_to_cpu32 (grub_get_unaligned32 (&info16[117]));
      if (secsize & (secsize - 1) || !secsize
	  || secsize > 1048576)
	secsize = 256;
      for (dev->log_sector_size = 0;
	   (1U << dev->log_sector_size) < secsize;
	   dev->log_sector_size++);
      dev->log_sector_size++;
    }
  else
    dev->log_sector_size = 9;

  /* Read CHS information.  */
  dev->cylinders = grub_le_to_cpu16 (info16[1]);
  dev->heads = grub_le_to_cpu16 (info16[3]);
  dev->sectors_per_track = grub_le_to_cpu16 (info16[6]);

  grub_ata_dumpinfo (dev, info16);

  grub_free (info16);

  return 0;
}

static grub_err_t
grub_ata_setaddress (struct grub_ata *dev,
		     struct grub_disk_ata_pass_through_parms *parms,
		     grub_disk_addr_t sector,
		     grub_size_t size,
		     grub_ata_addressing_t addressing)
{
  switch (addressing)
    {
    case GRUB_ATA_CHS:
      {
	unsigned int cylinder;
	unsigned int head;
	unsigned int sect;

	if (dev->sectors_per_track == 0
	    || dev->heads == 0)
	  return grub_error (GRUB_ERR_OUT_OF_RANGE,
			     "sector %d cannot be addressed "
			     "using CHS addressing", sector);

	/* Calculate the sector, cylinder and head to use.  */
	sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
	cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)
		    / dev->heads);
	head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads;

	if (sect > dev->sectors_per_track
	    || cylinder > dev->cylinders
	    || head > dev->heads)
	  return grub_error (GRUB_ERR_OUT_OF_RANGE,
			     "sector %d cannot be addressed "
			     "using CHS addressing", sector);
	
	parms->taskfile.disk = 0xE0 | head;
	parms->taskfile.sectnum = sect;
	parms->taskfile.cyllsb = cylinder & 0xFF;
	parms->taskfile.cylmsb = cylinder >> 8;

	break;
      }

    case GRUB_ATA_LBA:
      if (size == 256)
	size = 0;
      parms->taskfile.disk = 0xE0 | ((sector >> 24) & 0x0F);

      parms->taskfile.sectors = size;
      parms->taskfile.lba_low = sector & 0xFF;
      parms->taskfile.lba_mid = (sector >> 8) & 0xFF;
      parms->taskfile.lba_high = (sector >> 16) & 0xFF;
      break;

    case GRUB_ATA_LBA48:
      if (size == 65536)
	size = 0;

      parms->taskfile.disk = 0xE0;

      /* Set "Previous".  */
      parms->taskfile.sectors = size & 0xFF;
      parms->taskfile.lba_low = sector & 0xFF;
      parms->taskfile.lba_mid = (sector >> 8) & 0xFF;
      parms->taskfile.lba_high = (sector >> 16) & 0xFF;

      /* Set "Current".  */
      parms->taskfile.sectors48 = (size >> 8) & 0xFF;
      parms->taskfile.lba48_low = (sector >> 24) & 0xFF;
      parms->taskfile.lba48_mid = (sector >> 32) & 0xFF;
      parms->taskfile.lba48_high = (sector >> 40) & 0xFF;

      break;
    }

  return GRUB_ERR_NONE;
}

static grub_err_t
grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
		    grub_size_t size, char *buf, int rw)
{
  struct grub_ata *ata = disk->data;

  grub_ata_addressing_t addressing = ata->addr;
  grub_size_t batch;
  int cmd, cmd_write;
  grub_size_t nsectors = 0;

  grub_dprintf("ata", "grub_ata_readwrite (size=%llu, rw=%d)\n",
	       (unsigned long long) size, rw);

  if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
    {
      if (ata->dma)
	{
	  cmd = GRUB_ATA_CMD_READ_SECTORS_DMA_EXT;
	  cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_DMA_EXT;
	}
      else
	{
	  cmd = GRUB_ATA_CMD_READ_SECTORS_EXT;
	  cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT;
	}
    }
  else
    {
      if (addressing == GRUB_ATA_LBA48)
	addressing = GRUB_ATA_LBA;
      if (ata->dma)
	{
	  cmd = GRUB_ATA_CMD_READ_SECTORS_DMA;
	  cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_DMA;
	}
      else
	{
	  cmd = GRUB_ATA_CMD_READ_SECTORS;
	  cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
	}
    }

  if (addressing != GRUB_ATA_CHS)
    batch = 256;
  else
    batch = 1;

  while (nsectors < size)
    {
      struct grub_disk_ata_pass_through_parms parms;
      grub_err_t err;

      if (size - nsectors < batch)
	batch = size - nsectors;

      grub_dprintf("ata", "rw=%d, sector=%llu, batch=%llu\n", rw, (unsigned long long) sector, (unsigned long long) batch);
      grub_memset (&parms, 0, sizeof (parms));
      grub_ata_setaddress (ata, &parms, sector, batch, addressing);
      parms.taskfile.cmd = (! rw ? cmd : cmd_write);
      parms.buffer = buf;
      parms.size = batch << ata->log_sector_size;
      parms.write = rw;
      if (ata->dma)
	parms.dma = 1;
  
      err = ata->dev->readwrite (ata, &parms, 0);
      if (err)
	return err;
      if (parms.size != batch << ata->log_sector_size)
	return grub_error (GRUB_ERR_READ_ERROR, "incomplete read");
      buf += batch << ata->log_sector_size;
      sector += batch;
      nsectors += batch;
    }

  return GRUB_ERR_NONE;
}



static inline void
grub_ata_real_close (struct grub_ata *ata)
{
  if (ata->dev->close)
    ata->dev->close (ata);
}

static struct grub_ata *
grub_ata_real_open (int id, int bus)
{
  struct grub_ata *ata;
  grub_ata_dev_t p;

  ata = grub_zalloc (sizeof (*ata));
  if (!ata)
    return NULL;
  for (p = grub_ata_dev_list; p; p = p->next)
    {
      grub_err_t err;
      if (p->open (id, bus, ata))
	{
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}
      ata->dev = p;
      /* Use the IDENTIFY DEVICE command to query the device.  */
      err = grub_ata_identify (ata);
      if (err)
	{
	  if (!grub_errno)
	    grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATA device");
	  grub_free (ata);
	  return NULL;
	}
      return ata;
    }
  grub_free (ata);
  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATA device");
  return NULL;
}

/* Context for grub_ata_iterate.  */
struct grub_ata_iterate_ctx
{
  grub_disk_dev_iterate_hook_t hook;
  void *hook_data;
};

/* Helper for grub_ata_iterate.  */
static int
grub_ata_iterate_iter (int id, int bus, void *data)
{
  struct grub_ata_iterate_ctx *ctx = data;
  struct grub_ata *ata;
  int ret;
  char devname[40];

  ata = grub_ata_real_open (id, bus);

  if (!ata)
    {
      grub_errno = GRUB_ERR_NONE;
      return 0;
    }
  if (ata->atapi)
    {
      grub_ata_real_close (ata);
      return 0;
    }
  grub_snprintf (devname, sizeof (devname), 
		 "%s%d", grub_scsi_names[id], bus);
  ret = ctx->hook (devname, ctx->hook_data);
  grub_ata_real_close (ata);
  return ret;
}

static int
grub_ata_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
		  grub_disk_pull_t pull)
{
  struct grub_ata_iterate_ctx ctx = { hook, hook_data };
  grub_ata_dev_t p;
  
  for (p = grub_ata_dev_list; p; p = p->next)
    if (p->iterate && p->iterate (grub_ata_iterate_iter, &ctx, pull))
      return 1;
  return 0;
}

static grub_err_t
grub_ata_open (const char *name, grub_disk_t disk)
{
  unsigned id, bus;
  struct grub_ata *ata;

  for (id = 0; id < GRUB_SCSI_NUM_SUBSYSTEMS; id++)
    if (grub_strncmp (grub_scsi_names[id], name,
		      grub_strlen (grub_scsi_names[id])) == 0
	&& grub_isdigit (name[grub_strlen (grub_scsi_names[id])]))
      break;
  if (id == GRUB_SCSI_NUM_SUBSYSTEMS)
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
  bus = grub_strtoul (name + grub_strlen (grub_scsi_names[id]), 0, 0);
  ata = grub_ata_real_open (id, bus);
  if (!ata)
    return grub_errno;

  if (ata->atapi)
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");

  disk->total_sectors = ata->size;
  disk->max_agglomerate = (ata->maxbuffer >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS));
  if (disk->max_agglomerate > (256U >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - ata->log_sector_size)))
    disk->max_agglomerate = (256U >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - ata->log_sector_size));

  disk->log_sector_size = ata->log_sector_size;

  disk->id = grub_make_scsi_id (id, bus, 0);

  disk->data = ata;

  return 0;
}

static void
grub_ata_close (grub_disk_t disk)
{
  struct grub_ata *ata = disk->data;
  grub_ata_real_close (ata);
}

static grub_err_t
grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector,
	       grub_size_t size, char *buf)
{
  return grub_ata_readwrite (disk, sector, size, buf, 0);
}

static grub_err_t
grub_ata_write (grub_disk_t disk,
		grub_disk_addr_t sector,
		grub_size_t size,
		const char *buf)
{
  return grub_ata_readwrite (disk, sector, size, (char *) buf, 1);
}

static struct grub_disk_dev grub_atadisk_dev =
  {
    .name = "ATA",
    .id = GRUB_DISK_DEVICE_ATA_ID,
    .iterate = grub_ata_iterate,
    .open = grub_ata_open,
    .close = grub_ata_close,
    .read = grub_ata_read,
    .write = grub_ata_write,
    .next = 0
  };



/* ATAPI code.  */

static grub_err_t
grub_atapi_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
		 grub_size_t size, char *buf)
{
  struct grub_ata *dev = scsi->data;
  struct grub_disk_ata_pass_through_parms parms;
  grub_err_t err;

  grub_dprintf("ata", "grub_atapi_read (size=%llu)\n", (unsigned long long) size);
  grub_memset (&parms, 0, sizeof (parms));

  parms.taskfile.disk = 0;
  parms.taskfile.features = 0;
  parms.taskfile.atapi_ireason = 0;
  parms.taskfile.atapi_cnthigh = size >> 8;
  parms.taskfile.atapi_cntlow = size & 0xff;
  parms.taskfile.cmd = GRUB_ATA_CMD_PACKET;
  parms.cmd = cmd;
  parms.cmdsize = cmdsize;

  parms.size = size;
  parms.buffer = buf;
  
  err = dev->dev->readwrite (dev, &parms, 0);
  if (err)
    return err;

  if (parms.size != size)
    return grub_error (GRUB_ERR_READ_ERROR, "incomplete ATAPI read");
  return GRUB_ERR_NONE;
}

static grub_err_t
grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
		  grub_size_t cmdsize __attribute__((unused)),
		  char *cmd __attribute__((unused)),
		  grub_size_t size __attribute__((unused)),
		  const char *buf __attribute__((unused)))
{
  // XXX: scsi.mod does not use write yet.
  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ATAPI write not implemented");
}

static grub_err_t
grub_atapi_open (int id, int bus, struct grub_scsi *scsi)
{
  struct grub_ata *ata;

  ata = grub_ata_real_open (id, bus);
  if (!ata)
    return grub_errno;
    
  if (! ata->atapi)
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");

  scsi->data = ata;
  scsi->luns = 1;

  return GRUB_ERR_NONE;
}

/* Context for grub_atapi_iterate.  */
struct grub_atapi_iterate_ctx
{
  grub_scsi_dev_iterate_hook_t hook;
  void *hook_data;
};

/* Helper for grub_atapi_iterate.  */
static int
grub_atapi_iterate_iter (int id, int bus, void *data)
{
  struct grub_atapi_iterate_ctx *ctx = data;
  struct grub_ata *ata;
  int ret;

  ata = grub_ata_real_open (id, bus);

  if (!ata)
    {
      grub_errno = GRUB_ERR_NONE;
      return 0;
    }
  if (!ata->atapi)
    {
      grub_ata_real_close (ata);
      return 0;
    }
  ret = ctx->hook (id, bus, 1, ctx->hook_data);
  grub_ata_real_close (ata);
  return ret;
}

static int
grub_atapi_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
		    grub_disk_pull_t pull)
{
  struct grub_atapi_iterate_ctx ctx = { hook, hook_data };
  grub_ata_dev_t p;
  
  for (p = grub_ata_dev_list; p; p = p->next)
    if (p->iterate && p->iterate (grub_atapi_iterate_iter, &ctx, pull))
      return 1;
  return 0;
}

static void
grub_atapi_close (grub_scsi_t disk)
{
  struct grub_ata *ata = disk->data;
  grub_ata_real_close (ata);
}


void
grub_ata_dev_register (grub_ata_dev_t dev)
{
  dev->next = grub_ata_dev_list;
  grub_ata_dev_list = dev;
}

void
grub_ata_dev_unregister (grub_ata_dev_t dev)
{
  grub_ata_dev_t *p, q;

  for (p = &grub_ata_dev_list, q = *p; q; p = &(q->next), q = q->next)
    if (q == dev)
      {
        *p = q->next;
	break;
      }
}

static struct grub_scsi_dev grub_atapi_dev =
  {
    .iterate = grub_atapi_iterate,
    .open = grub_atapi_open,
    .close = grub_atapi_close,
    .read = grub_atapi_read,
    .write = grub_atapi_write,
    .next = 0
  };



GRUB_MOD_INIT(ata)
{
  grub_disk_dev_register (&grub_atadisk_dev);

  /* ATAPI devices are handled by scsi.mod.  */
  grub_scsi_dev_register (&grub_atapi_dev);
}

GRUB_MOD_FINI(ata)
{
  grub_scsi_dev_unregister (&grub_atapi_dev);
  grub_disk_dev_unregister (&grub_atadisk_dev);
}
