1 package org.jscsi.target.scsi.cdb; 2 3 4 import java.nio.ByteBuffer; 5 6 import org.jscsi.target.scsi.inquiry.PageCode; 7 import org.jscsi.target.scsi.inquiry.PageCode.VitalProductDataPageName; 8 import org.jscsi.target.scsi.inquiry.SupportedVpdPages; 9 import org.jscsi.target.util.BitManip; 10 import org.jscsi.target.util.ReadWrite; 11 12 13 /** 14 * This class represents Command Descriptor Blocks for the <code>INQUIRY</code> SCSI command. 15 * 16 * @author Andreas Ergenzinger 17 */ 18 public class InquiryCDB extends CommandDescriptorBlock { 19 20 /** 21 * An enable vital product data (EVPD) bit set to one specifies that the device server shall return the vital 22 * product data specified by the PAGE CODE field. 23 * <p> 24 * If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data. If the PAGE CODE field 25 * is not set to zero when the EVPD bit is set to zero, the command shall be terminated with CHECK CONDITION status, 26 * with the sense key set to ILLEGAL REQUEST, and the additional sense code set to INVALID FIELD IN CDB. 27 */ 28 private final boolean enableVitalProductData; 29 30 /** 31 * The ALLOCATION LENGTH field specifies the maximum number of bytes that an application client has allocated in the 32 * Data-In Buffer. An allocation length of zero specifies that no data shall be transferred. This condition shall 33 * not be considered as an error. The device server shall terminate transfers to the Data-In Buffer when the number 34 * of bytes specified by the ALLOCATION LENGTH field have been transferred or when all available data have been 35 * transferred, whichever is less. 36 * <p> 37 * The allocation length is used to limit the maximum amount of variable length data (e.g., mode data, log data, 38 * diagnostic data) returned to an application client. If the information being transferred to the Data-In Buffer 39 * includes fields containing counts of the number of bytes in some or all of the data, then the contents of these 40 * fields shall not be altered to reflect the truncation, if any, that results from an insufficient ALLOCATION 41 * LENGTH value, unless the standard that describes the Data-In Buffer format states otherwise. 42 * <p> 43 * If the amount of information to be transferred exceeds the maximum value that the ALLOCATION LENGTH field is 44 * capable of specifying, the device server shall transfer no data and terminate the command with CHECK CONDITION 45 * status, with the sense key set to ILLEGAL REQUEST, and the additional sense code set to INVALID FIELD IN CDB. 46 * <p> 47 * If EVPD is set to zero, the allocation length should be at least five, so that the ADDITIONAL LENGTH field in the 48 * parameter data is returned. If EVPD is set to one, the allocation length should be should be at least four, so 49 * that the PAGE LENGTH field in the parameter data is returned. 50 */ 51 private final int allocationLength; 52 53 /** 54 * When the EVPD bit is set to one, the PAGE CODE field specifies which page of vital product data information the 55 * device server shall return. 56 */ 57 private final PageCode pageCode; 58 59 public InquiryCDB (ByteBuffer buffer) { 60 super(buffer); 61 62 // EVPD 63 enableVitalProductData = BitManip.getBit(buffer.get(1),// byte 64 0);// bit number 65 66 // page code 67 pageCode = new PageCode(buffer.get(2)); 68 69 // allocation length 70 allocationLength = ReadWrite.readTwoByteInt(buffer, 3); 71 72 final VitalProductDataPageName vpdpn = pageCode.getVitalProductDataPageName(); 73 if (enableVitalProductData) { 74 if (!SupportedVpdPages.vpdPageCodeSupported(vpdpn)) addIllegalFieldPointer(2);// page code not supported 75 } else { 76 /* 77 * If the PAGE CODE field is not set to zero when the EVPD bit is set to zero, the command shall be 78 * terminated with CHECK CONDITION status, with the sense key set to ILLEGAL REQUEST, and the additional 79 * sense code set to INVALID FIELD IN CDB. 80 */ 81 if (vpdpn != VitalProductDataPageName.SUPPORTED_VPD_PAGES) addIllegalFieldPointer(2);// value should be 0x00 82 } 83 } 84 85 public boolean getEnableVitalProductData () { 86 return enableVitalProductData; 87 } 88 89 public PageCode getPageCode () { 90 return pageCode; 91 } 92 93 public int getAllocationLength () { 94 return allocationLength; 95 } 96 }