/* Common Flash Memory Interface (CFI) model.
   http://www.spansion.com/Support/AppNotes/CFI_Spec_AN_03.pdf
   http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf

   Copyright (C) 2010-2013 Free Software Foundation, Inc.
   Contributed by Analog Devices, Inc.

   This file is part of simulators.

   This program 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.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* TODO: support vendor query tables.  */

#include "cconfig.h"

#include <math.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <unistd.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

#include "sim-main.h"
#include "hw-base.h"
#include "hw-main.h"
#include "dv-cfi.h"

/* Flashes are simple state machines, so here we cover all the
   different states a device might be in at any particular time.  */
enum cfi_state
{
  CFI_STATE_READ,
  CFI_STATE_READ_ID,
  CFI_STATE_CFI_QUERY,
  CFI_STATE_PROTECT,
  CFI_STATE_STATUS,
  CFI_STATE_ERASE,
  CFI_STATE_WRITE,
  CFI_STATE_WRITE_BUFFER,
  CFI_STATE_WRITE_BUFFER_CONFIRM,
};

/* This is the structure that all CFI conforming devices must provided
   when asked for it.  This allows a single driver to dynamically support
   different flash geometries without having to hardcode specs.

   If you want to start mucking about here, you should just grab the
   CFI spec and review that (see top of this file for URIs).  */
struct cfi_query
{
  /* This is always 'Q' 'R' 'Y'.  */
  unsigned char qry[3];
  /* Primary vendor ID.  */
  unsigned char p_id[2];
  /* Primary query table address.  */
  unsigned char p_adr[2];
  /* Alternate vendor ID.  */
  unsigned char a_id[2];
  /* Alternate query table address.  */
  unsigned char a_adr[2];
  union
  {
    /* Voltage levels.  */
    unsigned char voltages[4];
    struct
    {
      /* Normal min voltage level.  */
      unsigned char vcc_min;
      /* Normal max voltage level.  */
      unsigned char vcc_max;
      /* Programming min volage level.  */
      unsigned char vpp_min;
      /* Programming max volage level.  */
      unsigned char vpp_max;
    };
  };
  union
  {
    /* Operational timeouts.  */
    unsigned char timeouts[8];
    struct
    {
      /* Typical timeout for writing a single "unit".  */
      unsigned char timeout_typ_unit_write;
      /* Typical timeout for writing a single "buffer".  */
      unsigned char timeout_typ_buf_write;
      /* Typical timeout for erasing a block.  */
      unsigned char timeout_typ_block_erase;
      /* Typical timeout for erasing the chip.  */
      unsigned char timeout_typ_chip_erase;
      /* Max timeout for writing a single "unit".  */
      unsigned char timeout_max_unit_write;
      /* Max timeout for writing a single "buffer".  */
      unsigned char timeout_max_buf_write;
      /* Max timeout for erasing a block.  */
      unsigned char timeout_max_block_erase;
      /* Max timeout for erasing the chip.  */
      unsigned char timeout_max_chip_erase;
    };
  };
  /* Flash size is 2^dev_size bytes.  */
  unsigned char dev_size;
  /* Flash device interface description.  */
  unsigned char iface_desc[2];
  /* Max length of a single buffer write is 2^max_buf_write_len bytes.  */
  unsigned char max_buf_write_len[2];
  /* Number of erase regions.  */
  unsigned char num_erase_regions;
  /* The erase regions would now be an array after this point, but since
     it is dynamic, we'll provide that from "struct cfi" when requested.  */
  /*unsigned char erase_region_info;*/
};

/* Flashes may have regions with different erase sizes.  There is one
   structure per erase region.  */
struct cfi_erase_region
{
  unsigned blocks;
  unsigned size;
  unsigned start;
  unsigned end;
};

struct cfi;

/* Flashes are accessed via commands -- you write a certain number to
   a special address to change the flash state and access info other
   than the data.  Diff companies have implemented their own command
   set.  This structure abstracts the different command sets so that
   we can support multiple ones with just a single sim driver.  */
struct cfi_cmdset
{
  unsigned id;
  void (*setup) (struct hw *me, struct cfi *cfi);
  bool (*write) (struct hw *me, struct cfi *cfi, const void *source,
		 unsigned offset, unsigned value, unsigned nr_bytes);
  bool (*read) (struct hw *me, struct cfi *cfi, void *dest,
		unsigned offset, unsigned shifted_offset, unsigned nr_bytes);
};

/* The per-flash state.  Much of this comes from the device tree which
   people declare themselves.  See top of attach_cfi_regs() for more
   info.  */
struct cfi
{
  unsigned width, dev_size, status;
  enum cfi_state state;
  unsigned char *data, *mmap;

  struct cfi_query query;
  const struct cfi_cmdset *cmdset;

  unsigned char *erase_region_info;
  struct cfi_erase_region *erase_regions;
};

/* Helpful strings which are used with HW_TRACE.  */
static const char * const state_names[] =
{
  "READ", "READ_ID", "CFI_QUERY", "PROTECT", "STATUS", "ERASE", "WRITE",
  "WRITE_BUFFER", "WRITE_BUFFER_CONFIRM",
};

/* Erase the block specified by the offset into the given CFI flash.  */
static void
cfi_erase_block (struct hw *me, struct cfi *cfi, unsigned offset)
{
  unsigned i;
  struct cfi_erase_region *region;

  /* If no erase regions, then we can only do whole chip erase.  */
  /* XXX: Is this within spec ?  Or must there always be at least one ?  */
  if (!cfi->query.num_erase_regions)
    memset (cfi->data, 0xff, cfi->dev_size);

  for (i = 0; i < cfi->query.num_erase_regions; ++i)
    {
      region = &cfi->erase_regions[i];

      if (offset >= region->end)
	continue;

      /* XXX: Does spec require the erase addr to be erase block aligned ?
	      Maybe this is check is overly cautious ...  */
      offset &= ~(region->size - 1);
      memset (cfi->data + offset, 0xff, region->size);
      break;
    }
}

/* Depending on the bus width, addresses might be bit shifted.  This
   helps us normalize everything without cluttering up the rest of
   the code.  */
static unsigned
cfi_unshift_addr (struct cfi *cfi, unsigned addr)
{
  switch (cfi->width)
    {
    case 4: addr >>= 1; /* fallthrough.  */
    case 2: addr >>= 1;
    }
  return addr;
}

/* CFI requires all values to be little endian in its structure, so
   this helper writes a 16bit value into a little endian byte buffer.  */
static void
cfi_encode_16bit (unsigned char *data, unsigned num)
{
  data[0] = num;
  data[1] = num >> 8;
}

/* The functions required to implement the Intel command set.  */

static bool
cmdset_intel_write (struct hw *me, struct cfi *cfi, const void *source,
		    unsigned offset, unsigned value, unsigned nr_bytes)
{
  switch (cfi->state)
    {
    case CFI_STATE_READ:
    case CFI_STATE_READ_ID:
      switch (value)
	{
	case INTEL_CMD_ERASE_BLOCK:
	  cfi->state = CFI_STATE_ERASE;
	  break;
	case INTEL_CMD_WRITE:
	case INTEL_CMD_WRITE_ALT:
	  cfi->state = CFI_STATE_WRITE;
	  break;
	case INTEL_CMD_STATUS_CLEAR:
	  cfi->status = INTEL_SR_DWS;
	  break;
	case INTEL_CMD_LOCK_SETUP:
	  cfi->state = CFI_STATE_PROTECT;
	  break;
	default:
	  return false;
	}
      break;

    case CFI_STATE_ERASE:
      if (value == INTEL_CMD_ERASE_CONFIRM)
	{
	  cfi_erase_block (me, cfi, offset);
	  cfi->status &= ~(INTEL_SR_PS | INTEL_SR_ES);
	}
      else
	cfi->status |= INTEL_SR_PS | INTEL_SR_ES;
      cfi->state = CFI_STATE_STATUS;
      break;

    case CFI_STATE_PROTECT:
      switch (value)
	{
	case INTEL_CMD_LOCK_BLOCK:
	case INTEL_CMD_UNLOCK_BLOCK:
	case INTEL_CMD_LOCK_DOWN_BLOCK:
	  /* XXX: Handle the command.  */
	  break;
	default:
	  /* Kick out.  */
	  cfi->status |= INTEL_SR_PS | INTEL_SR_ES;
	  break;
	}
      cfi->state = CFI_STATE_STATUS;
      break;

    default:
      return false;
    }

  return true;
}

static bool
cmdset_intel_read (struct hw *me, struct cfi *cfi, void *dest,
		   unsigned offset, unsigned shifted_offset, unsigned nr_bytes)
{
  unsigned char *sdest = dest;

  switch (cfi->state)
    {
    case CFI_STATE_STATUS:
    case CFI_STATE_ERASE:
      *sdest = cfi->status;
      break;

    case CFI_STATE_READ_ID:
      switch (shifted_offset & 0x1ff)
	{
	case 0x00:	/* Manufacturer Code.  */
	  cfi_encode_16bit (dest, INTEL_ID_MANU);
	  break;
	case 0x01:	/* Device ID Code.  */
	  /* XXX: Push to device tree ?  */
	  cfi_encode_16bit (dest, 0xad);
	  break;
	case 0x02:	/* Block lock state.  */
	  /* XXX: This is per-block ...  */
	  *sdest = 0x00;
	  break;
	case 0x05:	/* Read Configuration Register.  */
	  cfi_encode_16bit (dest, (1 << 15));
	  break;
	default:
	  return false;
	}
      break;

    default:
      return false;
    }

  return true;
}

static void
cmdset_intel_setup (struct hw *me, struct cfi *cfi)
{
  cfi->status = INTEL_SR_DWS;
}

static const struct cfi_cmdset cfi_cmdset_intel =
{
  CFI_CMDSET_INTEL, cmdset_intel_setup, cmdset_intel_write, cmdset_intel_read,
};

/* All of the supported command sets get listed here.  We then walk this
   array to see if the user requested command set is implemented.  */
static const struct cfi_cmdset * const cfi_cmdsets[] =
{
  &cfi_cmdset_intel,
};

/* All writes to the flash address space come here.  Using the state
   machine, we figure out what to do with this specific write.  All
   common code sits here and if there is a request we can't process,
   we hand it off to the command set-specific write function.  */
static unsigned
cfi_io_write_buffer (struct hw *me, const void *source, int space,
		     address_word addr, unsigned nr_bytes)
{
  struct cfi *cfi = hw_data (me);
  const unsigned char *ssource = source;
  enum cfi_state old_state;
  unsigned offset, shifted_offset, value;

  offset = addr & (cfi->dev_size - 1);
  shifted_offset = cfi_unshift_addr (cfi, offset);

  if (cfi->width != nr_bytes)
    {
      HW_TRACE ((me, "write 0x%08lx length %u does not match flash width %u",
		 (unsigned long) addr, nr_bytes, cfi->width));
      return nr_bytes;
    }

  if (cfi->state == CFI_STATE_WRITE)
    {
      /* NOR flash can only go from 1 to 0.  */
      unsigned i;

      HW_TRACE ((me, "program %#x length %u", offset, nr_bytes));

      for (i = 0; i < nr_bytes; ++i)
	cfi->data[offset + i] &= ssource[i];

      cfi->state = CFI_STATE_STATUS;

      return nr_bytes;
    }

  value = ssource[0];

  old_state = cfi->state;

  if (value == CFI_CMD_READ || value == CFI_CMD_RESET)
    {
      cfi->state = CFI_STATE_READ;
      goto done;
    }

  switch (cfi->state)
    {
    case CFI_STATE_READ:
    case CFI_STATE_READ_ID:
      if (value == CFI_CMD_CFI_QUERY)
	{
	  if (shifted_offset == CFI_ADDR_CFI_QUERY_START)
	    cfi->state = CFI_STATE_CFI_QUERY;
	  goto done;
	}

      if (value == CFI_CMD_READ_ID)
	{
	  cfi->state = CFI_STATE_READ_ID;
	  goto done;
	}

      /* Fall through.  */

    default:
      if (!cfi->cmdset->write (me, cfi, source, offset, value, nr_bytes))
	HW_TRACE ((me, "unhandled command %#x at %#x", value, offset));
      break;
    }

 done:
  HW_TRACE ((me, "write 0x%08lx command {%#x,%#x,%#x,%#x}; state %s -> %s",
	     (unsigned long) addr, ssource[0],
	     nr_bytes > 1 ? ssource[1] : 0,
	     nr_bytes > 2 ? ssource[2] : 0,
	     nr_bytes > 3 ? ssource[3] : 0,
	     state_names[old_state], state_names[cfi->state]));

  return nr_bytes;
}

/* All reads to the flash address space come here.  Using the state
   machine, we figure out what to return -- actual data stored in the
   flash, the CFI query structure, some status info, or something else ?
   Any requests that we can't handle are passed to the command set-
   specific read function.  */
static unsigned
cfi_io_read_buffer (struct hw *me, void *dest, int space,
		    address_word addr, unsigned nr_bytes)
{
  struct cfi *cfi = hw_data (me);
  unsigned char *sdest = dest;
  unsigned offset, shifted_offset;

  offset = addr & (cfi->dev_size - 1);
  shifted_offset = cfi_unshift_addr (cfi, offset);

  /* XXX: Is this OK to enforce ?  */
#if 0
  if (cfi->state != CFI_STATE_READ && cfi->width != nr_bytes)
    {
      HW_TRACE ((me, "read 0x%08lx length %u does not match flash width %u",
		 (unsigned long) addr, nr_bytes, cfi->width));
      return nr_bytes;
    }
#endif

  HW_TRACE ((me, "%s read 0x%08lx length %u",
	     state_names[cfi->state], (unsigned long) addr, nr_bytes));

  switch (cfi->state)
    {
    case CFI_STATE_READ:
      memcpy (dest, cfi->data + offset, nr_bytes);
      break;

    case CFI_STATE_CFI_QUERY:
      if (shifted_offset >= CFI_ADDR_CFI_QUERY_RESULT &&
	  shifted_offset < CFI_ADDR_CFI_QUERY_RESULT + sizeof (cfi->query) +
		     (cfi->query.num_erase_regions * 4))
	{
	  unsigned char *qry;

	  shifted_offset -= CFI_ADDR_CFI_QUERY_RESULT;
	  if (shifted_offset >= sizeof (cfi->query))
	    {
	      qry = cfi->erase_region_info;
	      shifted_offset -= sizeof (cfi->query);
	    }
	  else
	    qry = (void *) &cfi->query;

	  sdest[0] = qry[shifted_offset];
	  memset (sdest + 1, 0, nr_bytes - 1);

	  break;
	}

    default:
      if (!cfi->cmdset->read (me, cfi, dest, offset, shifted_offset, nr_bytes))
	HW_TRACE ((me, "unhandled state %s", state_names[cfi->state]));
      break;
    }

  return nr_bytes;
}

/* Clean up any state when this device is removed (e.g. when shutting
   down, or when reloading via gdb).  */
static void
cfi_delete_callback (struct hw *me)
{
#ifdef HAVE_MMAP
  struct cfi *cfi = hw_data (me);

  if (cfi->mmap)
    munmap (cfi->mmap, cfi->dev_size);
#endif
}

/* Helper function to easily add CFI erase regions to the existing set.  */
static void
cfi_add_erase_region (struct hw *me, struct cfi *cfi,
		      unsigned blocks, unsigned size)
{
  unsigned num_regions = cfi->query.num_erase_regions;
  struct cfi_erase_region *region;
  unsigned char *qry_region;

  /* Store for our own usage.  */
  region = &cfi->erase_regions[num_regions];
  region->blocks = blocks;
  region->size = size;
  if (num_regions == 0)
    region->start = 0;
  else
    region->start = region[-1].end;
  region->end = region->start + (blocks * size);

  /* Regions are 4 bytes long.  */
  qry_region = cfi->erase_region_info + 4 * num_regions;

  /* [0][1] = number erase blocks - 1 */
  if (blocks > 0xffff + 1)
    hw_abort (me, "erase blocks %u too big to fit into region info", blocks);
  cfi_encode_16bit (&qry_region[0], blocks - 1);

  /* [2][3] = block size / 256 bytes */
  if (size > 0xffff * 256)
    hw_abort (me, "erase size %u too big to fit into region info", size);
  cfi_encode_16bit (&qry_region[2], size / 256);

  /* Yet another region.  */
  cfi->query.num_erase_regions = num_regions + 1;
}

/* Device tree options:
     Required:
       .../reg <addr> <len>
       .../cmdset <primary; integer> [alt; integer]
     Optional:
       .../size <device size (must be pow of 2)>
       .../width <8|16|32>
       .../write_size <integer (must be pow of 2)>
       .../erase_regions <number blocks> <block size> \
                         [<number blocks> <block size> ...]
       .../voltage <vcc min> <vcc max> <vpp min> <vpp max>
       .../timeouts <typ unit write>  <typ buf write>  \
                    <typ block erase> <typ chip erase> \
                    <max unit write>  <max buf write>  \
                    <max block erase> <max chip erase>
       .../file <file> [ro|rw]
     Defaults:
       size: <len> from "reg"
       width: 8
       write_size: 0 (not supported)
       erase_region: 1 (can only erase whole chip)
       voltage: 0.0V (for all)
       timeouts: typ: 1µs, not supported, 1ms, not supported
                 max: 1µs, 1ms, 1ms, not supported

  TODO: Verify user args are valid (e.g. voltage is 8 bits).  */
static void
attach_cfi_regs (struct hw *me, struct cfi *cfi)
{
  address_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;
  bool fd_writable;
  int i, ret, fd;
  signed_cell ival;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");
  if (hw_find_property (me, "cmdset") == NULL)
    hw_abort (me, "Missing \"cmdset\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain three addr/size entries");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space, &attach_address, me);
  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);

  hw_attach_address (hw_parent (me),
		     0, attach_space, attach_address, attach_size, me);

  /* Extract the desired flash command set.  */
  ret = hw_find_integer_array_property (me, "cmdset", 0, &ival);
  if (ret != 1 && ret != 2)
    hw_abort (me, "\"cmdset\" property takes 1 or 2 entries");
  cfi_encode_16bit (cfi->query.p_id, ival);

  for (i = 0; i < ARRAY_SIZE (cfi_cmdsets); ++i)
    if (cfi_cmdsets[i]->id == ival)
      cfi->cmdset = cfi_cmdsets[i];
  if (cfi->cmdset == NULL)
    hw_abort (me, "cmdset %u not supported", ival);

  if (ret == 2)
    {
      hw_find_integer_array_property (me, "cmdset", 1, &ival);
      cfi_encode_16bit (cfi->query.a_id, ival);
    }

  /* Extract the desired device size.  */
  if (hw_find_property (me, "size"))
    cfi->dev_size = hw_find_integer_property (me, "size");
  else
    cfi->dev_size = attach_size;
  cfi->query.dev_size = log2 (cfi->dev_size);

  /* Extract the desired flash width.  */
  if (hw_find_property (me, "width"))
    {
      cfi->width = hw_find_integer_property (me, "width");
      if (cfi->width != 8 && cfi->width != 16 && cfi->width != 32)
	hw_abort (me, "\"width\" must be 8 or 16 or 32, not %u", cfi->width);
    }
  else
    /* Default to 8 bit.  */
    cfi->width = 8;
  /* Turn 8/16/32 into 1/2/4.  */
  cfi->width /= 8;

  /* Extract optional write buffer size.  */
  if (hw_find_property (me, "write_size"))
    {
      ival = hw_find_integer_property (me, "write_size");
      cfi_encode_16bit (cfi->query.max_buf_write_len, log2 (ival));
    }

  /* Extract optional erase regions.  */
  if (hw_find_property (me, "erase_regions"))
    {
      ret = hw_find_integer_array_property (me, "erase_regions", 0, &ival);
      if (ret % 2)
	hw_abort (me, "\"erase_regions\" must be specified in sets of 2");

      cfi->erase_region_info = HW_NALLOC (me, unsigned char, ret / 2);
      cfi->erase_regions = HW_NALLOC (me, struct cfi_erase_region, ret / 2);

      for (i = 0; i < ret; i += 2)
	{
	  unsigned blocks, size;

	  hw_find_integer_array_property (me, "erase_regions", i, &ival);
	  blocks = ival;

	  hw_find_integer_array_property (me, "erase_regions", i + 1, &ival);
	  size = ival;

	  cfi_add_erase_region (me, cfi, blocks, size);
	}
    }

  /* Extract optional voltages.  */
  if (hw_find_property (me, "voltage"))
    {
      unsigned num = ARRAY_SIZE (cfi->query.voltages);

      ret = hw_find_integer_array_property (me, "voltage", 0, &ival);
      if (ret > num)
	hw_abort (me, "\"voltage\" may have only %u arguments", num);

      for (i = 0; i < ret; ++i)
	{
	  hw_find_integer_array_property (me, "voltage", i, &ival);
	  cfi->query.voltages[i] = ival;
	}
    }

  /* Extract optional timeouts.  */
  if (hw_find_property (me, "timeout"))
    {
      unsigned num = ARRAY_SIZE (cfi->query.timeouts);

      ret = hw_find_integer_array_property (me, "timeout", 0, &ival);
      if (ret > num)
	hw_abort (me, "\"timeout\" may have only %u arguments", num);

      for (i = 0; i < ret; ++i)
	{
	  hw_find_integer_array_property (me, "timeout", i, &ival);
	  cfi->query.timeouts[i] = ival;
	}
    }

  /* Extract optional file.  */
  fd = -1;
  fd_writable = false;
  if (hw_find_property (me, "file"))
    {
      const char *file;

      ret = hw_find_string_array_property (me, "file", 0, &file);
      if (ret > 2)
	hw_abort (me, "\"file\" may take only one argument");
      if (ret == 2)
	{
	  const char *writable;

	  hw_find_string_array_property (me, "file", 1, &writable);
	  fd_writable = !strcmp (writable, "rw");
	}

      fd = open (file, fd_writable ? O_RDWR : O_RDONLY);
      if (fd < 0)
	hw_abort (me, "unable to read file `%s': %s", file, strerror (errno));
    }

  /* Figure out where our initial flash data is coming from.  */
  if (fd != -1 && fd_writable)
    {
#if defined (HAVE_MMAP) && defined (HAVE_POSIX_FALLOCATE)
      posix_fallocate (fd, 0, cfi->dev_size);

      cfi->mmap = mmap (NULL, cfi->dev_size,
			PROT_READ | (fd_writable ? PROT_WRITE : 0),
			MAP_SHARED, fd, 0);

      if (cfi->mmap == MAP_FAILED)
	cfi->mmap = NULL;
      else
	cfi->data = cfi->mmap;
#else
      sim_io_eprintf (hw_system (me),
		      "cfi: sorry, file write support requires mmap()\n");
#endif
    }
  if (!cfi->data)
    {
      size_t read_len;

      cfi->data = HW_NALLOC (me, unsigned char, cfi->dev_size);

      if (fd != -1)
	{
	  /* Use stdio to avoid EINTR issues with read().  */
	  FILE *fp = fdopen (fd, "r");

	  if (fp)
	    read_len = fread (cfi->data, 1, cfi->dev_size, fp);
	  else
	    read_len = 0;

	  /* Don't need to fclose() with fdopen("r").  */
	}
      else
	read_len = 0;

      memset (cfi->data, 0xff, cfi->dev_size - read_len);
    }

  close (fd);
}

/* Once we've been declared in the device tree, this is the main
   entry point. So allocate state, attach memory addresses, and
   all that fun stuff.  */
static void
cfi_finish (struct hw *me)
{
  struct cfi *cfi;

  cfi = HW_ZALLOC (me, struct cfi);

  set_hw_data (me, cfi);
  set_hw_io_read_buffer (me, cfi_io_read_buffer);
  set_hw_io_write_buffer (me, cfi_io_write_buffer);
  set_hw_delete (me, cfi_delete_callback);

  attach_cfi_regs (me, cfi);

  /* Initialize the CFI.  */
  cfi->state = CFI_STATE_READ;
  memcpy (cfi->query.qry, "QRY", 3);
  cfi->cmdset->setup (me, cfi);
}

/* Every device is required to declare this.  */
const struct hw_descriptor dv_cfi_descriptor[] =
{
  {"cfi", cfi_finish,},
  {NULL, NULL},
};
