package org.jscsi.target.scsi.cdb; import java.nio.ByteBuffer; import org.jscsi.target.scsi.inquiry.PageCode; import org.jscsi.target.scsi.inquiry.PageCode.VitalProductDataPageName; import org.jscsi.target.scsi.inquiry.SupportedVpdPages; import org.jscsi.target.util.BitManip; import org.jscsi.target.util.ReadWrite; /** * This class represents Command Descriptor Blocks for the <code>INQUIRY</code> SCSI command. * * @author Andreas Ergenzinger */ public class InquiryCDB extends CommandDescriptorBlock { /** * An enable vital product data (EVPD) bit set to one specifies that the * device server shall return the vital product data specified by the PAGE * CODE field. * <p> * If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data. If the PAGE * CODE field is not set to zero when the EVPD bit is set to zero, the command shall be terminated with * CHECK CONDITION status, with the sense key set to ILLEGAL REQUEST, and the additional sense code set to * INVALID FIELD IN CDB. */ private final boolean enableVitalProductData; /** * The ALLOCATION LENGTH field specifies the maximum number of bytes that an * application client has allocated in the Data-In Buffer. An allocation * length of zero specifies that no data shall be transferred. This * condition shall not be considered as an error. The device server shall * terminate transfers to the Data-In Buffer when the number of bytes * specified by the ALLOCATION LENGTH field have been transferred or when * all available data have been transferred, whichever is less. * <p> * The allocation length is used to limit the maximum amount of variable length data (e.g., mode data, log * data, diagnostic data) returned to an application client. If the information being transferred to the * Data-In Buffer includes fields containing counts of the number of bytes in some or all of the data, * then the contents of these fields shall not be altered to reflect the truncation, if any, that results * from an insufficient ALLOCATION LENGTH value, unless the standard that describes the Data-In Buffer * format states otherwise. * <p> * If the amount of information to be transferred exceeds the maximum value that the ALLOCATION LENGTH * field is capable of specifying, the device server shall transfer no data and terminate the command with * CHECK CONDITION status, with the sense key set to ILLEGAL REQUEST, and the additional sense code set to * INVALID FIELD IN CDB. * <p> * If EVPD is set to zero, the allocation length should be at least five, so that the ADDITIONAL LENGTH * field in the parameter data is returned. If EVPD is set to one, the allocation length should be should * be at least four, so that the PAGE LENGTH field in the parameter data is returned. */ private final int allocationLength; /** * When the EVPD bit is set to one, the PAGE CODE field specifies which page * of vital product data information the device server shall return. */ private final PageCode pageCode; public InquiryCDB(ByteBuffer buffer) { super(buffer); // EVPD enableVitalProductData = BitManip.getBit(buffer.get(1),// byte 0);// bit number // page code pageCode = new PageCode(buffer.get(2)); // allocation length allocationLength = ReadWrite.readTwoByteInt(buffer, 3); final VitalProductDataPageName vpdpn = pageCode.getVitalProductDataPageName(); if (enableVitalProductData) { if (!SupportedVpdPages.vpdPageCodeSupported(vpdpn)) addIllegalFieldPointer(2);// page code not supported } else { /* * If the PAGE CODE field is not set to zero when the EVPD bit is * set to zero, the command shall be terminated with CHECK CONDITION * status, with the sense key set to ILLEGAL REQUEST, and the * additional sense code set to INVALID FIELD IN CDB. */ if (vpdpn != VitalProductDataPageName.SUPPORTED_VPD_PAGES) addIllegalFieldPointer(2);// value should be 0x00 } } public boolean getEnableVitalProductData() { return enableVitalProductData; } public PageCode getPageCode() { return pageCode; } public int getAllocationLength() { return allocationLength; } }