/*
 * Copyright 2010-2011 Red Hat, Inc.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v2 or (at your option) any later version.
 */

#ifndef __DISKIO_H__
#define __DISKIO_H__

void offset_to_str(unsigned long long offset, int buflen, char *off_str);

void close_disks(struct sync_disk *disks, int num_disks);
int open_disk(struct sync_disk *disks);
int open_disks(struct sync_disk *disks, int num_disks);
int open_disks_fd(struct sync_disk *disks, int num_disks);
int majority_disks(int num_disks, int num);

int read_sysfs_size(const char *path, const char *name, unsigned int *val);
int set_max_sectors_kb(struct sync_disk *disk, uint32_t max_sectors_kb);
int get_max_sectors_kb(struct sync_disk *disk, uint32_t *max_sectors_kb);
int read_sysfs_uint(char *path, unsigned int *val);
int write_sysfs_uint(char *path, unsigned int val);

/*
 * iobuf functions require the caller to allocate iobuf using posix_memalign
 * and pass it into the function
 */

int write_iobuf(int fd, uint64_t offset, char *iobuf, int iobuf_len,
		struct task *task, int use_aio, int ioto, int *wr_ms);

int read_iobuf(int fd, uint64_t offset, char *iobuf, int iobuf_len,
	       struct task *task, int use_aio, int ioto, int *rd_ms);

int read_iobuf_reap(int fd, uint64_t offset, char *iobuf, int iobuf_len,
		    struct task *task, uint32_t ioto_msec);

/*
 * sector functions allocate an iobuf themselves, copy into it for read, use it
 * for io, copy out of it for write, and free it
 */

int write_sector(const struct sync_disk *disk, int sector_size, uint64_t sector_nr,
		 const char *data, int data_len,
		 struct task *task, int use_aio, int ioto,
		 const char *blktype);

int write_sectors(const struct sync_disk *disk, int sector_size, uint64_t sector_nr,
		  uint32_t sector_count, const char *data, int data_len,
		  struct task *task, int use_aio, int ioto,
		  const char *blktype);

int read_sectors(const struct sync_disk *disk, int sector_size, uint64_t sector_nr,
	 	 uint32_t sector_count, char *data, int data_len,
		 struct task *task, int use_aio, int ioto,
		 const char *blktype);

int read_sector(const struct sync_disk *disk, int sector_size, uint64_t sector_nr,
                 char *data, int data_len,
                 struct task *task, int use_aio, int ioto,
                 const char *blktype);

int lv_to_target(uint32_t major, uint32_t minor, uint64_t offset,
                 uint32_t *target_major, uint32_t *target_minor, uint64_t *target_offset);
int dev_is_lv(uint32_t major, uint32_t minor);
int dev_is_mpath(uint32_t major, uint32_t minor);
int dev_is_scsi(uint32_t major, uint32_t minor);
int devno_to_path(uint32_t major, uint32_t minor, char *path);
int scsi_compare_and_write(struct task *task, int fd, int timeout, uint32_t major, uint32_t minor, int sector_size, uint64_t lba,
			   const char *both_data, const char *prev_data, const char *next_data, int may_fail);
int compare_and_write(struct task *task, int fd, int io_timeout,
		      uint32_t major, uint32_t minor, int sector_size, uint64_t offset_bytes,
		      const char *both_data, const char *prev_data, const char *next_data);
int compare_and_write_test(struct task *task, char *disk_path, uint64_t disk_offset_bytes, int sector_size, int test_verify);

#endif
