1 package org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific; 2 3 4 import java.nio.ByteBuffer; 5 6 import org.jscsi.target.scsi.ISerializable; 7 import org.jscsi.target.scsi.sense.SenseData; 8 import org.jscsi.target.scsi.sense.SenseKey; 9 import org.jscsi.target.util.BitManip; 10 11 12 /** 13 * SENSE-KEY-SPECIFIC DATA further defines the reason for a CHECK CONDITION SCSI response status. 14 * <p> 15 * The definition of the SENSE KEY SPECIFIC field is determined by the value of the enclosing sense data's 16 * {@link SenseData#senseKey} field. 17 * 18 * <table border="1"> 19 * <tr> 20 * <th>Sense Key</th> 21 * <th>Sense Key Specific Field Definition</th> 22 * </tr> 23 * <tr> 24 * <td>{@link SenseKey#ILLEGAL_REQUEST}</td> 25 * <td>Field Pointer (see {@link FieldPointerSenseKeySpecificData})</td> 26 * </tr> 27 * <tr> 28 * <td>{@link SenseKey#HARDWARE_ERROR},<br> 29 * {@link SenseKey#MEDIUM_ERROR}, or<br> 30 * {@link SenseKey#RECOVERED_ERROR}</td> 31 * <td>Actual Retry Count (see {@link ActualRetryCountSenseKeySpecificData})</td> 32 * </tr> 33 * <tr> 34 * <td>{@link SenseKey#NO_SENSE} or<br> 35 * {@link SenseKey#NOT_READY}</td> 36 * <td>Progress Indication (see {@link ProgressIndicationSenseKeySpecificData})</td> 37 * </tr> 38 * <tr> 39 * <td>{@link SenseKey#COPY_ABORTED}</td> 40 * <td>Segment Pointer (see {@link SegmentPointerSenseKeySpecificData})</td> 41 * </tr> 42 * <tr> 43 * <td>All other Sense Keys</td> 44 * <td>The sense key specific sense data descriptor shall not<br> 45 * appear in the descriptor format sense data and the<br> 46 * SKSV (Sense Key Specific Field Valid) bit shall be set to<br> 47 * zero in the fixed format sense data.</td> 48 * </tr> 49 * </table> 50 * 51 * @author Andreas Ergenzinger 52 */ 53 public abstract class SenseKeySpecificData implements ISerializable { 54 55 /** 56 * The serialized length in bytes of SENSE-KEY-SPECIFIC DATA. 57 */ 58 public static final int SIZE = 3; 59 60 /** 61 * <code>true</code> if and only if the information fields of this data object are valid. 62 */ 63 protected final boolean senseKeySpecificDataValid; 64 65 /** 66 * The absctract constructor. 67 * 68 * @param senseKeySpecificDataValid <code>true</code> if and only if the information fields of this data object are 69 * valid 70 */ 71 public SenseKeySpecificData (final boolean senseKeySpecificDataValid) { 72 this.senseKeySpecificDataValid = senseKeySpecificDataValid; 73 } 74 75 /** 76 * Serializes the fields common to all sense-key-specific data. 77 * 78 * @param byteBuffer where the serialized fields will be stored 79 * @param index the position of the first byte of the sense data descriptor in the {@link ByteBuffer} 80 */ 81 private final void serializeCommonFields (final ByteBuffer byteBuffer, final int index) { 82 byteBuffer.position(index); 83 byte b = 0; 84 if (senseKeySpecificDataValid) b = BitManip.getByteWithBitSet(b, 7, true);// set MSB to 1 85 byteBuffer.put(b); 86 } 87 88 /** 89 * Serializes all fields which are not common to all sense-key-specific data, which means those that are 90 * sub-type-specific. 91 * 92 * @param byteBuffer where the serialized fields will be stored 93 * @param index the position of the first byte of the sense data descriptor in the {@link ByteBuffer} 94 */ 95 protected abstract void serializeSpecificFields (ByteBuffer byteBuffer, final int index); 96 97 public void serialize (ByteBuffer byteBuffer, int index) { 98 serializeCommonFields(byteBuffer, index); 99 serializeSpecificFields(byteBuffer, index); 100 } 101 102 public int size () { 103 return SIZE; 104 } 105 }