public static string PrettifyModePage_0A(ModePage_0A?modePage) { if (!modePage.HasValue) { return(null); } ModePage_0A page = modePage.Value; var sb = new StringBuilder(); sb.AppendLine("SCSI Control mode page:"); if (page.PS) { sb.AppendLine("\tParameters can be saved"); } if (page.RLEC) { sb.AppendLine("\tIf set, target shall report log exception conditions"); } if (page.DQue) { sb.AppendLine("\tTagged queuing is disabled"); } if (page.EECA) { sb.AppendLine("\tExtended Contingent Allegiance is enabled"); } if (page.RAENP) { sb.AppendLine("\tTarget may issue an asynchronous event notification upon completing its initialization"); } if (page.UAAENP) { sb.AppendLine("\tTarget may issue an asynchronous event notification instead of a unit attention condition"); } if (page.EAENP) { sb.AppendLine("\tTarget may issue an asynchronous event notification instead of a deferred error"); } if (page.GLTSD) { sb.AppendLine("\tGlobal logging target save disabled"); } if (page.RAC) { sb.AppendLine("\tCHECK CONDITION should be reported rather than a long busy condition"); } if (page.SWP) { sb.AppendLine("\tSoftware write protect is active"); } if (page.TAS) { sb.AppendLine("\tTasks aborted by other initiator's actions should be terminated with TASK ABORTED"); } if (page.TMF_ONLY) { sb.AppendLine("\tAll tasks received in nexus with ACA ACTIVE is set and an ACA condition is established shall terminate"); } if (page.D_SENSE) { sb.AppendLine("\tDevice shall return descriptor format sense data when returning sense data in the same transactions as a CHECK CONDITION"); } if (page.ATO) { sb.AppendLine("\tLOGICAL BLOCK APPLICATION TAG should not be modified"); } if (page.DPICZ) { sb.AppendLine("\tProtector information checking is disabled"); } if (page.NUAR) { sb.AppendLine("\tNo unit attention on release"); } if (page.ATMPE) { sb.AppendLine("\tApplication Tag mode page is enabled"); } if (page.RWWP) { sb.AppendLine("\tAbort any write command without protection information"); } if (page.SBLP) { sb.AppendLine("\tSupportes block lengths and protection information"); } switch (page.TST) { case 0: sb.AppendLine("\tThe logical unit maintains one task set for all nexuses"); break; case 1: sb.AppendLine("\tThe logical unit maintains separate task sets for each nexus"); break; default: sb.AppendFormat("\tUnknown Task set type {0}", page.TST).AppendLine(); break; } switch (page.QueueAlgorithm) { case 0: sb.AppendLine("\tCommands should be sent strictly ordered"); break; case 1: sb.AppendLine("\tCommands can be reordered in any manner"); break; default: sb.AppendFormat("\tUnknown Queue Algorithm Modifier {0}", page.QueueAlgorithm).AppendLine(); break; } switch (page.QErr) { case 0: sb.AppendLine("\tIf ACA is established, the task set commands shall resume after it is cleared, otherwise they shall terminate with CHECK CONDITION"); break; case 1: sb.AppendLine("\tAll the affected commands in the task set shall be aborted when CHECK CONDITION is returned"); break; case 3: sb.AppendLine("\tAffected commands in the task set belonging with the CHECK CONDITION nexus shall be aborted"); break; default: sb.AppendLine("\tReserved QErr value 2 is set"); break; } switch (page.UA_INTLCK_CTRL) { case 0: sb.AppendLine("\tLUN shall clear unit attention condition reported in the same nexus"); break; case 2: sb.AppendLine("\tLUN shall not clear unit attention condition reported in the same nexus"); break; case 3: sb.AppendLine("\tLUN shall not clear unit attention condition reported in the same nexus and shall establish a unit attention condition for the initiator"); break; default: sb.AppendLine("\tReserved UA_INTLCK_CTRL value 1 is set"); break; } switch (page.AutoloadMode) { case 0: sb.AppendLine("\tOn medium insertion, it shall be loaded for full access"); break; case 1: sb.AppendLine("\tOn medium insertion, it shall be loaded for auxiliary memory access only"); break; case 2: sb.AppendLine("\tOn medium insertion, it shall not be loaded"); break; default: sb.AppendFormat("\tReserved autoload mode {0} set", page.AutoloadMode).AppendLine(); break; } if (page.ReadyAENHoldOffPeriod > 0) { sb.AppendFormat("\t{0} ms before attempting asynchronous event notifications after initialization", page.ReadyAENHoldOffPeriod).AppendLine(); } if (page.BusyTimeoutPeriod > 0) { if (page.BusyTimeoutPeriod == 0xFFFF) { sb.AppendLine("\tThere is no limit on the maximum time that is allowed to remain busy"); } else { sb.AppendFormat("\tA maximum of {0} ms are allowed to remain busy", page.BusyTimeoutPeriod * 100). AppendLine(); } } if (page.ExtendedSelfTestCompletionTime > 0) { sb.AppendFormat("\t{0} seconds to complete extended self-test", page.ExtendedSelfTestCompletionTime); } return(sb.ToString()); }
public static ModePage_0A?DecodeModePage_0A(byte[] pageResponse) { if ((pageResponse?[0] &0x40) == 0x40) { return(null); } if ((pageResponse?[0] &0x3F) != 0x0A) { return(null); } if (pageResponse[1] + 2 != pageResponse.Length) { return(null); } if (pageResponse.Length < 8) { return(null); } var decoded = new ModePage_0A(); decoded.PS |= (pageResponse[0] & 0x80) == 0x80; decoded.RLEC |= (pageResponse[2] & 0x01) == 0x01; decoded.QueueAlgorithm = (byte)((pageResponse[3] & 0xF0) >> 4); decoded.QErr = (byte)((pageResponse[3] & 0x06) >> 1); decoded.DQue |= (pageResponse[3] & 0x01) == 0x01; decoded.EECA |= (pageResponse[4] & 0x80) == 0x80; decoded.RAENP |= (pageResponse[4] & 0x04) == 0x04; decoded.UAAENP |= (pageResponse[4] & 0x02) == 0x02; decoded.EAENP |= (pageResponse[4] & 0x01) == 0x01; decoded.ReadyAENHoldOffPeriod = (ushort)((pageResponse[6] << 8) + pageResponse[7]); if (pageResponse.Length < 10) { return(decoded); } // SPC-1 decoded.GLTSD |= (pageResponse[2] & 0x02) == 0x02; decoded.RAC |= (pageResponse[4] & 0x40) == 0x40; decoded.SWP |= (pageResponse[4] & 0x08) == 0x08; decoded.BusyTimeoutPeriod = (ushort)((pageResponse[8] << 8) + pageResponse[9]); // SPC-2 decoded.TST = (byte)((pageResponse[2] & 0xE0) >> 5); decoded.TAS |= (pageResponse[4] & 0x80) == 0x80; decoded.AutoloadMode = (byte)(pageResponse[5] & 0x07); decoded.BusyTimeoutPeriod = (ushort)((pageResponse[10] << 8) + pageResponse[11]); // SPC-3 decoded.TMF_ONLY |= (pageResponse[2] & 0x10) == 0x10; decoded.D_SENSE |= (pageResponse[2] & 0x04) == 0x04; decoded.UA_INTLCK_CTRL = (byte)((pageResponse[4] & 0x30) >> 4); decoded.TAS |= (pageResponse[5] & 0x40) == 0x40; decoded.ATO |= (pageResponse[5] & 0x80) == 0x80; // SPC-5 decoded.DPICZ |= (pageResponse[2] & 0x08) == 0x08; decoded.NUAR |= (pageResponse[3] & 0x08) == 0x08; decoded.ATMPE |= (pageResponse[5] & 0x20) == 0x20; decoded.RWWP |= (pageResponse[5] & 0x10) == 0x10; decoded.SBLP |= (pageResponse[5] & 0x08) == 0x08; return(decoded); }