mirror of
https://github.com/aaru-dps/aaruremote.git
synced 2025-12-16 19:24:37 +00:00
Implement SCSI types in FreeBSD.
This commit is contained in:
@@ -15,7 +15,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../aaruremote.h"
|
||||
#include "freebsd.h"
|
||||
@@ -32,5 +36,92 @@ int32_t SendScsiCommand(void* device_ctx,
|
||||
uint32_t* buf_len,
|
||||
uint32_t* sense_len)
|
||||
{
|
||||
return -1;
|
||||
DeviceContext* ctx = device_ctx;
|
||||
*sense_len = 0;
|
||||
*sense_buffer = NULL;
|
||||
*duration = 0;
|
||||
union ccb* camccb;
|
||||
u_int32_t flags;
|
||||
int error;
|
||||
|
||||
switch(direction)
|
||||
{
|
||||
case AARUREMOTE_SCSI_DIRECTION_NONE:
|
||||
flags = CAM_DIR_NONE;
|
||||
break;
|
||||
case AARUREMOTE_SCSI_DIRECTION_OUT:
|
||||
flags = CAM_DIR_OUT;
|
||||
break;
|
||||
case AARUREMOTE_SCSI_DIRECTION_IN:
|
||||
flags = CAM_DIR_IN;
|
||||
break;
|
||||
case AARUREMOTE_SCSI_DIRECTION_INOUT:
|
||||
flags = CAM_DIR_BOTH;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!ctx) return -1;
|
||||
if(!ctx->device) return -1;
|
||||
|
||||
*sense_buffer = malloc(32);
|
||||
|
||||
if(!*sense_buffer) return -1;
|
||||
|
||||
camccb = cam_getccb(ctx->device);
|
||||
|
||||
if(!camccb) return -1;
|
||||
|
||||
camccb->ccb_h.func_code = XPT_SCSI_IO;
|
||||
camccb->ccb_h.flags = flags;
|
||||
camccb->ccb_h.xflags = 0;
|
||||
camccb->ccb_h.retry_count = 1;
|
||||
camccb->ccb_h.cbfcnp = NULL;
|
||||
camccb->ccb_h.timeout = timeout;
|
||||
camccb->csio.data_ptr = (u_int8_t *)buffer;
|
||||
camccb->csio.dxfer_len = *buf_len;
|
||||
camccb->csio.sense_len = 32;
|
||||
camccb->csio.cdb_len = cdb_len;
|
||||
camccb->csio.tag_action = 0x20;
|
||||
|
||||
if(cdb_len <= CAM_MAX_CDBLEN)
|
||||
memcpy(camccb->csio.cdb_io.cdb_bytes, cdb, cdb_len);
|
||||
else
|
||||
{
|
||||
camccb->csio.cdb_io.cdb_ptr = (u_int8_t *)cdb;
|
||||
camccb->ccb_h.flags |= CAM_CDB_POINTER;
|
||||
}
|
||||
|
||||
camccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
|
||||
|
||||
// TODO: Measure duration
|
||||
error = cam_send_ccb(ctx->device, camccb);
|
||||
|
||||
if(error < 0)
|
||||
error = errno;
|
||||
|
||||
if((camccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP &&
|
||||
(camccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR)
|
||||
{
|
||||
error = errno;
|
||||
*sense = true;
|
||||
}
|
||||
|
||||
if((camccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
|
||||
{
|
||||
*sense = true;
|
||||
*sense_buffer = malloc(1);
|
||||
(*sense_buffer)[0] = camccb->csio.scsi_status;
|
||||
}
|
||||
|
||||
if((camccb->ccb_h.status & CAM_AUTOSNS_VALID) && camccb->csio.sense_len - camccb->csio.sense_resid > 0)
|
||||
{
|
||||
*sense = (camccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR;
|
||||
*sense_buffer = malloc(camccb->csio.sense_len - camccb->csio.sense_resid);
|
||||
(*sense_buffer)[0] = camccb->csio.sense_data.error_code;
|
||||
memcpy((*sense_buffer)+1, camccb->csio.sense_data.sense_buf, (camccb->csio.sense_len - camccb->csio.sense_resid) - 1);
|
||||
}
|
||||
|
||||
*buf_len = camccb->csio.dxfer_len;
|
||||
|
||||
return error;
|
||||
}
|
||||
Reference in New Issue
Block a user