static void
parse_general_definitions(struct drm_i915_private *dev_priv,
			  struct bdb_header *bdb)
{
	struct bdb_general_definitions *general;
	const int crt_bus_map_table[] = {
		GPIOB,
		GPIOA,
		GPIOC,
		GPIOD,
		GPIOE,
		GPIOF,
	};

	/* Set sensible defaults in case we can't find the general block
	   or it is the wrong chipset */
	dev_priv->crt_ddc_bus = -1;

	general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
	if (general) {
		u16 block_size = get_blocksize(general);
		if (block_size >= sizeof(*general)) {
			int bus_pin = general->crt_ddc_gmbus_pin;
			DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
			if ((bus_pin >= 1) && (bus_pin <= 6)) {
				dev_priv->crt_ddc_bus =
					crt_bus_map_table[bus_pin-1];
			}
		} else {
			DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
				  block_size);
		}
	}
}
char *blkdev_read_block(UID id, block_datastr *ptr) 
{
	int i,j, size;
	size = get_blocksize(ptr);

	j=0;
	while(size > 0){
		if(size > BLOCK_SIZE)
		{
			for(i=0; i<BLOCK_SIZE; i++)
			{
				tempblock[i] = ptr->data[i];
			}
			ptr = (unsigned int)(ptr->next)&0xFFFFFFFE;
			j+=i;
		}
		else
		{
			for(i=0; i<size; i++)
			{
				tempblock[i+j] = ptr->data[i];
			}
		}
		size = size - BLOCK_SIZE;
	}

	tempblock[i+j] = '\0';
	return tempblock;
}
static void
parse_general_definitions(struct drm_i915_private *dev_priv,
			  struct bdb_header *bdb)
{
	struct bdb_general_definitions *general;
	struct child_device_config *device_config;

	general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
	if (general) {
		u16 block_size = get_blocksize(general);
		DRM_DEBUG_KMS("block size of block 2 is %d\n", block_size);
		if (block_size >= sizeof(*general)) {
			int bus_pin = general->crt_ddc_gmbus_pin;
			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
			if (intel_gmbus_is_port_valid(bus_pin))
				dev_priv->vbt.crt_ddc_pin = bus_pin;
			device_config = (struct child_device_config *) &general->devices[0];
			if (device_config->device_type == MIPI_SUPPORT) {
				dev_priv->is_mipi_from_vbt = true;
				DRM_DEBUG_KMS("In VBT, MIPI is selected as LFP\n");
			} else if (device_config->device_type == EDP_SUPPORT) {
				dev_priv->is_mipi_from_vbt = false;
				DRM_DEBUG_KMS("In VBT, EDP is selected as LFP\n");
			}
		} else {
			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
				      block_size);
		}
	}
}
static void
parse_device_mapping(struct drm_i915_private *dev_priv,
		       struct bdb_header *bdb)
{
	struct bdb_general_definitions *p_defs;
	struct child_device_config *p_child, *child_dev_ptr;
	int i, child_device_num, count;
	u16	block_size;

	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
	if (!p_defs) {
		DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
		return;
	}
	if (p_defs->child_dev_size != sizeof(*p_child)) {
		
		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
		return;
	}
	
	block_size = get_blocksize(p_defs);
	
	child_device_num = (block_size - sizeof(*p_defs)) /
				sizeof(*p_child);
	count = 0;
	
	for (i = 0; i < child_device_num; i++) {
		p_child = &(p_defs->devices[i]);
		if (!p_child->device_type) {
			
			continue;
		}
		count++;
	}
	if (!count) {
		DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
		return;
	}
	dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL);
	if (!dev_priv->child_dev) {
		DRM_DEBUG_KMS("No memory space for child device\n");
		return;
	}

	dev_priv->child_dev_num = count;
	count = 0;
	for (i = 0; i < child_device_num; i++) {
		p_child = &(p_defs->devices[i]);
		if (!p_child->device_type) {
			
			continue;
		}
		child_dev_ptr = dev_priv->child_dev + count;
		count++;
		memcpy((void *)child_dev_ptr, (void *)p_child,
					sizeof(*p_child));
	}
	return;
}
Beispiel #5
0
static void setup(void)
{
    tst_tmpdir();

    fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0700);

    get_blocksize();
}
Beispiel #6
0
int main(int argc, char *argv[])
{
    char *dbg = NULL;
#ifdef ENABLE_CRYPTO
    int rnd;
    char *ckpasswd;
    char *p;
#endif
    if (argc < 2)
        usage(argv[0]);

    debug=0;
    setvbuf(stdout, (char*)NULL, _IONBF, 0);
    get_opts(argc,argv);
    if ( NULL == chkoptions.configfile ) {
        usage(argv[0]);
    }
    if (-1 == r_env_cfg(chkoptions.configfile))
        usage(argv[0]);
    parseconfig(0);
    dbg = getenv("DEBUG");
    if (NULL != dbg)
        debug = atoi(dbg);

    if ( 0 == chkoptions.fast ) {
       printf("Running lessfsck on a mounted filesystem will corrupt the databases.\n");
       printf("Press ctrl-c within 5 secondes when you are not sure that the filesystem is unmounted.\n");
       sleep(5);
    }
    BLKSIZE=get_blocksize();
    if ( NULL != config->blockdatabs ){
       printf("**************************************************\n");
       printf("* Running lessfsck on a tc data store.           *\n");
       printf("**************************************************\n");
       lessfsck_tc();
    } else {
       printf("**************************************************\n");
       printf("* Running lessfsck on a file_io data store.      *\n");
       printf("**************************************************\n");
       lessfsck_file_io();
    }
    printf("\nDone.\n");
    clear_dirty();
    tc_close(0);
#ifdef ENABLE_CRYPTO
    if (config->encryptdata) {
        free(config->passwd);
        free(config->iv);
    }
#endif
    free(config);
    exit(0);
}
Beispiel #7
0
void setup(void)
{
	/* Create temporary directories */
	TEST_PAUSE;

	tst_tmpdir();

	sprintf(fname, "tfile_sparse_%d", getpid());
	fd = open(fname, O_RDWR | O_CREAT, 0700);
	if (fd == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "open(%s) failed", fname);
	get_blocksize(fd);
	populate_file();
	file_seek(BLOCKS_WRITTEN + HOLE_SIZE_IN_BLOCKS);	/* create holes */
	populate_file();
	file_seek(0);		/* Rewind */
}
static void
parse_general_definitions(struct drm_i915_private *dev_priv,
			  struct bdb_header *bdb)
{
	struct bdb_general_definitions *general;

	general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
	if (general) {
		u16 block_size = get_blocksize(general);
		if (block_size >= sizeof(*general)) {
			int bus_pin = general->crt_ddc_gmbus_pin;
			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
			if (bus_pin >= 1 && bus_pin <= 6)
				dev_priv->crt_ddc_pin = bus_pin;
		} else {
			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
				  block_size);
		}
	}
}
Beispiel #9
0
/*****************************************************************************
 * Performs all one time setup for this test. This function is
 * used to create temporary dirs and temporary files
 * that may be used in the course of this test
 ******************************************************************************/
void setup(void)
{
	/* Create temporary directories */
	TEST_PAUSE;

	tst_tmpdir();

	sprintf(fname_mode1, "tfile_mode1_%d", getpid());
	fd_mode1 = open(fname_mode1, O_RDWR | O_CREAT, 0700);
	if (fd_mode1 == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "open(%s, O_RDWR) failed",
			 fname_mode1);
	get_blocksize(fd_mode1);
	populate_files(fd_mode1);

	sprintf(fname_mode2, "tfile_mode2_%d", getpid());
	fd_mode2 = open(fname_mode2, O_RDWR | O_CREAT, 0700);
	if (fd_mode2 == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "open(%s, O_RDWR) failed",
			 fname_mode2);
	populate_files(fd_mode2);
}
static void
parse_device_mapping(struct drm_i915_private *dev_priv,
		       struct bdb_header *bdb)
{
	struct bdb_general_definitions *p_defs;
	struct child_device_config *p_child, *child_dev_ptr;
	int i, child_device_num, count;
	u16	block_size;

	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
	if (!p_defs) {
		DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
		return;
	}
	/* judge whether the size of child device meets the requirements.
	 * If the child device size obtained from general definition block
	 * is different with sizeof(struct child_device_config), skip the
	 * parsing of sdvo device info
	 */
	if (p_defs->child_dev_size != sizeof(*p_child)) {
		/* different child dev size . Ignore it */
		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
		return;
	}
	/* get the block size of general definitions */
	block_size = get_blocksize(p_defs);
	/* get the number of child device */
	child_device_num = (block_size - sizeof(*p_defs)) /
				sizeof(*p_child);
	count = 0;
	/* get the number of child device that is present */
	for (i = 0; i < child_device_num; i++) {
		p_child = &(p_defs->devices[i]);
		if (!p_child->device_type) {
			/* skip the device block if device type is invalid */
			continue;
		}
		count++;
	}
	if (!count) {
		DRM_DEBUG_KMS("no child dev is parsed from VBT \n");
		return;
	}
	dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
	if (!dev_priv->child_dev) {
		DRM_DEBUG_KMS("No memory space for child device\n");
		return;
	}

	dev_priv->child_dev_num = count;
	count = 0;
	for (i = 0; i < child_device_num; i++) {
		p_child = &(p_defs->devices[i]);
		if (!p_child->device_type) {
			/* skip the device block if device type is invalid */
			continue;
		}
		child_dev_ptr = dev_priv->child_dev + count;
		count++;
		memcpy((void *)child_dev_ptr, (void *)p_child,
					sizeof(*p_child));
	}
	return;
}
static void
parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
			  struct bdb_header *bdb)
{
	struct sdvo_device_mapping *p_mapping;
	struct bdb_general_definitions *p_defs;
	struct child_device_config *p_child;
	int i, child_device_num, count;
	u16	block_size;

	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
	if (!p_defs) {
		DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
		return;
	}
	/* judge whether the size of child device meets the requirements.
	 * If the child device size obtained from general definition block
	 * is different with sizeof(struct child_device_config), skip the
	 * parsing of sdvo device info
	 */
	if (p_defs->child_dev_size != sizeof(*p_child)) {
		/* different child dev size . Ignore it */
		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
		return;
	}
	/* get the block size of general definitions */
	block_size = get_blocksize(p_defs);
	/* get the number of child device */
	child_device_num = (block_size - sizeof(*p_defs)) /
				sizeof(*p_child);
	count = 0;
	for (i = 0; i < child_device_num; i++) {
		p_child = &(p_defs->devices[i]);
		if (!p_child->device_type) {
			/* skip the device block if device type is invalid */
			continue;
		}
		if (p_child->slave_addr != SLAVE_ADDR1 &&
			p_child->slave_addr != SLAVE_ADDR2) {
			/*
			 * If the slave address is neither 0x70 nor 0x72,
			 * it is not a SDVO device. Skip it.
			 */
			continue;
		}
		if (p_child->dvo_port != DEVICE_PORT_DVOB &&
			p_child->dvo_port != DEVICE_PORT_DVOC) {
			/* skip the incorrect SDVO port */
			DRM_DEBUG_KMS("Incorrect SDVO port. Skip it \n");
			continue;
		}
		DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
				" %s port\n",
				p_child->slave_addr,
				(p_child->dvo_port == DEVICE_PORT_DVOB) ?
					"SDVOB" : "SDVOC");
		p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);
		if (!p_mapping->initialized) {
			p_mapping->dvo_port = p_child->dvo_port;
			p_mapping->slave_addr = p_child->slave_addr;
			p_mapping->dvo_wiring = p_child->dvo_wiring;
			p_mapping->ddc_pin = p_child->ddc_pin;
			p_mapping->i2c_pin = p_child->i2c_pin;
			p_mapping->i2c_speed = p_child->i2c_speed;
			p_mapping->initialized = 1;
			DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d, i2c_speed=%d\n",
				      p_mapping->dvo_port,
				      p_mapping->slave_addr,
				      p_mapping->dvo_wiring,
				      p_mapping->ddc_pin,
				      p_mapping->i2c_pin,
				      p_mapping->i2c_speed);
		} else {
			DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
					 "two SDVO device.\n");
		}
		if (p_child->slave2_addr) {
			/* Maybe this is a SDVO device with multiple inputs */
			/* And the mapping info is not added */
			DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
				" is a SDVO device with multiple inputs.\n");
		}
		count++;
	}

	if (!count) {
		/* No SDVO device info is found */
		DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
	}
	return;
}
Beispiel #12
0
int main(int argc, char **argv)
{
	int c, bdev = -1;
	unsigned i, ncache_devices = 0, nbacking_devices = 0;
	char *cache_devices[argc];
	char *backing_devices[argc];

	unsigned block_size = 0, bucket_size = 1024;
	int writeback = 0, discard = 0, wipe_bcache = 0;
	unsigned cache_replacement_policy = 0;
	uint64_t data_offset = BDEV_DATA_START_DEFAULT;
	uuid_t set_uuid;

	uuid_generate(set_uuid);

	struct option opts[] = {
		{ "cache",		0, NULL,	'C' },
		{ "bdev",		0, NULL,	'B' },
		{ "bucket",		1, NULL,	'b' },
		{ "block",		1, NULL,	'w' },
		{ "writeback",		0, &writeback,	1 },
		{ "wipe-bcache",	0, &wipe_bcache,	1 },
		{ "discard",		0, &discard,	1 },
		{ "cache_replacement_policy", 1, NULL, 'p' },
		{ "data_offset",	1, NULL,	'o' },
		{ "cset-uuid",		1, NULL,	'u' },
		{ "help",		0, NULL,	'h' },
		{ NULL,			0, NULL,	0 },
	};

	while ((c = getopt_long(argc, argv,
				"-hCBU:w:b:",
				opts, NULL)) != -1)
		switch (c) {
		case 'C':
			bdev = 0;
			break;
		case 'B':
			bdev = 1;
			break;
		case 'b':
			bucket_size = hatoi_validate(optarg, "bucket size");
			break;
		case 'w':
			block_size = hatoi_validate(optarg, "block size");
			break;
#if 0
		case 'U':
			if (uuid_parse(optarg, sb.uuid)) {
				fprintf(stderr, "Bad uuid\n");
				exit(EXIT_FAILURE);
			}
			break;
#endif
		case 'p':
			cache_replacement_policy = read_string_list(optarg,
						    cache_replacement_policies);
			break;
		case 'o':
			data_offset = atoll(optarg);
			if (data_offset < BDEV_DATA_START_DEFAULT) {
				fprintf(stderr, "Bad data offset; minimum %d sectors\n",
				       BDEV_DATA_START_DEFAULT);
				exit(EXIT_FAILURE);
			}
			break;
		case 'u':
			if (uuid_parse(optarg, set_uuid)) {
				fprintf(stderr, "Bad uuid\n");
				exit(EXIT_FAILURE);
			}
			break;
		case 'h':
			usage();
			break;
		case 1:
			if (bdev == -1) {
				fprintf(stderr, "Please specify -C or -B\n");
				exit(EXIT_FAILURE);
			}

			if (bdev)
				backing_devices[nbacking_devices++] = optarg;
			else
				cache_devices[ncache_devices++] = optarg;
			break;
		}

	if (!ncache_devices && !nbacking_devices) {
		fprintf(stderr, "Please supply a device\n");
		usage();
	}

	if (bucket_size < block_size) {
		fprintf(stderr, "Bucket size cannot be smaller than block size\n");
		exit(EXIT_FAILURE);
	}

	if (!block_size) {
		for (i = 0; i < ncache_devices; i++)
			block_size = max(block_size,
					 get_blocksize(cache_devices[i]));

		for (i = 0; i < nbacking_devices; i++)
			block_size = max(block_size,
					 get_blocksize(backing_devices[i]));
	}

	for (i = 0; i < ncache_devices; i++)
		write_sb(cache_devices[i], block_size, bucket_size,
			 writeback, discard, wipe_bcache,
			 cache_replacement_policy,
			 data_offset, set_uuid, false);

	for (i = 0; i < nbacking_devices; i++)
		write_sb(backing_devices[i], block_size, bucket_size,
			 writeback, discard, wipe_bcache,
			 cache_replacement_policy,
			 data_offset, set_uuid, true);

	return 0;
}
static void
parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
			  struct bdb_header *bdb)
{
	struct sdvo_device_mapping *p_mapping;
	struct bdb_general_definitions *p_defs;
	struct child_device_config *p_child;
	int i, child_device_num, count;
	u16	block_size;

	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
	if (!p_defs) {
		DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
		return;
	}
	if (p_defs->child_dev_size != sizeof(*p_child)) {
		
		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
		return;
	}
	
	block_size = get_blocksize(p_defs);
	
	child_device_num = (block_size - sizeof(*p_defs)) /
				sizeof(*p_child);
	count = 0;
	for (i = 0; i < child_device_num; i++) {
		p_child = &(p_defs->devices[i]);
		if (!p_child->device_type) {
			
			continue;
		}
		if (p_child->slave_addr != SLAVE_ADDR1 &&
			p_child->slave_addr != SLAVE_ADDR2) {
			continue;
		}
		if (p_child->dvo_port != DEVICE_PORT_DVOB &&
			p_child->dvo_port != DEVICE_PORT_DVOC) {
			
			DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
			continue;
		}
		DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
				" %s port\n",
				p_child->slave_addr,
				(p_child->dvo_port == DEVICE_PORT_DVOB) ?
					"SDVOB" : "SDVOC");
		p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);
		if (!p_mapping->initialized) {
			p_mapping->dvo_port = p_child->dvo_port;
			p_mapping->slave_addr = p_child->slave_addr;
			p_mapping->dvo_wiring = p_child->dvo_wiring;
			p_mapping->ddc_pin = p_child->ddc_pin;
			p_mapping->i2c_pin = p_child->i2c_pin;
			p_mapping->initialized = 1;
			DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
				      p_mapping->dvo_port,
				      p_mapping->slave_addr,
				      p_mapping->dvo_wiring,
				      p_mapping->ddc_pin,
				      p_mapping->i2c_pin);
		} else {
			DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
					 "two SDVO device.\n");
		}
		if (p_child->slave2_addr) {
			
			
			DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
				" is a SDVO device with multiple inputs.\n");
		}
		count++;
	}

	if (!count) {
		
		DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
	}
	return;
}
Beispiel #14
0
static int scsi_generic_initfn(SCSIDevice *dev)
{
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
    int sg_version;
    struct sg_scsi_id scsiid;

    if (!s->qdev.conf.bs) {
        error_report("scsi-generic: drive property not set");
        return -1;
    }
    s->bs = s->qdev.conf.bs;

    /* check we are really using a /dev/sg* file */
    if (!bdrv_is_sg(s->bs)) {
        error_report("scsi-generic: not /dev/sg*");
        return -1;
    }

    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
        error_report("Device doesn't support drive option werror");
        return -1;
    }
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
        error_report("Device doesn't support drive option rerror");
        return -1;
    }

    /* check we are using a driver managing SG_IO (version 3 and after */
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
        sg_version < 30000) {
        error_report("scsi-generic: scsi generic interface too old");
        return -1;
    }

    /* get LUN of the /dev/sg? */
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
        return -1;
    }

    /* define device state */
    s->lun = scsiid.lun;
    DPRINTF("LUN %d\n", s->lun);
    s->qdev.type = scsiid.scsi_type;
    DPRINTF("device type %d\n", s->qdev.type);
    if (s->qdev.type == TYPE_TAPE) {
        s->qdev.blocksize = get_stream_blocksize(s->bs);
        if (s->qdev.blocksize == -1)
            s->qdev.blocksize = 0;
    } else {
        s->qdev.blocksize = get_blocksize(s->bs);
        /* removable media returns 0 if not present */
        if (s->qdev.blocksize <= 0) {
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
                s->qdev.blocksize = 2048;
            else
                s->qdev.blocksize = 512;
        }
    }
    DPRINTF("block size %d\n", s->qdev.blocksize);
    s->driver_status = 0;
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
    bdrv_set_removable(s->bs, 0);
    return 0;
}
Beispiel #15
0
int media_main(int argc, FAR char *argv[])
#endif
{
  FAR uint8_t *txbuffer;
  FAR uint8_t *rxbuffer;
  FAR char *devpath;
  struct media_info_s info;
  ssize_t nwritten;
  ssize_t nread;
  off_t blockno;
  off_t pos;
  off_t seekpos;
  off_t i;
  uint32_t nerrors;
  uint8_t value;
  int fd;

  /* Open the character driver that wraps the media */

  if (argc < 2)
    {
      devpath = CONFIG_EXAMPLES_MEDIA_DEVPATH;
    }
  else
    {
      devpath = argv[1];
    }

  fd = open(devpath, O_RDWR);

  if (fd < 0)
    {
      fprintf(stderr, "ERROR: failed to open %s: %d\n",
              devpath, errno);
      return 1;
    }
  /* Get the block size to use */

  get_blocksize(fd, &info);

  printf("Using:\n");
  printf("  blocksize:    %lu\n", (unsigned long)info.blocksize);
  printf("  nblocks:      %lu\n", (unsigned long)info.nblocks);

  /* Allocate I/O buffers of the correct block size */

  txbuffer = (FAR uint8_t *)malloc((size_t)info.blocksize);
  if (txbuffer == NULL)
    {
      fprintf(stderr, "ERROR: failed to allocate TX I/O buffer of size %lu\n",
              (unsigned long)info.blocksize);
      close(fd);
      return 1;
    }

  rxbuffer = (FAR uint8_t *)malloc((size_t)info.blocksize);
  if (rxbuffer == NULL)
    {
      fprintf(stderr, "ERROR: failed to allocate IRX /O buffer of size %lu\n",
              (unsigned long)info.blocksize);
      free(txbuffer);
      close(fd);
      return 1;
    }

  /* Write and verify each sector */

  pos     = 0;
  nerrors = 0;
  value   = START_VALUE;

  for (blockno = 0; info.nblocks == 0 || blockno < info.nblocks; blockno++)
    {
      printf("Write/Verify: Block %lu\n", (unsigned long)blockno);

      /* Fill buffer with a (possibly) unique pattern */

      for (i = 0; i < info.blocksize; i++)
        {
          txbuffer[i] = value;
          if (++value >= END_VALUE)
            {
              value = START_VALUE;
            }
        }

      seekpos = lseek(fd, pos, SEEK_SET);
      if (seekpos == (off_t)-1)
        {
          int errcode = errno;

          fprintf(stderr, "ERROR: lseek to %lu failed: %d\n",
                  (unsigned long)pos, errcode);
          fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
          info.nblocks = blockno;
          break;
        }
      else if (seekpos != pos)
        {
          fprintf(stderr, "ERROR: lseek failed: %lu vs %lu\n",
                  (unsigned)seekpos, (unsigned long) pos);
          fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
          info.nblocks = blockno;
          break;
        }

      nwritten = write(fd, txbuffer, info.blocksize);
      if (nwritten < 0)
        {
          int errcode = errno;

          fprintf(stderr, "ERROR: write failed: %d\n", errcode);
          if (errno != EINTR)
            {
              fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
              info.nblocks = blockno;
              break;
            }
        }
      else if (nwritten != info.blocksize)
        {
          fprintf(stderr, "ERROR: Unexpected write size: %lu vs. %lu\n",
                  (unsigned long)nwritten, (unsigned long)info.blocksize);
          fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
          info.nblocks = blockno;
          break;
        }

      seekpos = lseek(fd, pos, SEEK_SET);
      if (seekpos == (off_t)-1)
        {
          int errcode = errno;

          fprintf(stderr, "ERROR: lseek to %lu failed: %d\n",
                  (unsigned long)pos, errcode);
          fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
          info.nblocks = blockno;
          break;
        }
      else if (seekpos != pos)
        {
          fprintf(stderr, "ERROR: lseek failed: %lu vs %lu\n",
                  (unsigned)seekpos, (unsigned long) pos);
          fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
          info.nblocks = blockno;
          break;
        }

      nread = read(fd, rxbuffer, info.blocksize);
      if (nread < 0)
        {
          int errcode = errno;

          fprintf(stderr, "ERROR: read failed: %d\n", errcode);
          if (errno != EINTR)
            {
              fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
              info.nblocks = blockno;
              break;
            }
        }
      else if (nread != info.blocksize)
        {
          fprintf(stderr, "ERROR: Unexpected read size: %lu vs. %lu\n",
                  (unsigned long)nread, (unsigned long)info.blocksize);
          fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
          info.nblocks = blockno;
          break;
        }
      else
        {
          for (i = 0; i < info.blocksize && nerrors <= 100; i++)
            {
              if (txbuffer[i] != rxbuffer[i])
                {
                  fprintf(stderr,
                          "ERROR: block=%lu offset=%lu.  Unexpected value: %02x vs. %02x\n",
                          blockno, i, rxbuffer[i], txbuffer[i]);
                  nerrors++;
                }
            }

          if (nerrors > 100)
            {
              fprintf(stderr, "ERROR: Too many errors\n");
              fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
              info.nblocks = blockno;
              break;
            }
        }

      pos += info.blocksize;
    }

  /* Set the number of blocks if it was unknown before */

  if (info.nblocks == 0)
    {
      info.nblocks = blockno;
    }

  /* Seek to the beginnin of the file */

  seekpos = lseek(fd, 0, SEEK_SET);
  if (seekpos == (off_t)-1)
    {
      int errcode = errno;

      fprintf(stderr, "ERROR: lseek to 0 failed: %d\n", errcode);
    }
  else if (seekpos != 0)
    {
      fprintf(stderr, "ERROR: lseek to 0 failed: %lu\n",
              (unsigned)seekpos);
    }

  /* Re-read and verify each sector */

  value = START_VALUE;

  for (blockno = 0; blockno < info.nblocks; blockno++)
    {
      printf("Re-read/Verify: Block %lu\n", (unsigned long)blockno);

      /* Fill buffer with a (possibly) unique pattern */

      for (i = 0; i < info.blocksize; i++)
        {
          txbuffer[i] = value;
          if (++value >= END_VALUE)
            {
              value = START_VALUE;
            }
        }

      nread = read(fd, rxbuffer, info.blocksize);
      if (nread < 0)
        {
          int errcode = errno;

          fprintf(stderr, "ERROR: read failed: %d\n", errcode);
          if (errno != EINTR)
            {
              fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
              break;
            }
        }
      else if (nread != info.blocksize)
        {
          fprintf(stderr, "ERROR: Unexpected read size: %lu vs. %lu\n",
                  (unsigned long)nread, (unsigned long)info.blocksize);
          fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
          break;
        }
      else
        {
          for (i = 0; i < info.blocksize && nerrors <= 100; i++)
            {
              if (txbuffer[i] != rxbuffer[i])
                {
                  fprintf(stderr,
                          "ERROR: block=%lu offset=%lu.  Unexpected value: %02x vs. %02x\n",
                          blockno, i, rxbuffer[i], txbuffer[i]);
                  nerrors++;
                }
            }

          if (nerrors > 100)
            {
              fprintf(stderr, "ERROR: Too many errors\n");
              fprintf(stderr, "ERROR: Aborting at block: %lu\n", blockno);
              info.nblocks = blockno;
              break;
            }
        }
    }

  /* Clean-up and exit */

  free(rxbuffer);
  free(txbuffer);
  close(fd);
  return 0;
}