/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <sys/sysmacros.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <values.h>
#include <unistd.h>
#include <pthread.h>
#include <devid.h>
#include <libgen.h>
#include <libdevinfo.h>
#include "disklog.h"
#include "libdisklog.h"
/*
* Debug output function. Prints messages to stdout only if debug flag
* debug_mode is set to true.
*/
/*PRINTFLIKE1*/
void
{
if (!debug_mode)
return;
}
static void
{
int ret;
if (ret < 0) {
}
}
static void
{
int i;
char *name_string;
/*
* Define the command string. For INQUIRY command, use page_code
* to specify if evpd is set, if yes, the subpage_code stands for
* the vpd page number. For vendor specific commands, both the
* page_code and the subpage_code are zero, which means the command
* doesn't need them.
*/
const struct page_strings {
char *message;
} extended_page_strings[] = {
"Software Interface Identification" },
"Management Network Addresses" },
"Protocol Specific Logical Unit Information" },
"Protocol Specific Port Information" },
"Block Device Characteristics VPD page" },
"Read Reverse Error Counter Log Page" },
"Verify Error Counter Log Page" },
"Last N Deferred Errors or Asynchronous Events Log Page" },
"Start-Stop Cycle Counter Log Page" },
"Background Scan Results Log Page" },
"Protocol-Specific Port Log Page" },
"General Statistics and Performance Log Page" },
"Power Condition Transitions Log Page" },
"Informational Exceptions Log Page" },
"Read-Write Error Recovery Mode Page" },
"Disconnect-Reconnect Mode Page" },
"Verify Error Recovery Mode Page" },
"Control Extension Mode Page" },
"Enclosure Services Management Mode Page" },
"Extended Device-Type Specific Mode Page" },
"Protocol Specific Logical Unit Mode Page" },
"Protocol Specific Port Mode Page" },
"Informational Exceptions Control Mode Page" },
"Background Control Mode Page" },
"Thin Provisioning Mode Page" },
"Supported Mode Pages and Subpages" },
"HITACHI VIPER-A Log Dump Command" },
"SEAGATE Drive Read Command" },
};
switch (cmd) {
case SPC3_CMD_INQUIRY:
"---- %s(evpd-%02xh,pc-%02xh) ----\n",
return;
case SPC3_CMD_LOG_SENSE:
"---- %s(pc-%02xh) ----\n",
return;
case SPC3_CMD_MODE_SENSE10:
"---- %s(pc-%02xh,spc-%02xh) ----\n",
return;
default:
return;
}
}
}
switch (cmd) {
case SPC3_CMD_INQUIRY:
"---- Vendor Specific INQUIRY Data(evpd-%02xh,pc-%02xh) "
return;
case SPC3_CMD_LOG_SENSE:
"---- Vendor Specific Log Page(pc-%02xh) ----\n",
return;
case SPC3_CMD_MODE_SENSE10:
"---- Vendor Specific Mode Page(pc-%02xh,spc-%02xh) ----\n",
return;
default:
"---- Unknown command(pc-%02xh,spc-%02xh) ----\n",
return;
}
}
static void
{
int i, j;
for (i = 0; i < len; i += 16) {
for (j = i; j < i + 16 && j < len; j++)
}
}
static void
{
int i;
for (i = 0; i < len; i++)
}
static void
{
int i;
for (i = 1; i < len; i++) {
}
}
static int
{
else
sizeof (struct spc3_inquiry_vpd_header))));
}
static boolean_t
{
int i;
for (i = 0; i < len; i++)
return (B_TRUE);
return (B_FALSE);
}
static void
{
int i;
for (i = 0; i < len; i++)
}
static void
{
int i;
for (i = 0; i < len; i++)
flags);
}
static void
{
int i;
};
for (i = 0; i < sizeof (basic_inquiry_vpd_pages) /
sizeof (spc3_inquiry_page_code_t); i++)
if ((is_vpd_page_supported(
flags);
}
static void
{
"PERIPHERAL DEVICE TYPE: %d PERIPHERAL QUALIFIER : %d\n"
"RMB : %d VERSION : %d RESPONSE DATA FORMAT : %d\n"
"HISUP : %d NORMACA : %d ADDITIONAL LENGTH : %d\n"
"PROTECT: %d 3PC : %d TPGS : %d ACC: %d\n"
"SCCS : %d ADDR16 : %d MCHANGER: %d MULTIP: %d\n"
"VS_6_5 : %d ENCSERV : %d BQUE : %d VS_7_0: %d\n"
"CMDQUE : %d LINKED : %d SYNC : %d WBUS16: %d\n"
"VENDOR_ID : %.8s\n"
"PRODUCT_ID : %.16s\n"
"PRODUCT_REVISION : %.4s\n"
"IUS : %d QAS : %d CLOCKING: %d\n"
"VERSION_DESCRIPTORS : %d\n\n",
}
static void
{
int i;
for (i = sizeof (struct spc3_inquiry_vpd_header); i < len; i++)
}
static void
{
int i, j;
int desc_len;
const struct vpd_protocol_id {
int pid;
char *id_str;
} extended_vpd_protocol_id[] = {
{ SPC3_IVDI_PI_FIBRE, "FIBRE CHANNEL" },
{ SPC3_IVDI_PI_SCSI, "PARALLEL SCSI" },
{ SPC3_IVDI_PI_SSA, "SSA" },
{ SPC3_IVDI_PI_IEEE, "IEEE 1394" },
{ SPC3_IVDI_PI_SRP, "SCSI REMOTE DIRECT MEMORY ACCESS PROTOCOL" },
{ SPC3_IVDI_PI_ISCSI, "ISCSI" },
{ SPC3_IVDI_PI_SAS, "SAS SERIAL SCSI PROTOCOL" },
{ SPC3_IVDI_PI_ADT, "AUTO/DRIVE INTERFACE TRANSPORT PROTOCOL" },
{ SPC3_IVDI_PI_ATA, "ATA/ATAPI" },
{ SPC3_IVDI_PI_NONE, "NO SPECIFIC PROTOCOL" },
{ 0xff, NULL }
};
const struct vpd_code_set {
int vpd_code;
char *vpd_cs_str;
} extended_vpd_code_set[] = {
{ SPC3_IVDI_CS_BINARY, "BINARY " },
{ SPC3_IVDI_CS_ASCII, "ASCII " },
{ SPC3_IVDI_CS_UTF, "UTF-8 " },
{ 0xff, NULL }
};
const struct vpd_id_type {
int vpd_code;
char *vpd_id_type_str;
} extended_vpd_id_type[] = {
{ SPC3_IVDI_TYPE_VENDOR_SPECIFIC, "VENDOR SPECIFIC" },
{ SPC3_IVDI_TYPE_T10, "T10 VENDOR ID BASED" },
{ SPC3_IVDI_TYPE_EUI64, "EUI-64 BASED" },
{ SPC3_IVDI_TYPE_NAA, "NAA" },
{ SPC3_IVDI_TYPE_TGT_PORT, "RELATIVE TARGET PORT IDENTIFIER" },
{ SPC3_IVDI_TYPE_TGT_PORT_GROUP, "TARGET PORT GROUP" },
{ SPC3_IVDI_TYPE_LU_GROUP, "LOGICAL UNIT GROUP" },
{ SPC3_IVDI_TYPE_MD5_LU, "MD5 LOGICAL UNIT IDENTIFIER" },
{ SPC3_IVDI_TYPE_SCSI_NAME_STRING, "SCSI NAME STRING" },
{ 0xff, NULL }
};
const char *str_association[] = {
"ASSOCIATED WITH THE ADDRESSED LU",
"ASSOCIATED WITH THE TARGET PORT THAT RECEIVED THE REQUEST",
"ASSOCIATED WITH THE SCSI TARGET DEVICE CONTAINING THE LU",
"RESERVED"
};
i = sizeof (struct spc3_inquiry_vpd_header);
while (i < len) {
if (i + sizeof (struct spc3_inquiry_vpd_id_header) > len) {
break;
}
desc_len = sizeof (struct spc3_inquiry_vpd_id_header) +
dp->ivih_idlen;
break;
}
j++) {
if (extended_vpd_protocol_id[j].pid ==
dp->ivih_protocol_id) {
break;
}
}
}
if (extended_vpd_code_set[j].vpd_code ==
dp->ivih_code_set) {
break;
}
}
j++) {
if (extended_vpd_id_type[j].vpd_code ==
dp->ivih_id_type) {
id_type =
break;
}
}
"CODE SET : %s\nPROTOCOL ID: %s\n"
"ID TYPE : %s\nASSOCIATION: %s\n"
"PIV : %d ID LEN : %d\n",
dp->ivih_idlen);
print_hex_value((char *)&inq_page83_data[i +
stream);
i += desc_len;
}
}
static void
{
if (len < sizeof (struct spc3_inquiry_vpd_ei_data)) {
return;
}
"REF_CHK : %d APP_CHK: %d GRD_CHK: %d RTO : %d\n"
"SIMPSUP : %d ORDSUP : %d HEADSUP: %d PRIOR_SUP: %d\n"
"GROUP_SUP: %d V_SUP : %d NV_SUP : %d\n\n",
}
static void
{
int i;
const char *policy_string[] = {
"SHARED",
"PER TARGET PORT",
"OBSOLETE",
"PER I_T NEXUS"
};
i = sizeof (struct spc3_inquiry_vpd_header);
while (i < len) {
if (i + sizeof (struct spc3_inquiry_vpd_mppd_data) > len) {
"INQUIRY mode page policy data invalid\n");
break;
}
"POLICY PAGE CODE: 0x%02x POLICY SUBPAGE CODE: 0x%02x\n"
"MLUS : %d MODE POLICY CODE : %s\n\n",
i += sizeof (struct spc3_inquiry_vpd_mppd_data);
}
}
static int
{
}
static boolean_t
{
int i;
for (i = 0; i < len; i++)
return (B_TRUE);
return (B_FALSE);
}
static void
{
int i;
for (i = 0; i < len; i++)
}
static void
{
int i;
for (i = 0; i < len; i ++)
if (log_pages[i] != SPC3_LOG_PC_ALL)
}
static void
{
int i;
};
for (i = 0; i < sizeof (basic_log_pages) /
sizeof (spc3_log_page_code_t); i++)
== B_TRUE)
}
dl_fprintf(stream, \
"LP : %d LBIN: %d TMC: %d ETC : %d\n" \
"TSD: %d DS : %d DU : %d PARAM LEN: %d\n", \
static void
{
int i, j;
const struct log_err_code_str {
int param_code;
char *code_str;
} extended_log_err_code_str[] = {
"ERRORS CORRECTED WITHOUT SUBSTANTIAL DELAY" },
{ SPC3_LOG_ERR_PC_DELAY, "ERRORS CORRECTED WITH POSSIBLE DELAYS" },
{ SPC3_LOG_ERR_PC_TOTAL, "TOTAL REWRITES OR REREADS" },
{ SPC3_LOG_ERR_PC_TOTAL_ERR, "TOTAL ERRORS CORRECTED" },
"TOTAL TIMES CORRECTION ALGORITHM PROCESSED" },
{ SPC3_LOG_ERR_PC_TOTAL_BYTES, "TOTAL BYTES PROCESSED" },
"TOTAL UNCORRECTED ERRORS" },
{ DL_LOG_PC_ERR_HITACHI_TR, "HITACHI TRACK FOLLWING ERRORS" },
{ DL_LOG_PC_ERR_HITACHI_POS, "HITACHI POSITIONING ERRORS" },
{ 0xfffff, NULL }
};
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct spc3_log_params_header) > len) {
break;
}
param_len = sizeof (struct spc3_log_params_header) +
break;
}
if (code > SPC3_LOG_ERR_PC_RSVD_END)
code_string = "VENDOR SPECIFIC";
j++) {
break;
}
}
code, code_string);
stream);
i += param_len;
}
}
static void
{
int i;
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct spc3_log_params_header) > len) {
break;
}
param_len = sizeof (struct spc3_log_params_header) +
break;
}
if (code == SPC3_LOG_NM_PC_ERR_CNT)
code_string = "Non Medium ERR COUNT";
else if (code > SPC3_LOG_NM_PC_ERR_CNT_RSVD_END)
code_string = "VENDER SPECIFIC ERR COUNT";
code, code_string);
stream);
i += param_len;
}
}
static void
{
int i;
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct spc3_log_params_header) > len) {
break;
}
param_len = sizeof (struct spc3_log_params_header) +
break;
}
if (code == SPC3_LOG_PTPC_TEMPERATURE)
"CURRENT TEMPERATURE : %d C\n\n",
else if (code == SPC3_LOG_PTPC_REF_TEMPERATURE)
"REFERENCE TEMPERATURE : %d C\n\n",
else
i += param_len;
}
}
static void
{
int i;
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct spc3_log_params_header) > len) {
break;
}
param_len = sizeof (struct spc3_log_params_header) +
break;
}
switch (code) {
"YEAR OF MANUFACTURE : %.4s\n"
"WEEK OF MANUFACTURE : %.2s\n\n",
break;
"ACCOUNTING DATE YEAR : %.4s\n"
"ACCOUNTING DATE WEEK : %.2s\n\n",
break;
"SPECIFIED CYCLE COUNT OVER DEVICE LIFETIME : "
break;
"SPECIFIED CYCLE COUNT OVER DEVICE LIFETIME : "
break;
default:
break;
}
i += param_len;
}
}
static void
{
int i;
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct spc3_log_params_header) > len) {
break;
}
param_len = sizeof (struct spc3_log_params_header) +
break;
}
break;
"SELF-TEST RESULT: %d SELF-TEST CODE : %d\n"
"SELF-TEST NUMBER: %d TIMESTAMP : %d\n"
"ADDR : 0x%llx\n"
"SENSE KEY: %d ASC: %d ASCQ: %d VS: %d\n\n",
i += param_len;
}
}
static void
{
int i, j;
const struct scan_status {
int scode;
char *s_str;
} extended_scan_status[] = {
{ DL_LPBS_SC_NONE, "NO ACTIVE BACK SCAN" },
{ DL_LPBS_SC_MEDIUM, "BACK MEDIUM SCAN ACTIVE" },
{ DL_LPBS_SC_PRESCAN, "BACK PRE-SCAN ACTIVE" },
"BACK SCAN HALTED DUE TO FATAL ERR" },
"BACK SCAN HALTED DUE TO VENDOR SPECIFIC PATTERN OF ERRS" },
"BACK SCAN HALTED DUE TO MEDIUM FORMATTED WITHOUT P-LIST" },
"BACK SCAN HALTED DUE TOH VENDOR CAUSE" },
"BACK SCAN HALTED DUE TO TOO HIGH TEMPERATURE" },
"BACK MEDIUM SCAN ENABLED, BUT NO ONE INACTIVE" },
{ 0xfff, NULL }
};
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct spc3_log_params_header) > len) {
break;
}
param_len = sizeof (struct spc3_log_params_header) +
break;
}
if (code > DL_LOG_PC_BACK_SCAN_STATUS) {
(&log_back_scan_data[i]);
if (code > DL_LOG_PC_BACK_SCAN_END) {
i += param_len;
continue;
}
}
"PARAM CODE : %04xh (%s)\n",
"STATUS PARAMETER" : "MEDIUM SCAN PARAMETER"));
if (extended_scan_status[j].scode ==
dp0->lpbss_status) {
break;
}
}
if (code == DL_LOG_PC_BACK_SCAN_STATUS)
"ACCUMULATED POWER ON MINUTES: %d\n"
"BACKGROUND SCAN STATUS : %s\n"
"NUMBER OF BACKGROUND SCANS PERFORMED : "
"%d\n"
"BACKGROUND SCAN PROGRESS : "
"%.2f%%\n"
"NUMBER OF BACKGROUND MEDIUM SCANS PERFORMED : "
"%d\n\n",
else if ((code > DL_LOG_PC_BACK_SCAN_STATUS) &&
(code <= DL_LOG_PC_BACK_SCAN_END)) {
"ACCUMULATED POWER ON MINUTES: %d\n"
"SENSE KEY : 0x%x "
"REASSIGN STATUS : %d\n"
"ASC: 0x%02x ASCQ: 0x%02x",
} else
i += param_len;
}
}
static void
{
int i, j, k;
int phy_number;
int phy_event_number;
int type = 0;
int desc_len2;
int desc_len3;
const struct reason {
int reason_code;
char *reason_str;
} extended_reason[] = {
{ DL_LOG_P_REASON_UNKOWN, "UNKNOWN REASON" },
{ DL_LOG_P_REASON_POWERON, "POWER ON" },
{ DL_LOG_P_REASON_HARDRESET, "HARD RESET" },
{ DL_LOG_P_REASON_SMP, "SMP PHY CONTROL FUNCTION" },
"LOSS OF DWORD SYNCHRONIZATION" },
{ DL_LOG_P_REASON_MUX, "MUX RECEIVED" },
{ DL_LOG_P_REASON_IT, "I_T NEXUS LOSS TIMER EXPIRED" },
{ DL_LOG_P_REASON_TIMEOUT, "BREAK TIMEOUT TIMER EXPIRED" },
{ DL_LOG_P_REASON_STOP, "PHY TEST FUNCTION STOPPED" },
{ DL_LOG_P_REASON_EXP, "EXPANDER DEVICE REDUCED FUNCTIONALITY" },
{ 0xff, NULL }
};
const struct dev_type {
int type_code;
char *type_str;
} extended_dev_type[] = {
{ DL_LOG_PD_TYPE_NONE, "NO DEVICE ATTACHED" },
{ DL_LOG_PD_TYPE_END_DEV, "SAS DEVICE OR SATA DEVICE" },
{ DL_LOG_PD_TYPE_EXPANDER, "EXPANDER DEVICE" },
"EXPANDER DEVICE COMPLIANT WITH A PREVIOUS VERSION"},
{ 0xf, NULL }
};
const struct link_rate {
int rate_code;
char *rate_str;
} extended_link_rate[] = {
"PHY ENABLED, UNKNOWN PHYISCAL LINK RATE" },
{ DL_LOG_PL_RATE_DISABLED, "PHY DISABLED" },
"PHY ENABLED, A PHY RESET PROBLEM OCCURRED" },
{ DL_LOG_PL_RATE_SPINUP_HOLD, "PHY ENABLED, SPINUP_HOLD STATE" },
{ DL_LOG_PL_RATE_PORT_SELECTOR, "PHY ENABLED, PORT_SELECTOR" },
{ DL_LOG_PL_RATE_RESET, "PHY ENABLED, RESET IN PROGRESS" },
"PHY ENABLED, UNSUPPORTED PHY ATTACHED" },
{ DL_LOG_PL_RESERVED, "RESERVED" },
{ DL_LOG_PL_RATE_G1, "PHY ENABLED, 1.5 GBPS" },
{ DL_LOG_PL_RATE_G2, "PHY ENABLED, 3 GBPS" },
{ DL_LOG_PL_RATE_G3, "PHY ENABLED, 6 GBPS" },
{ 0xff, NULL }
};
const struct phy_event_string {
int phy_type;
char *phy_string;
} event_strs[] = {
{ DL_LOG_PPEN_NO_EVENT, "NO EVENT" },
{ DL_LOG_PPEN_INVALID_DWORD_CNT, "INVALID WORD COUNT" },
"RUNNING DISPARITY ERROR COUNT" },
"LOSS OF DWORD SYNCHRONIZATION COUNT" },
{ DL_LOG_PPEN_PHY_RESET_CNT, "PHY RESET PROBLEM COUNT" },
"ELASTICITY BUFFER OVERFLOW COUNT" },
{ DL_LOG_PPEN_RECEIVED_ERR_CNT, "RECEIVED ERROR COUNT" },
"RECEIVED ADDRESS FRAME ERROR COUNT" },
"TRANSMITTED ABANDON-CLASS OPEN_REJECT COUNT" },
"RECEIVED ABANDON-CLASS OPEN_REJECT COUNT" },
"TRANSMITTED RETRY-CLASS OPEN_REJECT COUNT" },
"RECEIVED RETRY-CLASS OPEN_REJECT COUNT" },
"RECEIVED AIP(WAITING ON PARTIAL) COUNT" },
"RECEIVED AIP(WAITING ON CONNECTION) COUNT" },
{ DL_LOG_PPEN_TRANSMITTED_BREAK_CNT, "TRANSMITTED BREAK COUNT" },
{ DL_LOG_PPEN_RECEIVED_BREAK_CNT, "RECEIVED BREAK COUNT" },
{ DL_LOG_PPEN_BREAK_TIMEOUT_CNT, "BREAK TIMEOUT COUNT" },
{ DL_LOG_PPEN_CONN_CNT, "CONNECTION COUNT" },
"PEAK TRANSMITTED PATHWAY BLOCKED COUNT" },
"PEAK TRANSMITTED ARBITRATION WAIT TIME" },
{ DL_LOG_PPEN_PEAK_ARBI_TIME, "PEAK ARBITRATION TIME" },
{ DL_LOG_PPEN_PEAK_CONN_TIME, "PEAK CONNECTION TIME" },
"TRANSMITTED SSP FRAME COUNT" },
{ DL_LOG_PPEN_RECEIVED_SSP_CNT, "RECEIVED SSP FRAME COUNT" },
"TRANSMITTED SSP FRAME ERROR COUNT" },
"RECEIVED SSP FRAME ERROR COUNT" },
"TRANSMITTED CREDIT_BLOCKED COUNT" },
{ DL_LOG_PPEN_RECEIVED_CB_CNT, "RECEIVED CREDIT_BLOCKED COUNT" },
"TRANSMITTED SATA FRAME COUNT" },
{ DL_LOG_PPEN_RECEIVED_SATA_CNT, "RECEIVED SATA FRAME COUNT" },
"SATA FLOW CONTROL BUFFER OVERFLOW COUNT" },
"TRANSMITTED SMP FRAME COUNT" },
{ DL_LOG_PPEN_RECEIVED_SMP_CNT, "RECEIVED SMP FRAME COUNT" },
"RECEIVED SMP FRAME ERROR COUNT" },
{ 0xffff, NULL }
};
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct dl_log_params_protocol_port_header) >
len) {
break;
}
(&log_protocol_data[i]);
break;
}
"PROTOCOL IDENTIFIER : SAS SERIAL SCSI PROTOCOL\n"
"GENERATION CODE : %d NUMBER OF PHYS : %d\n",
i += sizeof (struct dl_log_params_protocol_port_header);
while (phy_number > 0) {
(&log_protocol_data[i]);
sizeof (dl_log_params_protocol_spld_header_t);
if (dp2->lppsh_spld_len == 0)
"SAS phy log descriptor invalid\n");
i += desc_len2;
break;
}
k++) {
if (extended_reason[k].reason_code ==
break;
}
}
k++) {
if (extended_dev_type[k].type_code ==
dev_type =
break;
}
}
k++) {
if (extended_link_rate[k].rate_code ==
dp2->lppsh_link_rate) {
break;
}
}
k++) {
if (extended_reason[k].reason_code ==
dp2->lppsh_reason) {
reason =
break;
}
}
"PHY IDENTIFIER : %d\n"
"SAS_PHY_LOG_DESCRIPTOR_LENGTH : "
"%d\n"
"ATTACHED REASON : %s\n"
"ATTACHED DEVICE : %s\n"
"NEGOTIATED LOGICAL LINK RATE: %s\n"
"REASON : %s\n"
"ATTACHED INITIATOR PORT\n"
"SMP: %d STP: %d SSP: %d\n"
"ATTACHED TARGET PORT\n"
"SMP: %d STP: %d SSP: %d\n",
"SAS ADDR : 0x");
"ATTACHED SAS ADDR : 0x");
"ATTACHED PHY ID : %d\n"
"INVALID DWORD COUNT : %d\n"
"RUNNING DISPARITY ERR COUNT : %d\n"
"LOSS OF DWORD SYNC : %d\n"
"PHY RESET PROBLEM : %d\n",
if (dp2->lppsh_spld_len == 0) {
phy_number--;
i += desc_len2;
continue;
}
"PHY EVENT DESCRIPTOR LEN : %d\n"
"# OF PHY EVENT DESCRIPTORS : %d\n",
i += desc_len2;
while (phy_event_number > 0) {
sizeof (dl_log_params_protocol_ped_t);
", phy event descriptor invalid\n");
i += desc_len3;
break;
}
(&log_protocol_data[i]);
for (j = 0; event_strs[j].phy_type !=
NULL; j++) {
if (event_strs[j].phy_type ==
event_strs[j].phy_string;
break;
}
}
"PHY EVENT SOURCE: %s\n"
"PHY EVEMT VALUE : %d\n",
if (type == DL_LOG_PPEN_PEAK_BLOCKED_CNT ||
"PEAK VAL DETECTOR THRESHOLD: %d"
"\n", SCSI_READ32(
&(dp3->lppp_peak_val)));
i += desc_len3;
}
phy_number--;
}
}
}
static void
{
int i;
int param_len;
i = sizeof (struct spc3_log_page_header);
while (i < len) {
if (i + sizeof (struct spc3_log_params_header) > len) {
break;
}
param_len = sizeof (struct spc3_log_params_header) +
break;
}
"INFORMATIONAl EXCEPTION ASC : %d\n"
"INFORMATIONAL EXCEPTION ASCQ: %d\n",
sizeof (struct spc3_log_params_ie_header) -
sizeof (struct spc3_log_params_header))
"MOST RECENT TEMPERATURE : %d C\n",
i += param_len;
}
}
static void
{
int i, j;
int code;
char *cache_str;
const struct cache_string {
int cache_code;
char *cache_str;
} extended_cache_string[] = {
"BLOCKS SENT TO INITIATOR " },
"BLOCKS RECEIVED FROM INITIATOR " },
"BLOCKS READ FROM CACHE AND SENT TO INITIATOR " },
"COMMAND # OF R/W WHOSE SIZE <= SEGMENT SIZE " },
"COMMAND # OF R/W WHOSE SIZE >= SEGMENT SIZE " },
{ 0xfffff, NULL }
};
i = sizeof (struct spc3_log_page_header);
while (i < len) {
hdr_len = sizeof (struct spc3_log_params_header);
break;
}
break;
}
break;
}
}
if (code >= DL_LOG_PC_SEAGATE_CACHE_BLKSENT &&
else {
stream);
}
} else
"UNKNOWN SEAGATE PARAMETER CODE: %04xh\n", code);
i += param_len;
}
}
static void
{
int i;
int code;
i = sizeof (struct spc3_log_page_header);
while (i < len) {
hdr_len = sizeof (struct spc3_log_params_header);
break;
}
break;
}
if (code == DL_LOG_PC_SEAGATE_FACTORY_HOURS)
" : %.2f\n\n",
((double)SCSI_READ32(
else if (code == DL_LOG_PC_SEAGATE_FACTORY_MINUTES)
"SMART TEST : %d\n\n",
else
i += param_len;
}
}
static int
{
}
static int
{
int i, k;
i = sizeof (struct spc3_mode_param_header10) +
for (k = 0; i < len; ) {
i += sizeof (struct spc3_mode_page_0) -
k += 2;
i += sizeof (struct spc3_mode_subpage) -
sizeof (sp->ms_mode_parameters) +
}
k += 2;
}
return (k);
}
static boolean_t
{
int i;
for (i = 0; i < len; i += 2)
return (B_TRUE);
return (B_FALSE);
}
static void
{
int i;
for (i = 0; i < len; i += 2) {
else
}
}
static void
{
int i;
for (i = 0; i < len; i += 2) {
if ((mode_pages[i] != SPC3_MODE_PC_ALL) &&
flags);
}
}
static void
{
}
static void
{
int i;
const struct page_codes {
int page_code;
int subpage_code;
} extended_page_codes [] = {
{ 0xffff, 0xffff }
};
== B_TRUE)
}
static void
{
int i;
for (i = 0; i < len; i += 2)
if (pc == mode_pages[i])
if (pc == SPC3_MODE_PC_ALL) {
}
}
static void
{
int hdr_len;
hdr_len = sizeof (struct spc3_mode_param_header10) +
return;
}
hdr_len + sizeof (struct spc3_mode_page_0) -
sizeof (pp->mp0_mode_parameters)]));
"RLEC: %d GLTSD: %d D_SENSE : %d TMF_ONLY: %d TST: %d\n"
"QERR: %d QUEUE ALGORITHM MODIFIER: %d SWP : %d\n"
"UA_INTLCK_CTRL: %d RAC: %d VS: %d AUTOLOAD MODE : %d\n"
"TAS : %d ATO: %d BUSY TIMEOUT PERIOD: %d\n"
"EXTENDED SELF-TEST COMPLETION TIME : %d\n\n",
}
static void
{
int hdr_len;
hdr_len = sizeof (struct spc3_mode_param_header10) +
sizeof (sp->ms_mode_parameters) +
"Control Extension Mode Page data incomplete\n\n");
return;
}
hdr_len + sizeof (struct spc3_mode_subpage) -
sizeof (sp->ms_mode_parameters)]));
"IALUAE: %d SCSIP: %d TCMOS: %d "
"Initial command priority: %d\n\n",
}
static void
{
int hdr_len;
hdr_len = sizeof (struct spc3_mode_param_header10) +
"Disconnect-Reconnect Mode Page data incomplete\n");
return;
}
hdr_len + sizeof (struct spc3_mode_page_0) -
sizeof (pp->mp0_mode_parameters)]));
"BUFFER FULL RATIO : %d\n"
"BUFFER EMPTY RATIO : %d\n"
"BUS INACTIVITY LIMIT : %d\n"
"DISCONNECT TIME LIMIT: %d\n"
"CONNECT TIME LIMIT : %d\n"
"MAX BURST SIZE : %d\n"
"DTDC: %d DIMM: %d FAIR ARBITRATION : %d\n"
"EMDP: %d FIRST BURST SIZE : %d\n\n",
}
static void
{
int hdr_len;
hdr_len = sizeof (struct spc3_mode_param_header10) +
"Information Exception Control Mode Page "
"data incomplete\n\n");
return;
}
hdr_len + sizeof (struct spc3_mode_page_0) -
sizeof (pp->mp0_mode_parameters)]));
"LOGERR: %d TEST: %d DEXCPT: %d EWASC: %d EBF : %d\n"
"PERF : %d MRIE: %d INTERVAL TIMER : %u\n"
"EPORT COUNT : %u\n\n",
}
static void
{
int hdr_len;
hdr_len = sizeof (struct spc3_mode_param_header10) +
"Power Condition Mode Page data incomplete\n\n");
return;
}
hdr_len + sizeof (struct spc3_mode_page_0) -
sizeof (pp->mp0_mode_parameters)]));
"STANDBY: %d IDLE : %d\nIDLE CONDITION TIMER : %u\n"
"STANDBY CONDITION TIMER: %u\n\n",
}
static void
{
"(no sense data available)",
return;
}
"SCSI status = 0x%x\nsense key = 0x%llx (%s)\n"
"sense code = 0x%llx/0x%llx (%s)\n\n",
}
int
{
return (DL_FAILURE);
}
libscsi_fini(*hpp);
if (quiet_flag == B_FALSE)
return (DL_FAILURE);
}
return (DL_SUCCESS);
}
void
{
}
/*
* Send an inquiry page request. Provides the ability to request a particular
* inquiry page for the scsi target specified by the libscsi_target_t parameter.
* This includes the ability to request all inquiry pages supported by the
* target. Once retrieved call the appropriate parse function and print the
* data to the stream.
*/
void
{
int status;
int vpdpage_len;
struct inquiry_parser {
} inquiry_parsers[] = {
{ 0, NULL }
};
libscsi_errmsg(hp));
return;
}
return;
}
if (status == SAM4_STATUS_GOOD) {
libscsi_errmsg(hp));
return;
}
if (pc == 0)
} else {
if (pc == SPC3_INQUIRY_PC_ALL) {
sizeof (struct spc3_inquiry_vpd_header);
sizeof (struct spc3_inquiry_vpd_header)],
flags);
flags);
} else {
break;
}
break;
}
}
}
}
} else {
}
}
/*
* Format and send a request to obtain the log pages from the the scsi target
* error counters, verify error counters and etc. Once the data is retrieved
* call parse and print functions to write this data to the stream.
*/
void
{
int status;
int logpage_len;
struct log_parser {
} log_parsers[] = {
{ SPC3_LOG_PC_IE, print_log_ie },
{ 0, NULL }
};
libscsi_errmsg(hp));
return;
}
return;
}
if (status == SAM4_STATUS_GOOD) {
libscsi_errmsg(hp));
return;
}
if (!((pc == SPC3_LOG_PC_ALL) &&
if (pc == SPC3_LOG_PC_ALL) {
sizeof (struct spc3_log_page_header);
sizeof (struct spc3_log_page_header)], logpage_len);
flags);
flags);
} else {
break;
}
break;
}
}
}
} else {
}
}
/*
* Format and send a request to obtain the mode pages from the the scsi target
* specified by the libscsi_target_t structure. These pages will contain data
* like the informational Exception settings and data. Once the data is
* retrieved call parse and print functions to write this data to the stream.
*/
void
{
int status;
int modepage_len;
struct mode_parser {
} mode_parsers[] = {
{ 0, NULL }
};
libscsi_errmsg(hp));
return;
}
if (spc == DL_MODE_SPC_SPECIAL) {
}
/* Send mode sense command to get supported pages and subpages */
return;
}
if (status == SAM4_STATUS_GOOD) {
libscsi_errmsg(hp));
return;
}
(pc == SPC3_MODE_PC_ALL)))
if (pc == SPC3_MODE_PC_ALL) {
flags);
flags);
} else {
break;
}
break;
}
}
}
} else if (spc == SPC3_MODE_SPC_ALL) {
else
} else {
}
}
/*
* Create a directory if it doesn't exist.
* Parameters:
* path: The directory path to create.
* mode: The mode used when creating the directory.
* If the indicated path does not exist, attempt to create it, if is does exist
* verify whether it is a directory or not.
*/
static int
{
int status = 0;
/* Directory does not exist */
status = -1;
status = -1;
}
return (status);
}
/*
* Walk the indcated path, checking whether each directory exists by calling
* the do_mkdir function.
*/
static int
{
char *pp;
char *sp;
int status = 0;
/* Neither root nor double slash in path */
*sp = '\0';
*sp = '/';
}
}
return (status);
}
static boolean_t
{
char *pname;
return (B_FALSE);
return (B_FALSE);
*pname = '\0';
return (B_TRUE);
}
int
{
int fd;
int retval;
char *devidstr;
char *minor;
char *path;
dprintf("disklog_print_diskinfo was passed a NULL parameter\n");
return (LDL_INVALID_PARAM);
}
/* Retrieve the devid from the args. */
return (LDL_INVALID_PARAM);
return (LDL_DEVID_DECODE_FAIL);
}
dprintf("failed to get dev path\n");
return (LDL_DEVPATH_DECODE_FAIL);
}
return (LDL_INVALID_DISK_NAME);
}
else
if (check_path(filename,
dprintf("Directory %s does not exist and could not be "
return (LDL_DIR_CREATE_ERROR);
}
if (fd < 0) {
return (LDL_FILE_ERROR);
}
dprintf("Could not open a stream for %s : %s\n",
return (LDL_FILE_ERROR);
}
if (disklog_open_device(
return (LDL_DISK_OPEN_ERROR);
}
}
return (LDL_SUCCESS);
}