aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDamien Le Moal <damien.lemoal@wdc.com>2016-10-28 16:57:00 +0900
committerJaegeuk Kim <jaegeuk@kernel.org>2016-11-01 17:27:34 -0700
commit9691420a990b81895c47b08be14b74d5ce8f8da4 (patch)
treed975ec28451dc70fc15badb1be5b5a58e04cf0c6 /lib
parent81c62e2537caaacfd0937b93535006edda73e1b5 (diff)
downloadandroid_external_f2fs-tools-9691420a990b81895c47b08be14b74d5ce8f8da4.tar.gz
android_external_f2fs-tools-9691420a990b81895c47b08be14b74d5ce8f8da4.tar.bz2
android_external_f2fs-tools-9691420a990b81895c47b08be14b74d5ce8f8da4.zip
f2fs-tools: introduce support for zoned block devices
With the availability of the BLKREPORTZONE and BLKRESETZONE ioctls, there is no need for using SG_IO to discover zoned block devices characteristics. This simplifies the code. Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/libf2fs.c36
-rw-r--r--lib/libf2fs_zoned.c294
-rw-r--r--lib/zbc.c647
-rw-r--r--lib/zbc.h361
5 files changed, 322 insertions, 1018 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 91e4b4c..b26b404 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -2,7 +2,7 @@
lib_LTLIBRARIES = libf2fs.la
-libf2fs_la_SOURCES = libf2fs.c libf2fs_io.c zbc.c
+libf2fs_la_SOURCES = libf2fs.c libf2fs_io.c libf2fs_zoned.c
libf2fs_la_CFLAGS = -Wall
libf2fs_la_CPPFLAGS = -I$(top_srcdir)/include
libf2fs_la_LDFLAGS = -version-info $(LIBF2FS_CURRENT):$(LIBF2FS_REVISION):$(LIBF2FS_AGE)
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 5407ff5..0485448 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -546,6 +546,8 @@ void f2fs_init_configuration(void)
c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
c.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT;
c.rootdev_name = get_rootdev();
+ c.zoned_mode = 0;
+ c.zoned_model = F2FS_ZONED_NONE;
/* calculated by overprovision ratio */
c.reserved_segments = 0;
@@ -746,17 +748,33 @@ int f2fs_get_device_info(void)
}
#ifndef WITH_ANDROID
- if (c.zoned_mode) {
- if (zbc_scsi_report_zones()) {
- MSG(0, "\tError: Not proper zoned block device\n");
+ if (S_ISBLK(stat_buf.st_mode))
+ f2fs_get_zoned_model();
+ if (c.zoned_model == F2FS_ZONED_NONE) {
+ c.zoned_mode = 0;
+ } else {
+ if (f2fs_get_zone_blocks()) {
+ MSG(0, "\tError: Failed to get number of blocks per zone\n");
+ return -1;
+ }
+
+ if (f2fs_check_zones()) {
+ MSG(0, "\tError: Failed to check zone configuration\n");
return -1;
}
- MSG(0, "Info: Zoned block device - ZONES = %u, CONV = %u, ZONE_SECTS = %lu\n",
- c.nr_zones, c.nr_conventional,
- c.zone_sectors);
- if (c.segs_per_sec == 1)
- c.segs_per_sec = c.zone_sectors /
- c.sectors_per_blk / DEFAULT_BLOCKS_PER_SEGMENT;
+ MSG(0, "Info: Host-%s zoned block device:\n",
+ (c.zoned_model == F2FS_ZONED_HA) ?
+ "aware" : "managed");
+ MSG(0, " %u zones, %u randomly writeable zones\n",
+ c.nr_zones, c.nr_rnd_zones);
+ MSG(0, " %lu blocks per zone\n",
+ c.zone_blocks);
+ /*
+ * Align sections to the device zone size
+ * and align F2FS zones to the device zones.
+ */
+ c.segs_per_sec = c.zone_blocks / DEFAULT_BLOCKS_PER_SEGMENT;
+ c.secs_per_zone = 1;
}
#endif
c.segs_per_zone = c.segs_per_sec * c.secs_per_zone;
diff --git a/lib/libf2fs_zoned.c b/lib/libf2fs_zoned.c
new file mode 100644
index 0000000..4ef4f1d
--- /dev/null
+++ b/lib/libf2fs_zoned.c
@@ -0,0 +1,294 @@
+/**
+ * libf2fs_zoned.c
+ *
+ * Copyright (c) 2016 Western Digital Corporation.
+ * Written by: Damien Le Moal <damien.lemoal@wdc.com>
+ *
+ * Dual licensed under the GPL or LGPL version 2 licenses.
+ */
+#define _LARGEFILE64_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <libgen.h>
+
+#include <f2fs_fs.h>
+
+#ifdef HAVE_LINUX_BLKZONED_H
+
+void f2fs_get_zoned_model()
+{
+ char str[128];
+ FILE *file;
+
+ /* Check that this is a zoned block device */
+ snprintf(str, sizeof(str),
+ "/sys/block/%s/queue/zoned",
+ basename(c.device_name));
+ file = fopen(str, "r");
+ if (!file)
+ goto not_zoned;
+
+ memset(str, 0, sizeof(str));
+ fscanf(file, "%s", str);
+ fclose(file);
+
+ if (strcmp(str, "host-aware") == 0) {
+ c.zoned_model = F2FS_ZONED_HA;
+ return;
+ }
+ if (strcmp(str, "host-managed") == 0) {
+ c.zoned_model = F2FS_ZONED_HM;
+ return;
+ }
+
+not_zoned:
+ c.zoned_model = F2FS_ZONED_NONE;
+}
+
+int f2fs_get_zone_blocks()
+{
+ uint64_t sectors;
+ char str[128];
+ FILE *file;
+
+ /* Get zone size */
+ c.zone_blocks = 0;
+
+ snprintf(str, sizeof(str),
+ "/sys/block/%s/queue/chunk_sectors",
+ basename(c.device_name));
+ file = fopen(str, "r");
+ if (!file)
+ return -1;
+
+ memset(str, 0, sizeof(str));
+ fscanf(file, "%s", str);
+ fclose(file);
+
+ sectors = atol(str);
+ if (!sectors)
+ return -1;
+
+ c.zone_blocks = sectors >> (F2FS_BLKSIZE_BITS - 9);
+ sectors = (sectors << 9) / c.sector_size;
+
+ /*
+ * Total number of zones: there may
+ * be a last smaller runt zone.
+ */
+ c.nr_zones = c.total_sectors / sectors;
+ if (c.total_sectors % sectors)
+ c.nr_zones++;
+
+ return 0;
+}
+
+#define F2FS_REPORT_ZONES_BUFSZ 524288
+
+int f2fs_check_zones()
+{
+ struct blk_zone_report *rep;
+ struct blk_zone *blkz;
+ unsigned int i, n = 0;
+ u_int64_t total_sectors;
+ u_int64_t sector;
+ int last_is_conv = 1;
+ int ret = -1;
+
+ rep = malloc(F2FS_REPORT_ZONES_BUFSZ);
+ if (!rep) {
+ ERR_MSG("No memory for report zones\n");
+ return -ENOMEM;
+ }
+
+ c.nr_rnd_zones = 0;
+ sector = 0;
+ total_sectors = (c.total_sectors * c.sector_size) >> 9;
+
+ while (sector < total_sectors) {
+
+ /* Get zone info */
+ memset(rep, 0, F2FS_REPORT_ZONES_BUFSZ);
+ rep->sector = sector;
+ rep->nr_zones = (F2FS_REPORT_ZONES_BUFSZ - sizeof(struct blk_zone_report))
+ / sizeof(struct blk_zone);
+
+ ret = ioctl(c.fd, BLKREPORTZONE, rep);
+ if (ret != 0) {
+ ret = -errno;
+ ERR_MSG("ioctl BLKREPORTZONE failed\n");
+ goto out;
+ }
+
+ if (!rep->nr_zones)
+ break;
+
+ blkz = (struct blk_zone *)(rep + 1);
+ for (i = 0; i < rep->nr_zones && sector < total_sectors; i++) {
+
+ if (blk_zone_cond(blkz) == BLK_ZONE_COND_READONLY ||
+ blk_zone_cond(blkz) == BLK_ZONE_COND_OFFLINE)
+ last_is_conv = 0;
+ if (blk_zone_conv(blkz) ||
+ blk_zone_seq_pref(blkz)) {
+ if (last_is_conv)
+ c.nr_rnd_zones++;
+ } else {
+ last_is_conv = 0;
+ }
+
+ if (blk_zone_conv(blkz)) {
+ DBG(2,
+ "Zone %05u: Conventional, cond 0x%x (%s), sector %llu, %llu sectors\n",
+ n,
+ blk_zone_cond(blkz),
+ blk_zone_cond_str(blkz),
+ blk_zone_sector(blkz),
+ blk_zone_length(blkz));
+ } else {
+ DBG(2,
+ "Zone %05u: type 0x%x (%s), cond 0x%x (%s), need_reset %d, "
+ "non_seq %d, sector %llu, %llu sectors, wp sector %llu\n",
+ n,
+ blk_zone_type(blkz),
+ blk_zone_type_str(blkz),
+ blk_zone_cond(blkz),
+ blk_zone_cond_str(blkz),
+ blk_zone_need_reset(blkz),
+ blk_zone_non_seq(blkz),
+ blk_zone_sector(blkz),
+ blk_zone_length(blkz),
+ blk_zone_wp_sector(blkz));
+ }
+
+ sector = blk_zone_sector(blkz) + blk_zone_length(blkz);
+ n++;
+ blkz++;
+ }
+
+ }
+
+ if (sector != total_sectors) {
+ ERR_MSG("Invalid zones: last sector reported is %llu, expected %llu\n",
+ (unsigned long long)(sector << 9) / c.sector_size,
+ (unsigned long long)c.total_sectors);
+ ret = -1;
+ goto out;
+ }
+
+ if (n != c.nr_zones) {
+ ERR_MSG("Inconsistent number of zones: expected %u zones, got %u\n",
+ c.nr_zones, n);
+ ret = -1;
+ goto out;
+ }
+
+ if (c.zoned_model == F2FS_ZONED_HM &&
+ !c.nr_rnd_zones) {
+ ERR_MSG("No conventional zone for super block\n");
+ ret = -1;
+ }
+out:
+ free(rep);
+ return ret;
+}
+
+int f2fs_reset_zones()
+{
+ struct blk_zone_report *rep;
+ struct blk_zone *blkz;
+ struct blk_zone_range range;
+ u_int64_t total_sectors;
+ u_int64_t sector;
+ unsigned int i;
+ int ret = -1;
+
+ rep = malloc(F2FS_REPORT_ZONES_BUFSZ);
+ if (!rep) {
+ ERR_MSG("No memory for report zones\n");
+ return -1;
+ }
+
+ sector = 0;
+ total_sectors = (c.total_sectors * c.sector_size) >> 9;
+ while (sector < total_sectors) {
+
+ /* Get zone info */
+ memset(rep, 0, F2FS_REPORT_ZONES_BUFSZ);
+ rep->sector = sector;
+ rep->nr_zones = (F2FS_REPORT_ZONES_BUFSZ - sizeof(struct blk_zone_report))
+ / sizeof(struct blk_zone);
+
+ ret = ioctl(c.fd, BLKREPORTZONE, rep);
+ if (ret != 0) {
+ ret = -errno;
+ ERR_MSG("ioctl BLKREPORTZONES failed\n");
+ goto out;
+ }
+
+ if (!rep->nr_zones)
+ break;
+
+ blkz = (struct blk_zone *)(rep + 1);
+ for (i = 0; i < rep->nr_zones && sector < total_sectors; i++) {
+ if (blk_zone_seq(blkz) &&
+ !blk_zone_empty(blkz)) {
+ /* Non empty sequential zone: reset */
+ range.sector = blk_zone_sector(blkz);
+ range.nr_sectors = blk_zone_length(blkz);
+ ret = ioctl(c.fd, BLKRESETZONE, &range);
+ if (ret != 0) {
+ ERR_MSG("ioctl BLKRESETZONE failed\n");
+ goto out;
+ }
+ }
+ sector = blk_zone_sector(blkz) + blk_zone_length(blkz);
+ blkz++;
+ }
+
+ }
+
+out:
+ free(rep);
+ return 0;
+}
+
+#else
+
+void f2fs_get_zoned_model()
+{
+ c.zoned_mode = 0;
+ c.zoned_model = F2FS_ZONED_NONE;
+}
+
+int f2fs_get_zone_blocks()
+{
+ c.zoned_mode = 0;
+ c.nr_zones = 0;
+ c.zone_blocks = 0;
+ c.zoned_model = F2FS_ZONED_NONE;
+
+ return 0;
+}
+
+int f2fs_check_zones()
+{
+ ERR_MSG("Zoned block devices are not supported\n");
+ return -1;
+}
+
+int f2fs_reset_zones()
+{
+ ERR_MSG("Zoned block devices are not supported\n");
+ return -1;
+}
+
+#endif
+
diff --git a/lib/zbc.c b/lib/zbc.c
deleted file mode 100644
index 1783bd5..0000000
--- a/lib/zbc.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * This file is mostly copied from libzbc.
- *
- * Copyright (C) 2009-2014, HGST, Inc. All rights reserved.
- *
- * This software is distributed under the terms of the BSD 2-clause license,
- * "as is," without technical support, and WITHOUT ANY WARRANTY, without
- * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. You should have received a copy of the BSD 2-clause license along
- * with libzbc. If not, see <http://opensource.org/licenses/BSD-2-Clause>.
- *
- * Authors: Damien Le Moal (damien.lemoal@hgst.com)
- * Christophe Louargant (christophe.louargant@hgst.com)
- *
- * Integrated into f2fs-tools by:
- * Jaegeuk Kim (jaegeuk@kernel.org)
- */
-
-#include <f2fs_fs.h>
-
-#include "zbc.h"
-
-static struct zbc_sg_cmd_s
-{
-
- char *cdb_cmd_name;
- int cdb_opcode;
- int cdb_sa;
- size_t cdb_length;
- int dir;
-
-} zbc_sg_cmd_list[ZBC_SG_CMD_NUM] = {
-
- /* ZBC_SG_TEST_UNIT_READY */
- {
- "TEST UNIT READY",
- ZBC_SG_TEST_UNIT_READY_CDB_OPCODE,
- 0,
- ZBC_SG_TEST_UNIT_READY_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_INQUIRY */
- {
- "INQUIRY",
- ZBC_SG_INQUIRY_CDB_OPCODE,
- 0,
- ZBC_SG_INQUIRY_CDB_LENGTH,
- SG_DXFER_FROM_DEV
- },
-
- /* ZBC_SG_READ_CAPACITY */
- {
- "READ CAPACITY 16",
- ZBC_SG_READ_CAPACITY_CDB_OPCODE,
- ZBC_SG_READ_CAPACITY_CDB_SA,
- ZBC_SG_READ_CAPACITY_CDB_LENGTH,
- SG_DXFER_FROM_DEV
- },
-
- /* ZBC_SG_READ */
- {
- "READ 16",
- ZBC_SG_READ_CDB_OPCODE,
- 0,
- ZBC_SG_READ_CDB_LENGTH,
- SG_DXFER_FROM_DEV
- },
-
- /* ZBC_SG_WRITE */
- {
- "WRITE 16",
- ZBC_SG_WRITE_CDB_OPCODE,
- 0,
- ZBC_SG_WRITE_CDB_LENGTH,
- SG_DXFER_TO_DEV
- },
-
- /* ZBC_SG_SYNC_CACHE */
- {
- "SYNCHRONIZE CACHE 16",
- ZBC_SG_SYNC_CACHE_CDB_OPCODE,
- 0,
- ZBC_SG_SYNC_CACHE_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_REPORT_ZONES */
- {
- "REPORT ZONES",
- ZBC_SG_REPORT_ZONES_CDB_OPCODE,
- ZBC_SG_REPORT_ZONES_CDB_SA,
- ZBC_SG_REPORT_ZONES_CDB_LENGTH,
- SG_DXFER_FROM_DEV
- },
-
- /* ZBC_SG_OPEN_ZONE */
- {
- "OPEN ZONE",
- ZBC_SG_OPEN_ZONE_CDB_OPCODE,
- ZBC_SG_OPEN_ZONE_CDB_SA,
- ZBC_SG_OPEN_ZONE_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_CLOSE_ZONE */
- {
- "CLOSE ZONE",
- ZBC_SG_CLOSE_ZONE_CDB_OPCODE,
- ZBC_SG_CLOSE_ZONE_CDB_SA,
- ZBC_SG_CLOSE_ZONE_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_FINISH_ZONE */
- {
- "FINISH ZONE",
- ZBC_SG_FINISH_ZONE_CDB_OPCODE,
- ZBC_SG_FINISH_ZONE_CDB_SA,
- ZBC_SG_FINISH_ZONE_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_RESET_WRITE_POINTER */
- {
- "RESET WRITE POINTER",
- ZBC_SG_RESET_WRITE_POINTER_CDB_OPCODE,
- ZBC_SG_RESET_WRITE_POINTER_CDB_SA,
- ZBC_SG_RESET_WRITE_POINTER_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_SET_ZONES */
- {
- "SET ZONES",
- ZBC_SG_SET_ZONES_CDB_OPCODE,
- ZBC_SG_SET_ZONES_CDB_SA,
- ZBC_SG_SET_ZONES_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_SET_WRITE_POINTER */
- {
- "SET WRITE POINTER",
- ZBC_SG_SET_WRITE_POINTER_CDB_OPCODE,
- ZBC_SG_SET_WRITE_POINTER_CDB_SA,
- ZBC_SG_SET_WRITE_POINTER_CDB_LENGTH,
- SG_DXFER_NONE
- },
-
- /* ZBC_SG_ATA12 */
- {
- "ATA 12",
- ZBC_SG_ATA12_CDB_OPCODE,
- 0,
- ZBC_SG_ATA12_CDB_LENGTH,
- 0
- },
-
- /* ZBC_SG_ATA16 */
- {
- "ATA 16",
- ZBC_SG_ATA16_CDB_OPCODE,
- 0,
- ZBC_SG_ATA16_CDB_LENGTH,
- 0
- }
-};
-
-static void zbc_sg_cmd_set_bytes(uint8_t *cmd, void *buf, int bytes)
-{
- uint8_t *v = (uint8_t *) buf;
- int i;
-
- for (i = 0; i < bytes; i++) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- /* The least significant byte is stored last */
- cmd[bytes - i - 1] = v[i];
-#else
- /* The most significant byte is stored first */
- cmd[i] = v[i];
-#endif
- }
- return;
-}
-
-static void zbc_sg_cmd_get_bytes(uint8_t *val, union converter *conv, int bytes)
-{
- uint8_t *v = (uint8_t *) val;
- int i;
-
- memset(conv, 0, sizeof(union converter));
-
- for(i = 0; i < bytes; i++) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- conv->val_buf[bytes - i - 1] = v[i];
-#else
- conv->val_buf[i] = v[i];
-#endif
- }
- return;
-}
-
-static inline void zbc_sg_cmd_set_int64(uint8_t *buf, uint64_t val)
-{
- zbc_sg_cmd_set_bytes(buf, &val, 8);
- return;
-}
-
-static inline void zbc_sg_cmd_set_int32(uint8_t *buf, uint32_t val)
-{
- zbc_sg_cmd_set_bytes(buf, &val, 4);
- return;
-}
-
-static inline uint32_t zbc_sg_cmd_get_int32(uint8_t *buf)
-{
- union converter conv;
-
- zbc_sg_cmd_get_bytes(buf, &conv, 4);
- return conv.val32;
-}
-
-static inline uint64_t zbc_sg_cmd_get_int64(uint8_t *buf)
-{
- union converter conv;
-
- zbc_sg_cmd_get_bytes(buf, &conv, 8);
- return( conv.val64 );
-
-}
-
-static void zbc_sg_cmd_destroy(zbc_sg_cmd_t *cmd)
-{
- /* Free the command */
- if (!cmd)
- return;
-
- if (cmd->out_buf && cmd->out_buf_needfree) {
- free(cmd->out_buf);
- cmd->out_buf = NULL;
- cmd->out_bufsz = 0;
- }
- memset(cmd, 0, sizeof(*cmd));
- return;
-}
-
-static int zbc_sg_cmd_init(zbc_sg_cmd_t *cmd, int cmd_code,
- uint8_t *out_buf, size_t out_bufsz)
-{
- int ret = 0;
-
- if ((!cmd) || (cmd_code < 0) || (cmd_code >= ZBC_SG_CMD_NUM) ) {
- ERR_MSG("Invalid command specified\n");
- return -EINVAL;
- }
-
- /* Set command */
- memset(cmd, 0, sizeof(zbc_sg_cmd_t));
- cmd->code = cmd_code;
- cmd->cdb_sz = zbc_sg_cmd_list[cmd_code].cdb_length;
- cmd->cdb_opcode = zbc_sg_cmd_list[cmd_code].cdb_opcode;
- cmd->cdb_sa = zbc_sg_cmd_list[cmd_code].cdb_sa;
-
- /* Set output buffer */
- if (out_buf) {
- /* Set specified buffer */
- if (!out_bufsz) {
- ERR_MSG("Invalid 0 output buffer size\n");
- ret = -EINVAL;
- goto out;
- }
- cmd->out_buf = out_buf;
- cmd->out_bufsz = out_bufsz;
- } else if (out_bufsz) {
- /* Allocate a buffer */
- ret = posix_memalign((void **)&cmd->out_buf,
- sysconf(_SC_PAGESIZE), out_bufsz);
- if ( ret != 0 ) {
- ERR_MSG("No memory for output buffer (%zu B)\n",
- out_bufsz);
- ret = -ENOMEM;
- goto out;
- }
- memset(cmd->out_buf, 0, out_bufsz);
- cmd->out_bufsz = out_bufsz;
- cmd->out_buf_needfree = 1;
- }
-
- /* OK: setup SGIO header */
- memset(&cmd->io_hdr, 0, sizeof(sg_io_hdr_t));
-
- cmd->io_hdr.interface_id = 'S';
- cmd->io_hdr.timeout = 20000;
- cmd->io_hdr.flags = 0; //SG_FLAG_DIRECT_IO;
-
- cmd->io_hdr.cmd_len = cmd->cdb_sz;
- cmd->io_hdr.cmdp = &cmd->cdb[0];
-
- cmd->io_hdr.dxfer_direction = zbc_sg_cmd_list[cmd_code].dir;
- cmd->io_hdr.dxfer_len = cmd->out_bufsz;
- cmd->io_hdr.dxferp = cmd->out_buf;
-
- cmd->io_hdr.mx_sb_len = ZBC_SG_SENSE_MAX_LENGTH;
- cmd->io_hdr.sbp = cmd->sense_buf;
-out:
- if (ret != 0)
- zbc_sg_cmd_destroy(cmd);
-
- return ret;
-}
-
-static char *zbc_sg_cmd_name(zbc_sg_cmd_t *cmd)
-{
- char *name;
-
- if ((cmd->code >= 0)
- && (cmd->code < ZBC_SG_CMD_NUM)) {
- name = zbc_sg_cmd_list[cmd->code].cdb_cmd_name;
- } else {
- name = "(UNKNOWN COMMAND)";
- }
-
- return name;
-}
-
-static void zbc_sg_set_sense(uint8_t *sense_buf)
-{
- if (sense_buf == NULL) {
- c.zbd_errno.sk = 0x00;
- c.zbd_errno.asc_ascq = 0x0000;
- } else {
- if ((sense_buf[0] & 0x7F) == 0x72
- || (sense_buf[0] & 0x7F) == 0x73) {
- /* store sense key, ASC/ASCQ */
- c.zbd_errno.sk = sense_buf[1] & 0x0F;
- c.zbd_errno.asc_ascq = ((int)sense_buf[2] << 8) |
- (int)sense_buf[3];
- } else if ((sense_buf[0] & 0x7F) == 0x70
- || (sense_buf[0] & 0x7F) == 0x71) {
- /* store sense key, ASC/ASCQ */
- c.zbd_errno.sk = sense_buf[2] & 0x0F;
- c.zbd_errno.asc_ascq = ((int)sense_buf[12] << 8) |
- (int)sense_buf[13];
- }
- }
- return;
-}
-
-static int zbc_sg_cmd_exec(zbc_sg_cmd_t *cmd)
-{
- int ret;
-
- /* Send the SG_IO command */
- ret = ioctl(c.fd, SG_IO, &cmd->io_hdr);
- if (ret) {
- ERR_MSG("SG_IO ioctl failed (%s)\n", strerror(errno));
- goto out;
- }
-
- /* Reset errno */
- zbc_sg_set_sense(NULL);
-
- DBG(1, "Command %s done: status 0x%02x (0x%02x), host status 0x%04x, driver status 0x%04x (flags 0x%04x)\n",
- zbc_sg_cmd_name(cmd),
- (unsigned int)cmd->io_hdr.status,
- (unsigned int)cmd->io_hdr.masked_status,
- (unsigned int)cmd->io_hdr.host_status,
- (unsigned int)zbc_sg_cmd_driver_status(cmd),
- (unsigned int)zbc_sg_cmd_driver_flags(cmd));
-
- /* Check status */
- if (((cmd->code == ZBC_SG_ATA12) || (cmd->code == ZBC_SG_ATA16))
- && (cmd->cdb[2] & (1 << 5)) ) {
-
- /* ATA command status */
- if (cmd->io_hdr.status != ZBC_SG_CHECK_CONDITION) {
- zbc_sg_set_sense(cmd->sense_buf);
- ret = -EIO;
- goto out;
- }
-
- if ((zbc_sg_cmd_driver_status(cmd) == ZBC_SG_DRIVER_SENSE)
- && (cmd->io_hdr.sb_len_wr > 21)
- && (cmd->sense_buf[21] != 0x50) ) {
- zbc_sg_set_sense(cmd->sense_buf);
- ret = -EIO;
- goto out;
- }
- cmd->io_hdr.status = 0;
- }
-
- if (cmd->io_hdr.status
- || (cmd->io_hdr.host_status != ZBC_SG_DID_OK)
- || (zbc_sg_cmd_driver_status(cmd) &&
- (zbc_sg_cmd_driver_status(cmd) != ZBC_SG_DRIVER_SENSE)) ) {
-
- ERR_MSG("Command %s failed with status 0x%02x (0x%02x), host status 0x%04x, driver status 0x%04x (flags 0x%04x)\n",
- zbc_sg_cmd_name(cmd),
- (unsigned int)cmd->io_hdr.status,
- (unsigned int)cmd->io_hdr.masked_status,
- (unsigned int)cmd->io_hdr.host_status,
- (unsigned int)zbc_sg_cmd_driver_status(cmd),
- (unsigned int)zbc_sg_cmd_driver_flags(cmd));
- zbc_sg_set_sense(cmd->sense_buf);
- ret = -EIO;
- goto out;
- }
-
- if (cmd->io_hdr.resid) {
- ERR_MSG("Transfer missing %d B of data\n",
- cmd->io_hdr.resid);
- cmd->out_bufsz -= cmd->io_hdr.resid;
- }
-out:
- return ret;
-}
-
-#define ZBC_SCSI_REPORT_ZONES_BUFSZ 524288
-
-int zbc_scsi_report_zones(void)
-{
- zbc_sg_cmd_t cmd;
- uint8_t *buf;
- zbc_zone_t *z, *zones = NULL;
- int i, buf_nz, ret;
- size_t bufsz;
- uint32_t idx = 0, nr_zones = 0;
- uint64_t next_lba = 0;
- int phase = 0;
-next:
- bufsz = ZBC_ZONE_DESCRIPTOR_OFFSET;
- if (phase) {
- if (c.nr_zones - idx == 0)
- return 0;
-
- bufsz += (size_t)(c.nr_zones - idx) *
- ZBC_ZONE_DESCRIPTOR_LENGTH;
- if (bufsz > ZBC_SCSI_REPORT_ZONES_BUFSZ)
- bufsz = ZBC_SCSI_REPORT_ZONES_BUFSZ;
- }
-
- /* For in kernel ATA translation: align to 512 B */
- bufsz = (bufsz + 511) & ~511;
-
- /* Allocate and intialize report zones command */
- ret = zbc_sg_cmd_init(&cmd, ZBC_SG_REPORT_ZONES, NULL, bufsz);
- if (ret) {
- ERR_MSG("zbc_sg_cmd_init failed\n");
- return ret;
- }
-
- /* Fill command CDB:
- * +=============================================================================+
- * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- * |Byte | | | | | | | | |
- * |=====+==========================+============================================|
- * | 0 | Operation Code (95h) |
- * |-----+-----------------------------------------------------------------------|
- * | 1 | Reserved | Service Action (00h) |
- * |-----+-----------------------------------------------------------------------|
- * | 2 | (MSB) |
- * |- - -+--- Zone Start LBA ---|
- * | 9 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | 10 | (MSB) |
- * |- - -+--- Allocation Length ---|
- * | 13 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | 14 |Partial |Reserved| Reporting Options |
- * |-----+-----------------------------------------------------------------------|
- * | 15 | Control |
- * +=============================================================================+
- */
- cmd.cdb[0] = ZBC_SG_REPORT_ZONES_CDB_OPCODE;
- cmd.cdb[1] = ZBC_SG_REPORT_ZONES_CDB_SA;
- zbc_sg_cmd_set_int64(&cmd.cdb[2], next_lba);
- zbc_sg_cmd_set_int32(&cmd.cdb[10], (unsigned int) bufsz);
- cmd.cdb[14] = 0;
-
- /* Send the SG_IO command */
- ret = zbc_sg_cmd_exec(&cmd);
- if (ret != 0)
- goto out;
-
- if (cmd.out_bufsz < ZBC_ZONE_DESCRIPTOR_OFFSET) {
- ERR_MSG("Not enough data received (need at least %d B, got %zu B)\n",
- ZBC_ZONE_DESCRIPTOR_OFFSET,
- cmd.out_bufsz);
- ret = -EIO;
- goto out;
- }
-
- /* Process output:
- * +=============================================================================+
- * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- * |Byte | | | | | | | | |
- * |=====+=======================================================================|
- * | 0 | (MSB) |
- * |- - -+--- Zone List Length (n - 64) ---|
- * | 3 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | 4 | Reserved | Same |
- * |-----+-----------------------------------------------------------------------|
- * | 5 | |
- * |- - -+--- Reserved ---|
- * | 7 | |
- * |-----+-----------------------------------------------------------------------|
- * | 8 | (MSB) |
- * |- - -+--- Maximum LBA ---|
- * | 15 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | 16 | (MSB) |
- * |- - -+--- Reserved ---|
- * | 63 | (LSB) |
- * |=====+=======================================================================|
- * | | Vendor-Specific Parameters |
- * |=====+=======================================================================|
- * | 64 | (MSB) |
- * |- - -+--- Zone Descriptor [first] ---|
- * | 127 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | . |
- * | . |
- * | . |
- * |-----+-----------------------------------------------------------------------|
- * |n-63 | |
- * |- - -+--- Zone Descriptor [last] ---|
- * | n | |
- * +=============================================================================+
- */
-
- /* Get number of zones in result */
- buf = (uint8_t *)cmd.out_buf;
- nr_zones = zbc_sg_cmd_get_int32(buf) / ZBC_ZONE_DESCRIPTOR_LENGTH;
-
- /* read # of zones and then get all the zone info */
- if (phase == 0) {
- c.nr_zones = nr_zones;
- c.nr_conventional = 0;
- zbc_sg_cmd_destroy(&cmd);
- phase++;
- goto next;
- }
-
- if (nr_zones > c.nr_zones - idx)
- nr_zones = c.nr_zones - idx;
-
- buf_nz = (cmd.out_bufsz - ZBC_ZONE_DESCRIPTOR_OFFSET) /
- ZBC_ZONE_DESCRIPTOR_LENGTH;
- if (nr_zones > buf_nz)
- nr_zones = buf_nz;
-
- if (!nr_zones) {
- ERR_MSG("No more zones\n");
- goto out;
- }
-
- /* Allocate zone array */
- zones = (zbc_zone_t *)malloc(sizeof(zbc_zone_t) * nr_zones);
- if (!zones) {
- ERR_MSG("No memory\n");
- goto out;
- }
- memset(zones, 0, sizeof(zbc_zone_t) * nr_zones);
-
- /* Get zone descriptors:
- * +=============================================================================+
- * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- * |Byte | | | | | | | | |
- * |=====+=======================================================================|
- * | 0 | Reserved | Zone type |
- * |-----+-----------------------------------------------------------------------|
- * | 1 | Zone condition | Reserved |non-seq | Reset |
- * |-----+-----------------------------------------------------------------------|
- * | 2 | |
- * |- - -+--- Reserved ---|
- * | 7 | |
- * |-----+-----------------------------------------------------------------------|
- * | 8 | (MSB) |
- * |- - -+--- Zone Length ---|
- * | 15 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | 16 | (MSB) |
- * |- - -+--- Zone Start LBA ---|
- * | 23 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | 24 | (MSB) |
- * |- - -+--- Write Pointer LBA ---|
- * | 31 | (LSB) |
- * |-----+-----------------------------------------------------------------------|
- * | 32 | |
- * |- - -+--- Reserved ---|
- * | 63 | |
- * +=============================================================================+
- */
- buf += ZBC_ZONE_DESCRIPTOR_OFFSET;
-
- for(i = 0; i < nr_zones; i++) {
- zones[i].zbz_type = buf[0] & 0x0f;
- zones[i].zbz_condition = (buf[1] >> 4) & 0x0f;
- zones[i].zbz_length = zbc_sg_cmd_get_int64(&buf[8]);
- zones[i].zbz_start = zbc_sg_cmd_get_int64(&buf[16]);
- zones[i].zbz_write_pointer = zbc_sg_cmd_get_int64(&buf[24]);
- zones[i].zbz_flags = buf[1] & 0x03;
-
- buf += ZBC_ZONE_DESCRIPTOR_LENGTH;
- }
-
- for (i = 0; i < nr_zones; i++) {
- z = &zones[i];
- if ( zbc_zone_conventional(z) ) {
- c.nr_conventional++;
- DBG(1, "Zone %05d: type 0x%x (%s), cond 0x%x (%s), LBA %llu, %llu sectors, wp N/A\n",
- i + idx,
- zbc_zone_type(z),
- zbc_zone_type_str(zbc_zone_type(z)),
- zbc_zone_condition(z),
- zbc_zone_condition_str(zbc_zone_condition(z)),
- zbc_zone_start_lba(z),
- zbc_zone_length(z));
- } else {
- DBG(1, "Zone %05d: type 0x%x (%s), cond 0x%x (%s), need_reset %d, non_seq %d, LBA %llu, %llu sectors, wp %llu\n",
- i + idx,
- zbc_zone_type(z),
- zbc_zone_type_str(zbc_zone_type(z)),
- zbc_zone_condition(z),
- zbc_zone_condition_str(zbc_zone_condition(z)),
- zbc_zone_need_reset(z),
- zbc_zone_non_seq(z),
- zbc_zone_start_lba(z),
- zbc_zone_length(z),
- zbc_zone_wp_lba(z));
- }
- }
-
- idx += nr_zones;
- next_lba = zones[nr_zones - 1].zbz_start + zones[nr_zones - 1].zbz_length;
- c.zone_sectors = zones[nr_zones - 1].zbz_length;
- phase++;
- zbc_sg_cmd_destroy(&cmd);
- free(zones);
- goto next;
-out:
- zbc_sg_cmd_destroy(&cmd);
- return ret;
-}
diff --git a/lib/zbc.h b/lib/zbc.h
deleted file mode 100644
index 15692c1..0000000
--- a/lib/zbc.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * This file is copied from libzbc.
- *
- * Copyright (C) 2009-2014, HGST, Inc. All rights reserved.
- *
- * This software is distributed under the terms of the BSD 2-clause license,
- * "as is," without technical support, and WITHOUT ANY WARRANTY, without
- * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. You should have received a copy of the BSD 2-clause license along
- * with libzbc. If not, see <http://opensource.org/licenses/BSD-2-Clause>.
- *
- * Author: Damien Le Moal (damien.lemoal@hgst.com)
- * Christophe Louargant (christophe.louargant@hgst.com)
- */
-
-#ifndef __LIBZBC_SG_H__
-#define __LIBZBC_SG_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <linux/types.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <scsi/scsi.h>
-#include <scsi/sg.h>
-
-#define zbc_error(format, args...) \
- fprintf(stderr, "[ERROR] " format, ##args)
-
-/**
- * SG SCSI command names.
- */
-enum {
-
- ZBC_SG_TEST_UNIT_READY = 0,
- ZBC_SG_INQUIRY,
- ZBC_SG_READ_CAPACITY,
- ZBC_SG_READ,
- ZBC_SG_WRITE,
- ZBC_SG_SYNC_CACHE,
- ZBC_SG_REPORT_ZONES,
- ZBC_SG_OPEN_ZONE,
- ZBC_SG_CLOSE_ZONE,
- ZBC_SG_FINISH_ZONE,
- ZBC_SG_RESET_WRITE_POINTER,
- ZBC_SG_SET_ZONES,
- ZBC_SG_SET_WRITE_POINTER,
- ZBC_SG_ATA12,
- ZBC_SG_ATA16,
-
- ZBC_SG_CMD_NUM,
-};
-
-/**
- * Test unit ready command definition.
- */
-#define ZBC_SG_TEST_UNIT_READY_CDB_OPCODE 0x00
-#define ZBC_SG_TEST_UNIT_READY_CDB_LENGTH 6
-#define ZBC_ZONE_DESCRIPTOR_LENGTH 64
-
-/**
- * Number of bytes in the buffer before the first Zone Descriptor.
- */
-#define ZBC_ZONE_DESCRIPTOR_OFFSET 64
-
-/**
- * Inquiry command definition.
- */
-#define ZBC_SG_INQUIRY_CDB_OPCODE 0x12
-#define ZBC_SG_INQUIRY_CDB_LENGTH 6
-#define ZBC_SG_INQUIRY_REPLY_LEN 96
-#define ZBC_SG_INQUIRY_REPLY_LEN_VPD_PAGE_B1 64
-#define ZBC_SG_INQUIRY_REPLY_LEN_VPD_PAGE_B6 64
-
-/**
- * Read capacity command definition.
- */
-#define ZBC_SG_READ_CAPACITY_CDB_OPCODE 0x9E
-#define ZBC_SG_READ_CAPACITY_CDB_SA 0x10
-#define ZBC_SG_READ_CAPACITY_CDB_LENGTH 16
-#define ZBC_SG_READ_CAPACITY_REPLY_LEN 32
-
-/**
- * Read command definition.
- */
-#define ZBC_SG_READ_CDB_OPCODE 0x88
-#define ZBC_SG_READ_CDB_LENGTH 16
-
-/**
- * Write command definition.
- */
-#define ZBC_SG_WRITE_CDB_OPCODE 0x8A
-#define ZBC_SG_WRITE_CDB_LENGTH 16
-
-/**
- * Sync cache command definition.
- */
-#define ZBC_SG_SYNC_CACHE_CDB_OPCODE 0x91
-#define ZBC_SG_SYNC_CACHE_CDB_LENGTH 16
-
-/**
- * Report zones command definition.
- */
-#define ZBC_SG_REPORT_ZONES_CDB_OPCODE 0x95
-#define ZBC_SG_REPORT_ZONES_CDB_SA 0x00
-#define ZBC_SG_REPORT_ZONES_CDB_LENGTH 16
-
-/**
- * Open zone command definition.
- */
-#define ZBC_SG_OPEN_ZONE_CDB_OPCODE 0x94
-#define ZBC_SG_OPEN_ZONE_CDB_SA 0x03
-#define ZBC_SG_OPEN_ZONE_CDB_LENGTH 16
-
-/**
- * Close zone command definition.
- */
-#define ZBC_SG_CLOSE_ZONE_CDB_OPCODE 0x94
-#define ZBC_SG_CLOSE_ZONE_CDB_SA 0x01
-#define ZBC_SG_CLOSE_ZONE_CDB_LENGTH 16
-
-/**
- * Finish zone command definition.
- */
-#define ZBC_SG_FINISH_ZONE_CDB_OPCODE 0x94
-#define ZBC_SG_FINISH_ZONE_CDB_SA 0x02
-#define ZBC_SG_FINISH_ZONE_CDB_LENGTH 16
-
-/**
- * Reset write pointer command definition.
- */
-#define ZBC_SG_RESET_WRITE_POINTER_CDB_OPCODE 0x94
-#define ZBC_SG_RESET_WRITE_POINTER_CDB_SA 0x04
-#define ZBC_SG_RESET_WRITE_POINTER_CDB_LENGTH 16
-
-/**
- * Set zones command definition.
- */
-#define ZBC_SG_SET_ZONES_CDB_OPCODE 0x9F
-#define ZBC_SG_SET_ZONES_CDB_SA 0x15
-#define ZBC_SG_SET_ZONES_CDB_LENGTH 16
-
-/**
- * Set write pointer command definition.
- */
-#define ZBC_SG_SET_WRITE_POINTER_CDB_OPCODE 0x9F
-#define ZBC_SG_SET_WRITE_POINTER_CDB_SA 0x16
-#define ZBC_SG_SET_WRITE_POINTER_CDB_LENGTH 16
-
-/**
- * ATA pass through 12.
- */
-#define ZBC_SG_ATA12_CDB_OPCODE 0xA1
-#define ZBC_SG_ATA12_CDB_LENGTH 12
-
-/**
- * ATA pass through 16.
- */
-#define ZBC_SG_ATA16_CDB_OPCODE 0x85
-#define ZBC_SG_ATA16_CDB_LENGTH 16
-
-/**
- * Command sense buffer maximum length.
- */
-#define ZBC_SG_SENSE_MAX_LENGTH 64
-
-/**
- * Maximum command CDB length.
- */
-#define ZBC_SG_CDB_MAX_LENGTH 16
-
-/**
- * Status codes.
- */
-#define ZBC_SG_CHECK_CONDITION 0x02
-
-/**
- * Host status codes.
- */
-#define ZBC_SG_DID_OK 0x00 /* No error */
-#define ZBC_SG_DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */
-#define ZBC_SG_DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */
-#define ZBC_SG_DID_TIME_OUT 0x03 /* Timed out for other reason */
-#define ZBC_SG_DID_BAD_TARGET 0x04 /* Bad target, device not responding? */
-#define ZBC_SG_DID_ABORT 0x05 /* Told to abort for some other reason. */
-#define ZBC_SG_DID_PARITY 0x06 /* Parity error. */
-#define ZBC_SG_DID_ERROR 0x07 /* Internal error detected in the host adapter. */
-#define ZBC_SG_DID_RESET 0x08 /* The SCSI bus (or this device) has been reset. */
-#define ZBC_SG_DID_BAD_INTR 0x09 /* Got an unexpected interrupt */
-#define ZBC_SG_DID_PASSTHROUGH 0x0a /* Forced command past mid-layer. */
-#define ZBC_SG_DID_SOFT_ERROR 0x0b /* The low level driver wants a retry. */
-
-/**
- * Driver status codes.
- */
-#define ZBC_SG_DRIVER_OK 0x00
-#define ZBC_SG_DRIVER_BUSY 0x01
-#define ZBC_SG_DRIVER_SOFT 0x02
-#define ZBC_SG_DRIVER_MEDIA 0x03
-#define ZBC_SG_DRIVER_ERROR 0x04
-#define ZBC_SG_DRIVER_INVALID 0x05
-#define ZBC_SG_DRIVER_TIMEOUT 0x06
-#define ZBC_SG_DRIVER_HARD 0x07
-#define ZBC_SG_DRIVER_SENSE 0x08
-#define ZBC_SG_DRIVER_STATUS_MASK 0x0f
-
-/**
- * Driver status code flags ('or'ed with code)
- */
-#define ZBC_SG_DRIVER_SUGGEST_RETRY 0x10
-#define ZBC_SG_DRIVER_SUGGEST_ABORT 0x20
-#define ZBC_SG_DRIVER_SUGGEST_REMAP 0x30
-#define ZBC_SG_DRIVER_SUGGEST_DIE 0x40
-#define ZBC_SG_DRIVER_SUGGEST_SENSE 0x80
-#define ZBC_SG_DRIVER_FLAGS_MASK 0xf0
-
-/***** Type definitions *****/
-
-/**
- * SG command descriptor. Used to process SCSI commands.
- */
-typedef struct zbc_sg_cmd {
-
- int code;
-
- int cdb_opcode;
- int cdb_sa;
- size_t cdb_sz;
- uint8_t cdb[ZBC_SG_CDB_MAX_LENGTH];
-
- size_t sense_bufsz;
- uint8_t sense_buf[ZBC_SG_SENSE_MAX_LENGTH];
-
- int out_buf_needfree;
- size_t out_bufsz;
- uint8_t *out_buf;
-
- sg_io_hdr_t io_hdr;
-
-} zbc_sg_cmd_t;
-
-/**
- * Zone descriptor.
- */
-struct zbc_zone {
-
- uint64_t zbz_length;
- uint64_t zbz_start;
- uint64_t zbz_write_pointer;
-
- uint8_t zbz_type;
- uint8_t zbz_condition;
- uint8_t zbz_flags;
-
- uint8_t __pad[5];
-
-};
-typedef struct zbc_zone zbc_zone_t;
-
-#define ZBC_FORCE_ATA_RW 0x40000000
-#define zbc_open_flags(f) ((f) & ~ZBC_FORCE_ATA_RW)
-
-/**
- * Zone type.
- */
-enum zbc_zone_type {
- ZBC_ZT_CONVENTIONAL = 0x01,
- ZBC_ZT_SEQUENTIAL_REQ = 0x02,
- ZBC_ZT_SEQUENTIAL_PREF = 0x03,
-};
-#define zbc_zone_type(z) ((int)(z)->zbz_type)
-
-#define zbc_zone_conventional(z) ((z)->zbz_type == ZBC_ZT_CONVENTIONAL)
-static inline const char *zbc_zone_type_str(enum zbc_zone_type type)
-{
- switch( type ) {
- case ZBC_ZT_CONVENTIONAL:
- return( "Conventional" );
- case ZBC_ZT_SEQUENTIAL_REQ:
- return( "Sequential-write-required" );
- case ZBC_ZT_SEQUENTIAL_PREF:
- return( "Sequential-write-preferred" );
- }
- return( "Unknown-type" );
-}
-
-/**
- * Zone condition.
- */
-enum zbc_zone_condition {
- ZBC_ZC_NOT_WP = 0x00,
- ZBC_ZC_EMPTY = 0x01,
- ZBC_ZC_IMP_OPEN = 0x02,
- ZBC_ZC_EXP_OPEN = 0x03,
- ZBC_ZC_CLOSED = 0x04,
- ZBC_ZC_RDONLY = 0x0d,
- ZBC_ZC_FULL = 0x0e,
- ZBC_ZC_OFFLINE = 0x0f,
-};
-
-/**
- * zbc_zone_cond_str - returns a string describing a zone condition.
- * @zone: (IN) ZBC_ZC_NOT_WP, ZBC_ZC_EMPTY, ZBC_ZC_IMP_OPEN, ZBC_ZC_EXP_OPEN,
- * ZBC_ZC_CLOSED, ZBC_ZC_RDONLY, ZBC_ZC_FULL or ZBC_ZC_OFFLINE
- *
- * Returns a string describing a zone condition.
- */
-static inline const char *zbc_zone_condition_str(enum zbc_zone_condition cond)
-{
- switch( cond ) {
- case ZBC_ZC_NOT_WP:
- return "Not-write-pointer";
- case ZBC_ZC_EMPTY:
- return "Empty";
- case ZBC_ZC_IMP_OPEN:
- return "Implicit-open";
- case ZBC_ZC_EXP_OPEN:
- return "Explicit-open";
- case ZBC_ZC_CLOSED:
- return "Closed";
- case ZBC_ZC_RDONLY:
- return "Read-only";
- case ZBC_ZC_FULL:
- return "Full";
- case ZBC_ZC_OFFLINE:
- return "Offline";
- }
- return "Unknown-cond";
-}
-
-#define zbc_zone_condition(z) ((int)(z)->zbz_condition)
-#define zbc_zone_start_lba(z) ((unsigned long long)((z)->zbz_start))
-#define zbc_zone_length(z) ((unsigned long long)((z)->zbz_length))
-#define zbc_zone_wp_lba(z) ((unsigned long long)((z)->zbz_write_pointer))
-
-/**
- * Zone flags: need reset, and non-seq write.
- */
-enum zbc_zone_flags {
- ZBC_ZF_NEED_RESET = 0x0001,
- ZBC_ZF_NON_SEQ = 0x0002,
-};
-#define zbc_zone_need_reset(z) (((z)->zbz_flags & ZBC_ZF_NEED_RESET) != 0)
-#define zbc_zone_non_seq(z) (((z)->zbz_flags & ZBC_ZF_NON_SEQ) != 0)
-
-#define zbc_sg_cmd_driver_status(cmd) ((cmd)->io_hdr.driver_status & ZBC_SG_DRIVER_STATUS_MASK)
-#define zbc_sg_cmd_driver_flags(cmd) ((cmd)->io_hdr.driver_status & ZBC_SG_DRIVER_FLAGS_MASK)
-
-union converter {
- uint8_t val_buf[8];
- uint16_t val16;
- uint32_t val32;
- uint64_t val64;
-};
-
-#endif /* __LIBZBC_SG_H__ */