Use CAM and the pass(4) device instead of the optional sg(4) device on FreeBSD (#30)

This commit is contained in:
James Wilson
2022-05-09 02:53:49 -07:00
committed by GitHub
parent 8b7e99556a
commit 88975cc9ed
2 changed files with 34 additions and 3 deletions

View File

@@ -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

View File

@@ -37,7 +37,8 @@ GNU General Public License for more details.
#include <scsi/sg.h>
#define SCSI_TIMEOUT 5000
#elif defined(OS_FREEBSD)
#include <cam/scsi/scsi_sg.h>
#include <camlib.h>
#include <cam/scsi/scsi_message.h>
#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;