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