View Javadoc

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  }