From 88975cc9ed2add63a7666553c165df9081b26ec6 Mon Sep 17 00:00:00 2001 From: James Wilson Date: Mon, 9 May 2022 02:53:49 -0700 Subject: [PATCH] Use CAM and the pass(4) device instead of the optional sg(4) device on FreeBSD (#30) --- configure.ac | 4 ++++ src/scsiencrypt.cpp | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index c2a6542..75083e3 100644 --- a/configure.ac +++ b/configure.ac @@ -83,5 +83,9 @@ AC_CHECK_PROG(PANDOC, [pandoc], [yes]) AM_CONDITIONAL([FOUND_PANDOC], [test "x$PANDOC" = xyes]) AM_COND_IF([FOUND_PANDOC],,[AC_MSG_ERROR([required program 'pandoc' not found.])]) +if test "${system}" = "FreeBSD"; then + LIBS="${LIBS} -lcam" +fi + AC_CONFIG_FILES([Makefile src/Makefile man/Makefile tests/Makefile]) AC_OUTPUT diff --git a/src/scsiencrypt.cpp b/src/scsiencrypt.cpp index aed0c1e..2c5a29f 100644 --- a/src/scsiencrypt.cpp +++ b/src/scsiencrypt.cpp @@ -37,7 +37,8 @@ GNU General Public License for more details. #include #define SCSI_TIMEOUT 5000 #elif defined(OS_FREEBSD) -#include +#include +#include #define SCSI_TIMEOUT 5000 #else #error "OS type is not set" @@ -285,7 +286,7 @@ bool SCSIExecute(std::string tapedrive, unsigned char *cmd_p, int cmd_len, SCSI_PAGE_SENSE *sd = new SCSI_PAGE_SENSE; memset(sd, 0, sizeof(SCSI_PAGE_SENSE)); -#if defined(OS_LINUX) || defined(OS_FREEBSD) // Linux or FreeBSD System +#if defined(OS_LINUX) errno = 0; sg_fd = open(tapedevice, O_RDONLY); if (sg_fd == -1) { @@ -315,6 +316,33 @@ bool SCSIExecute(std::string tapedrive, unsigned char *cmd_p, int cmd_len, } while (errno != 0 && retries <= RETRYCOUNT); sresult = cmdio.status; + close(sg_fd); +#elif defined(OS_FREEBSD) + errno = 0; + auto dev = cam_open_device(tapedevice, O_RDWR); + auto ccb = dev ? cam_getccb(dev) : nullptr; + + if (dev == nullptr || ccb == nullptr) { + std::cerr << "Could not open device '" << tapedevice << "': " << cam_errbuf << "\n"; + exit(EXIT_FAILURE); + } + CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); + + cam_fill_csio(&ccb->csio, RETRYCOUNT, nullptr, + CAM_PASS_ERR_RECOVER | CAM_CDB_POINTER | + (cmd_to_device ? CAM_DIR_OUT : CAM_DIR_IN), + MSG_SIMPLE_Q_TAG, dxfer_p, dxfer_len, SSD_FULL_SIZE, cmd_len, + SCSI_TIMEOUT); + ccb->csio.cdb_io.cdb_ptr = cmd_p; + eresult = cam_send_ccb(dev, ccb); + if (eresult != 0) { + ioerr = errno; + } + sresult = ccb->csio.scsi_status; + memcpy(sd, &ccb->csio.sense_data, sizeof(SCSI_PAGE_SENSE)); + + cam_freeccb(ccb); + cam_close_device(dev); #else #error "OS type is not set" #endif @@ -331,7 +359,6 @@ bool SCSIExecute(std::string tapedrive, unsigned char *cmd_p, int cmd_len, } std::cout << std::endl; #endif - close(sg_fd); bool retval = true;