package org.jscsi.target.scsi.modeSense; import java.util.HashMap; import java.util.Map; /** * Mode Pages for direct-access block devices, as defined in SBC-3. * <p> * Instances of this enumeration are used to identify a requested or a returned {@link ModePage}. * * @author Andreas Ergenzinger */ public enum ModePageCode { APPLICATION_TAG_MODE_PAGE(0x0a, 0x02), BACKGROUND_CONTROL_MODE_PAGE(0x1c, 0x01), CACHING_MODE_PAGE(0x08, 0x00), CONTROL_EXTENSION_MODE_PAGE(0x0a, 0x01), CONTROL_MODE_PAGE(0x0a, 0x00), DISCONNECT_RECONNECT_MODE_PAGE(0x02, 0x00), ENCLOSURE_SERVICES_MANAGEMENT_MODE_PAGE(0x14, 0x00), // do // not // support, // since // ENCSERV // bit // in // Inquiry // data // is // 0 INFORMATIONAL_EXCEPTIONS_CONTROL_MODE_PAGE(0x1c, 0x00), LOGICAL_BLOCK_PROVISIONING_MODE_PAGE(0x1c, 0x02), POWER_CONDITION_MODE_PAGE(0x1a, 0x00), PROTOCOL_SPECIFIC_LUN_MODE_PAGE(0x18, 0x00), PROTOCOL_SPECIFIC_PORT_MODE_PAGE(0x19, 0x00), READ_WRITE_ERROR_RECOVERY_MODE_PAGE(0x01, 0x00), RETURN_ALL_MODE_PAGES_AND_SUBPAGES(0x3f, 0xff), RETURN_ALL_MODE_PAGES_ONLY(0x3f, 0x00), VERIFY_ERROR_RECOVERY_MODE_PAGE(0x07, 0x00), XOR_CONTROL_MODE_PAGE(0x10, 0x00), // for returning subpages of the above mode pages (subpageCode = 0xff) APPLICATION_TAG_MODE_PAGE_SUBPAGES(0x0a, 0xff), BACKGROUND_CONTROL_MODE_PAGE_SUBPAGES(0x1c, 0xff), CACHING_MODE_PAGE_SUBPAGES(0x08, 0xff), CONTROL_EXTENSION_MODE_PAGE_SUBPAGES(0x0a, 0xff), CONTROL_MODE_PAGE_SUBPAGES(0x0a, 0xff), DISCONNECT_RECONNECT_MODE_PAGE_SUBPAGES(0x02, 0xff), ENCLOSURE_SERVICES_MANAGEMENT_MODE_PAGE_SUBPAGES(0x14, 0xff), // do not support, since ENCSERV bit in // Inquiry data is 0 INFORMATIONAL_EXCEPTIONS_CONTROL_MODE_PAGE_SUBPAGES(0x1c, 0xff), LOGICAL_BLOCK_PROVISIONING_MODE_PAGE_SUBPAGES(0x1c, 0xff), POWER_CONDITION_MODE_PAGE_SUBPAGES(0x1a, 0xff), PROTOCOL_SPECIFIC_LUN_MODE_PAGE_SUBPAGES(0x18, 0xff), PROTOCOL_SPECIFIC_PORT_MODE_PAGE_SUBPAGES(0x19, 0xff), READ_WRITE_ERROR_RECOVERY_MODE_PAGE_SUBPAGES( 0x01, 0xff), VERIFY_ERROR_RECOVERY_MODE_PAGE_SUBPAGES(0x07, 0xff), XOR_CONTROL_MODE_PAGE_SUBPAGES(0x10, 0xff); /** * Allows the retrieval of {@link ModePageCode} instances based on merged * PAGE CODE and SUBPAGE CODE field values. * * @see #joinCodes(int, int) */ private static Map<Integer, ModePageCode> map = new HashMap<Integer, ModePageCode>(); static {// initialize map final ModePageCode[] modePages = values(); for (ModePageCode mp : modePages) map.put(joinCodes(mp.pageCode, mp.subpageCode),// key mp);// value } /** * Returns the {@link ModePageCode} instance identified by the passed * parameters. * * @param pageCode * determines the general category of a {@link ModePage} * @param subpageCode * determines the sub-category of a {@link ModePage} * @return the corresponding {@link ModePageCode} instance of <code> * null</code> if there is no corresponding object */ public static ModePageCode getModePage(final int pageCode, final int subpageCode) { return map.get(joinCodes(pageCode, subpageCode)); } /** * Determines the general category of the MODE PAGE. */ private final int pageCode; /** * Determines the sub-category of the MODE PAGE, if applicable. */ private final int subpageCode; /** * The constructor. * * @param pageCode * determines the general category of a {@link ModePage} * @param subpageCode * determines the sub-category of a {@link ModePage} */ private ModePageCode(final int pageCode, final int subpageCode) { this.pageCode = pageCode; this.subpageCode = subpageCode; } /** * Merges the the passed PAGE CODE and SUBPAGE CODE field values to a single * value * * @param pageCode * the value of a PAGE CODE field * @param subpageCode * the value of a SUBPAGE CODE field * @return a merged value containing the relevant bits from both parameters */ private static int joinCodes(final int pageCode, final int subpageCode) { return (pageCode << 8) | subpageCode; } }