1 package org.jscsi.target.scsi.cdb; 2 3 4 import java.nio.ByteBuffer; 5 6 import org.jscsi.target.util.BitManip; 7 import org.jscsi.target.util.ReadWrite; 8 9 10 /** 11 * This class represents Command Descriptor Blocks for the <code>SEND DIAGNOSTIC</code> SCSI command. 12 * 13 * @author Andreas Ergenzinger 14 */ 15 public final class SendDiagnosticCdb extends CommandDescriptorBlock { 16 17 /** 18 * If the {@link #selfTest} bit is set to one, the {@link #selfTestCode} field shall contain 000b ( 19 * {@link SelfTestCode#ALL_ZEROS}. If the SELFTEST bit is set to zero, the contents of SELF-TEST CODE specifies 20 * which diagnostic operation the device server shall perform. 21 * 22 * @see SelfTestCode 23 */ 24 private final SelfTestCode selfTestCode; 25 26 /** 27 * A self-test (SELFTEST) bit set to one specifies that the device server shall perform the logical unit default 28 * self-test. 29 * <p> 30 * A SELFTEST bit set to zero specifies that the device server shall perform the diagnostic operation specified by 31 * the {@link #selfTestCode} field or in the parameter list. 32 * <p> 33 * Only support for the default self-test feature, as required by SPC-3, is implemented. Request for other types of 34 * self-test operations will be declined. 35 */ 36 private final boolean selfTest; 37 38 /** 39 * A page format (PF) bit set to one specifies that the SEND DIAGNOSTIC parameters and any parameters returned by a 40 * following RECEIVE DIAGNOSTIC RESULTS command with the PCV bit set to zero shall contain a single diagnostic page. 41 * <p> 42 * A PF bit set to zero specifies that all SEND DIAGNOSTIC parameters are vendor specific. If the PARAMETER LIST 43 * LENGTH field is set to zero and the SEND DIAGNOSTIC command is not going to be followed by a corresponding 44 * RECEIVE DIAGNOSTIC RESULTS command with the PCV bit set to zero, then the application client shall set the PF bit 45 * to zero. 46 * <p> 47 * The implementation of the PF bit is optional and therefore not supported by the jSCSI Target. 48 */ 49 private final boolean pageFormat; 50 51 /** 52 * A unit offline (UNITOFFL) bit set to one specifies that the device server may perform diagnostic operations that 53 * may affect the user accessible medium on the logical unit (e.g., write operations to the user accessible medium, 54 * or repositioning of the medium on sequential access devices). The device server may ignore the UNITOFFL bit. A 55 * UNITOFFL bit set to zero prohibits any diagnostic operations that may be detected by subsequent tasks. When the 56 * {@link #selfTest} bit is set to zero, the UNITOFFL bit shall be ignored. 57 */ 58 private final boolean unitOffline; 59 60 /** 61 * A SCSI target device offline (DEVOFFL) bit set to one grants permission to the device server to perform 62 * diagnostic operations that may affect all the logical units in the SCSI target device (e.g., alteration of 63 * reservations, log parameters, or sense data). The device server may ignore the DEVOFFL bit. A DEVOFFL bit set to 64 * zero prohibits diagnostic operations that may be detected by subsequent tasks. When the {@link #selfTest} bit is 65 * set to zero, the DEVOFFL bit shall be ignored. 66 */ 67 private final boolean deviceOffline; 68 69 /** 70 * The PARAMETER LIST LENGTH field specifies the length in bytes of the parameter list that shall be transferred 71 * from the application client Data-Out Buffer to the device server. A parameter list length of zero specifies that 72 * no data shall be transferred. This condition shall not be considered an error. If PF bit is set to one and the 73 * specified parameter list length results in the truncation of the diagnostic page (e.g., the parameter list length 74 * does not match the page length specified in the diagnostic page), then the command shall be terminated with CHECK 75 * CONDITION status, with the sense key set to ILLEGAL REQUEST, and the additional sense code set to INVALID FIELD 76 * IN CDB. 77 */ 78 private final short parameterListLength; 79 80 public SendDiagnosticCdb (ByteBuffer buffer) { 81 super(buffer); 82 83 // deserialize specific fields 84 final byte b = buffer.get(1); 85 86 // self test 87 selfTest = BitManip.getBit(b, 2); 88 if (!selfTest) addIllegalFieldPointer(1, 2);// only the default self-test feature 89 // is supported 90 91 // self test code 92 selfTestCode = SelfTestCode.getValue(b >>> 5); 93 if (selfTest && selfTestCode != SelfTestCode.ALL_ZEROS) addIllegalFieldPointer(1, 7); 94 95 // page format 96 pageFormat = BitManip.getBit(b, 4); 97 if (pageFormat) addIllegalFieldPointer(1, 4);// The implementation of the PF bit is 98 // optional. 99 100 // device offline 101 deviceOffline = BitManip.getBit(b, 1); 102 103 // unit offline 104 unitOffline = BitManip.getBit(b, 0); 105 106 // parameter list length 107 parameterListLength = (short) ReadWrite.readTwoByteInt(buffer, 3); 108 } 109 110 public final boolean getSelfTest () { 111 return selfTest; 112 } 113 114 public final SelfTestCode getSelfTestCode () { 115 return selfTestCode; 116 } 117 118 public final boolean getPageFormat () { 119 return pageFormat; 120 } 121 122 public final boolean getUnitOffline () { 123 return unitOffline; 124 } 125 126 public final boolean getDeviceOffline () { 127 return deviceOffline; 128 } 129 130 public final short getParameterListLength () { 131 return parameterListLength; 132 } 133 134 }