emulation.c 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. #include "qemu/osdep.h"
  2. #include "qemu/units.h"
  3. #include "qemu/bswap.h"
  4. #include "hw/scsi/emulation.h"
  5. int scsi_emulate_block_limits(uint8_t *outbuf, const SCSIBlockLimits *bl)
  6. {
  7. /* required VPD size with unmap support */
  8. memset(outbuf, 0, 0x3c);
  9. outbuf[0] = bl->wsnz; /* wsnz */
  10. if (bl->max_io_sectors) {
  11. /* optimal transfer length granularity. This field and the optimal
  12. * transfer length can't be greater than maximum transfer length.
  13. */
  14. stw_be_p(outbuf + 2, MIN(bl->min_io_size, bl->max_io_sectors));
  15. /* maximum transfer length */
  16. stl_be_p(outbuf + 4, bl->max_io_sectors);
  17. /* optimal transfer length */
  18. stl_be_p(outbuf + 8, MIN(bl->opt_io_size, bl->max_io_sectors));
  19. } else {
  20. stw_be_p(outbuf + 2, bl->min_io_size);
  21. stl_be_p(outbuf + 8, bl->opt_io_size);
  22. }
  23. /* max unmap LBA count */
  24. stl_be_p(outbuf + 16, bl->max_unmap_sectors);
  25. /* max unmap descriptors */
  26. stl_be_p(outbuf + 20, bl->max_unmap_descr);
  27. /* optimal unmap granularity; alignment is zero */
  28. stl_be_p(outbuf + 24, bl->unmap_sectors);
  29. /* max write same size, make it the same as maximum transfer length */
  30. stl_be_p(outbuf + 36, bl->max_io_sectors);
  31. return 0x3c;
  32. }