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;
}
}