--- b/sys/cam/scsi/scsi_sg.c +++ b/sys/cam/scsi/scsi_sg.c @@ -553,6 +553,8 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) } if (req->dxfer_len > MAXPHYS) { + printf("%s: dxfer_len (%u) > MAXPHYS (%u)\n", + __func__, req->dxfer_len, MAXPHYS); error = EINVAL; break; } @@ -578,7 +580,7 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) dir = CAM_DIR_IN; break; case SG_DXFER_TO_FROM_DEV: - dir = CAM_DIR_BOTH; + dir = CAM_DIR_IN | CAM_DIR_OUT; break; case SG_DXFER_NONE: default: @@ -586,7 +588,7 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) break; } - if (dir == CAM_DIR_IN || dir == CAM_DIR_BOTH) { + if (dir & CAM_DIR_IN) { error = copyin(req->dxferp, data_ptr, req->dxfer_len); if (error) { free(data_ptr, M_DEVBUF); @@ -629,7 +631,7 @@ sgioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) req->sb_len_wr); } - if ((dir == CAM_DIR_OUT || dir == CAM_DIR_BOTH) && error == 0) + if ((dir & CAM_DIR_OUT) && error == 0) error = copyout(data_ptr, req->dxferp, req->dxfer_len); free(data_ptr, M_DEVBUF);