/* 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-2021 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.  */

/* This must come before any other includes.  */
#include "defs.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 %" PRIiTC " 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},
};
