[SeaBIOS] usb-msc.c: TEST_UNIT_READY needs USB_DIR_OUT?

Paolo Bonzini pbonzini at redhat.com
Thu Mar 15 09:04:41 CET 2012


Il 15/03/2012 03:44, Peter Stuge ha scritto:
> Kevin O'Connor wrote:
>> Subject: [PATCH] Use OUT mode for all zero byte "scsi" transfers.
> ..
>> +++ b/src/blockcmd.c
>> @@ -35,6 +35,13 @@ cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
>>      }
>>  }
>>  
>> +// 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;
>> +}
> 
> Suggest that this only evaluates commands, ..

blocksize == 0 identifies a command that has no DMA, so it's a good way
to catch all the problematic commands, in case more are added in the future.
> 
>> diff --git a/src/usb-msc.c b/src/usb-msc.c
>> index dadb9ca..c53a1f5 100644
>> --- a/src/usb-msc.c
>> +++ b/src/usb-msc.c
>> @@ -77,13 +77,13 @@ usb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
>>      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;
> 
> ..and that blocksize is checked here:
> 
> cbw.bmCBWFlags = cdb_is_read(&cbw) && blocksize ? USB_DIR_IN : USB_DIR_OUT;

That would duplicate the check in virtio-scsi too.

>> diff --git a/src/virtio-scsi.c b/src/virtio-scsi.c
>> index 3c59438..50339d7 100644
>> --- a/src/virtio-scsi.c
>> +++ b/src/virtio-scsi.c
>> @@ -31,7 +31,7 @@ struct virtio_lun_s {
>>  
>>  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;
>> @@ -44,7 +44,8 @@ virtio_scsi_cmd(u16 ioaddr, struct vring_virtqueue *vq, struct disk_op_s *op,
>>      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;
>> @@ -89,7 +90,7 @@ virtio_scsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
>>      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);
>>  }
> 
> This also seems to be an unrelated change?

virtio_scsi_cmd needs blocksize to pass it to cdb_is_read.  So it's related.

FWIW,

Acked-by: Paolo Bonzini <pbonzini at redhat.com>

Paolo





More information about the SeaBIOS mailing list