package org.jscsi.target.scsi.inquiry; import java.nio.ByteBuffer; import org.jscsi.target.Target; import org.jscsi.target.scsi.IResponseData; import org.jscsi.target.util.ReadWrite; /** * The Device Identification VPD page provides the means to retrieve * identification descriptors applying to the logical unit. Logical units may * have more than one identification descriptor (e.g., if several types or * associations of identifier are supported). * <p> * Device identifiers consist of one or more of the following: * <ul> * <li>Logical unit names</li> * <li>SCSI target port identifiers</li> * <li>SCSI target port names</li> * <li>SCSI target device names</li> * <li>Relative target port identifiers</li> * <li>SCSI target port group number or</li> * <li>Logical unit group number.</li> * </ul> * Identification descriptors shall be assigned to the peripheral device (e.g., a disk drive) and not to the * currently mounted media, in the case of removable media devices. Operating systems are expected to use the * identification descriptors during system configuration activities to determine whether alternate paths * exist for the same peripheral device. * <p> * This class uses the singleton pattern since the content of the DEVICE IDENTIFICATION VPD PAGE will never * change. * * @author Andreas Ergenzinger */ public class DeviceIdentificationVpdPage implements IResponseData { /** * The total length of all mandatory fields in bytes. */ private static final int HEADER_LENGTH = 4; /** * The position of the PAGE LENGTH field's most significant byte. */ private static final int PAGE_LENGTH_FIELD_INDEX = 2; /** * The joint content of the PERIPHERAL QUALIFIER and the PERIPHERAL DEVICE * TYPE fields with a total length of one byte. * <p> * These values have the following meaning: * <p> * A peripheral device having the specified peripheral device type is connected to this logical unit. If * the device server is unable to determine whether or not a peripheral device is connected, it also shall * use this peripheral qualifier. This peripheral qualifier does not mean that the peripheral device * connected to the logical unit is ready for access. * <p> * The Logical Unit is a direct access block device (e.g., magnetic disk). */ private final byte peripheralQualifierAndPeripheralDeviceType = 0; /** * Identifies this PAGE as a DEVICE IDENTIFICATION VPD PAGE. */ private final byte pageCode = (byte)0x83; private final IdentificationDescriptor[] identificationDescriptors; public DeviceIdentificationVpdPage(Target target) { /* * For each logical unit that is not a well known logical unit, the * Device Identification VPD page shall include at least one * identification descriptor in which a logical unit name (see SAM-3) is * indicated. */ final ProtocolIdentifier protocolIdentifier = ProtocolIdentifier.INTERNET_SCSI; final CodeSet codeSet = CodeSet.UTF8_CODES; final boolean protocolIdentifierValid = true; final Association association = Association.SCSI_TARGET_DEVICE; final IdentifierType identifierType = IdentifierType.SCSI_NAME_STRING; String targetName = target.getTargetName(); // OODRIVE identificationDescriptors = new IdentificationDescriptor[1]; // OODRIVE for (int curTargetNum = 0; curTargetNum < targetNames.length; curTargetNum++) { final IdentificationDescriptor identDescriptor = new IdentificationDescriptor(protocolIdentifier, codeSet, protocolIdentifierValid, association, identifierType, new ScsiNameStringIdentifier(targetName)); identificationDescriptors[0] = identDescriptor; // OODRIVE } } /** * Returns the combined length of all contained IDENTIFICATION DESCRIPTORs. * * @return the combined length of all contained IDENTIFICATION DESCRIPTORs */ private short getPageLength() { short pageLength = 0; for (int i = 0; i < identificationDescriptors.length; ++i) { pageLength += (identificationDescriptors[i].size()); } return pageLength; } public void serialize(ByteBuffer byteBuffer, int index) { // serialize header byteBuffer.position(index); byteBuffer.put(peripheralQualifierAndPeripheralDeviceType); byteBuffer.put(pageCode); ReadWrite.writeTwoByteInt(byteBuffer,// buffer getPageLength(), index + PAGE_LENGTH_FIELD_INDEX);// index } public int size() { return getPageLength() + HEADER_LENGTH; } }