#ifndef _VIOBLK_H
#define _VIOBLK_H
#include "virtio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define VIRTIO_BLK_CONFIG_CAPACITY 0x00
#define VIRTIO_BLK_CONFIG_SIZE_MAX 0x08
#define VIRTIO_BLK_CONFIG_SEG_MAX 0x0C
#define VIRTIO_BLK_CONFIG_GEOMETRY_C 0x10
#define VIRTIO_BLK_CONFIG_GEOMETRY_H 0x12
#define VIRTIO_BLK_CONFIG_GEOMETRY_S 0x13
#define VIRTIO_BLK_CONFIG_BLK_SIZE 0x14
#define VIRTIO_BLK_CONFIG_TOPO_PBEXP 0x18
#define VIRTIO_BLK_CONFIG_TOPO_ALIGN 0x19
#define VIRTIO_BLK_CONFIG_TOPO_MIN_SZ 0x1A
#define VIRTIO_BLK_CONFIG_TOPO_OPT_SZ 0x1C
#define VIRTIO_BLK_CONFIG_WRITEBACK 0x20
#define VIRTIO_BLK_CONFIG_NUM_QUEUES 0x22
#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SECT 0x24
#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SEG 0x28
#define VIRTIO_BLK_CONFIG_DISCARD_ALIGN 0x2C
#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZERO_SECT 0x30
#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZERO_SEG 0x34
#define VIRTIO_BLK_CONFIG_WRITE_ZERO_UNMAP 0x38
#define VIRTIO_BLK_VIRTQ_IO 0
#define VIRTIO_BLK_F_BARRIER (1ULL << 0)
#define VIRTIO_BLK_F_SIZE_MAX (1ULL << 1)
#define VIRTIO_BLK_F_SEG_MAX (1ULL << 2)
#define VIRTIO_BLK_F_GEOMETRY (1ULL << 4)
#define VIRTIO_BLK_F_RO (1ULL << 5)
#define VIRTIO_BLK_F_BLK_SIZE (1ULL << 6)
#define VIRTIO_BLK_F_SCSI (1ULL << 7)
#define VIRTIO_BLK_F_FLUSH (1ULL << 9)
#define VIRTIO_BLK_F_TOPOLOGY (1ULL << 10)
#define VIRTIO_BLK_F_CONFIG_WCE (1ULL << 11)
#define VIRTIO_BLK_F_MQ (1ULL << 12)
#define VIRTIO_BLK_F_DISCARD (1ULL << 13)
#define VIRTIO_BLK_F_WRITE_ZEROES (1ULL << 14)
#define VIRTIO_BLK_WANTED_FEATURES (VIRTIO_BLK_F_RO | \
VIRTIO_BLK_F_BLK_SIZE | \
VIRTIO_BLK_F_FLUSH | \
VIRTIO_BLK_F_TOPOLOGY | \
VIRTIO_BLK_F_SEG_MAX | \
VIRTIO_BLK_F_SIZE_MAX | \
VIRTIO_BLK_F_DISCARD)
struct vioblk_req_hdr {
uint32_t vbh_type;
uint32_t vbh_ioprio;
uint64_t vbh_sector;
} __packed;
#define VIRTIO_BLK_T_IN 0
#define VIRTIO_BLK_T_OUT 1
#define VIRTIO_BLK_T_SCSI_CMD 2
#define VIRTIO_BLK_T_SCSI_CMD_OUT 3
#define VIRTIO_BLK_T_FLUSH 4
#define VIRTIO_BLK_T_FLUSH_OUT 5
#define VIRTIO_BLK_T_GET_ID 8
#define VIRTIO_BLK_T_DISCARD 11
#define VIRTIO_BLK_T_WRITE_ZEROES 13
#define VIRTIO_BLK_T_BARRIER 0x80000000
struct vioblk_discard_write_zeroes {
uint64_t vdwz_sector;
uint32_t vdwz_num_sectors;
uint32_t vdwz_flags;
} __packed;
#define VIRTIO_BLK_WRITE_ZEROS_UNMAP (1U << 0)
#define VIRTIO_BLK_ID_BYTES 20
#define VIRTIO_BLK_S_OK 0
#define VIRTIO_BLK_S_IOERR 1
#define VIRTIO_BLK_S_UNSUPP 2
#define VIRTIO_BLK_DEFAULT_MAX_SEG 128
#define VIRTIO_BLK_DEFAULT_MAX_SIZE 4096
#define VIRTIO_BLK_REQ_BUFS 256
typedef enum vioblk_req_status {
VIOBLK_REQSTAT_ALLOCATED = (0x1 << 0),
VIOBLK_REQSTAT_INFLIGHT = (0x1 << 1),
VIOBLK_REQSTAT_COMPLETE = (0x1 << 2),
VIOBLK_REQSTAT_POLLED = (0x1 << 3),
VIOBLK_REQSTAT_POLL_COMPLETE = (0x1 << 4),
} vioblk_req_status_t;
typedef struct vioblk_req {
vioblk_req_status_t vbr_status;
uint64_t vbr_seqno;
int vbr_type;
int vbr_error;
virtio_dma_t *vbr_dma;
virtio_chain_t *vbr_chain;
bd_xfer_t *vbr_xfer;
list_node_t vbr_link;
} vioblk_req_t;
typedef struct vioblk_stats {
struct kstat_named vbs_rw_outofmemory;
struct kstat_named vbs_rw_badoffset;
struct kstat_named vbs_rw_queuemax;
struct kstat_named vbs_rw_cookiesmax;
struct kstat_named vbs_rw_cacheflush;
struct kstat_named vbs_intr_queuemax;
struct kstat_named vbs_intr_total;
struct kstat_named vbs_io_errors;
struct kstat_named vbs_unsupp_errors;
struct kstat_named vbs_nxio_errors;
} vioblk_stats_t;
typedef struct vioblk {
dev_info_t *vib_dip;
virtio_t *vib_virtio;
virtio_queue_t *vib_vq;
kmutex_t vib_mutex;
kcondvar_t vib_cv;
bd_handle_t vib_bd_h;
ddi_dma_attr_t vib_bd_dma_attr;
list_t vib_reqs;
uint_t vib_nreqs_alloc;
uint_t vib_reqs_capacity;
vioblk_req_t *vib_reqs_mem;
kstat_t *vib_kstat;
vioblk_stats_t *vib_stats;
uint64_t vib_nblks;
boolean_t vib_readonly;
uint_t vib_blk_size;
uint_t vib_pblk_size;
uint_t vib_seg_max;
uint_t vib_seg_size_max;
boolean_t vib_can_discard;
uint_t vib_max_discard_sectors;
uint_t vib_max_discard_seg;
uint_t vib_discard_sector_align;
boolean_t vib_devid_fetched;
char vib_devid[VIRTIO_BLK_ID_BYTES + 1];
uint8_t vib_rawid[VIRTIO_BLK_ID_BYTES];
} vioblk_t;
#ifdef __cplusplus
}
#endif
#endif