43 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			43 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#include "qemu/osdep.h"
							 | 
						||
| 
								 | 
							
								#include "qemu/units.h"
							 | 
						||
| 
								 | 
							
								#include "qemu/bswap.h"
							 | 
						||
| 
								 | 
							
								#include "hw/scsi/emulation.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int scsi_emulate_block_limits(uint8_t *outbuf, const SCSIBlockLimits *bl)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* required VPD size with unmap support */
							 | 
						||
| 
								 | 
							
								    memset(outbuf, 0, 0x3c);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    outbuf[0] = bl->wsnz; /* wsnz */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (bl->max_io_sectors) {
							 | 
						||
| 
								 | 
							
								        /* optimal transfer length granularity.  This field and the optimal
							 | 
						||
| 
								 | 
							
								         * transfer length can't be greater than maximum transfer length.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        stw_be_p(outbuf + 2, MIN(bl->min_io_size, bl->max_io_sectors));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* maximum transfer length */
							 | 
						||
| 
								 | 
							
								        stl_be_p(outbuf + 4, bl->max_io_sectors);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* optimal transfer length */
							 | 
						||
| 
								 | 
							
								        stl_be_p(outbuf + 8, MIN(bl->opt_io_size, bl->max_io_sectors));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        stw_be_p(outbuf + 2, bl->min_io_size);
							 | 
						||
| 
								 | 
							
								        stl_be_p(outbuf + 8, bl->opt_io_size);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* max unmap LBA count */
							 | 
						||
| 
								 | 
							
								    stl_be_p(outbuf + 16, bl->max_unmap_sectors);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* max unmap descriptors */
							 | 
						||
| 
								 | 
							
								    stl_be_p(outbuf + 20, bl->max_unmap_descr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* optimal unmap granularity; alignment is zero */
							 | 
						||
| 
								 | 
							
								    stl_be_p(outbuf + 24, bl->unmap_sectors);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* max write same size, make it the same as maximum transfer length */
							 | 
						||
| 
								 | 
							
								    stl_be_p(outbuf + 36, bl->max_io_sectors);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 0x3c;
							 | 
						||
| 
								 | 
							
								}
							 |