}
}
+// Determine if the command is a request to pull data from the device
+int
+cdb_is_read(u8 *cdbcmd, u16 blocksize)
+{
+ return blocksize && cdbcmd[0] != CDB_CMD_WRITE_10;
+}
+
int
scsi_is_ready(struct disk_op_s *op)
{
} PACKED;
// blockcmd.c
+int cdb_is_read(u8 *cdbcmd, u16 blocksize);
int cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data);
int cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data);
int cdb_test_unit_ready(struct disk_op_s *op);
cbw.dCBWSignature = CBW_SIGNATURE;
cbw.dCBWTag = 999; // XXX
cbw.dCBWDataTransferLength = bytes;
- cbw.bmCBWFlags = (cbw.CBWCB[0] == CDB_CMD_WRITE_10) ? USB_DIR_OUT : USB_DIR_IN;
+ cbw.bmCBWFlags = cdb_is_read(cdbcmd, blocksize) ? USB_DIR_IN : USB_DIR_OUT;
cbw.bCBWLUN = 0; // XXX
cbw.bCBWCBLength = USB_CDB_SIZE;
// Transfer cbw to device.
int ret = usb_msc_send(udrive_g, USB_DIR_OUT
- , MAKE_FLATPTR(GET_SEG(SS), &cbw), sizeof(cbw));
+ , MAKE_FLATPTR(GET_SEG(SS), &cbw), sizeof(cbw));
if (ret)
goto fail;
static int
virtio_scsi_cmd(u16 ioaddr, struct vring_virtqueue *vq, struct disk_op_s *op,
- void *cdbcmd, u16 target, u16 lun, u32 len)
+ void *cdbcmd, u16 target, u16 lun, u16 blocksize)
{
struct virtio_scsi_req_cmd req;
struct virtio_scsi_resp_cmd resp;
req.lun[3] = (lun & 0xff);
memcpy(req.cdb, cdbcmd, 16);
- int datain = (req.cdb[0] != CDB_CMD_WRITE_10);
+ u32 len = op->count * blocksize;
+ int datain = cdb_is_read(cdbcmd, blocksize);
int data_idx = (datain ? 2 : 1);
int out_num = (datain ? 1 : 2);
int in_num = (len ? 3 : 2) - out_num;
return virtio_scsi_cmd(GET_GLOBAL(vlun->ioaddr),
GET_GLOBAL(vlun->vq), op, cdbcmd,
GET_GLOBAL(vlun->target), GET_GLOBAL(vlun->lun),
- blocksize * op->count);
+ blocksize);
}
static int