#!/usr/bin/perl -w
#
##########################################################################
#
# IBM_PROLOG_BEGIN_TAG
# 
# Licensed Materials - Property of IBM
# (C) COPYRIGHT International Business Machines Corp. 1986,2014
# All Rights Reserved.
# 
#   THIS PROGRAM IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EX- 
#   PRESS   OR   IMPLIED,   INCLUDING   THE   IMPLIED   WARRANTIES   OF  
#   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IBM does not 
#   warrant uninterrupted or error free operation of  the  Program,  or  
#   that the Program is free from claims by a third party of copyright,
#   patent, trademark, trade secret, or any other intellectual property
#   infringement.    IBM  has  no obligation to provide service, defect
#   correction, or any maintenance for the Program. IBM  has  no  obli-
#   gation to supply any Program updates or enhancements to you even if
#   such are or later become available.
#
#   Under no circumstances is IBM liable for any of the following:
#
#   1.  third-party claims against you for losses or damages;
#   2.  loss of, or damage to, your records or data; or
#   3.  direct  damages,  lost  profits, lost savings, incidental, spe-
#       cial, or indirect damages or other consequential damages,  even
#       if IBM or its authorized supplier, has been advised of the pos-
#       sibility of such damages.
#
#   Some jurisdictions do not allow these limitations or exclusions, so
#   they may not apply to you.
#
##########################################################################
#
#
# - 04/28/2006 - bwh - initial cut from err_decode
# - 02/17/2007 - bwh - LVM_ errors
# - 04/09/2007 - bwh - first FCS_ERRs
# - 04/12/2007 - bwh - enhanced some dyntrk related FSCSI_ERRs
# - 07/18/2007 - bwh - FCS_ERR 00000021
# - 07/23/2007 - bwh - FCS_ERR 0000005D & 0000005E
# - 07/31/2007 - bwh - Show abending program for CORE_DUMP errors, FSCSI_ERR 4E
# - 08/01/2007 - bwh - FCS_ERR 00000026
# - 08/15/2007 - bwh - [SC_]TAPE_ERRx, J2/JFS errors, SDDPCM_PATH_RECOVER, etc.
# - 08/16/2007 - bwh - Fixed FS errors, added FCS_ERR 0x30, 0x51, 0x53, etc
# - 08/17/2007 - bwh - LOST_EVENTS, DISK_ERR, refactor some routines
# - 08/20/2007 - bwh - Fix: FSCSI 0x15, 0x2E, 0xAA, 0xAC, 0xD9; CORE_DUMP;
#                      FCS 0x21; JFS_general errno; NS&LS reject codes;
#                      [SC_]DISK_ERR.
#                      Add: FSCSI 0x4F; FCS 0x5, 0x6, 0x7; PCI_xxx_ERR
# - 08/21/2007 - bwh - Fix: FSCSI 0x01, 0x03, 0x29; tidy up layout, improve
#                      comments
# - 09/14/2007 - bwh - Typos
# - 11/09/2007 - bwh - Typos, disk driver status 0x84
# - 01/03/2008 - bwh - FCS_ERR 0x127 
# - 02/29/2008 - bwh - DMA_ERR; Happy Leap Year!
# - 05/23/2008 - bwh - FCS_ERR 0x0c, 0x48
# - 05/29/2008 - bwh - Decode RSP_CODEs from FCP_RSP's RSP_INFO
# - 08/12/2008 - bwh - Add "-s" flag to force printing of Sequence Number
# - 08/18/2008 - bwh - Retrieve LBAs from LVM_* errors
# - 09/09/2008 - bwh - Add new SCSI-3 driver adapter stats
# - 09/25/2008 - bwh - Add specific EEH error codes for PCI_RECOVERABLE_ERR
# - 09/29/2008 - bwh - FCP_ERR for some Emulex errors; DMA_ERR changes for 6.1;
#		       EEH_ERR
# - 10/21/2008 - bwh - FSCSI/FCP_ERR 0x41, 0x42, 0xb7; Add OPMSG & VFC_ERR
# - 10/23/2008 - bwh - FCA_ERR 0x06, 0x21
# - 10/27/2008 - bwh - FSCSI_ERR 0x25
# - 11/13/2008 - bwh - Emulex FCA_ERR 0x24, 0x27, and 0xD303
#                      Emulex FCP_ERR 0xA5, 0xAC
# - 11/14/2008 - bwh - Emulex FCA_ERR 0xD300, 0xD301, 0xD302
#                      Emulex FCP_ERR 0x29, 0xA30
# - 11/15/2008 - bwh - Emulex FCA_ERR 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xA5,
#                      0x11, correct 0x24, 0xD300, 0xD301, 0xD302, 0xD303
#		       Emulex FCP_ERR 0xB5; add ELS 'ACCEPT'
# - 11/25/2008 - bwh - Emulex FCP_ERR 0x23, 0x2A, 0x6B, 0x6C, 0x6E, 0x6F, 0xAD,
#                      0xAF, 0xB8
# - 11/30/2008 - bwh - FSCSI_ERR 0xB4, 0xBD, 0xC7
# - 12/17/2008 - bwh - First QLogic FCP_ERRs, 0x0B, 0x4A, 0x4E
# - 03/04/2009 - bwh - Emulex FCP_ERR 0x73, 0x327; Emulex FCA_ERR 0x41
# - 03/26/2009 - bwh - Treat SC_DISK_PCM_ERR label same as SC_DISK_ERR
# - 04/21/2009 - bwh - First QLogic v4/NPIV FCP_ERRs; QLogic FCP 0x1EA;
#                      Emulex FCP 0x07, 0x70
# - 04/22/2009 - bwh - First QLogic FCA_ERRs; QLogic FCA_ERR 0x2E;
#                      QLogic FCP_ERR 0x16, 0x2C, 0xA1
# - 04/23/2009 - bwh - QLogic FCP_ERR 0x23, 0x26, 0x29;
#                      QLogic FCA_ERR 0x26, 0x41; Emulex FCP_ERR 0x302
#                      VFC_HOST errors
# - 04/24/2009 - bwh - QLogic FCP_ERR 0xb1
# - 04/30/2009 - bwh - Tweak VFC_HOST errors
# - 05/04/2009 - bwh - Emulex FCP_ERR 0xD3
# - 05/07/2009 - bwh - Many new QLogic FCP_ERRs; QLogic FCA_ERR 0x30
# - 05/20/2009 - bwh - Emulex FCP_ERR 0x26; QLogic FCA_ERR 0x4A;
#                      Quiet complaint about substitution in regex
# - 06/09/2009 - bwh - QLogic FCA_ERRs 0x1E, 0x34
# - 06/12/2009 - bwh - FSCSI_ERR 0x73
# - 06/16/2009 - bwh - Emulex FCP_ERR 0x4A, 0xC0; FCS_ERR 0x1B, 0x24 & be
#                      explicit about Unknown error numbers;
#                      Emulex FCA_ERR 0x52, 0x38
# - 06/30/2009 - bwh - QLogic FCA_ERR 0x16, 0x39, 0x3A
# - 07/01/2009 - bwh - QLogic FCA_ERR 0x23, 0x105; QLogic FCP_ERR 0x40
# - 08/10/2009 - bwh - Fix Emulex FCA_ERR 0xD301
# - 08/11/2009 - bwh - QLogic FCP_ERR 0x17, 0x48
# - 08/14/2009 - bwh - QLogic FCA_ERR 0x29;
#                      QLogic FCP_ERR 0x6C, 0xA5, 0xAC, 0xAD, 0xAF, 0xB8
# - 08/20/2009 - bwh - Emulex FCP_ERR 0x4F, 0xAA, 0xB01; QLogic FCP_ERR 0xAA
# - 08/25/2009 - bwh - QLogic FCA_ERR 0x10, 0x82
# - 09/16/2009 - bwh - Emulex FCA_ERR 0x4C
# - 09/17/2009 - bwh - Emulex FCP_ERR 0x09; QLogic FCA_ERR 0x03
# - 11/11/2009 - bwh - Emulex FCA_ERR 0x17, 0x30, 0x51, 0x53;
#                      QLogic FCA_ERR 0x6A; QLogic FCP_ERR 0xA2, 0xC3
# - 01/06/2010 - bwh - Emulex FCP_ERR 0xD9
# - 02/05/2010 - bwh - Emulex FSCSI_ERR 0x7; Add Location to VFC_ERR;
#                      Generalize SDDPCM_* to just SDDPCM and collect path_id;
#                      Generalize VFC_HOST and VSCSI_HOST to Vxx_HOST;
#                      Add old & new serial for disk serial mismatch;
#                      Initial SAS_ERR processing
# - 02/19/2010 - bwh - Handle all 0xAF errors same; include WWPN
# - 02/22/2010 - bwh - Complete ELS listing; QLogic FCP_ERR 0x03, 0xC8
# - 04/26/2010 - bwh - Added Emulex error version 0x11
# - 06/01/2010 - bwh - Emulex FCP_ERR 0x5B2
# - 06/11/2010 - bwh - Emulex FCP_ERR 0xB9
# - 06/15/2010 - bwh - Fix problem w/ strip leading zeros in VFC_HOST
# - 11/15/2010 - rew - QLogic FCP_ERR 0x1, 0x4, 0x1ED; QLogic FCA_ERR 0x27, 0x75
# - 12/10/2010 - rew - Show error numbers for protocol & adapter errors
# - 12/16/2010 - bwh - Include CDB op and failure reason for SC_DISK_ERR7
#                      path fail.  FSCSI_ERR 0xB1 include retry count.
#                      Emulex FCP_ERR 0x3E, 0xBFF
# - 12/17/2010 - bwh - Emulex FCA_ERR 0x14, 0x29, 0x4B;
#                      Emulex FCS_ERR 0x3A;
#                      Emulex FCP_ERR 0x4E, 0xA2, 0x509, 0x525;
#                      QLogic FCA_ERR 0x4B, 0x75;
#                      Initial support for SC_DISK_SDDAPPCM_ER;
#                      Fixed Emulex FCA_ERR 0x21 for V11 errlog;
#                      Improved argument handling; print errnums w/ '-e';
#                      Improved VFC_ERR parsing;
#                      Fixed Emulex FSCSI_ERR 0xD9
# - 12/20/2010 - bwh - Emulex FCS_ERR 0xC4; QLogic FCA_ERR 0x0E;
#                      QLogic FCP_ERR 0xE5; Minor cleanups;
#                      Fix QLogic FCP_ERR 0xA2, Emulex FCS_ERR 0x41;
#                      Initial support for DMPCHK_NOSPACE, DUMP_STATS, 
#                      FIRMWARE_EVENT, INIT_RAPID, LVM_GS_RLEAVE, SRC_RSTRT,
#                      SRC_TRYX
# - 12/21/2010 - bwh - Improve FIRMWARE_EVENT, Emulex FCP_ERR 0xBFF,
#                      Emulex FCA_ERR 0x27, QLogic FCA_ERR 0x1E;
#                      Initial support for DMPCHK_LDMPFSFULL, DMPCHK_TOOSMALL,
#                      DSI_*, SISSAS_*, SH_LOST_IO;
#                      Sort per-error decoders; Gather only last SENSE DATA;
#                      SIS SAS IOASC 01080000, 04050000, 066B9100, 066B9200;
#                      Generalize handling of SRC_* errors;
#                      QLogic FCP_ERR 0x07, 0x6A
# - 01/25/2011 - bwh - QLogic FCA_ERR 0x49
# - 03/19/2012 - bwh - Initial Emulex SLI-4 driver errors
# - 03/21/2012 - bwh - Emulex SLI-4 FCA errors 0x158, 0x178, 0x300, 0xA20,
#                      0xEAB.  Initial Emulex SLI-4 FCP error handling.
# - 03/22/2012 - bwh - Emulex SLI-4 FCA error 0x140, 0x62A, 0xDB8, 0xC9C
# - 04/16/2012 - bwh - Emulex SLI-4 FCA error 0x12C, 0x809
# - 04/27/2012 - bwh - Emulex SLI-4 FCA error 0x168, 0x23C, 0x403, 0x405,
#                      0x470, 0x60C, 0x80F, 0x827, 0xA30, 0xA50, 0xA80, 0xC1C,
#                      0xE22, 0xE23, 0xE27, 0xE2A, 0xE36, 0xE42, 0xE48, 0xE54,
#                      0xEAF; Initial support for LDMP_COMPLETE
# - 05/04/2012 - bwh - Initial support for LDMP_PASSTIME;
#                      Emulex SLI-4 FCA error 0xC28, 0xE62, 0xE66
# - 05/07/2012 - bwh - Emulex SLI-4 FCP error 0x48, 0x61, 0xA5, 0xAC, 0xAF,
#                      0x326, 0x327, 0x328, 0x403;
#                      Emulex SLI-4 FCA error 0x104, 0x624, 0x67B, 0x80E,
#                      0x833, 0x958;
#                      Update Emulex SLI-4 FCA error 0x80F, 0xA20;
#                      Emulex SLI-3 FCP error 0x403
# - 06/15/2012 - bwh - Pulled in Marcus' changes for Emulex SLI-4 FCA error
#                      0xE45 and 0xE4F;
#                      Emulex SLI-4 FCA error 0x621, 0x928, 0xA60, 0xC26,
#                      0xDB0, 0xE2D;
#                      Emulex SLI-4 FCP error 0x7, 0x30, 0xB8, 0xA3, 0x402
# - 06/21/2012 - bwh - Emulex SLI-4 FCA error 0xA48, 0xE63
#                      Emulex SLI-4 FCP error 0x2A, 0xA1
#                      Emulex SLI-3 FCP error 0xBD
# - 06/27/2012 - bwh - Emulex SLI-4 FCA error 0x170, 0xC48
#                      Emulex SLI-4 FCP error 0x6A
# - 07/05/2012 - bwh - Emulex SLI-4 FCA error 0xC4C
#                      Emulex SLI-4 FCP error 0x36
# - 07/09/2012 - bwh - Emulex SLI-4 FCA error 0x812
#                      Emulex SLI-4 FCP error 0x71
# - 07/10/2012 - bwh - Emulex SLI-4 FCA error 0x530, 0x68A, 0x81B, 0x88D,
#                      0xBA8, 0xE57
# - 07/10/2012 - bwh - Emulex SLI-4 FCA error 0x530, 0x68A, 0x81B, 0x88D,
# - 07/25/2012 - bwh - Emulex SLI-4 FCA error 0xDC8, 0xE6C
#                      Emulex SLI-4 FCP error 0x2E, 0x302
# - 08/14/2012 - bwh - Emulex SLI-4 FCA error 0x410, 0x460, 0x550
#                      Emulex SLI-4 FCP error 0xAC (improved)
#                      Emulex SLI-3 FCA error 0x26
#                      Emulex SLI-3 FCP error 0xC8
#                      Initial support for LDMP_DUMPERR
# - 08/15/2012 - bwh - QLogic FCA error 0x2B
#                      Emulex SLI-4 FCP error 0xC8, 0x330
#                      Initial support for KERNEL_ABEND
# - 08/21/2012 - bwh - Emulex SLI-4 FCA error 0x402, 0x812 (improved),
#                      0x81B (improved), 0x84B, 0xC1B, 0xCD0
# - 08/22/2012 - mg  - Emulex SLI-4 FCA error 0x6C8 (link recovery),
#                      0xE4F (improved)
# - 08/23/2012 - mg  - Emulex SLI-4 FCA error 0xC04, 0x68A (improved)
# - 08/24/2012 - bwh - Emulex SLI-4 FCA error 0x160, 0x6C8 (mark INFO)
# - 08/27/2012 - bwh - Emulex SLI-4 FCA error 0x4B0, 0xAB4, 0xABC, 0xCDA, 0xEB0
#                      Emulex SLI-4 FCP error 0xB
# - 08/29/2012 - bwh - Emulex SLI-4 FCP error 0x4A
#                      Emulex SLI-3 FCP error 0x3
# - 09/04/2012 - bwh - Emulex SLI-4 FCA error 0x250, 0xB08, 0xDC4, 0xE64, 0xEB4
#                      Emulex SLI-4 FCP error 0x1, 0x28, 0x2c, 0x49,
#                      0x70, 0x277
# - 09/07/2012 - bwh - Emulex SLI-4 FCA error 0xDA0, 0xE66 (improve), 0xE79,
#                      0xEB4 (improve)
# - 09/13/2012 - bwh - Emulex SLI-4 FCA error 0x612
# - 09/14/2012 - bwh - Emulex SLI-4 FCP error 0x323
# - 09/19/2012 - bwh - Emulex SLI-4 FCA error 0x4A1, 0xE25, 0xEAB (improve),
#                      0xEC4, 0xECC, 0xED0
# - 09/20/2012 - bwh - Emulex SLI-4 FCA error 0xEC6, 0xECE
# - 09/24/2012 - bwh - Emulex SLI-4 FCP error 0x1B8
#                      Emulex SLI-4 FCA error 0x402 (defunct), 0x405 (defunct)
# - 10/02/2012 - bwh - Initial support for Emulex SLI-4 FCP Version 1 layout
# - 10/04/2012 - bwh - Emulex SLI-4 FCA error 0xAB8, 0xEC2
#                      Emulex SLI-4 FCP V1 errors 0x402 (improve),
#                      0x403 (improve)
# - 10/09/2012 - bwh - Emulex SLI-4 FCP errors - fix version retrieval
# - 10/10/2012 -  mg - Emulex SLI-4 FCP error 0xAA (improve)
# - 10/10/2012 - bwh - Emulex SLI-4 FCP V0 error 0x402 (improve),
#                      0x403 (improve both)
#                      Emulex SLI-3 FCP error 0x402, 0x403 (improve)
# - 10/10/2012 -  lm - Emulex SLI-3 FCA error 0x7, 0x19, 0x1F, 0x2E, 0x121,
#                      0xD04; QLogic FCA error 0x114; Emulex SLI-3 FCP error
#                      0x4, 0x1F, 0x71, 0xD3 (improve), 0xE2, 0x326;
#                      QLogic FCP error 0x2E, 0xD3; FSCSI_ERR 0xD3
# - 10/15/2012 - bwh - Emulex SLI-4 FCA error 0xE14, 0xE15
#                      Emulex SLI-4 FCP v0 error 0xA30
#                      Emulex SLI-4 FCP v1 error 0x26, 0x4F, 0x277 (fix),
#                      0x279, 0xA30
# - 10/16/2012 - bwh - Emulex SLI-4 FCP v1 error 0x7A
# - 10/25/2012 - bwh - Emulex SLI-4 FCP v1 error 0xA2
# - 10/30/2012 - bwh - Emulex SLI-4 FCA error 0xCD6, 0xEC8, and fix ordering
# - 11/14/2012 - bwh - Initial VFC_CLIENT_FAILURE decoding
# - 11/19/2012 - bwh - Emulex SLI-3 FCP error 0x25, 0x226;
#                      QLogic FCP error 0x6D, 0x6F, 0x402, 0x403;
#                      QLogic FCA error 0x3E, 0x72;
#                      Improved handling of some SC_DISK_PCM_ERRx
# - 11/20/2012 - bwh - Emulex SLI-4 FCA error 0xA00, 0xEAE, 0xECA
# - 12/12/2012 - bwh - Emulex SLI-4 FCP v1 error 0x3, 0x4, 0x228, remove FIXME
#                      from 0x1
# - 12/17/2012 - bwh - Emulex SLI-4 FCA error 0x690
# - 01/16/2013 - bwh - Emulex SLI-4 FCA error 0x6C6
# - 02/18/2013 - bwh - QLogic FCP error 0x47; QLogic FCA_ERR 0x107
# - 02/27/2013 - bwh - Emulex SLI-4 FCP error 0x150 - 0x159
# - 02/28/2013 - bwh - Emulex SLI-4 FCP renumber 0x150 - 0x15B
# - 03/13/2013 - bwh - Emulex SLI-3 FCP error 0x150 - 0x15B
# - 03/25/2013 - bwh - QLogic FCP error 0x150 - 0x15B
# - 04/03/2013 - bwh - Emulex SLI-4 FCP error 0x25
# - 08/08/2013 - bwh - QLogic FCP error 0x30, 0x71, 0xA3
# - 08/14/2013 -  mg - QLogic FCA error 0x50, 0x94, 0x306
#                      update to QLogic FCP error 0xA3
# - 08/19/2013 - gsd - Add support for SC_DISK_PPRC_ERRx
# - 08/30/2013 - bwh - Emulex SLI-3 FCA error 0xBB
#                      Emulex SLI-3 FCP error 0x31, 0x32, 0x33, 0x38, 0x48, 0x61
#                      Emulex SLI-4 FCP error 0x22
#                      Emulex SLI-4 FCA error 0xAD0
# - 02/27/2014 - gus - Handle REBOOT_ID, AIXIF_ARP_DUP_ADDR, etc.
# - 10/12/2014 - gus - PGSP_KILL
# - 10/18/2014 -  lm - Emulex SLI-3 FCA error 0x9E
# - 11/19/2014 - sfl - Qlogic FCA 0x84, 0x100, 0x113, 0x93, 0x82
# - 11/19/2014 - sfl - Qlogic FCP 0x59, 0xD9
# - 12/02/2014 - sfl - Qlogic FCA 0x74, 0xB4
# - 02/25/2015 - sfl   Emulex SLI-4 FCA error 0x305
# - 02/25/2015 - sfl   Emulex SLI-4 FCA error 0x491
# - 03/04/2015 - sfl   Emulex SLI-4 FCA error 0x492
# - 03/04/2015 - sfl   Emulex SLI-4 FCA error 0x340
# - 04/23/2015 - sfl - Qlogic FCA    0x104
# - 04/28/2015 - sfl - Emulex SLI-4 FCA error 0xe72
# - 08/03/2015 - sfl - Emulex SLI-3 FCP error 0x6
#                      Emulex SLI-3 FCA error 0xC
#                      Emulex SLI-3 FCA error 0xD28
#                      Emulex SLI-3 FCA error 0x27 - added vwwn decode
# - 08/11/2015 - sfl - Emulex SLI-3 FCP error 0xDD
# - 08/24/2015 - sfl - Emulex SLI-3 FCP error 0x330
# - 09/10/2015 - sfl - Emulex SLI-3 FCP added n_port req to 000000AC
# - 02/22/2016 - sfl - Emulex SLI-4 FCP error 0x7B
# - 07/12/2016 - sfl - Qlogic FCA_ERR2 0x14 & FCA_ERR6 0x00
# - 08/12/2016 - sfl - Emulex SLI-4 FCA 0x518
# - 09/06/2016 - sfl - Emulex SLI-3 FCA 0x53 added wwpn for virtual wwn
# - 09/07/2016 - sfl - 0x403 FCP_ERR10 - reason code 2 (improved)
#                      Emulex SLI-4 FCP 0x32A
#               sfl/cw Emulex SLI-3 0x3F1 
#                                   0xAC (improved)                         
# - 10/21/2016 - sfl - Emulex SLI-4 FCP 0xD32
# - 10/24/2016 - sfl - Qlogic FCA   0x7B
# - 11/17/2016 - sfl - SC_DISK_ERR12 A9 strat error decodes
# - 12/02/2016 - sfl - Emulex SLI-4 FCP error 0x22a / FCA 0x6BD
# - 12/12/2016 - sfl - Emulex SLI-3 FCA error 0x2A
# - 01/20/2017 - sfl - Qlogic 0x5A 
# - 01/27/2017 - sfl - Emulex SLI-4 FCA error 0xc1d
# - 03/09/2017 - sfl - Corrected Dynamic traking failed to tracking 
# - 03/21/2017 - sfl - Emulex SLI-3 FCP_ERR6 0x348
# - 04/03/2017 - sfl - Qlogic FCP_ERR6 0x5b2
# - 04/10/2017 - sfl - Qlogic FCA_ERR2 0x86
# - 05/03/2017 - sfl - Emulex SLI-3 FCA_ERR4 0x48 
# - 06/05/2017 - sfl - Emulex SLI-4 FCA_ERR4 0x68
# - 06/06/2017 - sfl - Emulex SLI-3 FCP_ERR6 0xB0
# - 06/19/2017 - sfl - Emulex SLI-3 FCP_ERR6 0xD2 
# - 06/20/2017 - sfl - Emulex SLI-3 FCP_ERR6 0x67
# - 07/07/2017 - sfl - scsi decode (service action in) 9E xlate to readcap 16 
# - 09/15/2017 - sfl - Qlogic 0x27 vwwn decode 
# - 09/19/2017 - sfl - Emulex SLI-3 FCP_ERR14 0xC
# - 10/02/2017 - sfl - Emulex SLI-3 FCP_ERR14 0xA
# - 10/02/2017 - sfl - General clean up in FCP_ERR_Emulex section
# - 10/25/2017 - sfl - Qlogic 0x26 Enhancement 
# - 10/25/2017 - sfl - Qlogic 0xD04 
# - 10/26/2017 - sfl - General clean up in the FC area related to spacing / tabs etc .. 
# - 11/01/2017 - sfl - Emulex SLI-3 FCA 0x53 Enhancement
# - 11/01/2017 - sfl - Qlogic FCA_ERR2 0x17
# - 11/02/2017 - sas - General cleanup of whitespace
# - 11/14/2017 - sas - Sometimes "MESSAGE FROM ERRLOGGER COMMAND" first line is blank
# - 01/08/2018 - sfl - Emulex SLI-4 FCA_ERR6 0xca0
# - 01/16/2018 - sfl - Emulex SLI-3 FCA_ERR6 0x5D
# - 01/17/2018 - sfl - Emulex SLI-4 FCP_ERR4 0x17
# - 02/07/2018 - sfl - Scsidisk Strat err 9 correction
# - 02/12/2018 - sfl - Emulex SLI-3 FCP_ERR14 0xA2 enhancement
# - 02/22/2018 - sfl - Emulex SLI-3 FCP_ERR12 0xAC enhancement
# - 02/22/2018 - sfl - Emulex SLI-4 FCA_ERR6 0xC8C 
# - 03/02/2018 - sfl - Qlogic FCA_ERR14 0x21
# - 03/04/2018 - sfl - Emulex SLI-4 0x326 enhanced  
# - 04/24/2018 - sfl - Qlogic FCA_ERR6 0x6E 
# - 06/04/2018 - sfl - Strat err 1 enhancement
# - 06/12/2018 - sfl - Qlogic FCA_ERR6 0xA4
# - 06/14/2018 - sfl - Emulex SLI-4 FCP_ERR6 0x6B and 0x6F
# - 06/19/2018 - sfl - Emulex SLI-4 FCA_ERR6 0x681
# - 06/25/2018 - sfl - Initial decoding for vfc client errors 88, E0, F5
# - 08/06/2018 - sfl - Emulex SLI-4 FCA_ERR12 0xED5
# - 10/04/2018 - sfl - Emulex SLI-4 FCP_ERR14 0xA
# - 10/26/2018 - sfl - Emulex SLI-4 FCP_ERR4 0x4A - added local_rjt code 
# - 11/04/2018 - sfl - Emulex SLI-3 FCP_ERR4 0x2
# - 11/10/2018 - sas - Added sort, pagination, and usage
# - 02/14/2019 - sfl - Reverted prev commit added by sas 
# - 02/14/2019 - sfl - Broadcom SLI-4 FCA_ERR12 0x6BB 
# - 02/15/2019 - sfl - Broadcom SLI-3 FCA_ERR6 0xC6
# - 02/15/2019 - sfl - Broadcom SLI-3 FCP_ERR6 0x330 (improved)   
# - 02/21/2019 - sas - Use non-blocking input
# - 03/05/2019 - sas - Add SCAN_ERROR_CHRP, fix "errpt -ac" empty case
# - 03/05/2019 - sfl - Broadcom SLI-4 FCA_ERR6 0x815 
# - 03/11/2019 - sfl - Broadcom SLI-4 FCP_ERR4 0x327 enhanced 
# - 03/14/2019 - sfl - Broadcom SLI-4 FCA_ERR6 0xE9C
# - 03/15/2019 - sas - Allow for non-US date format (month/day reversed)
# - 04/01/2019 - sfl - Added SC_DISK_PCM_ERR22 - path disabled & corrected SC_DISK_PCM_ERR2 
# - 04/09/2019 - sfl - Scsidisk dk_driver status 0x2b
# - 04/30/2019 - sfl - Broadcom SLI-3 FCP_ERR6 0x2D
# - 05/28/2019 - sfl - Corrected define for combined DK_DRIVER status & scsi_status for 0x10 in abix_scdisk_stat_lt
# - 06/27/2019 - sfl - Broadcom SLI-4 FCA_ERR6 0x130 and 0x140
# - 07/01/2019 - sas - EPOW_SUS_CHRP and updated REBOOT_ID
# - 07/01/2019 - sas - Added KERNEL_PANIC
# - 08/20/2019 - sfl - Broadcom SLI-4 FCA_ERR6 0xED8 
# - 08/20/2019 - sfl - KERNEL_ABEND decodes added for SLI-4 driver 
# - 08/21/2019 - sfl - Broadcom SLI-4 FCA_ERR6 0x512 0xE78
# - 09/03/2019 - sfl - Fixed REBOOT_ID from printing over the date with parent/program name
# - 09/03/2019 - sfl - Fixed LOST_EVENTS from printing over the date
# - 09/26/2019 - sfl - Added misc info to qlfc 0x2B 
# - 10/16/2019 - sfl - Broadcom SLI-4 FCA_ERR6 0xEA8 FCA_ERR2 0xED1
# - 10/18/2019 - sfl - Added kernel abend code for sli3 / corrected duplicate output in abend code print 
#                      Renamed abend code driver id's to sli4 / sli3 
# - 10/22/2019 - sfl - SLI-3 FCA_ERR1 0x74
# - 10/31/2019 - sfl - SLI-4 FCP_ERR10 0xD3
# - 10/31/2019 - sfl - SLI-4 FCP_ERR10 0xD3 corrected PID location 
# - 04/13/2020 - sfl - SLI-4 FCA_ERR12 0xE14 enhancement conv values from hex to decimal
# - 04/21/2020 - lm  - added scsi_sense detection for Descriptor or Fixed based scsi sense data format
# - 05/08/2020 - sfl - Corrected for new offset in iscsisw error number 
# - 05/11/2020 - sfl - Enhanced SLI-4 FCA_ERR6 0x6BD, added SLI-4 FCP_ERR4 0x2, SLI-3 FCP_ERR6 0xD0
#                      QL FCA_ERR6 0x59, added QL abend code 63
# - 07/16/2020 - sfl - FCA_ERR6 SLI-4 0xA20 Enhanced - added src and dest to abort timeout
# - 08/10/2020 - sfl - FCP_ERR6 SLI-4 0x360
# - 08/20/2020 - sfl - FCP_ERR6 SLI-4 0x22F further changes to lm added code 
# - 08/27/2020 - sfl - added VIOS_CLIENT_FAILURE VIOS_SERVER_INFO and VIO_ERR initial minimal decode
# - 08/20/2020 - sfl - updated error map aix_scdisk_stat_lt with latest decodes            
#                      added lookup map aix_scdisk_ras_err_lt and decode for scsidisk ras errors
# - 08/31/2020 - sfl - added scsidisk cmd history lookup for supported AIX levels
#                      further defined scope of scsidisk dk driver errors
# - 09/08/2020 - sfl - VIOS_CLIENT_FAILURE 0x40 max_xfer_size represented now in hex
# - 09/09/2020 - sfl - SLI-4 FCP_ERR4 0xD30
# - 09/11/2020 - sfl - SLI-4 FCP_ERR2 0xC0
# - 09/22/2020 - sfl - SLI-3 FCP_ERR10 0xD3 corrected pid location
# - 09/25/2020 - sfl - Added VIOS_VSCSI_HOST
# - 10/06/2020 - sfl - Enhanced VIOS error 1000 0080 vscsi disconnect
# - 10/08/2020 - sfl - Initial add for VNIC errors  
# - 11/05/2020 - sfl - VIOS_VFC_HOST 0089 further extended decoding of failure errors 
#                      SLI-3 FCP_ERR6 SLI-4 0x360
#                      added lookup map fc_failure_type_lt for VIO failure type
# - 01/13/2021 - sfl - SLI-4 FCA_ERR6 0xE09, 0xE06, FCA_ERR2 0xE033, FCA_ERR2 0x0800
# - 02/02/2021 - sfl - SLI-4 FCP_ERR12 0x302 Enhancement; print src and dest wwn, VIOS_VFC_HOST 0112 
# - 02/04/2021 - sfl - SLI-4 FCP_ERR6 0x22C
# - 02/05/2021 - sfl - VIOS_VFC_HOST 00A9
# - 02/11/2021 - sfl - Added kern errno lookup tables, Enhanced VIOS_VFC_HOST 00A9
# - 02/12/2021 - sfl - Improved FCP_ERR4 0x330 
# - 03/23/2021 - sfl - VFC_ERR 0047, 007C, 0080 
# - 03/25/2021 - sfl - SC_DISK_ERR - Added LBA and Transfer length decode for (16) byte scsi cdb; R/W (16) cmds
# - 03/30/2021 - sfl - FCA_ERR6 0x250
# - 04/01/2021 - sfl - VIOS_VFC_HOST 0089 - distinguish betwen LS_RJT and non LS_RJT errno's 
# - 04/03/2021 - sfl - SLI-4 0x327 enhancement 
# - 04/06/2021 - slf - VIOS_VFC_HOST 06E enhancement 
# - 04/06/2021 - slf - SLI4 FCP_ERR6 0x221, enhanced FCP_ERR6 0x226 0x227 0x2AA
# - 04/28/2021 - sfl - SLI4 FCP_ERR4 0x327 enhancement 
# - 06/07/2021 - sfl - SISSAS Check driver_id for correct offset / location of IOASC & PRC
#                      VIOS_VFC_CLIENT_FAI 0048, SLI4 D59 
# - 06/10/2021 - sfl - SLI4 FCP_ERR6 0xC74
# - 06/14/2021 - sfl - SLI4 FCP_ERR4 0x49 enhanced 
# - 06/15/2021 - sfl - Further extend SISSAS prc / ioasc error detection using prc location
#                      VRSAS_ERR21T and SISSAS_ERR11TD use common SISSAS decode function
# - 06/16/2021 - sfl - Added new decoder for all VFC4_ERR type errors / npiv clients
#                      VIOS_VFC_CLIENT_CON 0114 00B5
# - 06/22/2021 - sfl - VIOS_VFC_HOST 0039, added default VIOS_VFC_HOST error_num label 
# - 06/24/2021 - sfl - extended SCAN_ERROR_CHRP with lookup table
# - 06/25/2021 - sfl - VFC4_ERR14 243, SLI4 FCP_ERR6 27A, extended FIRMWARE_EVENT to print SRC and decode
# - 06/30/2021 - sfl - Added basic decoding for VIOS_SEAHA labels 
#                      Added Cavium adapter and protocol driver
#                      basic decoding for Labels: POOL, VKE_INFO, CL_FFDC, VIO_ALERT_EVENT, MVR_
#                      SEAHA_, ECH_, CL_NETWORK_ISSUE_, CFLASH_ERR
#                      Moved disk driver cmd_history to seperate function   
#                      Added VFC_ERR NUMBER to older vfc errpt's 
# - 07/06/2021 - sfl - SLI4 FCP_ERR6 0xBD 0xF0
# - 07/13/2021 - sfl - VFC4_ERR14 0x244 0x242
# - 07/14/2021 - sfl - SLI3 FCP_ERR4 0x16B
# - 07/19/2021 - sfl - VFC4_ERR Extended error formatting 
# - 08/04/2021 - sfl - Added decodes for SCAN_ERROR_CHRP BA180020, B7006A72, B7006971, BA180010
# - 08/05/2021 - sfl - SCAN_ERROR_CHRP BA180030
#                      LDMP_COMPLETE also print if livedump is truncated 
# - 08/20/2021 - sfl - Missing / added driver_status 03 detection and decode for cmd_history 
# - 08/31/2021 - sfl - SLI4 FCA_ERR6 0x68F 0x68D
# - 10/07/2021 - sfl - SLI4 FCP_ERR4 0x17 enhancment
# - 10/12/2021 - sfl - SLI4 0xE62 enhanced, added SRC lookup B150493F 
# - 10/13/2021 - sfl - Cavium FCP_ERR6 0x360 enhanced 
# - 11/16/2021 - sfl - Enhanced PPRC DISK errors 
# - 11/22/2021 - sfl - Added PCI NVME initial decode, minor wording change for NPIV_ERR_0112
# - 11/22/2021 - sfl - SLI4 - Added phy layer stats when FC link problems are logged
#                      SLI4 - 0xE45  
#
#
#
#
##############################################################################

use strict;

#
# We use several lookup tables for common translations (errno names,
# SCSI opcodes, etc).  To keep the code clean we'll declare them all
# global and initialize them up front.
#

my %aix_d_map_list_rc_lt;
my %aix_errno_lt;
my %aix_rdac_stat_lt;
my %aix_s2_adap_stat_lt;
my %aix_s3_adap_stat_lt;
my %aix_scdisk_stat_lt;
my %aix_scdisk_strat_err_lt;
my %scsi_sbcop_lt;
my %scsi_sscop_lt;
my %scsi_status_lt;
my %scsi_skey_lt;
my %scsi_ascq_lt;
my %fc_payload_op_lt;
my %fc_nsrjt_lt;
my %fc_lsrjt_rc_lt;
my %fc_lsrjt_re_lt;
my %fcp_rsp_code_lt;
my %plat_eeh_err_lt;
my %vfc_err_loc_lt;
my %fc_cmd_op_lt;
my %kernel_abend_lt;
my %vfc_host_err_loc_lt;
my %vscsi_host_err_loc_lt;
my %aix_scdisk_ras_err_lt;
my %fc_failure_type_lt;
my %com_scsi_status_lt;
my %npiv_mad_status_lt;
my %kerrno_lt;
my %scan_err_src_lt;
my %fcp_tm_flags_lt;
my %pprc_loc_lt;


&initialize_lookup_tables();

our ($VERSION) = ' $Revision: 2.00 $ ' =~ /Revision: ([^ ]*)/;	
sub HELP_MESSAGE {
	use File::Basename;
	my $PROG=basename($0);
	(my $message = <<"	END_MESSAGE") =~ s/^\t\t//gm;

		AIX error summarizer
		Usage: $PROG [-serpc] | --help
		 -s	sequence numbers included and sorted
		 -e	error numbers included from FC driver
		 -r	reverse output lines
		 -p	paginate output
            -c scsi cmd history

		Reads "errpt -a" output from stdin and decodes errors.
	END_MESSAGE
	print $message;
	exit(1);
}

#
# Check for commandline options:
#
# -s  Include sequence numbers in each line's header.  Useful for
#     re-sorting errors from an error log recovered with 'errlog_recover'.
#
# -e  Include FC driver error numbers for each error.
#
# -r  Reverse the order of output
#
# -p  Paginate the output
#
# -c  disk driver scsi error cmd failure history
#
# Setting STANDARD_HELP_VERSION causes processing to stop immediately
# if --help is specified.  (Without that "summ --help" would print the
# help message then wait for data on stdin.)
#

use Getopt::Std;

$Getopt::Std::STANDARD_HELP_VERSION = 1;

my %opts;

my $SEQNO   = 0;
my $ERRNUMS = 0;
my $OPT_REV = 0;
my $OPT_PG  = 0;
my $CMD_HIST = 0;

getopts('serpc', \%opts) or die "Use '--help' for usage.\n  ";

$SEQNO   = 1 if defined $opts{'s'};
$ERRNUMS = 1 if defined $opts{'e'};
$OPT_REV = 1 if defined $opts{'r'};
$OPT_PG  = 1 if defined $opts{'p'};
$CMD_HIST= 1 if defined $opts{'c'};

# Determine if we are processing continuous records
my $stdin;
my $PPID=getppid;
my $ERRPT_PID=0;
foreach (`/usr/bin/ps -o pid,args -T $PPID`)
{
	$ERRPT_PID = $1 if /^([0-9]+) .*-errpt .*c/;
}
if ($ERRPT_PID)
{
	# Unset incompatible options
	$OPT_REV=0;
	$OPT_PG=0;
	# Use select() calls for non-blocking read of input
	use IO::Select;
	$stdin = IO::Select->new(\*STDIN);
}

my $saved_output="";
if ($OPT_REV||$OPT_PG)
{
	# Temporarily save all output into a scalar
	open(SAVEOUT, '>', \$saved_output) or die;
	select(SAVEOUT);
}

#
# Read each error into an array then decode it.
#
# We assume that each error entry starts with the "LABEL:" line and ends
# with a line of dashes ("---").  The last entry may (will) not be followed
# by a line of dashes so we may need one extra decode call at EOF.
#
#

my @error;
my $need_decode = 0;

while(1)
{
	if (!$ERRPT_PID)
	{
		# read buffered input
		last unless defined($_ = <>);
	}
	elsif ($stdin->can_read(1))
	{
		# Input is ready, fetch one line bypassing input buffer
		# When value is undef, we are done
		last unless defined($_ = &get_unbuf_line);
	}
	else
	{
		# Input timeout, probably reading continuous output from "errpt -ac"
		if ($saved_output)
		{
			select(STDOUT);
			close(SAVEOUT);
			print $saved_output;
			$saved_output="";
		}
		if ($need_decode)
		{
			&decode(@error);
			$need_decode = 0;
		}
		next;
	}

	if (/^LABEL:/)
	{
		undef @error;
		$need_decode = 1;
	}
	elsif (/^----------------/)
	{
		# First is often dashes--not ready to decode then.
		if ($need_decode)
		{
			&decode(@error);
		}
		$need_decode = 0;
	}

	$error[$#error + 1] = $_;
}

if ($need_decode)
{
	&decode(@error);
}

# Sort and print output, if data is in "$saved_output"
select(STDOUT);
close(SAVEOUT);
my @data = split(/^/, $saved_output);
if ($SEQNO) {
	# Sort by the sequence number (first field)
	# Schwartzian Transform algorithm sort
	@data = map {
		# Get original line back
		$_->[0]
	} sort {
		# Compare input fields numerically
		$b->[1] <=> $a->[1]
	} map {
		# Turn each line into [original line, sort field]
		[ $_, (split /\s+/, $_)[0] ]
	} @data;
}
if ($OPT_REV) {
	# Print the output in reverse order (newest at bottom)
	@data = reverse(@data);
}
if ($OPT_PG) {
	# options for "less":
		# S chops long lines instead of wrapping (use horizontal scrolling)
		# e will exit upon end-of-file (default exit is via "q")
		# F will quit less immediately if the output already fits the screen.
		# X will prevent less from trying to clear the screen on exit.
	open(MORE,"|less -SeFX") || open(MORE,"|more") || open(MORE,">&STDOUT");
	select(MORE);
}
foreach (@data) {
	print $_;
}
select(STDOUT);
close(MORE);

exit 0;


#######################################################################
##
#  Main dispatcher and header routines
#
#  The dispatcher routine prints a header that's common for all
#  errors then calls out a specific decoder to further summarize
#  the error.
#
#  Then individual decoders are given a copy of the complete error
#  and are expected to _print_ (to stdout) a one-line string that
#  summarizes the error.  The printed strings need not start with
#  any spaces and should not include a newline.
##
#######################################################################

#
# decode - The main dispatcher routine.  Print the header for the
# error then call out an appropriate decoder based on the error's
# LABEL:
#
sub decode
{
	my @error = @_;

	#
	# Print a line "header" that's common to any error.  print_header
	# will not emit a newline--that will be the responsibility of the
	# individual decoders below.
	#

	&print_header(@error);

	my $label = "";
	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^LABEL:/)
		{
			$label = (split /\s+/, $error[$i])[1];
			last;
		}
	}

	$_ = $label;
	if    (/^AIXIF_ARP_DUP_ADDR/)	{ &AIXIF_ARP_DUP_ADDR(@error) }
	elsif (/^CL_VAR_FULL/)		{ &CL_VAR_FULL(@error) }
	elsif (/^CORE_DUMP/)		{ &CORE_DUMP(@error) }
	elsif (/^DISK_ERR/)		{ &DISK_ERR(@error) }
	elsif (/^DMA_ERR/)		{ &DMA_ERR(@error) }
	elsif (/^DMPCHK_LDMPFSFULL/)	{ &DMPCHK_LDMPFSFULL(@error) }
	elsif (/^DMPCHK_NOSPACE/)	{ &DMPCHK_NOSPACE(@error) }
	elsif (/^DMPCHK_TOOSMALL/)	{ &DMPCHK_TOOSMALL(@error) }
	elsif (/^DUMP_STATS/)		{ &DUMP_STATS(@error) }
	elsif (/^DSI_/)			{ &DSI_general(@error) }
	elsif (/^EEH_ERR/)		{ &EEH_ERR(@error) }
	elsif (/^EPOW_SUS_CHRP/)	{ &EPOW_SUS_CHRP(@error) }
	elsif (/^FCA_ERR/)		{ &FCA_ERR(@error) }
	elsif (/^FCP_ARRAY_ERR/)	{ &SC_DISK_ERR(@error) }
	elsif (/^FCP_ERR/)		{ &FCP_ERR(@error) }
	elsif (/^FCS_ERR/)		{ &FCS_ERR(@error) }
	elsif (/^FIRMWARE_EVENT/)	{ &FIRMWARE_EVENT(@error) }
	elsif (/^FSCSI_ERR/)		{ &FSCSI_ERR(@error) }
	elsif (/^INIT_RAPID/)		{ &INIT_RAPID(@error) }
	elsif (/^ISCSISW_ERR/)		{ &ISCSISW_ERR(@error) }
	elsif (/^JFS_/)			{ &JFS_general(@error) }
	elsif (/^J2_/)			{ &JFS_general(@error) }
	elsif (/^KERNEL_ABEND/)		{ &KERNEL_ABEND(@error) }
	elsif (/^KERNEL_PANIC/)		{ &KERNEL_PANIC(@error) }
	elsif (/^LDMP_COMPLETE/)	{ &LDMP_COMPLETE(@error) }
	elsif (/^LDMP_DUMPERR/)		{ &LDMP_DUMPERR(@error) }
	elsif (/^LDMP_PASSTIME/)	{ &LDMP_PASSTIME(@error) }
	elsif (/^LOST_EVENTS/)		{ &LOST_EVENTS(@error) }
	elsif (/^LVM_GS_RLEAVE/)	{ &LVM_GS_RLEAVE(@error) }
	elsif (/^LVM_/)			{ &LVM_ERR(@error) }
	elsif (/^OPMSG/)		{ &OPMSG(@error) }
	elsif (/^PCI_/)			{ &PCI_err(@error) }
	elsif (/^PGSP_KILL/)		{ &PGSP_KILL(@error) }
	elsif (/^REBOOT_ID/)		{ &REBOOT_ID(@error) }
	elsif (/^SAS_ERR/)		{ &SAS_ERR(@error) }
	elsif (/^SCAN_ERROR_CHRP/)	{ &SCAN_ERROR_CHRP(@error) }
	elsif (/^SC_DISK_ERR/)		{ &SC_DISK_ERR(@error) }
	elsif (/^SC_DISK_PCM_ERR/)	{ &SC_DISK_ERR(@error) }
	elsif (/^SC_DISK_PPRC_ERR/)	{ &SC_DISK_PPRC_ERR(@error) }
	elsif (/^SC_DISK_SDDAPPCM_ER/)	{ &SC_DISK_ERR(@error) }
	elsif (/^SC_TAPE_ERR/)		{ &SC_TAPE_ERR(@error) }
	elsif (/^SDDPCM/)		{ &SDDPCM(@error) }
	elsif (/^SH_LOST_IO/)		{ &SH_LOST_IO(@error) }
	elsif (/^SISSAS_/)		{ &SAS_ERR_SIS_proto(@error) }
    elsif (/^VRSAS_/)      { &SAS_ERR_SIS_proto(@error) }
	elsif (/^SRC_/)			{ &SRC_general(@error) }
	elsif (/^TAPE_ERR/)		{ &TAPE_ERR(@error) }
	elsif (/^VFC_ERR/)		{ &VFC_ERR(@error) }
	elsif (/^VFC_HOST/)		{ &Vxx_HOST(@error) }
	elsif (/^VSCSI_HOST/)		{ &Vxx_HOST(@error) }
    elsif (/^VIOS_VFC_HOST/)            { &VIOS_VFC_HOST(@error) }
    elsif (/^VIOS_CLIENT_FAILURE/)      { &VIOS_CLIENT_FAILURE(@error) }
    elsif (/^VIOS_SERVER_INFO/)         { &VIOS_CLIENT_FAILURE(@error) }
    elsif (/^VIOS_VSCSI_HOST/)          { &VIOS_CLIENT_FAILURE(@error) }
    elsif (/^VIOS_CLIENT_CONNECT/)      { &VIOS_CLIENT_FAILURE(@error) }
    elsif (/^VIOS_VFC_CLIENT_CON/)      { &VIOS_CLIENT_FAILURE(@error) }
    elsif (/^VIOS_VFC_CLIENT_FAI/)      { &VIOS_CLIENT_FAILURE(@error) }
    elsif (/^VIOS_VFC_SERVER_INF/)      { &VIOS_CLIENT_FAILURE(@error) }
    elsif (/^VFC_CLIENT_FAILURE/)       { &VFC_CLIENT_FAILURE(@error) }
    elsif (/^VIO_ERR/)                  { &VIO_ERR(@error) }
    elsif (/^VFC4_ERR/)                 { &VFC4_ERR(@error) }
    elsif (/^DELAYED_INTS/)             { &DELAYED_INTS(@error) }
    elsif (/^VS_/)                      { &VNIC_SERVER(@error) }
    elsif (/^VIOS_SEAHA_/)              { &VIOS_SEAHA(@error) }
    elsif (/^POOL_/)                    { &POOL(@error) }
    elsif (/^VKE_INFO/)                 { &VKE_INFO(@error) }
    elsif (/^CL_FFDC/)                  { &CL_FFDC(@error) }
    elsif (/^VIO_ALERT_EVENT/)          { &VIO_ALERT_EVENT(@error) }
    elsif (/^MVR_/)                     { &MVR_(@error) }
    elsif (/^SEAHA_/)                   { &SEA_(@error) }
    elsif (/^ECH_/)                     { &SEA_(@error) }
    elsif (/^CL_NETWORK_ISSUE_/)        { &CL_NETWORK_ISSUE(@error) }
    elsif (/^CFLASH_ERR/)               { &CFLASH_ERR(@error)}
    elsif (/^PHAKE_KENEXT/)             { &PHAKE_KENEXT(@error)}
    elsif (/^NVME_/)                    { &nvme_decode(@error)}
	else				                { &general_description(@error) }

	printf("\n");

	return;
}

#
# get_unbuf_line - read one line directly from input via sysread.
# Used with non-blocking IO::Select->can_read() to enable continuous
# processing of input records in real-time (i.e. "errpt -ac")
#
sub get_unbuf_line
{
	my $line="";
	while (sysread(STDIN, my $nextbyte, 1)) {
		return $line if $nextbyte eq "\n";
		$line .= $nextbyte;
	}
	return(undef);
}

sub general_description
{
	my @error	= @_;
	my $info	= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^Description/)
		{
			chomp($info = $error[$i + 1]);
			last;
		}
	}
	printf("%s", $info);

	return;
}

#
# print_header - Prints a common header for any error, including things
# like the date/time, label, resource, and type.  E.g.:
#
# An error with the following header would produce the header shown below.
#
# ---------------------------------------------------------------------------
# LABEL:          FSCSI_ERR6
# IDENTIFIER:     B8FBD189
# 
# Date/Time:       Mon Aug  4 08:24:20 2008
# Sequence Number: 76736
# Machine Id:      00C252B04C00
# Class:           S
# Type:            TEMP
# Resource Name:   fscsi3
# ---------------------------------------------------------------------------
#
# Aug  4 08:24:20 fscsi3     T FSCSI_ERR6
#
# -or, if the '-s' flag was used
#
# 76736 Aug  4 08:24:20 fscsi3     T FSCSI_ERR6
#
sub print_header
{
	my @error = @_;

	my $label	= "";
	my $tstamp	= "";
	my $seqno	= 0;
	my $etype	= "";
	my $res		= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		my @f = split /\s+/, $error[$i];
	
		if ($error[$i] =~ /^LABEL:/)
		{
			$label = defined($f[1]) ? $f[1] : "";
		}
		elsif ($error[$i] =~ /^Date\/Time:/)
		{
			# Not all dates are in US format
			if ($f[3] =~ m/^\d{1,2}$/)
			{
				$tstamp = sprintf("%s %2d %s", $f[2], $f[3], $f[4]);
			}
			elsif ($f[2] =~ m/^\d{1,2}$/)
			{
				$tstamp = sprintf("%2d %s %s", $f[2], $f[3], $f[4]);
			}
			else
			{
				$tstamp = sprintf("%s %s %s", $f[2], $f[3], $f[4]);
			}
		}
		elsif ($error[$i] =~ /^Sequence Number:/)
		{
			$seqno = defined($f[2]) ? $f[2] : 0;
		}
		elsif ($error[$i] =~ /^Type:/)
		{
			$etype = defined($f[1]) ? substr($f[1], 0, 1) : "?";
		}
		elsif ($error[$i] =~ /^Resource Name:/)
		{
			$res = defined($f[2]) ? $f[2] : "(none)";
			$res = "unspecifie" if ($res eq "unspecified");		# output field only 10 chars
		}
	}

	if ($SEQNO eq 1)
	{
		printf("%d %s %-10s %1s %-19s ", $seqno, $tstamp, $res, $etype,
			$label);
	}
	else
	{
		printf("%s %-10s %1s %-19s ", $tstamp, $res, $etype, $label);
	}

	return;
}

#######################################################################
##
#  Subroutines for common operations
#
#  Includes service routines that are be used by several of the
#  individual decoders.  Things like routines to break apart sense
#  data or do simple lookups, etc. 
#
#  These routines do not produce any output.
#
#  Note that some of the retrieval routines may traverse the entire
#  error to find the requested information.  Callers may wish to cache
#  the retrieved information locally, rather than using multiple calls
#  to the retrieval function.
#
##
#######################################################################

#############################################
##
#  Routines for manipulating hex SENSE DATA
##
#############################################

#
# get_sense_data - Retrieve and return the SENSE DATA section from an
# error entry.  Assumes the sense data follows the LAST line starting with
# "SENSE DATA" or "ADDITIONAL HEX DATA" and spans to the end of the error
# entry.
#
# The return is a hexstring (ASCII-encoded hex digits, e.g. "DEADBEEF")
# with no whitespace.
#
# TODO: Note that the returned string may contain non-hex characters if,
# say, other text follows the actual SENSE DATA.  Perhaps we should stop
# gathering at the first non-hex digit, or at the first line that contains
# a non-hex digit.
#
sub get_sense_data
{
	my @error = @_;
	my $sense = "";

	#
	# Search backwards from the bottom of the error so that we
	# find only the last batch of sense data.
	#
	for (my $i = $#error; $i >= 0; $i--)
	{
		if (($error[$i] =~ /^SENSE DATA/) ||
		    ($error[$i] =~ /^ADDITIONAL HEX DATA/))
		{
			# Found the start of the SENSE DATA; grab it all
			# then get out.

			for (my $j = $i + 1; $j <= $#error; $j++)
			{
				$sense = $sense . $error[$j];
			}
			last;
		}
	}

	$sense =~ s/\s+//g;

	return $sense;
}

#
# nibbles - Return a hexstring representing one or more nibbles 
# retrieved from the input hexstring.
#
# &nibbles("DEADBEEF", 3, 2) returns "DB"
#
sub nibbles
{
	my ($hexstr, $offset, $len) = @_;
	return substr($hexstr, $offset, $len);
}

#
# bytes - See nibbles.  Return one or more bytes (8-bit) from a hexstring.
#
# &bytes("DEADBEEF", 1, 2) returns "ADBE"
#
sub bytes
{
	my ($hexstr, $offset, $len) = @_;
	return substr($hexstr, $offset * 2, $len * 2);
}

#
# shorts - See nibbles.  Return one or more shorts (16-bit) from a hexstring.
#
# &shorts("DEADBEEF", 1, 1) returns "BEEF"
#
sub shorts
{
	my ($hexstr, $offset, $len) = @_;
	return substr($hexstr, $offset * 4, $len * 4);
}

#
# words - See nibbles.  Return one or more words (32-bit) from a hexstring.
#
sub words
{
	my ($hexstr, $offset, $len) = @_;
	return substr($hexstr, $offset * 8, $len * 8);
}

#
# longs - See nibbles.  Return one or more longs (64-bit) from a hexstring.
#
sub longs
{
	my ($hexstr, $offset, $len) = @_;
	return substr($hexstr, $offset * 16, $len * 16);
}

#
# mask - Given a hexstring and a mask (also expressed as a hexstring), 
# apply the mask to the hexstring.  If the mask is shorter than the 
# source hexstring, the mask is effectively zero-padded to length.
#
# Returns a hexstring the same length as the input string.
#
# &mask("AAAAAAAA", "0707") returns "00000202"
#
sub mask
{
	my ($val, $mask) = @_;

	my $len = length($val);

	return int2hex(hex($val) & hex($mask), $len);
}

#
# int2hex - Given an int value and a length, converts the int value
# to a hexstring of _at least_ the requested length, padding with zeros
# as necessary.
#
# Returns the hexstring representing the value.
#
# &int2hex(255, 4) returns "00FF"
# 
sub int2hex
{
	my ($num, $digits) = @_;
	return sprintf("%0" . $digits . "X", $num);	# the easy way

	my $hex = "";
	my $len = 0;

	while (($num > 0) || ($len < $digits))
	{
		$hex = substr("0123456789ABCDEF", ($num % 16), 1) . $hex;
		$len++;
		$num = int($num / 16);
	}

	return $hex
}

#
# hex2int - Convert a hexstring to an int.
#
# Returns the value represented by the hexstring
#
# &hex2int("FF") returns 255
#
sub hex2int
{
	return hex((@_)[0]);		# the easy way

	# TODO: Assumes upper case!
	my ($hex) = @_;
	my $i;
	my $value = 0;

	for ($i = 0; $i < length($hex); $i++)
	{
		my $digval = index("0123456789ABCDEF", substr($hex, $i, 1));
		$value = $value * 16 + $digval;
	}

	return $value;
}

#
# hex2ipaddr - Convert a hexstring to a IP-style address, expressed as
# ASCII-encoded decimal values (one-per-byte) seperated by dots (".").
#
# Returns a string containing the IP-style address.
#
# &hex2ipaddr("C0A80001") returns "192.168.0.1"
#
sub hex2ipaddr
{
	return join(".", unpack("C*", pack("H*", $_)));		# the easy way

	my ($hex) = @_;

	my $i;
	my $num_octets = length($hex)/2;
	my $addr = "";


	for ($i = 0; $i < $num_octets; $i++)
	{

		if ($i != 0)
		{
			$addr .= ".";
		}

		$addr .= hex(&bytes($hex, $i, 2));

	}
	
	return $addr;
}

#
# byte_reverse - Reverse the byte order of a hexstring.
#
# Returns a hexstring with bytes reversed.
#
# &byte_reverse("DEADBEEF") returns "EFBEADDE"
#
sub byte_reverse
{
	my ($hexstr) = @_;

	my $reversed = "";
	my $bytenum = (length($hexstr) / 2) - 1;

	while ($bytenum >= 0)
	{
		$reversed .= &bytes($hexstr, $bytenum--, 1);
	}

	return $reversed;
}

#############################################
##
#  Routines for simple lookups
##
#############################################

#
# lookup - Perform a hash table lookup.
#
# Given a prefix-string, a key, and a reference to a hash, retrieves
# the key's value in the hash.
#
# Returns:
#
# - Hash value if the key is present in the hash
#     &lookup("Opcode ", "2A", \%sbc_opcodes) returns "WRITE(10)"
#
# - String consisting of the prefix-string and the key value if the
#   key is not present in the hash (note no whitespace is inserted
#   between the prefix and the key):
#     &lookup("Opcode ", "FF", \%sbc_opcodes) returns "Opcode FF"
#
sub lookup
{
	my ($decoration, $key, $hashref) = @_;

	return exists $hashref->{$key} ? $hashref->{$key} : "$decoration$key";
}


#############################################
##
#  Routines to retrieve specific fields from
#  the error
##
#############################################

#
# get_description - Retrieve and return the text in the Description field.
#
sub get_description
{
	my @error = @_;
	my $description = "";

	#
	# Search error for the description

	#
	for (my $i = 0; $i < $#error; $i++)
	{
		if ($error[$i] =~ /^Description/)
		{
			# Found the start of the Description. grab it
			# and get out.
			$description = $error[$i+1];
			last;
		}
	}
	$description =~ s/\s+$//;
	return $description;
}

#
# get_group_name - Retrieve and return the group name from PPRC errors
#
sub get_group_name
{
	my @error = @_;
	my $group_name = "";

	#
	# Search backwards from the bottom of the error so that we
	# find only the last batch of sense data.
	#
	for (my $i = $#error; $i >= 0; $i--)
	{
		if ($error[$i] =~ /^GROUP NAME/)
		{
			# Found the start of the Group Name; grab it
			# then get out.
			$group_name = $error[$i+1];
			last;
		}
	}
	$group_name =~ s/\s+//g;
    chomp($group_name);

	return $group_name;
}

#
# kerrno_to_errno - Decode the kernel errno to a usable errno.
#
# Defined in kerrno.h
# 
# Kernel errno's are divided into 2 interesting sections 
# 
# block     == driver_type and 
# sub_block == specific error reported by the driver 
#
sub kerrno_to_errno
{
    my ($kerror) = @_;

    my $errno =     substr($kerror, 8, 2);
    my $block =     substr($kerror, 10, 3);
    my $sub_block = substr($kerror, 13, 3);

    my $driver = &lookup("", $block,\%kerrno_lt);

    # SLI4 protocol 
    if ( $driver eq 'sysxemfcp' )
    {
        if ( $sub_block eq '016' )
        {
            $sub_block = "ENETDOWN"; 
        }
        elsif ( $sub_block eq '0F6' )
        {
            $sub_block = "need_update_vport";
        }

    }

    return "$driver failed cmd; $sub_block" ;
}


#
# get_label - Get the label field from the error.
#
# Returns a string containing the label or "(unknown)" if the label
# could not be found.
#
# If the error contains:
#
# LABEL: SC_DISK_ERR4
#
# &get_label() returns "SC_DISK_ERR4"
# 
sub get_label
{
	my @error = @_;
	my $label = "(unknown)";

	for (my $i = 0; $i < $#error; $i++)
	{
		if ($error[$i] =~ /^LABEL:/)
		{
			$label = (split /\s+/, $error[$i])[1];
			last;
		}
	}

	return $label;
}

#
# get_path_id - Get the path ID from the error.  The path ID is assumed
# to be alone on a line following a line starting with "PATH ID".
#
# Returns a scalar containing the path ID or undefined if the path ID
# could not be found.
#
# If the error contains:
#
# PATH ID
#        7
#
# &get_path_id() returns 7
#
sub get_path_id
{
	my @error = @_;
	my $path;

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^PATH ID/)
		{
			$path = $error[$i + 1];
			$path =~ s/^\s+//;
			chomp($path);
			last;
		}
	}

	return $path;
}


#######################################################################
##
#  Decoders
#
#  Decoders for the full error entries and for self-contained data
#  items that may appear in various log entries (e.g. SCSI Autosense
#  data).
#
#
#
##
#######################################################################

#############################################
##
#  Decoders for self-contained objects
#
#  These generally build a message string
#  to be returned to the caller
##
#############################################

#
# sbc_command - Decode a SCSI Block-device CDB (as described by the SPC/SBC
# standards available from www.t10.org)
#
# Returns a string describing the command, which is provided as a hexstring.
# The returned string will include the command opcode and may include other
# fields from the command as well, such as LBA and transfer length.  E.g.
#
# &sbc_command("2A00031F280000000804") returns "WRITE(10)      (031F2800,0008)"
#
sub sbc_command
{
	my ($command) = @_;

	my $op = substr($command, 0, 2);

	my $msg = "";

	if (defined($scsi_sbcop_lt{$op}))
	{
		$msg = sprintf("%-16s", $scsi_sbcop_lt{$op});

		if ($op eq '28' || $op eq '2A' || $op eq '2E')
		{
			my $lba = &bytes($command, 2, 4);
			my $len = &bytes($command, 7, 2);

			$msg = sprintf("%s (%s,%s)", $msg, $lba, $len);
		}
        elsif ($op eq '88' || $op eq '8A' || $op eq '8E')
        {
            my $lba = &bytes($command, 2, 7);
            my $len = &bytes($command, 10, 4);

            $msg = sprintf("%s (%s,%s)", $msg, $lba, $len);
        }
	}
	else
	{
		$msg = sprintf("(unknown SCSI block command %s)", $op);
	}

	return $msg;
}

#
# ssc_command - Decode a SCSI Stream-device CDB (as described in the SPC/SSC
# standard available from www.t10.org)
#
# Returns a string describing the command, which is provided as a hexstring.
# The returned string will include the command opcode and may include other
# fields from the command as well, such as LBA and transfer length.  E.g.
#
# &ssc_command("080004000000") returns "READ(6)        (040000)"
#

sub ssc_command
{
	my ($command) = @_;
	my $op = substr($command, 0, 2);
	my $msg = "";

	if (defined($scsi_sscop_lt{$op}))
	{
		$msg = sprintf("%-16s", $scsi_sscop_lt{$op});

		if ($op eq '08' || $op eq '0A')
		{
			my $len = &bytes($command, 2, 3);
			$msg = sprintf("%s (%s)", $msg, $len);
		}
        elsif ($op ne '00' || $op ne '12')
        {
            my $len = &bytes($command, 2, 4);
            $msg = sprintf("%s (%s)", $msg, $len);
        }
	}
	else
	{
		$msg = sprintf("(unknown SCSI stream command %s)", $op);
	}

	return $msg;
}

#
# FCP_RSP_IU - Decode an FCP_RSP IU (as described in the FCP standard
# available from www.t11.org)
#
# Returns a string describing interesting bits relating to the FCP and
# SCSI status returned in the FCP_RSP IU (which is provided as a hexstring).
# Tries to include the SCSI Autosense data if it was provided in the FCP_RSP.
#
sub FCP_RSP_IU
{
	my ($rsp) = @_;

	my $flags   = &bytes($rsp, 10, 1);
	my $rlvalid = &mask($flags, "01");
	my $slvalid = &mask($flags, "02");
	my $over    = &mask($flags, "04");
	my $under   = &mask($flags, "08");

	my $sstat = &bytes($rsp, 11, 1);
	my $resid = &bytes($rsp, 12, 4);

	my $rsp_len = 0;
	my $rsp_info = "";

	my $sns_len = 0;
	my $sns_info = "";

	# Retrieve FCP_RSP_LEN and FCP_RSP_INFO if FCP_RSP_LEN_VALID set
	if ($rlvalid ne '00')
	{
		$rsp_len  = &hex2int(&bytes($rsp, 20, 4));
		$rsp_info = &bytes($rsp, 24, $rsp_len);
	}

	# Retrieve FCP_SNS_LEN and FCP_SNS_INFO if FCP_SNS_LEN_VALID set
	if ($slvalid ne '00')
	{
		$sns_len = &hex2int(&bytes($rsp, 16, 4));
		$sns_info = &bytes($rsp, 24 + $rsp_len, $sns_len);
	}

	#
	# FCP Section
	#
	# Include names of interesting FCP flags and the FCP_RSP_INFO
	# field if included
	#
	my $msg = "FCP:";
	if ($rlvalid ne '00' || $over ne '00' || $under ne '00')
	{
		if ($over ne '00' || $under ne '00')
		{
			if ($over ne '00')
			{
				$msg .= " OVER";
			}
			if ($under ne '00')
			{
				$msg .= " UNDER";
			}
			$msg .= " ($resid)";
		}
		if ($rlvalid ne '00')
		{
			#
			# Decode the RSP_CODE in the RSP_INFO if possible.
			# But if something's wrong (reserved field is non-zero
			# or insufficient length of RSP_INFO, then just go
			# with the whole RSP_INFO
			#
			if ($rsp_info =~ /^000000..0*$/)
			{
				my $rsp_code = &bytes($rsp_info, 3, 1);
				$msg .= " " . &lookup("RSP_CODE ", $rsp_code,
					\%fcp_rsp_code_lt);
			}
			else
			{
				$msg .= " RSP_INFO $rsp_info";
			}
		}
	}
	else
	{
		$msg .= " -no flags-";
	}

	#
	# SCSI section
	#
	$msg .= "; SCSI: ";
	$msg .= &lookup("status ", $sstat, \%scsi_status_lt);

	#
	# SCSI Autosense data if included.  The included Autosense
	# may be too small to include the Sense Key or ASC/Q.  Or,
	# the full FCP_RSP IU may not have been provided, which would
	# have the effect of truncating the Autosense.  Note either of
	# those situations.
	#
	if ($slvalid ne '00')
	{
		if (length($sns_info) >= 13)
		{
			# Got enough SENSE to fully decode
            my $rsp_code   = &bytes($sns_info, 0, 1);
			$msg .= "; " . &scsi_sense($sns_info, $rsp_code);
		}
		elsif (length($sns_info) >= 3)
		{
			# Only enough to get the Key
			my $sk = &bytes($sns_info, 2, 1);
			$msg =  "; " . &lookup("Key ", $sk, \%scsi_skey_lt);
		}
	
		if ($sns_len < 13 && (length($sns_info) < $sns_len))
		{
			$msg .= " (short, truncated)";
		}
		elsif ($sns_len < 13)
		{
			$msg .= " (short)";
		}
		elsif (length($sns_info) < $sns_len)
		{
			$msg .= " (truncated)";
		}
	}

	return $msg;
}

#
# scsi_sense - Decode SCSI Autosense data (as described in the SPC standard
# available from www.t10.org)
#
# Returns a string describing the Autosense data (which is provided as a 
# hexstring).  The string will include the name of the Sense Key and the
# decoded string representing the ASC/ASCQ.
#
# &scsi_sense("F00005000000000F000000002400...") returns
#     "ILLEGAL REQUEST; INVALID FIELD IN CDB"
#
# NOTE: check for either Descriptor or Fixed Sense Data Format 
#

sub scsi_sense
{

    my ($sense, $rsp_code) = @_;
    my $msg = "";
    my ($cur, $sk, $ascq);


    # Error Codes 72h and 73h Descriptor Sense Data Format
    if ($rsp_code eq '72' || $rsp_code eq '73')
    {
        $cur  = &bytes($sense, 0, 1);
        $sk   = substr(&bytes($sense, 1, 1), 1, 1);
        $ascq = &bytes($sense, 2, 2);
    }
    else # Error Codes 70h and 71h Fixed Sense Data Format
    {
        $cur  = &bytes($sense, 0, 1);
        $sk   = substr(&bytes($sense, 2, 1), 1, 1);
        $ascq = &bytes($sense, 12, 2);
    }

    if ($cur ne '00')
    {
        $msg =  &lookup("Key ", $sk, \%scsi_skey_lt);
        $msg .= "; " . &lookup("ASC/ASCQ ", $ascq, \%scsi_ascq_lt);
    }

    # $msg .= $rsp_code;

    return $msg 

}


#############################################
##
#  Full decoders for various errors
#
#  These will make use of any of the service
#  or decode routines above and will _print_
#  the decoding string before returning to
#  the dispatcher.
##
#############################################



#---------------------------------------------------------------------------
#LABEL:          AIXIF_ARP_DUP_ADDR
#IDENTIFIER:     FE2DEE00
#
#Resource Name:   SYSXAIXIF
#
#Description
#DUPLICATE IP ADDRESS DETECTED IN THE NET
#
#Failure Causes
#ARP RESPONSE RECEIVED FOR MY IP ADDRESS
#
#Detail Data
#DUPLICATE IP ADDRESS
#0A01 CC01
#MAC ADDRESS
#6CAE 8B00 C200
#Duplicates
#Number of duplicates
#          11
#Time of first duplicate
#Fri Feb 21 16:39:38 2014
#Time of last duplicate
#Fri Feb 21 16:39:58 2014
#---------------------------------------------------------------------------
sub AIXIF_ARP_DUP_ADDR
{
	my @error	= @_;
	my $addr	= "address unknown";
	my $mac		= "MAC unknown";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^DUPLICATE IP ADDRESS *$/)
		{
			$addr = join(".", map { hex } unpack("(h2)4", pack("(h4)2", split(" ",$error[$i + 1]))));
		}
		elsif ($error[$i] =~ /^MAC ADDRESS/)
		{
			$mac = join(":", unpack("(h2)6", pack("(h4)3", split(" ",$error[$i + 1]))));
			last;
		}
	}
	printf("%-15s (%s)", $addr, $mac);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          CL_VAR_FULL
#
#[...]
#
#Description
#/var filesystem is running low on space
#
#Detail Data
#Percent full 
#          94
#Percent threshold 
#          75
#---------------------------------------------------------------------------
sub CL_VAR_FULL
{
	my @error	= @_;
	my $info	= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^Description/)
		{
			chomp($info = $error[$i + 1]);
		}
		if ($error[$i] =~ /^Percent full/)
		{
			chomp($info .= $error[$i + 1]);
			$info .= "%";
			last;
		}
	}
	printf("%s", $info);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          CORE_DUMP
#
#[...]
#
#Detail Data
#SIGNAL NUMBER
#           6
#USER'S PROCESS ID:
#              25538658
#FILE SYSTEM SERIAL NUMBER
#          24
#INODE NUMBER
#       12352
#PROCESSOR ID
#           4
#CORE FILE NAME
#/epeople/log/hrwtprod/cdump/core_25538658/core
#PROGRAM NAME
#oracle
#STACK EXECUTION DISABLED
#           0
#ADDITIONAL INFORMATION
#slcra 40C
#??
#ssexhd 2C0
#??
#
#Symptom Data
#REPORTABLE
#1
#INTERNAL ERROR
#0
#SYMPTOM CODE
#PCSS/SPI2 FLDS/oracle SIG/6 FLDS/slcra VALU/40c
#---------------------------------------------------------------------------
sub CORE_DUMP
{
	my @error	= @_;
	my $prog	= "(unknown)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^PROGRAM NAME/)
		{
			$prog = $error[$i + 1];
			chomp($prog);
			last;
		}
	}
	printf("Program: %s", $prog);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          DISK_ERR4
#
#[...]
#
#Detail Data
#PATH ID
#           0
#SENSE DATA
#0A08 0000 2800 0349 AB18 0000 0800 0000 0102 0000 F000 0400 0000 070A 0000 0000
#4200 1500 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 243B 000D
#---------------------------------------------------------------------------
sub DISK_ERR
{
	my @error = @_;
	my $sense = &get_sense_data(@error);
	my $path  = &get_path_id(@error);

    my $rsp_code   = &bytes($sense, 0, 1);

	if (defined($path))
	{
		printf("path %2s ", $path);
	}

	#
	# Extract and print the SCSI command information
	#

	my $cdb = &bytes($sense, 4, 10);
	print &sbc_command($cdb) . " ";


	#
	# Now the SS/VV/AA section
	#

	my $sv  = &bytes($sense, 16, 1);
	my $ss  = &bytes($sense, 17, 1);
	my $as  = &bytes($sense, 18, 1);
	my $r3	= &bytes($sense, 19, 1);

	if ($sv eq '01')
	{
		print &lookup("SCSI status ", $ss, \%scsi_status_lt);
	}
	elsif ($sv eq '02')
	{
		print &lookup("adap_stat=", $as, \%aix_s2_adap_stat_lt);
	}
	

	#
	# And the SCSI sense data if this was a CHECK or if a
	# REQUEST SENSE just finished
	#
	if (($sv eq '01' && $ss eq '02') || (substr($cdb, 0, 2) eq '03'))
	{
        print " " . &scsi_sense(&bytes($sense, 28, 14), $rsp_code);
		# print " " . &scsi_sense(&bytes($sense, 20, 14));
	}

	return;
}


#---------------------------------------------------------------------------
#LABEL:          DMA_ERR
#
#[...]
#
#Detail Data
#BUS NUMBER
#FFFF FFFF 9000 00C1 
#CHANNEL UNIT ADDRESS
#0000 0000 0000 0005 
#ERROR CODE
#0000 0000 1000 0003
#---------------------------------------------------------------------------
#
# -or-
#
#---------------------------------------------------------------------------
#LABEL:          DMA_ERR
#IDENTIFIER:     02D12055
#
#[...]
#
#Detail Data
#BUS ID
#9000 0385 
#EVENT CODE
#2000 0000 
#LINK REGISTER
#0000 0000 043E EEB8 
#SOURCE LOCATION
#line: 3150 file: pci_bus.c
#PROBLEM DATA
#0000 0000 0100 0205 0000 0000
#---------------------------------------------------------------------------
sub DMA_ERR
{
	my @error	= @_;
	my $bn		= "unknown";
	my $cu		= "unknown";
	my $ec		= "unknown";
	my $sl		= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^BUS NUMBER/ ||
		    $error[$i] =~ /^BUS ID/)
		{
			$bn = $error[$i + 1];
			chomp($bn);
			$bn =~ s/\s+//g;
			next
		}
		if ($error[$i] =~ /^CHANNEL UNIT ADDRESS/ ||
		    $error[$i] =~ /^EVENT CODE/)
		{
			$cu = $error[$i + 1];
			chomp($cu);
			$cu =~ s/\s+//g;
			next
		}
		if ($error[$i] =~ /^ERROR CODE/ ||
		    $error[$i] =~ /^LINK REGISTER/)
		{
			$ec = $error[$i + 1];
			chomp($ec);
			$ec =~ s/\s+//g;
			next
		}
		if ($error[$i] =~ /^SOURCE LOCATION/)
		{
			$sl = $error[$i + 1];
			chomp($sl);
			$sl = "[" . $sl . "]";
			next
		}
	}
	printf("%s %s %s %s", $bn, $cu, $ec, $sl);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          DMPCHK_LDMPFSFULL
# 
# [...]
# 
# Detail Data
# percent free
#           24
# desired percent free
#           25
# FILE SYSTEM MOUNT POINT
# /var/adm/ras/livedump
# ---------------------------------------------------------------------------
sub DMPCHK_LDMPFSFULL
{
	my @error	= @_;
	my $dev		= "(unknown)";
	my $free	= "(unknown)";
	my $desired	= "(unknown)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^FILE SYSTEM MOUNT POINT/)
		{
			$dev = $error[$i + 1];
			chomp($dev);
			$dev =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^percent free$/)
		{
			$free = $error[$i + 1];
			chomp($free);
			$free =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^desired percent free/)
		{
			$desired = $error[$i + 1];
			chomp($desired);
			$desired =~ s/\s+//g;
			next;
		}
	}

	printf("%s  Desired percent free: %s  Actual: %s",
		$dev, $desired, $free);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          DMPCHK_NOSPACE
# 
# [...]
# 
# Detail Data
# File system name
# /var/adm/ras
#     
# Current free space in kb
#       643840
# Current estimated dump size in kb
#      1391411
# ---------------------------------------------------------------------------
sub DMPCHK_NOSPACE
{
	my @error	= @_;
	my $dev		= "(unknown)";
	my $free	= "(unknown)";
	my $est		= "(unknown)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^File system name/)
		{
			$dev = $error[$i + 1];
			chomp($dev);
			$dev =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^Current free space in kb/)
		{
			$free = $error[$i + 1];
			chomp($free);
			$free =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^Current estimated dump size in kb/)
		{
			$est = $error[$i + 1];
			chomp($est);
			$est =~ s/\s+//g;
			next;
		}
	}

	printf("%s  Estimated KB: %s, Free KB: %s", $dev, $est, $free);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          DMPCHK_TOOSMALL
# 
# [...]
# 
# Detail Data
# Largest dump device
# lg_dumplv
#     
# Largest dump device size in kb
#      2621440
# Current estimated dump size in kb
#      5871616
# ---------------------------------------------------------------------------
sub DMPCHK_TOOSMALL
{
	my @error	= @_;
	my $dev		= "(unknown)";
	my $size	= "(unknown)";
	my $est		= "(unknown)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^Largest dump device$/)
		{
			$dev = $error[$i + 1];
			chomp($dev);
			$dev =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^Largest dump device size in kb/)
		{
			$size = $error[$i + 1];
			chomp($size);
			$size =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^Current estimated dump size in kb/)
		{
			$est = $error[$i + 1];
			chomp($est);
			$est =~ s/\s+//g;
			next;
		}
	}

	printf("%s  Estimated KB: %s, Size KB: %s", $dev, $est, $size);

	return;
}


#
# DSI error handling
#
# The various DSI errors will log any of the data items below.
# The list was generated with the following command:
#
# $ errpt -a -t | awk '/^-----/       {f=0}
#                      /Label: DSI_/  {f++; next}
#                      /Detail Data/  {f++; next}
#                      f==2           {print}' | sort -u
#
# -----------------------------------------
# CHANNEL STATUS REGISTER 15, CSR15
# DATA STORAGE INTERRUPT ADDRESS REGISTER
# DATA STORAGE INTERRUPT REASON REGISTER
# DATA STORAGE INTERRUPT STATUS REGISTER
# EXVAL
# SEGMENT REGISTER, SEGREG
# -----------------------------------------
sub DSI_general
{
	my @error	= @_;
	my $csr15	= "";
	my $dar		= "";
	my $dsirr	= "";
	my $dsisr	= "";
	my $exval	= "";
	my $srval	= "";
	my $msg		= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^CHANNEL STATUS REGISTER 15, CSR15/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$csr15 = "CSR15 $_";
		}

		if ($error[$i] =~ /^DATA STORAGE INTERRUPT ADDRESS REGISTER/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$dar = "DAR $_";
		}

		if ($error[$i] =~ /^DATA STORAGE INTERRUPT REASON REGISTER/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$dsirr = "DSIRR $_";
		}

		if ($error[$i] =~ /^DATA STORAGE INTERRUPT STATUS REGISTER/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$dsisr = "DSISR $_";
		}

		if ($error[$i] =~ /^EXVAL/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$exval = "EXVAL $_";
		}

		if ($error[$i] =~ /^SEGMENT REGISTER, SEGREG/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$srval = "SRVAL $_";
		}

	}

	$msg = "$dar $dsisr $srval $exval $dsirr $csr15";
	$msg =~ s/^\s+//g;
	$msg =~ s/\s+/ /g;
	printf("%s", $msg);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          DUMP_STATS
# 
# [...]
# 
# Detail Data
# DUMP DEVICE
# /dev/lg_dumplv1
# DUMP SIZE
#              537529856
# TIME
# Wed Jul  7 13:41:01 2010
# DUMP TYPE (1 = PRIMARY, 2 = SECONDARY)
#            1
# DUMP STATUS
#            0
# ERROR CODE
# 0000 0000 0000 0000 
# DUMP INTEGRITY
# Compressed dump - Run dmpfmt with -c flag on dump after uncompressing. 
# 
# FILE NAME
# 
# PROCESSOR ID
#            0
# ---------------------------------------------------------------------------
sub DUMP_STATS
{
	my @error	= @_;
	my $dev		= "unknown";
	my $size	= "unknown";
	my $when	= "unknown";
	my $status	= "unknown";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^DUMP DEVICE/)
		{
			$dev = $error[$i + 1];
			chomp($dev);
			$dev =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^DUMP SIZE/)
		{
			$size = $error[$i + 1];
			chomp($size);
			$size =~ s/\s+//g;
			next;
		}

		if ($error[$i] =~ /^TIME/)
		{
			$when = $error[$i + 1];
			chomp($when);
			$when =~ s/\s+/ /g;
			next;
		}

		if ($error[$i] =~ /^DUMP STATUS/)
		{
			$status = $error[$i + 1];
			chomp($status);
			$status =~ s/\s+//g;
			next;
		}
	}

	printf("%s Status: %s Size: %s Dev: %s", $when, $status, $size, $dev);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          EEH_ERR
# IDENTIFIER:     32651A56
# 
# Resource Name:   PCIEEH          
# 
# [...]
# 
# Detail Data
# BID
# 9000 0385 
# DEVFUNC
# 0000 0000 
# RTAS TOKEN
# FFFF FFFF 
# ERROR CODE
# 1000 0006 
# PROBLEM DATA
# 0000 0000 0000 0000 0000 0000 [...]
# ---------------------------------------------------------------------------
sub EEH_ERR
{
	my @error	= @_;
	my $msg		= "";
	my $bid		= "(unknown)";
	my $err		= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^BID/)
		{
			$bid = $error[$i + 1];
			chomp($bid);
			$bid =~ s/\s+//g;

			$msg = "Bus ID " . $bid;
			next;
		}

		if ($error[$i] =~ /^ERROR CODE/)
		{
			$err = $error[$i + 1];
			chomp($err);
			$err =~ s/\s+//g;

			$msg .= " " . &lookup("Error ", $err,
						\%plat_eeh_err_lt);
			next;
		}
	}
	printf("%s", $msg);
}


# ---------------------------------------------------------------------------
# LABEL:          EPOW_SUS_CHRP
# IDENTIFIER:     BE0A03E5
# 
# Class:           H
# Type:            PERM
# WPAR:            Global
# Resource Name:   sysplanar0      
# Resource Class:  planar
# Resource Type:   sysplanar_rspc
# 
# Description
# ENVIRONMENTAL PROBLEM
# 
# Probable Causes
# Power Turned Off Without a Shutdown
# POWER OR FAN COMPONENT
# 
# Detail Data
# POWER STATUS REGISTER
# 0000 0003 
# PROBLEM DATA
# 0624 0040 0000 00B8 8600 8E00 0000 0000 0000 0000 4942 4D00 5048 0030 0100 A207 
# 2019 0627 2358 0400 0000 0000 0000 0000 4C00 0004 0000 0000 0000 0000 0000 0000 
# 838C 9734 0000 0000 5548 0018 0100 A207 8303 0001 0000 0000 0000 0000 0000 0000 
# 4548 004C 0100 A207 3832 3032 2D45 3443 3130 3443 3033 5400 0000 0000 414C 3734 
# 305F 3130 3000 0000 0000 0000 5046 3132 3037 3138 2E70 6677 3734 3000 0000 0000 
# 0000 0000 0000 0000 0000 0000 4550 0014 0200 A207 0301 0100 0420 0000 0000 0000 
# 
# Diagnostic Analysis
# Diagnostic Log sequence number:	6
# Resource tested:	sysplanar0
# Menu Number:		651303
# Description:
# 
# The following informational event was reported by Platform Firmware.
# 
# Platform Firmware Miscellaneous, Information Only.
# 
# Normal system shutdown with no additional delay.
# ---------------------------------------------------------------------------
sub EPOW_SUS_CHRP
{
	my @error	= @_;
	my $info	= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^Description/)
		{
			chomp($info = $error[$i + 1]);
			next;
		}
		if ($error[$i] =~ /^Platform Firmware Miscellaneous, Information Only/)
		{
			# Resaon for HMC shutdown of LPAR given here
			chomp($info = $error[$i + 1]);
			chomp($info = $error[$i + 2]) unless $info;
		}
	}
	printf("%s", $info);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          FCA_ERR6
# IDENTIFIER:     ECCE4018
# 
# [...]
# 
# Detail Data
# SENSE DATA
# 0000 0010 0000 0047 [...]
# ---------------------------------------------------------------------------
sub FCA_ERR
{
	my @error = @_;
	my $sense = &get_sense_data(@error);
	my $driver = &bytes($sense, 3, 1);

	#
	# A few drivers use this error log, with different indicators:
	#
	# 0x01 - Qlogic 2G adapter driver (qfcdd)
	# 0x03 - Qlogic 4G & 8G adapter driver (qlfcdd)
	# 0x10 - Emulex FC adapter (efcdd)
	# 0x11 - Emulex FC adapter (efcdd)
	#
	if ($driver eq '01')
	{
	}
	elsif ($driver eq '03')
	{
		&FCA_ERR_QLogic_qlfc(@error);
	}
    elsif ($driver eq '04')
    {
        &FCA_ERR_Cavium_cvfc(@error);
    }
	elsif (($driver eq '10') || ($driver eq '11'))
	{
		&FCA_ERR_Emulex_v10v11(@error);
	}
	elsif ($driver eq '20')
	{
		&FCA_ERR_emfcs_v0(@error);
	}
	else
	{
		printf("unknown driver type: " . $driver);
	}
}


sub FCA_ERR_emfcs_v0
{
	my @error   = @_;
	my $sense   = &get_sense_data(@error);
	my $version = &bytes($sense, 3, 1);
	my $errnum  = &words($sense, 1, 1);

    my $scsi_state       = &words($sense,  24,   2);

	my $msg     = "";

	if    ($errnum eq 'xxxxxxxx')
	{
		$msg  = "huh?";
	}
	elsif ($errnum eq '00000104')
	{
		my $exchange = &bytes($sense, 412, 2);
		$msg  = "Abort Process abandoned while exchange ($exchange) ";
		$msg .= "still busy; exchange indicator may be leaked";
	}
	elsif ($errnum eq '0000012C')
	{
		$msg  = "Abort process initiated for XRI-less command";
	}
	elsif ($errnum eq '00000130')
	{
		$msg  = "Unable to allocate an abort from the pool";
	}
	elsif ($errnum eq '00000140')
	{
		$msg  = "DEFECT: No VPI found for active RPI";
	}
	elsif ($errnum eq '00000150')
	{
		$msg  = "Adapter and driver disagree about who initiated ";
		$msg .= "an aborted exchange";
	}
	elsif ($errnum eq '00000160')
	{
		$msg  = "Adapter and driver disagree about who initiated ";
		$msg .= "an aborted exchange";
	}
	elsif ($errnum eq '00000168')
	{
		$msg  = "Adapter and driver disagree about who aborted ";
		$msg .= "a request";
	}
	elsif ($errnum eq '00000158')
	{
		$msg  = "Could not find abort context for XRI Aborted";
	}
	elsif ($errnum eq '00000170')
	{
		$msg  = "DEFECT: Bad or already-ineligible exchange context ";
		$msg .= "in XRI Aborted";
	}
	elsif ($errnum eq '00000178')
	{
		$msg  = "Unexpected status in XRI Aborted completion";
	}
	elsif ($errnum eq '0000023C')
	{
		my $errno = &hex2int(&bytes($sense, 388, 4));
		$msg  = "Control N_Port logout unregister mailbox failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000250')
	{
		$msg  = "Virtual port failed to idle during clear; will reset and wait";
	}
    elsif ($errnum eq '00000251')
    {
        $msg  = "Virtual port failed to idle during clear; will reset and wait forever";
    }
	elsif ($errnum eq '00000300')
	{
		$msg  = "Adapter firmware dump time out";
	}
	elsif ($errnum eq '00000305')
	{
		$msg  = "Adapter isn't READY; can't force a dump now";
	}
	elsif ($errnum eq '00000340')
	{
		$msg  = "Dump Mailbox timeout; can't force a dump now";
	}
	elsif ($errnum eq '00000402')
	{
		$msg  = "DEFUNCT: Attempt to claim spontaneous adapter dump ";
		$msg .= "failed";
	}
	elsif ($errnum eq '00000403')
	{
		$msg  = "Intended to dump adapter, but adapter not ready";
	}
	elsif ($errnum eq '00000405')
	{
		$msg  = "DEFUNCT: Spontaneous adapter dump detected; will ";
		$msg .= "collect";
	}
	elsif ($errnum eq '00000410')
	{
		my $rc = &bytes($sense, 384, 4);
		$msg  = "Collection of 'SID' data for dump failed; rc = $rc";
	}
	elsif ($errnum eq '00000410')
	{
		my $rc = &bytes($sense, 384, 4);
		$msg  = "Collection of 'SID' data for dump failed; rc = $rc";
	}
	elsif ($errnum eq '00000470')
	{
		my $krc = &bytes($sense, 388, 8);
		$msg  = "Attempt to force livedump failed (krc $krc)";
	}
	elsif ($errnum eq '00000475')
	{
		my $krc = &bytes($sense, 388, 8);
		$msg  = "Attempt to force livedump failed (krc $krc)";
	}
	elsif ($errnum eq '00000491')
	{
		$msg  = "forced dump of the adapter FW Failed";
	}
	elsif ($errnum eq '00000492')
	{
		$msg  = "Adapter firmware dump read or delete failed";
	}
	elsif ($errnum eq '000004A1')
	{
		$msg  = "INFO: Adapter not ready for dump (already dumping?)";
	}
	elsif ($errnum eq '000004B0')
	{
		$msg  = "Unable to force dump; adapter not READY";
	}
    elsif ($errnum eq '00000512')
    {
        $msg  = "Firmware updated failed due to adapter being opened";
    }
	elsif ($errnum eq '00000518')
	{
		$msg  = "Firmware update failed due to adapter reset raw failure";
	}
	elsif ($errnum eq '00000530')
	{
		$msg  = "Firmware update failed due to image write failure";
	}
	elsif ($errnum eq '00000550')
	{
		my $errno = &hex2int(&bytes($sense, 384, 4));

		$msg  = "Reset failed after firmware update; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000060C')
	{
		$msg  = "DEFECT: Completion with invalid type on receive CQ";
	}
	elsif ($errnum eq '00000612')
	{
		$msg  = "DEFECT: Completed mailbox does not match issued ";
		$msg .= "mailbox"
	}
	elsif ($errnum eq '00000621')
	{
		$msg  = "DEFECT: No active admin request matches request tag";
	}
	elsif ($errnum eq '00000624')
	{
		$msg  = "Protocol CQE surprisingly failed with invalid RPI";
	}
	elsif ($errnum eq '0000062A')
	{
		$msg  = "Protocol CQE surprisingly indicates XRI busy";
	}
    elsif ($errnum eq '00000672')
    {
        $msg  = "Async ELS recieved; sr buf had good status but provided more data than expected";
    }
	elsif ($errnum eq '0000067B')
	{
		$msg  = "Async ELS for inactive local context";
	}
	elsif ($errnum eq '00000681')
	{
		$msg  = "Sequence Reporting Buffer discarded due to either no XRI or empty RQ";
	}
	elsif ($errnum eq '0000068A')
	{
		my $els = &bytes($sense, 384, 4);
		my $sid = &bytes($sense, 389, 3);
		$msg  = "Unrecognized async ELS from $sid; ";
		$msg .= &lookup("ELS ", $els, \%fc_payload_op_lt);
	}
    elsif ($errnum eq '0000068D')
    {
        $msg  = "Unable to respond to Async PLOGI; cmd_elem exhaustion";
    }
    elsif ($errnum eq '0000068F')
    {
        $msg  = "Unexpected Async PLOGI recieved while in pt2pt mode";
    }
	elsif ($errnum eq '000006BB')
	{
		$msg  = "Adapter reporting mis-configured SFP";
	}
	elsif ($errnum eq '000006BD')
	{
        my $event_type = &bytes($sense, 398, 1);
        my $event_code = &bytes($sense, 397, 1);
		$msg  = "Undetermined adapter port event type $event_type code $event_code";
	}
	elsif ($errnum eq '00000690')
	{
		$msg  = "Received unsolicited LOGO ELS with missing payload ";
		$msg .= "N_Port ID";
	}
	elsif ($errnum eq '000006C6')
	{
		my $async = &bytes($sense, 384, 4);
		$msg  = "Async event ($async) dropped for lack of queue elems";
	}
	elsif ($errnum eq '000006C8')
	{
		my $lk_fail_cnt = &hex2int(&bytes($sense, 64, 4));
        my $loss_sync_cnt = &hex2int(&bytes($sense,  68, 4));
        my $loss_of_sig_cnt = &hex2int(&bytes($sense,  72, 4));
        my $inv_word_cnt = &hex2int(&bytes($sense,  80, 4));

		$msg  = "INFO: Adapter link up recovery; lk_failure ($lk_fail_cnt); loss_of_sync ($loss_sync_cnt) inv_words ($inv_word_cnt)";
	}
    elsif ($errnum eq '00000800')
    {
        my $cmd    = &bytes($sense, 385, 1);
        my $status = &bytes($sense, 386, 2);
        $msg  = "Mailbox command failure (cmd $cmd, status $status)";
    }
	elsif ($errnum eq '00000809')
	{
		my $cmd    = &bytes($sense, 385, 1);
		my $status = &bytes($sense, 386, 2);
		$msg  = "Mailbox command failure (cmd $cmd, status $status)";
	}
	elsif ($errnum eq '00000827')
	{
		$msg  = "Dumping adapter due to mailbox failure";
	}
	elsif ($errnum eq '00000833')
	{
		my $status = &bytes($sense, 386, 2);
		$msg  = "Mailbox reg rpi failure (status $status) registering ";
		$msg .= "target port context";
	}
	elsif ($errnum eq '0000080E')
	{
		my $cmd    = &bytes($sense, 385, 1);
		my $status = &bytes($sense, 386, 2);
		$msg  = "Mailbox command failure (cmd $cmd, status $status)";
	}
	elsif ($errnum eq '0000080F')
	{
		my $cmd    = &bytes($sense, 385, 1);
		my $status = &bytes($sense, 386, 2);
		$msg  = "Mailbox command failed with unknown status ";
		$msg .= "(cmd $cmd, status $status)";
	}
	elsif ($errnum eq '00000812')
	{
		my $embed  = &mask(&bytes($sense, 388, 1), "01");
		$msg  = "Config mailbox subcommand failure ";
		if ($embed eq "01") {
			my $opcode = &bytes($sense, 408, 1);
			my $subsys = &bytes($sense, 409, 1);
			my $status = &bytes($sense, 412, 1);
			my $add_st = &bytes($sense, 413, 1);
			$msg .= "(subsys $subsys, op $opcode, ";
			$msg .= "status $status, add status $add_st)";
		} else {
			my $status = &bytes($sense, 386, 2);
			$msg .= "(cmd not embedded, wrapper status $status)";
		}
	}
	elsif ($errnum eq '00000815')
	{
		my $embed  = &mask(&bytes($sense, 388, 1), "01");
		$msg  = "Config mailbox subcommand failure ";
		if ($embed eq "01") {
			my $opcode = &bytes($sense, 408, 1);
			my $subsys = &bytes($sense, 409, 1);
			my $status = &bytes($sense, 412, 1);
			my $add_st = &bytes($sense, 413, 1);
			$msg .= "(subsys $subsys, op $opcode, ";
			$msg .= "status $status, add status $add_st)";
		} else {
			my $status = &bytes($sense, 386, 2);
			$msg .= "(cmd not embedded, wrapper status $status)";
		}
	}
	elsif ($errnum eq '0000081B')
	{
		my $embed  = &mask(&bytes($sense, 388, 1), "01");
		$msg  = "Config mailbox subcommand failure w/ unknown status ";
		if ($embed eq "01") {
			my $opcode = &bytes($sense, 408, 1);
			my $subsys = &bytes($sense, 409, 1);
			my $status = &bytes($sense, 412, 1);
			my $add_st = &bytes($sense, 413, 1);
			$msg .= "(subsys $subsys, op $opcode, ";
			$msg .= "status $status, add status $add_st)";
		} else {
			my $status = &bytes($sense, 386, 2);
			$msg .= "(cmd not embedded, wrapper status $status)";
		}
	}
	elsif ($errnum eq '0000084B')
	{
		my $embed  = &mask(&bytes($sense, 388, 1), "01");
		$msg  = "Config mailbox buffer too small for response";
		if ($embed eq "01") {
			my $opcode = &bytes($sense, 408, 1);
			my $subsys = &bytes($sense, 409, 1);
			my $status = &bytes($sense, 412, 1);
			my $add_st = &bytes($sense, 413, 1);
			$msg .= "(subsys $subsys, op $opcode, ";
			$msg .= "status $status, add status $add_st)";
		} else {
			my $status = &bytes($sense, 386, 2);
			$msg .= "(cmd not embedded, wrapper status $status)";
		}
	}
	elsif ($errnum eq '0000088D')
	{
		$msg  = "Write Object mailbox command failure";
	}
	elsif ($errnum eq '00000908')
	{
		$msg  = "Initialization of control DMA handle failed";
	}
	elsif ($errnum eq '00000910')
	{
		$msg  = "Initialization of I/O DMA handle failed";
	}
	elsif ($errnum eq '00000918')
	{
		my $size = &bytes($sense, 388, 8);

		$msg  = "INFO: I/O DMA handle smaller than ODM requested; ";
		$msg .= "size = $size"
	}
	elsif ($errnum eq '00000928')
	{
		my $size = &bytes($sense, 388, 4);

		$msg  = "INFO: max_xfer_size smaller than ODM requested; ";
		$msg .= "size = $size"
	}
	elsif ($errnum eq '00000958')
	{
		$msg  = "Initialization of adapter driver DMA handle failed";
	}
	elsif ($errnum eq '00000A00')
	{
		$msg  = "Timeout waiting for bootstrap mailbox to come ready";
	}
	elsif ($errnum eq '00000A20')
	{
		my $exchange = &bytes($sense, 412, 2);
        my $cwwpn = &bytes($sense, 184, 8);
        my $rnport = &bytes($sense, 241, 3);
        my $twwpn = &bytes($sense, 248, 8);
		$msg  = "Abort Processing stall $cwwpn (exchange $exchange) ";
        $msg .= "for dest 0x$rnport $twwpn"
	}
	elsif ($errnum eq '00000A30')
	{
		$msg  = "POST watchdog retries exceeded";
	}
	elsif ($errnum eq '00000A48')
	{
		$msg  = "Initialization heartbeat timer popped, but not ";
		$msg .= "in heartbeat phase";
	}
	elsif ($errnum eq '00000A50')
	{
		my $cmd    = &bytes($sense, 385, 1);
		$msg  = "Mailbox timeout (cmd $cmd)";
	}
	elsif ($errnum eq '00000A60')
	{
		$msg  = "Admin queue request timed out; aborting it";
	}
	elsif ($errnum eq '00000A80')
	{
		$msg  = "Admin WQE cancel timed out; will reset adapter";
	}
	elsif ($errnum eq '00000AB4')
	{
		$msg  = "Coordinated activity timed out and another function ";
		$msg .= "has pre-empted the session";
	}
	elsif ($errnum eq '00000AB8')
	{
		$msg  = "Coordinated activity timed out and previous ";
		$msg .= "broadcast still incomplete";
	}
	elsif ($errnum eq '00000ABC')
	{
		$msg  = "Coordinated activity timed out; will abnormally ";
		$msg .= "terminate";
	}
	elsif ($errnum eq '00000AD0')
	{
		$msg  = "Unable to preserve FW dump via livedump; discarding";
	}
	elsif ($errnum eq '00000B08')
	{
		$msg  = "DEFECT: Mailbox issue failure";
	}
	elsif ($errnum eq '00000BA8')
	{
		$msg  = "DEFECT: Missing login context for async ELS response";
	}
	elsif ($errnum eq '00000C04')
	{
		$msg  = "INFO: Adapter link in dead state during driver close";
	}
	elsif ($errnum eq '00000C1B')
	{
		$msg  = "Driver failed to come ready for mailboxes during ";
		$msg .= "VPD query";
	}
	elsif ($errnum eq '00000C1C')
	{
		my $cause = &bytes($sense, 391, 1);
		$msg  = "Driver has declared fatal error (cause $cause)";
	}
	elsif ($errnum eq '00000C1D')
	{
		$msg  = "Exceeded the maximum time waiting for Coordinated Activity ";
		$msg .= "Failing request";
	}
	elsif ($errnum eq '00000C26')
	{
		$msg  = "Error restoring interrupt vector";
	}
	elsif ($errnum eq '00000C28')
	{
		$msg  = "INFO: An EEH event has been detected";
	}
	elsif ($errnum eq '00000C48')
	{
		$msg  = "DEFECT: Unable to find virtual port to unregister ";
		$msg .= "targets";
	}
	elsif ($errnum eq '00000C4C')
	{
		$msg  = "INFO: WWPN change for Well Known N_Port";
	}
	elsif ($errnum eq '00000C74')
	{
        my $cwwpn = &bytes($sense, 184, 8);
        my $twwpn = &bytes($sense, 248, 8);
        my $rnport = &bytes($sense, 241, 3);

		$msg  = "Driver returned $cwwpn login to 0x$rnport $twwpn with EBUSY due to command is currently active";
	}
    elsif ($errnum eq '00000C8C')
    {
        $msg  = "Free map range is 0 or exceeded";
    }
	elsif ($errnum eq '00000C9C')
	{
		$msg  = "DEFECT: Double free of freemap entity";
	}
	elsif ($errnum eq '00000CA0')
	{
		$msg  = "Attempting to free zero entities";
	}
	elsif ($errnum eq '00000CA8')
	{
		$msg  = "While freeing resources we found they were allready free ";
	}
	elsif ($errnum eq '00000CD0')
	{
		$msg  = "INFO: Lost the race to become broadcast initiator";
	}
	elsif ($errnum eq '00000CD6')
	{
		$msg  = "Received coordinated activity msg that conflicts ";
		$msg .= "with current state";
	}
	elsif ($errnum eq '00000CDA')
	{
		$msg  = "Coordinated activity continuation broadcast failed";
	}
	elsif ($errnum eq '00000D08')
	{
		$msg  = "Command entry point request delayed due to XRI ";
		$msg .= "exhaustion";
	}
    elsif ($errnum eq '00000D58')
    {
        $msg  = "SGL build failure;";
    }
	elsif ($errnum eq '00000DA0')
	{
		my $rnport = &bytes($sense, 53, 3);
		$msg  = "Admin WQE failed due to abort by remote port $rnport";
	}
	elsif ($errnum eq '00000DB0')
	{
		$msg  = "Protocol WQE failed with DMA failure indication";
	}
	elsif ($errnum eq '00000DB8')
	{
        my $cwwpn = &bytes($sense, 184, 8);
        my $rnport = &bytes($sense, 53, 3);

		$msg  = "Protocol WQE failed with unexpected Invalid RPI ";
        $msg  .= "($cwwpn <-> 0x$rnport)"
	}
	elsif ($errnum eq '00000DC4')
	{
		$msg  = "Admin WQE failed with adapter local reject; no XRI";
	}
	elsif ($errnum eq '00000DC8')
	{
		$msg  = "Admin WQE failed with unknown Local Reject code";
	}
    elsif ($errnum eq '00000E06')
    {
        $msg  = "Available RQ's reported by adapter is less than the minimum";
    }
    elsif ($errnum eq '00000E09')
    {
        $msg  = "Available CQ's reported by adapter is less than the minimum";
    }
	elsif ($errnum eq '00000E14')
	{
		my $adap = hex2int(&bytes($sense, 386, 2));
		my $odm  = hex2int(&bytes($sense, 390, 2));
		$msg  = "Adapter supports fewer cmd_elems ($adap) than were ";
		$msg .= "requested in ODM ($odm)";
	}
	elsif ($errnum eq '00000E15')
	{
		my $rtype = &bytes($sense, 387, 1);
		my $count = &bytes($sense, 390, 2);
		$msg  = "Adapter supports fewer resources than needed to ";
		$msg .= "configure ($count of type $rtype)";
	}
	elsif ($errnum eq '00000E22')
	{
		$msg  = "Preferred FCF not found; switching to alternate";
	}
	elsif ($errnum eq '00000E23')
	{
		$msg  = "Switching back to preferred FCF from alternate";
	}
	elsif ($errnum eq '00000E25')
	{
		$msg  = "FLOGI succeeded, but bad connection type";
	}
	elsif ($errnum eq '00000E27')
	{
		$msg  = "Adapter initialization retries exceeded";
	}
	elsif ($errnum eq '00000E2A')
	{
		$msg  = "Adapter initialization POST failed";
	}
	elsif ($errnum eq '00000E2D')
	{
		$msg  = "Adapter initialization adapter info collection ";
		$msg .= "failure";
	}
    elsif ($errnum eq '00000E33')
    {
        $msg  = "Failure setting up one of the adapter queues";
    }
	elsif ($errnum eq '00000E36')
	{
		$msg  = "Adapter initialization resource setup failure";
	}
	elsif ($errnum eq '00000E42')
	{
		$msg  = "Mailbox failure during unregisters for link down";
	}
	elsif ($errnum eq '00000E45')
	{
        my $lk_fail_cnt = &hex2int(&bytes($sense, 64, 4));
        my $loss_sync_cnt = &hex2int(&bytes($sense,  68, 4));
        my $loss_of_sig_cnt = &hex2int(&bytes($sense,  72, 4));
        my $inv_word_cnt = &hex2int(&bytes($sense,  80, 4));

		$msg  = "Adapter link up failure; lk_failure ($lk_fail_cnt); loss_of_sync ($loss_sync_cnt) inv_words ($inv_word_cnt)";
	}
	elsif ($errnum eq '00000E48')
	{
		$msg  = "Mailbox failure while reading FCF table";
	}
	elsif ($errnum eq '00000E4B')
	{
		$msg  = "Link discovery FCF selection failed";
	}
	elsif ($errnum eq '00000E4F')
	{
		my $els = &words($sense, 160, 1);

		$msg  = "Too many FABRIC_OPS failures (";
		$msg .= &lookup("ELS ", $els, \%fc_payload_op_lt) . " fail)";
	}
	elsif ($errnum eq '00000E54')
	{
		$msg  = "Link registration failed";
	}
	elsif ($errnum eq '00000E57')
	{
		$msg  = "Firmware update image write failure";
	}
	elsif ($errnum eq '00000E60')
	{
		my $cwwpn = &bytes($sense, 184, 8);
		$msg  = "Local context in bad state for Update NPIV ($cwwpn)";
	}
	elsif ($errnum eq '00000E62')
	{
        my $num_act_vports = &bytes($sense, 146, 2);
        my $errno = &hex2int(&bytes($sense, 392, 4));
        my $errno_2 = &lookup("", $errno, \%aix_errno_lt);

        my $rnport = &bytes($sense, 53, 3);
        my $scsi_id = &bytes($sense, 181, 3);

        my $cwwpn = &bytes($sense, 184, 8);
		$msg  = "Fabric logout failed with $errno_2 during NPIV teardown for ($cwwpn 0x$scsi_id <-> $rnport) act_vp's $num_act_vports ";
	}
	elsif ($errnum eq '00000E63')
	{
		my $cwwpn = &bytes($sense, 184, 8);
		$msg  = "VPI unreg failed during NPIV update for $cwwpn";
	}
	elsif ($errnum eq '00000E64')
	{
		my $cwwpn = &bytes($sense, 184, 8);
		$msg  = "RPI unreg failed during NPIV update for $cwwpn";
	}
	elsif ($errnum eq '00000E66')
	{
		my $cwwpn = &bytes($sense, 184, 8);
		$msg  = "VPI init failed during NPIV setup for $cwwpn";
	}
	elsif ($errnum eq '00000E6C')
	{

        # SFL 

		my $cwwpn = &bytes($sense, 184, 8);

        my $cmd = &words($sense, 96, 8);
        my $status = &bytes($cmd, 11, 1);

        my $failure_type = &bytes($cmd, 15, 1);
        my $fail_rc = &bytes($cmd, 16, 1);
        my $fail_exp = &bytes($cmd, 17, 1);

		$msg  = "FDISC failed during NPIV setup for $cwwpn status ($status)";

        if ( $failure_type eq '01' ) # LS_RJT
        {
            $msg .= " " .  &lookup(" ", $failure_type, \%fc_failure_type_lt);    
            $msg .= ", " . &lookup("Reason code ", $fail_rc, \%fc_lsrjt_rc_lt);
            $msg .= ", " . &lookup("Explanation ", $fail_exp, \%fc_lsrjt_re_lt);
        }

        # my $sense   = &get_sense_data(@error);
        # emfc_print_cmd_err($cmd)

	}
	elsif ($errnum eq '00000E72')
	{
		my $cwwpn = &bytes($sense, 184, 8);
		$msg  = "FDISC failed w/ Logical Error / Invalid Port Name $cwwpn";
	}
    elsif ($errnum eq '00000E78')
    {
        my $cwwpn = &bytes($sense, 184, 8);
        $msg  = "SCR failed during NPIV setup for $cwwpn";
    }
	elsif ($errnum eq '00000E79')
	{
		my $cwwpn = &bytes($sense, 184, 8);
		$msg  = "Nameserver login failed during NPIV setup for $cwwpn";
	}
	elsif ($errnum eq '00000E9C')
	{
		my $cmd_opcode = &bytes($sense, 396, 1);
		my $rnport = &bytes($sense, 413, 3);
		my $twwpn = &bytes($sense, 416, 8);
		my $cwwpn = &bytes($sense, 184, 8);

		my $opcode = &lookup("", $cmd_opcode, \%fc_cmd_op_lt);

		$msg  = "Plogi op ($opcode) failed for $cwwpn -> $rnport $twwpn";
	}
    elsif ($errnum eq '00000EA8')
    {
        $msg  = "Adapter firmware dump collection failed";
    }
	elsif ($errnum eq '00000EAB')
	{
		$msg  = "INFO: Adapter firmware dump collected; will ";
		$msg .= "live dump";
	}
	elsif ($errnum eq '00000EAE')
	{
		my $errno = &hex2int(&bytes($sense, 388, 4));

		$msg  = "Firmware dump mailbox failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000EAF')
	{
		my $errno = &hex2int(&bytes($sense, 388, 4));

		$msg  = "Live dump initiation failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000EB0')
	{
		$msg  = "Broadcast of completion message for FW dump failed";
	}
	elsif ($errnum eq '00000EB4')
	{
		my $rnport = &bytes($sense, 53, 3);
		$msg  = "RPI unreg failed during logout with remote $rnport";
	}
	elsif ($errnum eq '00000EC2')
	{
		$msg  = "INFO: Lost the race to become fw dump collector";
	}
	elsif ($errnum eq '00000EC4')
	{
		$msg  = "INFO: Spontaneous adapter dump; will collect";
	}
	elsif ($errnum eq '00000EC6')
	{
		$msg  = "INFO: Expected adapter dump, but none appeared";
	}
	elsif ($errnum eq '00000EC8')
	{
		$msg  = "Broadcast of FINISH_FW_DUMP message failed";
	}
	elsif ($errnum eq '00000ECA')
	{
		my $ps = &bytes($sense, 392, 4);
		$msg  = "INFO: Found undefined Port Status value ($ps)";
	}
	elsif ($errnum eq '00000ECC')
	{
		my $e1 = &bytes($sense, 400, 4);
		my $e2 = &bytes($sense, 404, 4);
		$msg  = "INFO: Adapter has entered error state ($e1, $e2)";
	}
	elsif ($errnum eq '00000ECE')
	{
		$msg  = "Adapter is signalling over temperature condition";
	}
	elsif ($errnum eq '00000ED0')
	{
		$msg  = "INFO: Lost the race to manage adapter error data ";
		$msg .= "collection";
	}
    elsif ($errnum eq '00000ED1')
    {
        $msg  = "Adapter initialization retries exceeded";
    }
	elsif ($errnum eq '00000ED5')
	{
		my $e1 = &bytes($sense, 387, 1);
		my $e2 = &bytes($sense, 391, 1);

		$msg  = "INFO: Requested num of W/Q's ($e1) could not be created due to resource shortage, ";
		$msg .= "act W/Q's ($e2)"
	}
    elsif ($errnum eq '00000ED8')
    {
        my $e1 = &bytes($sense, 387, 1);
        my $e2 = &bytes($sense, 391, 1);

        $msg  = "INFO: Requested num of W/Q's ($e1) could not be created due to resource shortage, ";
        $msg .= "act W/Q's ($e2)"
    }
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);
}


sub FCA_ERR_Emulex_v10v11
{
	my @error   = @_;
	my $sense   = &get_sense_data(@error);
	my $version = &bytes($sense, 3, 1);
	my $errnum  = &words($sense, 1, 1);
	my $msg     = "";

	if    ($errnum eq 'xxxxxxxx')
	{
		$msg = "huh?";
	}
	elsif ($errnum eq '00000006')
	{
		my $st = &byte_reverse(&bytes($sense, 322, 2));
		my $mb = &bytes($sense, 321, 1);
		$msg = "Adapter mailbox request ($mb) failed with unknown ";
		$msg .= "status $st";
	}
	elsif ($errnum eq '00000007')
	{
		$msg  = "A config port mailbox failed. Mailbox is included";
	}
	elsif ($errnum eq '0000000C')
	{
		my $pay_op	= &words($sense,  88, 1);
		my $rc		= &bytes($sense, 338, 1);
		my $re		= &bytes($sense, 337, 1);
		my $lnport;

		$lnport  = &bytes($sense, 338, 1);
		$lnport .= &bytes($sense, 337, 1);
		$lnport .= &bytes($sense, 336, 1);

		my $rnport;

		$rnport  = &bytes($sense, 342, 1);
		$rnport .= &bytes($sense, 341, 1);
		$rnport .= &bytes($sense, 340, 1);

		$msg = "Unknown unsolicited ELS for N_Port $lnport rec from $rnport ";
	}
	elsif ($errnum eq '00000011')
	{
		my $els = &words($sense, 2, 1);
		$msg  = "LS_RJT Login Required and retries exceeded; ";
		$msg .= &lookup("ELS ", $els, \%fc_payload_op_lt);
	}
	elsif ($errnum eq '00000014')
	{
		my $els  = "unknown";

		if ($version eq '10')
		{
			$els = &words($sense, 88, 1);
		}
		else
		{
			$els = &words($sense, 96, 1);
		}

		$msg  = &lookup("ELS ", $els, \%fc_payload_op_lt);
		$msg .= " suffered Fabric or N_Port reject: ";
		$msg .= "Fabric Path Not Available";
	}
	elsif ($errnum eq '00000017')
	{
		my $pay_op	= &words($sense,  88, 1);
		my $rc		= &bytes($sense, 338, 1);
		my $re		= &bytes($sense, 337, 1);
		my $rnport;

		$rnport  = &bytes($sense, 342, 1);
		$rnport .= &bytes($sense, 341, 1);
		$rnport .= &bytes($sense, 340, 1);

		$msg = "(1 of 2) ELS to $rnport failed with LS_RJT, ";
		$msg .= &lookup("payload opcode ", $pay_op, \%fc_payload_op_lt);
		$msg .= ", " . &lookup("Reason code ", $rc, \%fc_lsrjt_rc_lt);
		$msg .= ", " . &lookup("Explanation ", $re, \%fc_lsrjt_re_lt);
	}
	elsif ($errnum eq '00000019')
	{
		$msg  = "An IOCB failed with a local reject, with an ";
		$msg .= "undocumented parameter error";
	}
	elsif ($errnum eq '0000001F')
	{
		$msg  = "An IOCB failed with an error indicating link down";
	}
	elsif ($errnum eq '00000021')
	{
		my $icmd = &bytes($sense, 349, 1);
		my $para = &byte_reverse(&bytes($sense, 336, 4));
		my $els  = "unknown";

		if ($version eq '10')
		{
			$els = &words($sense, 88, 1);
		}
		else
		{
			$els = &words($sense, 96, 1);
		}

		$msg  = "IOCB (";
		$msg .= &lookup("ELS ", $els, \%fc_payload_op_lt);
		$msg .= ") failed with unknown Local Reject ($para)";
	}
	elsif ($errnum eq '00000024')
	{
		$msg  = "Misc (not FLOGI or SCR) adap ring IOCB failure";
	}
	elsif ($errnum eq '00000026')
	{
		my $mb = &bytes($sense, 321, 1);
		my $st = &bytes($sense, 322, 2);
		$msg  = "Mailbox command ($mb) timed out (status $st)";
	}
	elsif ($errnum eq '00000027')
	{
		# sfl Needs more work to determine if this is vp or phyiscal
		# We may end up printing out the wrong vwwn / target for vp enabled
		# IOCB failures

		# look for a target wwn here
		my $rwwpn = &bytes($sense, 112, 8);
		if ($rwwpn eq '0000000000000000')
		{
			# must have supplied an n_port and not a wwn
			$rwwpn = &bytes($sense, 105, 3);
		}

		my $vwwpn = &bytes($sense, 170, 8);
		my $payload_op = &words($sense, 80, 1);
		$msg = "IOCB timeout 0x$vwwpn => 0x$rwwpn " ;
		$msg .= &lookup("payload opcode ", $payload_op,
			\%fc_payload_op_lt);
	}
	elsif ($errnum eq '00000029')
	{
		my $bytes = &bytes($sense, 320, 4);
		$msg  = "DMA map for $bytes bytes failed w/ DMA_NORES";
	}
	elsif ($errnum eq '0000002A')
	{
		$msg  = "Adapter reset failed and exceeded our retries";
	}
	elsif ($errnum eq '0000002E')
	{
		$msg  = "An abort IOCB has timed out";
	}
	elsif ($errnum eq '00000030')
	{
		$msg = "Error attention";

		# Some of these have the SENSE DATA decorated with a
		# diagnostic analysis including an SRN.  Retrieve it if so.
		my $srn = "";
		for (my $i = 0; $i <= $#error; $i++)
		{
			if ($error[$i] =~ /^SRN:/)
			{
				$srn = $error[$i];
				chomp($srn);
				$srn =~ s/\s+/ /g;
				$msg = "$msg $srn";
				last;
			}
		}
	}
	elsif ($errnum eq '00000038')
	{
		$msg  = "No free cmd to respond to unsolicited ELS";
	}
	elsif ($errnum eq '00000041')
	{
		$msg  = "Link is dead (has been down several seconds)";
	}
	elsif ($errnum eq '0000004B')
	{
		$msg  = "DMA initialization failed; check adapter tuning and ";
		$msg  .= "slot capability";
	}
	elsif ($errnum eq '0000004C')
	{
		$msg  = "D_MAP_INIT failed; cannot set up initial DMA TCE pool";
	}
	elsif ($errnum eq '00000047')
	{
		my $port = &byte_reverse(&bytes($sense, 328, 3));
		$msg  = "Register login MB completed for port ID not in ";
		$msg .= "login table: $port";
	}
	elsif ($errnum eq '00000048')
	{
		$msg = "Async LOGO payload missing N_Port ID";
	}
	elsif ($errnum eq '00000051')
	{
		$msg = "Error attention (continued from previous error)";
	}
	elsif ($errnum eq '00000052')
	{
		$msg  = "Unsolicited ELS IOCB arrived with invalid buffer";
	}
	elsif ($errnum eq '00000053')
	{
		my $vwwpn = &bytes($sense, 170, 8);
		if ($vwwpn eq '0000000000000000')
		{
			$msg = "(2 of 2) ELS failed with LS_RJT";
		}
		else
		{
			$msg = "(2 of 2) $vwwpn ELS failed with LS_RJT";
		}
	}
	elsif ($errnum eq '0000005D')
	{
		my $my_iocb = &bytes($sense, 387, 1);
		$msg = "An unknown unsolicited IOCB was received. ";
		$msg .= "The IOCB $my_iocb is included.";
	}
    elsif ($errnum eq '00000074')
    {
        $msg = "Restart adapter retries exceeded; declaring ";
        $msg .= "FATAL";
    }
	elsif ($errnum eq '0000009E')
	{
		$msg = "The WWPN for a well Known port ID changed";
	}
	elsif ($errnum eq '000000BB')
	{
		$msg  = "Completed mailbox differs from issued; declaring ";
		$msg .= "FATAL";
	}
	elsif ($errnum eq '000000C0')
	{
		my $rpi = &bytes($sense, 8, 2);
		$msg  = "Proto IOCB Invalid RPI ($rpi); no login entry";
	}
	elsif ($errnum eq '000000C1')
	{
		my $rpi = &bytes($sense, 8, 2);
		$msg  = "Proto IOCB Invalid RPI ($rpi); wrong vport";
	}
	elsif ($errnum eq '000000C2')
	{
		my $rpi = &bytes($sense, 8, 2);
		$msg  = "Proto IOCB Invalid RPI ($rpi); wrong RPI";
	}
	elsif ($errnum eq '000000C3')
	{
		my $rpi = &bytes($sense, 8, 2);
		$msg  = "Proto IOCB failed w/ Invalid RPI ($rpi); ";
		$msg .= "expected failure (debug)";
	}
	elsif ($errnum eq '000000C4')
	{
		my $rpi = &bytes($sense, 8, 2);
		$msg  = "Proto IOCB failed w/ Invalid RPI ($rpi); RPI not free";
	}
	elsif ($errnum eq '000000C5')
	{
		my $rpi = &bytes($sense, 8, 2);
		$msg  = "Adap IOCB failed w/ Invalid RPI ($rpi); ";
		$msg .= "expected failure (debug)";
	}
	elsif ($errnum eq '000000C6')
	{
		$msg  = "Proto IOCB Invalid RPI; no RPI in cmd";
	}
	elsif ($errnum eq '00000121')
	{
		$msg  = "Un-anticipated async IOCB on the proto ring. ";
		$msg .= "The IOCB is included.";
	}
	elsif ($errnum eq '00000D04')
	{
		$msg  = "Cmd for vport timed out in adapter ";
	}
	elsif ($errnum eq '00000D28')
	{
		$msg  = "NPIV command timed out in the adapter ";
	}
	elsif ($errnum eq '0000D300')
	{
		my $vpi = &bytes($sense, 8, 2);
		$msg  = "REG_VPI failed and associated VPI ($vpi) not valid";
	}
	elsif ($errnum eq '0000D301')
	{
		my $vpi = &bytes($sense, 326, 2);
		$msg  = "UNREG_VPI completed but included VPI ($vpi) not valid";
	}
	elsif ($errnum eq '0000D302')
	{
		$msg  = "REG_VPI mailbox failure (non-cmd_fcn entry point)";
	}
	elsif ($errnum eq '0000D303')
	{
		$msg  = "Unknown REG_VPI mailbox failure (cmd_fcn entry point)";
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}
	printf("%s", $msg);
}


sub FCA_ERR_QLogic_qlfc
{
	my @error  = @_;
	my $sense  = &get_sense_data(@error);
	my $errnum = &words($sense, 1, 1);
	my $msg    = "";

	if    ($errnum eq 'xxxxxxxx')
	{
		$msg = "huh?";
	}
	elsif ($errnum eq '00000000')
	{
		$msg  = "Expected MB as inuse but it's not";
	}
	elsif ($errnum eq '00000001')
	{
		$msg  = "Verify Checksum command failed";
	}
	elsif ($errnum eq '00000003')
	{
		$msg  = "Adapter suffered an internal error";
	}
	elsif ($errnum eq '0000000E')
	{
		$msg  = "Adapter failed login request with: No PCB";
	}
	elsif ($errnum eq '00000010')
	{
		$msg  = "Unable to connect; GET_ID mailbox failed at startup";
	}
	elsif ($errnum eq '00000012')
	{
		$msg  = "Registration for State Change Notifications failed";
	}
	elsif ($errnum eq '00000014')
	{
		$msg  = "Exec FW MB failed,reset in progress";
	}
	elsif ($errnum eq '00000016')
	{
		my $rnport = &byte_reverse(&bytes($sense, 208, 3));
		$msg  = "Login to $rnport failed; not in correct state and retry count exceeded";
	}
	elsif ($errnum eq '00000017')
	{
		my $vwwpn = &bytes($sense, 220, 8);
		$msg  = "Modify vp config failed for $vwwpn ";
	}
	elsif ($errnum eq '0000001B')
	{
		$msg = "Command issued is not supported by Firmware";
	}
	elsif ($errnum eq '0000001E')
	{
		$msg = "Link is dead (has been down several seconds)";
	}
	elsif ($errnum eq '00000021')
	{
		$msg  = "Recieved async port db changed for non unknown vport";
	}
	elsif ($errnum eq '00000023')
	{
		$msg  = "Adapter generated unknown interrupt type";
	}
	elsif ($errnum eq '00000026')
	{
		my $mb_type = &bytes($sense, 192, 2);
		$msg  = "Mailbox timeout $mb_type";
	}
	elsif ($errnum eq '00000027')
	{
		my $vwwpn = &bytes($sense, 320, 8);
		if ($vwwpn eq '0000000000000000')
		{
			$msg  = "IOCB timeout";
		}
		else
		{
			$msg  = "$vwwpn IOCB timeout";
		}
	}
	elsif ($errnum eq '00000029')
	{
		my $bytes = &bytes($sense, 148, 4);
		$msg  = "DMA map for $bytes bytes failed w/ DMA_NORES";
	}
	elsif ($errnum eq '0000002B')
	{   
        my $misc1       = &bytes($sense, 142, 2);
        my $misc2       = &bytes($sense, 149, 3);
		$msg  = "Login collision during login (address in use)";
        $msg .= " $misc1 / $misc2";
	}
	elsif ($errnum eq '0000002E')
	{
		$msg  = "Format 0 Rpt ID Acquisition mailbox received (info)";
	}
	elsif ($errnum eq '00000030')
	{
		$msg  = "Couldn't find vport for Report ID Acquisition";
	}
	elsif ($errnum eq '00000034')
	{
		$msg  = "Build IOCB routine received unknown adap_opcode";
	}
	elsif ($errnum eq '00000039')
	{
		my $rnport = &byte_reverse(&bytes($sense, 208, 3));
		$msg  = "Login to $rnport failed (usually timeout or LOGO ";
		$msg .= "received)";
	}
	elsif ($errnum eq '0000003A')
	{
		my $rnport	= &byte_reverse(&bytes($sense, 208, 3));
		my $rc		= &bytes($sense, 218, 1);
		my $re		= &bytes($sense, 217, 1);
		my $rct		= &lookup("", $rc, \%fc_lsrjt_rc_lt);
		my $ret		= &lookup("", $re, \%fc_lsrjt_re_lt);

		$msg  = "Login to $rnport failed with LS_RJT ($rct/$ret)";
	}
	elsif ($errnum eq '0000003E')
	{
		$msg  = "Adapter driver IOCB failed at startup/shutdown; ";
		$msg .= "will reset at next open";
	}
	elsif ($errnum eq '00000041')
	{
		$msg  = "Adapter reset timeout; DMA wouldn't shut down";
	}
	elsif ($errnum eq '00000049')
	{
		my $rnport = &byte_reverse(&bytes($sense, 208, 3));
		$msg  = "Login/logout request for $rnport failed due to ";
		$msg .= "link down";
	}
	elsif ($errnum eq '0000004A')
	{
		$msg  = "Adapter rejected IOCB due to invalid parameter";
	}
	elsif ($errnum eq '0000004B')
	{
		$msg  = "DMA initialization failed; check adapter tuning and ";
		$msg  .= "slot capability";
	}
	elsif ($errnum eq '00000050')
	{
		$msg  = "Unable to connect; GET_ID mailbox failed";
	}
    elsif ($errnum eq '00000059')
    {
        $msg  = "Cmd returned by adapter not found in the active queue,";
        $msg  .= " driver or adap fw bug";
    }
	elsif ($errnum eq '0000005A')
	{
		$msg  = "RIDA / Report ID Acquisition Failed";
	}
	elsif ($errnum eq '0000006A')
	{
		$msg  = "Login failed by adapter due to handle in use";
	}
	elsif ($errnum eq '0000006E')
	{
		$msg  = "Update vport cmd failed; unable to find vport";
	}
	elsif ($errnum eq '00000072')
	{
		$msg  = "Adapter driver detected login collision due to ";
		$msg .= "STALE target information";
	}
	elsif ($errnum eq '00000074')
	{
		$msg  = "Adapter driver detected Move Login in progress; " ;
		$msg .= "Adapter driver rejecting Plogi request";
	}
	elsif ($errnum eq '00000075')
	{
		$msg  = "Timed out waiting for link to come up";
	}
	elsif ($errnum eq '0000007B')
	{
		$msg  = "Unable to acquire free q_elem";
	}
	elsif ($errnum eq '00000082')
	{
		$msg  = "Verify checksum failed due to startup failure";
	}
	elsif ($errnum eq '00000084')
	{
		$msg  = "Load ram mb failed - startup failed";
	}
	elsif ($errnum eq '00000086')
	{
		$msg  = "Unknown IOCB status";
	}
	elsif ($errnum eq '00000093')
	{
		$msg  = "DMA shutdown not completing";
	}
	elsif ($errnum eq '00000094')
	{
		$msg  = "VP0 Enable Timeout; expecting Rpt ID Acq from adapter";
	}
	elsif ($errnum eq '000000A4')
	{
		$msg  = "Adapter livedump request failed";
	}
	elsif ($errnum eq '00000100')
	{
		$msg  = "Adapter Firmware reporting the Fabric name has changed";
	}
	elsif ($errnum eq '00000104')
	{
		$msg  = "Adapter Firmware reporting a configuration error for FCFs";
	}
	elsif ($errnum eq '00000105')
	{
		$msg  = "Unexpected inter-driver message received";
	}
	elsif ($errnum eq '00000107')
	{
		$msg  = "Adapter reports FCF discovery timeout; advertising ";
		$msg .= "link down";
	}
	elsif ($errnum eq '00000113')
	{
		$msg  = "Adapter firmware reports FCF has changed for vp0 ";
	}
	elsif ($errnum eq '00000114')
	{
		$msg  = "FIP Clear VLink received for the physical link. ";
		$msg .= "This is typically associated with a lost link.";
	}
	elsif ($errnum eq '00000306')
	{
		$msg  = "VP0 Enable failed; ";
		$msg .= "likely FLOGI, SCR, or SNS Login failure";
	}
	elsif ($errnum eq '00000D04')
	{
		$msg  = "NPIV VP disable failed; ";
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);
}


# ---------------------------------------------------------------------------
# LABEL:          FCP_ERR6
# IDENTIFIER:     DC73C03A
# 
# [...]
# Resource Name:   fscsi5          
# 
# [...]
# 
# Detail Data
# SENSE DATA
# 0000 0010 0000 00B1 [...]
# ---------------------------------------------------------------------------
sub FCP_ERR
{
	my @error = @_;
	my $sense = &get_sense_data(@error);
	my $driver = &bytes($sense, 3, 1);

	#
	# A few drivers use this error log, with different indicators:
	#
	# 0x02 - QLogic (qfscsi)
	# 0x03 - QLogic 4Gbps (qlfscsi)
	# 0x10 - Emulex (efscsi)
	#
	if ($driver eq '02')
	{
	}
	elsif (($driver eq '03') || ($driver eq '04'))
	{
		&FCP_ERR_QLogic_qlfsc(@error)
	}
    elsif ($driver eq '05')
    {
        &FCP_ERR_Cavium_cvfsc(@error)
    }
	elsif ($driver eq '10')
	{
		&FCP_ERR_Emulex(@error)
	}
	elsif ($driver eq '20')
	{
		&FCP_ERR_emfcp(@error)
	}
	else
	{
		printf("unknown driver type: " . $driver);
	}
}


sub FCP_ERR_emfcp
{
	my @error = @_;
	my $sense   = &get_sense_data(@error);
	my $version = &bytes($sense, 15, 1);

	if ($version eq '00')
	{
		&FCP_ERR_emfcp_v0(@error);
	}
	elsif ($version eq '01')
	{
		&FCP_ERR_emfcp_v1(@error);
	}
	else
	{
		printf("unknown error log version: " . $version);
	}
}


#
# NOTE: VERSION 0 is DEFUNCT.  Do not add entries here
#
sub FCP_ERR_emfcp_v0
{
	my @error = @_;

	my $sense  = &get_sense_data(@error);

	my $errnum = &bytes($sense,  4, 4);
	my $errno  = &hex2int(&bytes($sense, 8, 4));	# often an errno value
	my $rnport = &bytes($sense, 85, 3);
	my $wwpn   = &bytes($sense, 96, 8);

	my $msg = "";

	if    ($errnum eq 'xxxxxxxx')
	{
		$msg  = "huh?";
	}
	elsif ($errnum eq '00000001')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg = "ioctl(SCIOLINQU) timeout; $rnport $lun";
	}
    elsif ($errnum eq '00000002')
    {
        my $lun = "lun 0x" . &bytes($sense, 20, 8);
        $msg = "ioctl(SCIOLSTUNIT) timeout; $rnport $lun";
    }
	elsif ($errnum eq '00000007')
	{
		$msg  = "Cancel failed (and wasn't flushed)";
	}
	elsif ($errnum eq '0000000B')
	{
		my $reason = &bytes($sense, 8, 4);
		$msg  = "Directory server rejected GCS_ID for $rnport; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '00000028')
	{
		$msg  = "Target cancel timeout for port $rnport";
	}
	elsif ($errnum eq '0000002A')
	{
		$msg  = "Process Login timeout for port $rnport";
	}
	elsif ($errnum eq '0000002C')
	{
		$msg  = "Target reset timeout for port $rnport";
	}
	elsif ($errnum eq '0000002E')
	{
		my $rspiu = &words($sense, 144, 72);
		$msg = "Data underrun receiving from $rnport ";
		$msg .= &FCP_RSP_IU($rspiu);
	}
	elsif ($errnum eq '00000030')
	{
		$msg  = "Received HARD_FAIL notification from adap DD";
	}
	elsif ($errnum eq '00000036')
	{
		$msg  = "Link came up, but connection type changed";
	}
	elsif ($errnum eq '00000048')
	{
		$msg  = "Adapter failed request for port $rnport; ";
		$msg .= "DMA failure";
	}
	elsif ($errnum eq '00000049')
	{
		$msg  = "Adapter failed request for port $rnport; ";
		$msg .= "formal problem";
	}
	elsif ($errnum eq '0000004A')
	{
		$msg = "Error detected receiving from $rnport ";
		$msg .= "(possible marginal link)";
	}
	elsif ($errnum eq '00000061')
	{
		$msg = "Target $rnport does not support suitable FC classes";
	}
	elsif ($errnum eq '0000006A')
	{
		$msg = "Adapter DD rejected I/O request for port $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000070')
	{
		$msg = "Timeout waiting for link to come up";
	}
	elsif ($errnum eq '00000071')
	{
		$msg = "Timeout waiting for adapter driver to RESUME";
	}
	elsif ($errnum eq '000000A1')
	{
		$msg  = "Relogin to port $rnport failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A3')
	{
		$msg  = "Reset interface request failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A5')
	{
		$msg  = "ioctl() send seq failure for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AA')
	{
		$msg  = "CTIU request failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AC')
	{
		$msg = "GID_PN ($wwpn) or GPN_ID ($rnport) failed by ";

		if ($errno < 128)
		{
			$msg .= "adapter driver; ";
			$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
		}
		else
		{
			my $reason = &bytes($sense, 8, 4);
			$msg .= "directory server; ";
			$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
		}
	}
	elsif ($errnum eq '000000AD')
	{
		$msg  = "Recovery operation failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AF')
	{
		my $reason = &bytes($sense, 8, 4);
		$msg  = "Nameserver GID_PN reject for " . $wwpn . "; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '000000B8')
	{
		$msg  = "Adap DD rejected generic request (GEN_REQ)";
		$msg .= " for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000C8')
	{
		$msg  = "Dynamic tracking failed for $wwpn; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000001B8')
	{
		$msg = "Adapter DD rejected CT_IU request for port $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000277')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg  = "Dev cancel timed out; escalating to target cancel; ";
		$msg .= "$rnport $lun";
	}
	elsif ($errnum eq '00000302')
	{
		$msg  = "Adapter driver rejected output request for NPIV ";
		$msg .= "client IO";
	}
	elsif ($errnum eq '00000323')
	{
	my $status = &bytes($sense, 16, 4);
		$msg  = "NPIV SCSI command for $rnport failed with unknown ";
		$msg .= "adapter element status $status";
	}
	elsif ($errnum eq '00000326')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "formal problem with request";
	}
	elsif ($errnum eq '00000327')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "poss dropped or damaged frame";
	}
	elsif ($errnum eq '00000328')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "unexpected reason";
	}
	elsif ($errnum eq '00000330')
	{
		$msg  = "Adap DD rejected NPIV admin request; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000402')
	{
		my $reason = &bytes($sense, 8, 4);
		if ($reason eq '00000001')
		{
			$msg = "Driver is closing with unlogged errors for link";
	}
		elsif ($reason eq '00000002')
		{
			$msg = "Link has recovered";
		}
		else
		{
			$msg = "Error counts reset for link (unknown reason)";
		}
	}
	elsif ($errnum eq '00000403')
	{
		my $reason = &bytes($sense, 8, 4);
		if ($reason eq '00000001')
		{
			$msg  = "Driver is closing with unlogged errors for ";
			$msg .= "target $rnport";
		}
		elsif ($reason eq '00000002')
		{
			$msg = "Target $rnport has recovered";
		}
		else
		{
			$msg  = "Error counts reset for target $rnport ";
			$msg .= "(unknown reason)";
		}
	}
	elsif ($errnum eq '00000A30')
	{
		$msg  = "Admin cancel command failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);
}


sub FCP_ERR_emfcp_v1
{
	my @error = @_;

	my $sense  = &get_sense_data(@error);

	my $errnum = &bytes($sense,   4, 4);
	my $errno  = &hex2int(&bytes($sense, 8, 4));	# often an errno value
	my $rwwpn  = &bytes($sense, 192, 8);
	my $rnport = &bytes($sense, 225, 3);
    my $scsi_state = &bytes($sense, 24, 4);

    if ($scsi_state eq '00000008' )
    {

    }

	my $msg = "";

	if    ($errnum eq 'xxxxxxxx')
	{
		$msg  = "huh?";
	}
	elsif ($errnum eq '00000001')
	{
		my $lun = "lun 0x" . &bytes($sense, 320, 8);
		$msg = "ioctl(SCIOLINQU) timeout; $rnport $lun";
	}
    elsif ($errnum eq '00000002')
    {
        my $lun = "lun 0x" . &bytes($sense, 320, 8);
        $msg = "ioctl(SCIOLSTUNIT) timeout; $rnport $lun";
    }
	elsif ($errnum eq '00000003')
	{
		my $lun = "lun 0x" . &bytes($sense, 320, 8);
		$msg = "ioctl(SCIOLTUR) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000004')
	{
		my $lun = "lun 0x" . &bytes($sense, 320, 8);
		$msg = "ioctl(SCIOLREAD) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000007')
	{
		$msg  = "Cancel failed (and wasn't flushed)";
	}
	elsif ($errnum eq '0000000A')
	{
		my $reason = &bytes($sense, 8, 4);
		$msg  = "Directory server rejected GID_PN for $rwwpn; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '0000000B')
	{
		my $reason = &bytes($sense, 8, 4);
		$msg  = "Directory server rejected GCS_ID for $rnport; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
    elsif ($errnum eq '00000016')
    {
        $msg  = "Process level task management request has failed";
    }
	elsif ($errnum eq '00000017')
	{
        my $lun = "lun 0x" . &bytes($sense, 320, 8);
        my $tm_flags = &bytes($sense, 714, 1);

        my $tm = &lookup("", $tm_flags, \%fcp_tm_flags_lt);

		$msg  = "Interrupt level task management request $tm has failed; $rwwpn $lun";
	}
	elsif ($errnum eq '00000022')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "Device timer popped ($rnport lun $lun), but no ";
		$msg .= "active request!";
	}
	elsif ($errnum eq '00000025')
	{
		$msg  = "Send sequence timed out; will cancel";
	}
	elsif ($errnum eq '00000026')
	{
		my $lun = "lun 0x" . &bytes($sense, 320, 8);
		$msg  = "Return of I/Os timed out after LUN cancel for ";
		$msg .= "$rnport $lun";
	}
	elsif ($errnum eq '00000028')
	{
		$msg  = "Target cancel timeout for port $rnport";
	}
	elsif ($errnum eq '0000002A')
	{
        my $initiator = &bytes($sense, 16, 8);
        $msg  = "Process Login timeout from $initiator to port $rnport $rwwpn";
	}
	elsif ($errnum eq '0000002C')
	{
		$msg  = "Target reset timeout for port $rnport";
	}
	elsif ($errnum eq '0000002E')
	{
        my $rspiu = &words($sense, 184, 72);
        $msg = "Data underrun receiving from 0x$rnport $rwwpn ";
		$msg .= &FCP_RSP_IU($rspiu);
	}
	elsif ($errnum eq '00000030')
	{
		$msg  = "DEBUG: Link Up detected";
	}
    elsif ($errnum eq '00000031')
    {
        $msg  = "DEBUG: Link Down detected";
    }
    elsif ($errnum eq '00000032')
    {
        $msg  = "Received HARD_FAIL notification from adap DD";
    }
	elsif ($errnum eq '00000036')
	{
		$msg  = "Link came up, but connection type changed";
	}
    elsif ($errnum eq '00000046')
    {
        $msg  = "Adapter failed request for port $rnport; ";
    }
	elsif ($errnum eq '00000048')
	{
		$msg  = "Adapter failed request for port $rnport; ";
		$msg .= "DMA failure";
	}
	elsif ($errnum eq '00000049')
	{
        my $lr_code =  &bytes($sense, 643, 1);
		$msg  = "Adapter failed request for port $rnport; ";
        $msg .= "lr_code ($lr_code) poss. dropped or damaged frame ";
	}
	elsif ($errnum eq '0000004A')
	{
		my $rc = &bytes($sense, 648, 1);
		$msg = "Error detected receiving from $rnport ";
		$msg .= "(possible marginal link Local reject status $rc)";
	}
	elsif ($errnum eq '0000004F')
	{
		$msg = "CT_IU for $rnport timed out";
	}
	elsif ($errnum eq '00000061')
	{
		$msg = "Target $rnport does not support suitable FC classes";
	}
	elsif ($errnum eq '00000068')
	{
		$msg = "Adapter DD rejected ABTS request for port $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006A')
	{
		$msg = "Adapter DD rejected I/O request for port $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006B')
	{
		$msg = "Adapter DD rejected I/O request for Target Cancel";
	}
	elsif ($errnum eq '0000006F')
	{
		$msg = "Adapter DD rejected I/O request for Target Cancel all";
	}
	elsif ($errnum eq '00000070')
	{
		$msg = "Timeout waiting for link to come up";
	}
	elsif ($errnum eq '00000071')
	{
		$msg = "Timeout waiting for adapter driver to RESUME";
	}
	elsif ($errnum eq '0000007B')
	{
		$msg = "DEBUG: RESET_ADAP_FAIL async adapter reset failed";
	}
	elsif ($errnum eq '0000007A')
	{
		$msg = "DEBUG: RESET_ADAP async notification received";
	}
	elsif ($errnum eq '000000A1')
	{
		$msg  = "Relogin to port $rnport failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A2')
	{
		$msg  = "Relogin or PDISC to $rnport finds unexpected WWPN";
	}
	elsif ($errnum eq '000000A3')
	{
		$msg  = "Reset interface request failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A5')
	{
		$msg  = "ioctl() send seq failure for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AA')
	{
		$msg  = "Generic request (GEN_REQ) failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AC')
	{
		$msg = "GID_PN ($rwwpn) or GPN_ID ($rnport) failed by ";

		if ($errno < 128)
		{
			$msg .= "adapter driver; ";
			$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
		}
		else
		{
			my $reason = &bytes($sense, 8, 4);
			$msg .= "directory server; ";
			$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
		}
	}
	elsif ($errnum eq '000000AD')
	{
		$msg  = "Recovery operation failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AF')
	{
		my $reason = &bytes($sense, 8, 4);
		$msg  = "Nameserver GID_PN reject for " . $rwwpn . "; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '000000B8')
	{
		$msg  = "Adap DD rejected generic request (GEN_REQ)";
		$msg .= " for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
    elsif ($errnum eq '000000BD')
    {
        my $alt_rnport = &bytes($sense, 229, 3);
        $msg  = "Dynamic tracking failure $rwwpn ";
        $msg .= "(0x$rnport <-> 0x$alt_rnport)"
    }
	elsif ($errnum eq '000000C8')
	{
		$msg  = "Dynamic tracking failed for rwwpn; ";
	}
    elsif ($errnum eq '000000C0')
    {
        my $initiator = &bytes($sense, 16, 8);
        $msg  = "Process Login timeout from $initiator to port $rnport $rwwpn; recovery action initiated";
    }
    elsif ($errnum eq '000000CD')
    {
        my $initiator = &bytes($sense, 16, 8);
        $msg  = "Plogi from $initiator does not match our gid_pn lookup; fcid must have changed while logging in  ";
    }
    elsif ($errnum eq '000000D3')
    {
        my $pid  = &hex2int(&words($sense,  115, 1));
        $msg  = "INFO: dyntrk enabled, but version 0 ioctl requested by ";
        $msg .= "PID $pid";
    }
    elsif ($errnum eq '000000E2')
    {
        my $error = &lookup("errno", $errno, \%aix_errno_lt);
        $msg = "Adapter driver's cmd entry point rejected an ELS due to $error";
    }
    elsif ($errnum eq '000000F0')
    {
        $msg  = "Protocol driver rejected clear ACA ";
        $msg .= &lookup("errno", $errno, \%aix_errno_lt);
        my $lun = "lun 0x" . &bytes($sense, 320, 8);
        $msg .= " $rwwpn $lun";

    }
	elsif ($errnum eq '00000150')
	{
		$msg  = "INFO: conc. attr. change requested, but driver not ";
		$msg .= "in fit state";
	}
	elsif ($errnum eq '00000151')
	{
		$msg  = "INFO: dyntrk=yes requested, but not fabric attached";
	}
	elsif ($errnum eq '00000153')
	{
		my $lun = &bytes($sense, 320, 8);
		$msg  = "INFO: dyntrk=yes requested, but V1 target has V0 ";
		$msg .= "LUNs ($rwwpn, $lun)";
	}
	elsif ($errnum eq '00000154')
	{
		my $lun = &bytes($sense, 320, 8);
		$msg  = "INFO: dyntrk=yes requested, but LUN doesn't support ";
		$msg .= "concurrent changes ($rwwpn, $lun)";
	}
	elsif ($errnum eq '00000155')
	{
		$msg  = "INFO: dyntrk=no requested, but target recovery is ";
		$msg .= "active ($rwwpn)";
	}
	elsif ($errnum eq '00000156')
	{
		my $lun = &bytes($sense, 320, 8);
		$msg  = "INFO: dyntrk=no requested, but LUN doesn't support ";
		$msg .= "concurrent changes ($rwwpn, $lun)";
	}
	elsif ($errnum eq '00000157')
	{
		my $lun = &bytes($sense, 320, 8);
		$msg  = "INFO: dyntrk=no requested, but LUN awaiting ";
		$msg .= "DEV_RESTART ($rwwpn, $lun)";
	}
	elsif ($errnum eq '00000158')
	{
		$msg  = "INFO: fc_err_recov=fast_fail requested, but not ";
		$msg .= "fabric attached";
	}
	elsif ($errnum eq '0000015A')
	{
		my $lun = &bytes($sense, 320, 8);
		$msg  = "INFO: fc_err_recov=delayed_fail requested, but LUN ";
		$msg .= "has recovery pending ($rwwpn, $lun)";
	}
	elsif ($errnum eq '0000015B')
	{
		$msg  = "INFO: dyntrk=yes succeeded, but target wont ";
		$msg .= "benefit due to V0 LUNs ($rwwpn)";
	}
	elsif ($errnum eq '000001B8')
	{
		$msg = "Adapter DD rejected CT_IU request for port $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
    elsif ($errnum eq '00000221')
    {
        $msg  = "exceeded our retry count on vfc initiated dev task mgm cancels; ";
        $msg  .= "issue reset_interface; ";
        $msg  .= "($rnport $rwwpn)";
    }
	elsif ($errnum eq '00000226')
	{
		my $lun = "lun 0x" . &bytes($sense, 320, 8);
		$msg  = "cancel_cmd returned but cmds we are trying to cancel have not; ";
		$msg .= "($rnport $rwwpn)";
	}
	elsif ($errnum eq '00000228')
	{
		$msg  = "target_cancel completed, but cancelled commands ";
		$msg .= "are still active; $rnport $rwwpn";
	}
	elsif ($errnum eq '00000277')
	{
		my $lun = "lun 0x" . &bytes($sense, 320, 8);
		$msg  = "dev_cancel timed out; escalating to target cancel; ";
		$msg .= "$rnport $rwwpn $lun";
	}
	elsif ($errnum eq '00000279')
	{
		my $lun = "lun 0x" . &bytes($sense, 320, 8);
		$msg  = "Return of cancel_cmd timed out after LUN cancel; ";
		$msg .= "$rnport $rwwpn $lun";
	}
	elsif ($errnum eq '0000022A')
	{
		$msg  = "target_cancel_all failed";
	}
    elsif ($errnum eq '0000022C')
    {
        $msg  = "target_cancel_all retry_count exceeded; ";
        $msg .= "escalating recovery action to reset_interface ";
        $msg .= "($rnport $rwwpn)"; 
    }
    elsif ($errnum eq '0000022F')
    {
        $msg  = "dev_cancel failed, issue reset_interface";
    }
    elsif ($errnum eq '0000027A')
    {
        $msg  = "target_cancel_luns has not completed, aborts may still be active; ";
        $msg .= "($rnport $rwwpn)";
    }
	elsif ($errnum eq '00000302')
	{
        my $initiator = &bytes($sense, 128, 8);
		$msg  = "Adapter driver rejected output request for NPIV ";
		$msg .= "$initiator, not logged into $rwwpn";
	}
	elsif ($errnum eq '00000323')
	{
		#my $status = &bytes($sense, 16, 4);
		my $status = "FIXME";
		$msg  = "NPIV SCSI command for $rnport failed with unknown ";
		$msg .= "adapter element status $status";
	}
	elsif ($errnum eq '00000326')
	{
		my $rc = &bytes($sense, 648, 1);
		$msg  = "NPIV SCSI cmd for $rnport failed with Local Reject status ($rc)";
	}
	elsif ($errnum eq '00000327')
	{
        my $cdb = &bytes($sense, 716, 16);
        my $cmd = &ssc_command($cdb);
		my $initiator = &bytes($sense, 128, 8);
        my $lr_code =  &bytes($sense, 648, 1);

		$msg  = "NPIV $initiator SCSI cmd for ($rnport $rwwpn) failed; ";
		$msg .= "lr_code ($lr_code) poss. dropped or damaged frame ";
        $msg .=  "$cmd" ;

	}
	elsif ($errnum eq '00000328')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "unexpected reason";
	}
	elsif ($errnum eq '00000330')
	{
        my $initiator = &bytes($sense, 128, 8);
		$msg  = "Adap DD rejected NPIV admin request; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
        $msg .= "; $initiator $rnport";
	}
    elsif ($errnum eq '00000360')
    {
        $msg = "VIOS NPIV driver rejected async status; client inaccessible";
    }
	elsif ($errnum eq '0000032A')
	{
		$msg  = "NPIV request failed, returned to caller; ";
	}
	elsif ($errnum eq '00000402')
	{
		my $reason = &bytes($sense, 8, 4);

		if ($reason eq '00000001')
		{
			$msg = "Driver is closing with unlogged errors for link";
		}
		elsif ($reason eq '00000002')
		{
			$msg = "Link has recovered";
		}
		else
		{
			$msg = "Error counts reset for link (unknown reason)";
		}
	}
	elsif ($errnum eq '00000403')
	{
		my $reason = &bytes($sense, 8, 4);

		if ($reason eq '00000001')
		{
			$msg  = "Driver is closing with unlogged errors for ";
			$msg .= "target $rnport";
		}
		elsif ($reason eq '00000002')
		{
			my $rwwpn = &bytes($sense, 192, 8);
			$msg = "Target $rnport $rwwpn has recovered";
		}
		else
		{
			$msg  = "Error counts reset for target $rnport ";
			$msg .= "(unknown reason)";
		}
	}
	elsif ($errnum eq '00000A30')
	{
		$msg  = "admin cancel command failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
    elsif ($errnum eq '00000D30')
    {
        $msg  = "Npiv stopinitter has active cmds not returning; reset interface";
    }
	elsif ($errnum eq '00000D32')
	{
		$msg  = "Npiv stopinitter timeout expired";
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

    if ($scsi_state eq '00000008' )
    {
        $msg .= " LINK_DOWN";
    }

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);
}


sub FCP_ERR_Emulex
{
	my @error = @_;

	my $sense  = &get_sense_data(@error);

	my $errnum = &bytes($sense,  4, 4);
	my $errno  = &hex2int(&bytes($sense, 8, 4));	# often an errno value
	my $rnport = "port 0x" . &bytes($sense, 85, 3);
	my $wwpn   = "wwpn 0x" . &bytes($sense, 96, 8);

	my $msg = "";

	if ($errnum eq '00000001')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg = "ioctl(SCIOLINQU) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000002')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg = "ioctl(SCIOSTUNIT) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000003')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg = "ioctl(SCIOLTUR) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000004')
	{
		$msg = "Command Time-out in Read Block ioctl.";
	}
	elsif ($errnum eq '00000006')
	{
		my $vpport = "wwpn " . &bytes($sense, 880, 8);
		$msg = "Received unknown IOCB cmd type for $vpport ";
	}
	elsif ($errnum eq '00000007')
	{
		$msg = "Cancel request failed for $rnport";
	}
	elsif ($errnum eq '00000009')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "Name server rejected GID_FT with ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '0000000A')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "Name server rejected GCS_ID for $wwpn, ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '0000000B')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "Name server rejected GCS_ID for $rnport, ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '0000000C')
	{
		$msg = "FC Classes returned for $rnport are not valid with this adapter";
	}
	elsif ($errnum eq '0000001F')
	{
		$msg  = "Data overrun reported in FCP response IU from ";
		$msg .= "$rnport; cmd element included";
	}
	elsif ($errnum eq '00000023')
	{
		$msg = "Timeout for a command that is not active";
	}
	elsif ($errnum eq '00000025')
	{
		$msg  = "Adapter driver rejected Abort Task Set for $rnport ";
		$msg .= "at cmd timeout; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000026')
	{
		$msg = "Device cancel for $rnport timed out";
	}
	elsif ($errnum eq '00000028')
	{
		$msg = "Target cancel for $rnport timed out";
	}
	elsif ($errnum eq '00000029')
	{
		$msg = "Relogin timed out for $rnport";
	}
	elsif ($errnum eq '0000002A')
	{
		$msg = "Process login timed out for $rnport";
	}
	elsif ($errnum eq '0000002C')
	{
		$msg = "Target reset to $rnport timed out";
	}
	elsif ($errnum eq '0000002D')
	{
		$msg = "Software error; unknown wdog timer id";
	}
	elsif ($errnum eq '0000002E')
	{
		my $rspiu = &words($sense, 136, 72);
		$msg = "Data underrun receiving from $rnport ";
		$msg .= &FCP_RSP_IU($rspiu);
	}
	elsif ($errnum eq '00000030')
	{
		$msg = "Async status - NDD_HARD_FAIL";
	}
	elsif ($errnum eq '00000031')
	{
		$msg = "(Debug) Async status - LINK_DOWN";
	}
	elsif ($errnum eq '00000032')
	{
		$msg = "(Debug) Async status - LINK_UP";
	}
	elsif ($errnum eq '00000033')
	{
		$msg =  "(Debug) Async status - LOGO from known target ";
		$msg .= "$rnport";
	}
	elsif ($errnum eq '00000038')
	{
		$msg = "(Debug) Async status - LINK_DEAD";
	}
	elsif ($errnum eq '0000003E')
	{
		$msg = "V0 SCIOLSTART requested for target ($rnport) already ";
		$msg .= "started V1";
	}
	elsif ($errnum eq '00000041')
	{
		$msg = "Request failed--adapter reported HW failure";
	}
	elsif ($errnum eq '00000042')
	{
		$msg = "Request failed--adapter reported software error";
	}
	elsif ($errnum eq '00000048')
	{
		$msg = "Request failed--adapter reported DMA failure";
	}
	elsif ($errnum eq '00000049')
	{
		$msg = "Request failed--adapter reported Local Reject ";
	}
	elsif ($errnum eq '0000004A')
	{
        my $cdb = &bytes($sense, 32, 16);
        my $cmd = &ssc_command($cdb);
		$msg = "Error detected receiving from $rnport $wwpn ";
		$msg .= "(possible marginal link) $cmd ";
	}
	elsif ($errnum eq '0000004E')
	{
		$msg = "SCIOLSTART requestor supplied scsi_id and WWPN; ";
		$msg .= "login finds different target ($rnport)";
	}
	elsif ($errnum eq '0000004F')
	{
		$msg = "Nameserver GID_PN timed out";
	}
	elsif ($errnum eq '00000061')
	{
		$msg = "Target $rnport does not support suitable FC classes";
	}
	elsif ($errnum eq '00000067')
	{
		$msg = "Adapter driver rejected clear ACA for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006A')
	{
		$msg = "Adapter driver rejected I/O request for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006B')
	{
		$msg = "Adapter driver rejected device cancel for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006C')
	{
		$msg = "Adapter driver rejected target cancel for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006E')
	{
		$msg = "Adapter driver rejected target reset for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006F')
	{
		$msg = "Adapter driver rejected target tg_cancel for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000070')
	{
		$msg = "Time out waiting for link up";
	}
	elsif ($errnum eq '00000071')
	{
		$msg = "We timed out waiting for the adapter to resume";
	}
	elsif ($errnum eq '00000073')
	{
		$msg = "Unexpected unsolicited IOCB received";
	}
	elsif ($errnum eq '000000A1')
	{
		$msg = "Relogin to $rnport failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A2')
	{
		my $wwpn     = &words($sense, 24, 2);
		my $alt_wwpn = &words($sense, 28, 2);

		if ($wwpn eq $alt_wwpn)
		{
			my $wwnn     = &words($sense, 26, 2);
			my $alt_wwnn = &words($sense, 30, 2);

			$msg = "Login with $rnport found unexpected WWNN. ";
			$msg .= "Actual: $alt_wwnn  Expected: $wwnn";
		}
		else
		{
			$msg = "Login with $rnport found unexpected WWPN. ";
			$msg .= "Actual: $alt_wwpn  Expected: $wwpn";
		}
	}
	elsif ($errnum eq '000000A3')
	{
		$msg = "Reset ring for SCSI IOCB ring failed";
	}
	elsif ($errnum eq '000000A5')
	{
		$msg = "ioctl() send seq failure for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AA')
	{
		$msg = "Nameserver GID_PN failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AC')
	{
		my $reason = &words($sense, 2, 1);
		my $cmd = &bytes($sense,840,2);

		if ($cmd eq '0112')
		{
			$rnport = &bytes($sense,849,3);
			$msg = "GPN_ID for port 0x$rnport ";
		}
		elsif ($cmd eq '0121')
		{
			$wwpn = &bytes($sense,848,8);
			$rnport = &bytes($sense,85,3);
			$msg = "GID_PN for 0x$rnport / 0x$wwpn ";
		}

		if ($reason =~ /00000000/)
		{
			$msg .= "failed by adapter driver";
		}
		elsif ($reason =~ /00000006/)
		{
			$msg .= "failed by adapter driver; ";
			$msg .= &lookup("errno ", 6, \%aix_errno_lt);
		}
		else
		{
			$msg .= "rejected with ";
			$msg .= &lookup("reason code ", $reason, \%fc_nsrjt_lt);
		}
	}
	elsif ($errnum eq '000000AD')
	{
		$msg = "dynamic tracking failed for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AF')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "NS GID_PN reject " . $wwpn . "; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '000000B0')
	{
		$msg = "Ring Reset failed by adapter driver";
	}
	elsif ($errnum eq '000000B1')
	{
		my $vwwpn = &bytes($sense, 896, 8);
		$msg = "Relogin $vwwpn to $rnport rejected; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B5')
	{
		$msg = "Relogin to nameserver ($rnport) failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B7')
	{
		$msg = "Adapter driver refused send sequence; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B8')
	{
		$msg = "Adapter driver refused gen_req; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B9')
	{
		$msg = "No new/alt scsi_id for target $wwpn after ";
		$msg .= "Move Login";
	}
	elsif ($errnum eq '000000BD')
	{
		$msg = "Move Login request for $wwpn failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000C0')
	{
		$msg = "PRLI failure; unexpected status or retries exceeded";
	}
	elsif ($errnum eq '000000C8')
	{
		$msg = "Dynamic tracking failed for $wwpn";
	}
    elsif ($errnum eq '000000D0')
    {
        $msg = "invalid scsi_buf cdb length of zero";
    }
	elsif ($errnum eq '000000D2')
	{
		$msg = "kernext_handle passed in with this scsi_buf is invalid ";
	}
	elsif ($errnum eq '000000D3')
	{
        my $pid  = &hex2int(&words($sense,  59, 1));
		$msg  = "INFO: dyntrk enabled, but version 0 ioctl requested by ";
		$msg .= "PID $pid";
	}
	elsif ($errnum eq '000000D9')
	{
		my $conn = &bytes($sense, 12, 1);
		my $fw   = &hex2int(&bytes($sense, 224, 1));
		my $pid  = &hex2int(&words($sense,  58, 2));

		$msg = "PID $pid wants fast_fail/dyntrk; unsupported ";
		$msg .= "FW level ($fw) or conn (";
		if ($conn eq '01')
		{
			$msg .= "point to point";
		}
		elsif ($conn eq '02')
		{
			$msg .= "switch";
		}
		elsif ($conn eq '03')
		{
			$msg .= "loop";
		}
		else
		{
			$msg .= "unknown";
		}
		$msg .= ")";
	}
	elsif ($errnum eq '000000DD')
	{
		$msg = "NS query failed to invalidate stale logins; wwn or scsi_id not provided in req ";
	}
	elsif ($errnum eq '000000E2')
	{
		$msg = "Adapter driver's cmd entry point rejected a Send ELS";
	}
	elsif ($errnum eq '00000150')
	{
		$msg  = "INFO: conc. attr. change requested, but driver not ";
		$msg .= "in fit state";
	}
	elsif ($errnum eq '00000151')
	{
		$msg  = "INFO: dyntrk=yes requested, but not fabric attached";
	}
	elsif ($errnum eq '00000153')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=yes requested, but V1 target has V0 ";
		$msg .= "LUNs ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000154')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=yes requested, but LUN doesn't support ";
		$msg .= "concurrent changes ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000155')
	{
		$msg  = "INFO: dyntrk=no requested, but target recovery is ";
		$msg .= "active ($wwpn)";
	}
	elsif ($errnum eq '00000156')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=no requested, but LUN doesn't support ";
		$msg .= "concurrent changes ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000157')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=no requested, but LUN awaiting ";
		$msg .= "DEV_RESTART ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000158')
	{
		$msg  = "INFO: fc_err_recov=fast_fail requested, but not ";
		$msg .= "fabric attached";
	}
	elsif ($errnum eq '0000015A')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: fc_err_recov=delayed_fail requested, but LUN ";
		$msg .= "has recovery pending ($wwpn, $lun)";
	}
	elsif ($errnum eq '0000015B')
	{
		$msg  = "INFO: dyntrk=yes succeeded, but target won't ";
		$msg .= "benefit due to V0 LUNs ($wwpn)";
	}
    elsif ($errnum eq '0000016B')
    {
        $msg  = "Adapter driver rejected taskmgm_lun_cancel for $rnport; ";
        $msg .= "ENETDOWN";
    }
	elsif ($errnum eq '00000226')
	{
		$msg  = "Cancel completed but task mgmt cancel timed out ";
		$msg .= "for $rnport; re-issuing cancel";
	}
	elsif ($errnum eq '00000302')
	{
		$msg = "Adapter driver refused NPIV SCSI cmd for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000326')
	{
		$msg  = "NPIV client SCSI request for $rnport was failed by ";
		$msg .= "adapter. See reply IOCB for exact reason";
	}
	elsif ($errnum eq '00000327')
	{
		$msg = "Dropped or damaged frames for NPIV client from $rnport";
	}
	elsif ($errnum eq '00000330')
	{
		my $vpport = "wwpn " . &bytes($sense, 880, 8);
		$msg = "Call to cmd entry point returned an error for $vpport";
	}
	elsif ($errnum eq '00000348')
	{
		$msg = "NPIV relogin request failed to $rnport";
	}
    elsif ($errnum eq '00000360')
    {
        $msg = "VIOS NPIV driver rejected async status; client inaccessible";
    }
	elsif ($errnum eq '000003F1')
	{
		my $maxtargets = &hex2int(&bytes($sense, 10, 2));
		$msg = "Maximum targets ($maxtargets) exceeded for VFC adapter ";
	}
	elsif ($errnum eq '00000402')
	{
		my $reason = &bytes($sense, 8, 4);
		if ($reason eq '00000001')
		{
			$msg = "Driver is closing with unlogged errors for link";
		}
		elsif ($reason eq '00000002')
		{
			my $iwwpn = &bytes($sense, 896, 8);
			if ($iwwpn !~ /0000000000000000/)
			{
				$msg = "Link has recovered for $iwwpn";
			}
			else
			{
				$msg = "Link has recovered";
			}
		}
		else
		{
			$msg = "Error counts reset for link (unknown reason)";
		}
	}
	elsif ($errnum eq '00000403')
	{
		my $reason = &bytes($sense, 8, 4);
		if ($reason eq '00000001')
		{
			$msg  = "Driver is closing with unlogged errors for ";
			$msg .= "target $rnport";
		}
		elsif ($reason eq '00000002')
		{
			my $rwwpn = &bytes($sense, 96, 8);
			$msg = "Target $rnport $rwwpn has recovered";
		}
		else
		{
			$msg  = "Error counts reset for target $rnport ";
			$msg .= "(unknown reason)";
		}
	}
	elsif ($errnum eq '00000509')
	{
		$msg = "Out of resources for newly-arrived Target Mode command";
	}
	elsif ($errnum eq '00000525')
	{
		my $parameter = &byte_reverse(&bytes($sense, 368, 4));
		my $status    = &nibbles(     &bytes($sense, 380, 1), 0, 1);
		my $cmd       =               &bytes($sense, 381, 1);

		$msg = "Target Mode IOCB failure ";
		$msg .= "(cmd $cmd, status $status, parameter $parameter)";
	}
	elsif ($errnum eq '000005B2')
	{
		$msg = "ABTS received for unknown Target Mode exchange";
	}
	elsif ($errnum eq '00000A30')
	{
		$msg = "Cancel for command entry point failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000B01')
	{
		$msg = "Adapter driver cmd entry rejected cancel; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000BFF')
	{
		my $size = &words($sense, 2, 1);
		$msg = "ioctl send sequence requested response buf over 4K; ";
		$msg .= "size = $size"
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);
}


sub FCP_ERR_QLogic_qlfsc
{
	my @error = @_;

	my $sense  = &get_sense_data(@error);

	my $errnum = &bytes($sense,  4, 4);
	my $errno  = &hex2int(&bytes($sense, 8, 4));	# often an errno value
	my $rnport = "port 0x" . &bytes($sense, 65, 3);
	my $wwpn   = "wwpn " . &bytes($sense, 822, 8);

	my $msg = "";

	if    ($errnum eq '00000001')
	{
		$msg = "INQUIRY (from SCIOLINQU) for $rnport timeout";
	}
	elsif    ($errnum eq '00000003')
	{
		$msg = "TEST UNIT READY (from SCIOLTUR) for $rnport timeout";
	}
	elsif    ($errnum eq '00000004')
	{
		$msg = "SCSI READ (from SCIOLREAD) for $rnport timeout";
	}
	elsif    ($errnum eq '00000007')
	{
		$msg = "Error on task management for $rnport";
	}
	elsif ($errnum eq '0000000B')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "Name server rejected GCS_ID for $rnport, ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '00000016')
	{
		$msg = "Interrupt level task mgmt failed for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000017')
	{
		$msg = "Interrupt level task mgmt failed for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000023')
	{
		$msg  = "Timeout for non-active (already timed out?) cmd ";
		$msg .= "for $rnport";
	}
	elsif ($errnum eq '00000026')
	{
		$msg = "Cancel timeout for $rnport";
	}
	elsif ($errnum eq '00000029')
	{
		$msg = "Login or move login timeout for $rnport";
	}
	elsif ($errnum eq '0000002E')
	{
		$msg = "Data underrun detected by adapter for $rnport";
	}
	elsif ($errnum eq '00000030')
	{
		$msg  = "Received HARD_FAIL notification from adap DD";
	}
	elsif ($errnum eq '00000040')
	{
		$msg = "Adap DD failed I/O for $rnport (DMA map failure?)";
	}
	elsif ($errnum eq '0000002C')
	{
		$msg = "Interrupt level target reset timeout for $rnport";
	}
	elsif ($errnum eq '00000047')
	{
		$msg = "SCSI request for $rnport failed by adapter because ";
		$msg .= "target port name has changed";
	}
	elsif ($errnum eq '00000048')
	{
		$msg = "SCSI request aborted by target $rnport";
	}
	elsif ($errnum eq '0000004A')
	{
		my $over_under = &bytes($sense, 8, 4);

		if ($over_under eq '00001500')
		{
			$msg = "Data underrun";
		}
		elsif ($over_under eq '00000700')
		{
			$msg = "Data overrun";
		}
		else
		{
			$msg = "Unknown error 0x4A subcode $over_under";
		}

		$msg .= " for $rnport";
	}
	elsif ($errnum eq '0000004E')
	{
		$msg = "PLOGI for device START found different target ";
		$msg .= "WWPN than expected"
	}
	elsif ($errnum eq '00000053')
	{
		$msg  = "ELS passthru failure for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000059')
	{
		$msg  = "we've exceeded our retry count with either Dynamic Tracking or nameserver queries ";
		$msg .= ";EIO"
	}
	elsif ($errnum eq '0000006A')
	{
		$msg = "Adapter driver rejected I/O request for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006C')
	{
		$msg  = "Adapter driver rejected target cancel for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006D')
	{
		my $hstat = &bytes($sense, 8, 4);
		$msg  = "Adapter failed I/O for $rnport with non-zero header ";
		$msg .= "status ($hstat)";
	}
	elsif ($errnum eq '0000006F')
	{
		$msg  = "Adapter driver rejected login/logout/lookup ";
		$msg .= "for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000071')
	{
		$msg = "Timeout waiting for adapter driver to RESUME";
	}
	elsif ($errnum eq '0000009A')
	{
		$msg = "Bad eyecatcher preparing to start cmds for device";
	}
	elsif ($errnum eq '000000A1')
	{
		$msg = "Relogin failed for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A2')
	{
		my $ewwpn = &bytes($sense, 822, 8);
		my $ewwnn = &bytes($sense, 830, 8);
		my $fwwpn = &bytes($sense, 838, 8);
		my $fwwnn = &bytes($sense, 846, 8);

		$msg = "Relogin completed, but new WWPN\/WWNN; ";
		$msg .= "expected $ewwpn\/$ewwnn found $fwwpn\/$fwwnn";
	}
	elsif ($errnum eq '000000A3')
	{
		$msg  = "Reset adapter request failed";
	}
	elsif ($errnum eq '000000A5')
	{
		$msg = "CT_IU passthru failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AA')
	{
		$msg = "GID_PN failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AC')
	{
		$msg = "Name server query failure";
	}
	elsif ($errnum eq '000000AD')
	{
		$msg = "Dynamic tracking operation for $rnport failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AF')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "NS GID_PN reject " . $wwpn . "; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '000000B1')
	{
		$msg = "Adapter driver rejected login for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B4')
	{
		$msg = "MOVE_LOGIN request refused by adap DD; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B8')
	{
		$msg = "Adapter driver rejected CT_IU (regarding $rnport?); ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000C3')
	{
		my $ewwpn = &bytes($sense, 822, 8);
		$msg = "SCIOLSTART with duplicate WWPN ($ewwpn) in target ";
		$msg .= "hash; (dyntrk in progress during START?)"
	}
	elsif ($errnum eq '000000C8')
	{
		$msg = "Dynamic tracking failed (or not enabled) $wwpn";
	}
	elsif ($errnum eq '000000D3')
	{
		my $pid  = &hex2int(&words($sense,  20, 1));
		$msg  = "dyntrk enabled, but version 0 ioctl requested by ";
		$msg .= "PID $pid";
	}
	elsif ($errnum eq '000000D9')
	{
		my $pid  = &hex2int(&words($sense,  20, 1));
		$msg = "fabric configuration does not support dynamic tracking / fastfail ";
		$msg .= "PID $pid";
	}
	elsif ($errnum eq '000000DB')
	{
		$msg = "Not issuing relogin--target's scsi_id ($rnport) ";
		$msg .= "is STALE";
	}
	elsif ($errnum eq '000000E5')
	{
		$msg = "SCIOLSTART attempted for own scsi_id with dyntrk off ";
		$msg .= "and no WWPN supplied (debug)";
	}
	elsif ($errnum eq '00000150')
	{
		$msg  = "INFO: conc. attr. change requested, but driver not ";
		$msg .= "in fit state";
	}
	elsif ($errnum eq '00000151')
	{
		$msg  = "INFO: dyntrk=yes requested, but not fabric attached";
	}
	elsif ($errnum eq '00000152')
	{
		$msg  = "INFO: dyntrk=no requested, but Target Mode started";
	}
	elsif ($errnum eq '00000153')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=yes requested, but V1 target has V0 ";
		$msg .= "LUNs ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000154')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=yes requested, but LUN doesn't support ";
		$msg .= "concurrent changes ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000155')
	{
		$msg  = "INFO: dyntrk=no requested, but target recovery is ";
		$msg .= "active ($wwpn)";
	}
	elsif ($errnum eq '00000156')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=no requested, but LUN doesn't support ";
		$msg .= "concurrent changes ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000157')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: dyntrk=no requested, but LUN awaiting ";
		$msg .= "DEV_RESTART ($wwpn, $lun)";
	}
	elsif ($errnum eq '00000158')
	{
		$msg  = "INFO: fc_err_recov=fast_fail requested, but not ";
		$msg .= "fabric attached";
	}
	elsif ($errnum eq '0000015A')
	{
		my $lun = &bytes($sense, 20, 8);
		$msg  = "INFO: fc_err_recov=delayed_fail requested, but LUN ";
		$msg .= "has recovery pending ($wwpn, $lun)";
	}
	elsif ($errnum eq '0000015B')
	{
		$msg  = "INFO: dyntrk=yes succeeded, but target won't ";
		$msg .= "benefit due to V0 LUNs ($wwpn)";
	}
	elsif ($errnum eq '000001E4')
	{
		$msg = "Kernel extension SCIOLSTOP for app-STARTed device";
	}
	elsif ($errnum eq '000001E5')
	{
		$msg = "App SCIOLSTOP from kernel extension-STARTed device";
	}
	elsif ($errnum eq '000001E6')
	{
		$msg = "App SCIOLSTOPINITR for kernel extension-STARTed initr";
	}
	elsif ($errnum eq '000001E7')
	{
		$msg = "Kernel extension SCIOLSTOPINITR for app-STARTed initr";
	}
	elsif ($errnum eq '000001E8')
	{
		$msg = "SCIOLSTOPINITR: active cmds after NPIV_CLR; resetting adapter";
	}
	elsif ($errnum eq '000001E9')
	{
		$msg = "SCIOLSTOPINITR: active cmds after reset; continuing to wait";
	}
	elsif ($errnum eq '000001EA')
	{
		$msg  = "Target logout failure for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000001EB')
	{
		$msg  = "SCIOLSTOP: active cmds after logout from $rnport; ";
		$msg .= "resetting adapter";
	}
	elsif ($errnum eq '000001EC')
	{
		$msg = "SCIOLSTOP: active cmds after reset; continuing to wait";
	}
	elsif ($errnum eq '000001ED')
	{
		$msg = "NPIV port logout for $rnport requested while NPIV client not ready";
	}
	elsif ($errnum eq '00000200')
	{
		$msg = "Kernel service registration failed (rc = $errno)";
	}
	elsif ($errnum eq '00000201')
	{
		$msg = "Kernel service unregistration failed (rc = $errno)";
	}
	elsif ($errnum eq '00000202')
	{
		$msg = "Kernel service couldn't be unregistered--busy";
	}
	elsif ($errnum eq '000002F1')
	{
		$msg = "Bad eyecatcher during SCIOLSTOP (errcheck only)";
	}
	elsif ($errnum eq '00000304')
	{
		$msg = "NPIV SCSI command build routine unexpected rc ($errno)";
	}
	elsif ($errnum eq '00000320')
	{
		$msg = "Adapter rejected NPIV SCSI IOCB for $rnport";
	}
	elsif ($errnum eq '00000321')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "DMA error";
	}
	elsif ($errnum eq '00000322')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "unspecified transport error";
	}
	elsif ($errnum eq '00000323')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "LIP reset";
	}
	elsif ($errnum eq '00000324')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "invalid exchange ID";
	}
	elsif ($errnum eq '00000325')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "overlapping, missing, or out of order frames";
	}
	elsif ($errnum eq '00000326')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "target aborted command";
	}
	elsif ($errnum eq '00000327')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "port not logged in";
	}
	elsif ($errnum eq '00000328')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "port logged out";
	}
	elsif ($errnum eq '00000329')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "new WWPN";
	}
	elsif ($errnum eq '0000032A')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "firmware out of resources";
	}
	elsif ($errnum eq '0000032B')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "task management resource shortage";
	}
	elsif ($errnum eq '0000032C')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "subcode error";
	}
	elsif ($errnum eq '0000032D')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "target aborted exchange";
	}
	elsif ($errnum eq '0000032E')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "unknown completion status";
	}
	elsif ($errnum eq '0000032F')
	{
		$msg  = "NPIV SCSI cmd for $rnport failed; ";
		$msg .= "adapter driver reports unknown status";
	}
	elsif ($errnum eq '00000330')
	{
		$msg  = "Adapter DD rejected NPIV Admin cmd for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000334')
	{
		$msg = "NPIV Admin cmd failed; unknown failure_type ($errno)";
	}
	elsif ($errnum eq '00000335')
	{
		$msg = "NPIV SCSI PRLI failed; unknown failure_type ($errno)";
	}
	elsif ($errnum eq '00000336')
	{
		$msg  = "NPIV SCSI cmd returned to Admin return point ";
		$msg .= "(for $rnport)";
	}
	elsif ($errnum eq '00000337')
	{
		$msg = "Unknown NPIV Admin cmd received at return point";
	}
	elsif ($errnum eq '00000340')
	{
		$msg = "VIOS NPIV DD rejected completion of NPIV Admin cmd";
	}
	elsif ($errnum eq '00000341')
	{
		$msg  = "No function ptr to return NPIV Admin cmd to ";
		$msg .= "VIOS NPIV DD";
	}
	elsif ($errnum eq '00000348')
	{
		$msg = "VIOS NPIV DD rejected completion of NPIV SCSI cmd";
	}
	elsif ($errnum eq '00000349')
	{
		$msg  = "No functionp ptr to return NPIV SCSI cmd to ";
		$msg .= "VIOS NPIV DD";
	}
	elsif ($errnum eq '00000350')
	{
		$msg  = "NPIV async processing: unknown async status option ";
		$msg .= " ($errno)";
	}
	elsif ($errnum eq '00000351')
	{
		$msg  = "NPIV async processing: unknown async status code ";
		$msg .= " ($errno)";
	}
	elsif ($errnum eq '00000355')
	{
		$msg = "FCP_RSP IU build failure for response from $rnport";
	}
	elsif ($errnum eq '00000356')
	{
		$msg  = "NPIV PRLI (for $rnport) returned to ";
		$msg .= "NPIV SCSI return point";
	}
	elsif ($errnum eq '00000357')
	{
		$msg = "Unknown NPIV cmd returned to NPIV SCSI return point";
	}
	elsif ($errnum eq '00000358')
	{
		$msg = "Adapter rejected NPIV Marker for $rnport";
	}
	elsif ($errnum eq '00000359')
	{
		$msg = "NPIV Marker command for $rnport failed";
	}
	elsif ($errnum eq '00000360')
	{
		$msg = "VIOS NPIV driver rejected async status";
	}
	elsif ($errnum eq '00000402')
	{
		my $reason = &bytes($sense, 8, 4);

		if ($reason eq '00000001')
		{
			$msg = "Driver is closing with unlogged errors for link";
		}
		elsif ($reason eq '00000002')
		{
			$msg = "Link has recovered";
		}
		else
		{
			$msg = "Error counts reset for link (unknown reason)";
		}
	}
	elsif ($errnum eq '00000403')
	{
		my $reason = &bytes($sense, 8, 4);

		if ($reason eq '00000001')
		{
			$msg  = "Driver is closing with unlogged errors for ";
			$msg .= "target $rnport";
		}
		elsif ($reason eq '00000002')
		{
			my $rwwpn = &bytes($sense, 192, 8);
			$msg = "Target $rnport $rwwpn has recovered";
		}
		else
		{
			$msg  = "Error counts reset for target $rnport ";
			$msg .= "(unknown reason)";
		}
	}
	elsif ($errnum eq '000005B2')
	{
		$msg = "Received an abts for an unknown TM exchange";
	}
	elsif ($errnum eq '00000D01')
	{
		$msg = "Bad initiator eyecatcher during SCIOLSTOPINITR";
	}
	elsif ($errnum eq '00000D15')
	{
		$msg = "Initiator cleanup called with invalid value (defect)";
	}
	elsif ($errnum eq '00000D16')
	{
		$msg = "Invalid eyecatcher while adding initiator for adapter";
	}
	elsif ($errnum eq '00000D17')
	{
		$msg  = "Adapter driver failed NPIV_CLR request; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000D19')
	{
		$msg = "Invalid eyecatcher while adding initiator (errcheck)";
	}
	elsif ($errnum eq '0000A102')
	{
		$msg = "Bad initiator eyecatcher during SCIOLSTOP";
	}
	elsif ($errnum eq '0000A103')
	{
		$msg = "Bad initiator eyecatcher during SCIOLSTART";
	}
	elsif ($errnum eq '0000A110')
	{
		$msg = "VIOS NPIV rejected completion of a flushed command";
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);
}


sub FCP_ERR_Cavium_cvfsc
{
    my @error = @_;

    my $sense  = &get_sense_data(@error);

    my $errnum = &bytes($sense,  4, 4);
    my $errno  = &hex2int(&bytes($sense, 8, 4));    # often an errno value
    my $rnport = "port 0x" . &bytes($sense, 65, 3);
    my $wwpn   = "wwpn " . &bytes($sense, 822, 8);

    my $msg = "";

    if    ($errnum eq '00000001')
    {
        $msg = "INQUIRY (from SCIOLINQU) for $rnport timeout";
    }
    elsif    ($errnum eq '00000003')
    {
        $msg = "TEST UNIT READY (from SCIOLTUR) for $rnport timeout";
    }
    elsif    ($errnum eq '00000004')
    {
        $msg = "SCSI READ (from SCIOLREAD) for $rnport timeout";
    }
    elsif    ($errnum eq '00000006')
    {
                    $msg = "DEFECT: Unknown ctl_elem type";
    }
    elsif    ($errnum eq '00000007')
    {
        $msg = "Error on task management for $rnport";
    }
    elsif ($errnum eq '0000000B')
    {
        my $reason = &words($sense, 2, 1);
        $msg = "Name server rejected GCS_ID for $rnport, ";
        $msg .= &lookup("", $reason, \%fc_nsrjt_lt);
    }
    elsif ($errnum eq '00000011')
    {
        $msg = "Failed issue target marker element; Return Code = $errno";
    }
    elsif ($errnum eq '00000012')
    {
        $msg = "Failed issue LUN marker element; Return Code = $errno";
    }
    elsif ($errnum eq '00000014')
    {
        $msg = "Process level task mgmt failed for $rnport; ";
    }
    elsif ($errnum eq '00000015')
    {
        $msg = "Process level task mgmt failed for $rnport; ";
    }
    elsif ($errnum eq '00000016')
    {
        $msg = "Interrupt level task mgmt failed for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000017')
    {
        $msg = "Interrupt level task mgmt failed for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '0000001D')
    {
        $msg = "Failed to issue LUN cancel request";
    }
    elsif ($errnum eq '0000001F')
    {
        $msg = "FCP data overrun error discovered";
    }
    elsif ($errnum eq '00000023')
    {
        $msg  = "Timeout for non-active (already timed out?) cmd ";
                $msg .= "for $rnport";
    }
    elsif ($errnum eq '00000024')
    {
        $msg  = "Nport login request failed;";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000025')
    {
        $msg = "Unknown cmd opcode received for login/out cmd request";
    }
    elsif ($errnum eq '00000026')
    {
        $msg = "Cancel timeout for $rnport";
    }
    elsif ($errnum eq '00000029')
    {
        $msg = "Login or move login timeout for $rnport";
    }
    elsif ($errnum eq '0000002C')
    {
        $msg = "Interrupt level target reset timeout for $rnport";
    }
    elsif ($errnum eq '0000002E')
    {
        $msg = "Data underrun detected by adapter for $rnport";
    }
    elsif ($errnum eq '00000030')
    {
        $msg  = "Received HARD_FAIL notification from adap DD";
    }
    elsif ($errnum eq '00000036')
    {
        $msg  = "Received unsupported async event from adap DD";
    }
    elsif ($errnum eq '00000040')
    {
        $msg = "Adap DD failed I/O for $rnport (DMA map failure?)";
    }
    elsif ($errnum eq '00000041')
    {
        $msg = "Adap DD failed I/O for $rnport (Hardware Error)";
    }
    elsif ($errnum eq '00000042')
    {
        $msg = "Adap DD failed I/O for $rnport (Adapter SW Error)";
    }
    elsif ($errnum eq '00000043')
    {
        $msg = "Marker element failed";
    }
    elsif ($errnum eq '00000044')
    {
        $msg = "Unknown ctl_elem status";
    }
    elsif ($errnum eq '00000045')
    {
        $msg = "SCSI request for $rnport failed by adapter because ";
        $msg .= "of Transport/Frame errors";
    }
    elsif ($errnum eq '00000046')
    {
        $msg = "Async event; P2P connection; Zero nport ID for the other port";
    }
    elsif ($errnum eq '00000047')
    {
        $msg = "SCSI request for $rnport failed by adapter because ";
        $msg .= "target port name has changed";
    }
    elsif ($errnum eq '00000048')
    {
        $msg = "SCSI request aborted by target $rnport";
    }
    elsif ($errnum eq '00000049')
    {
        $msg = "SCSI request for $rnport failed by adapter because ";
        $msg .= "of DMA error or adapter resources exhausted";
    }
    elsif ($errnum eq '0000004A')
    {
        my $over_under = &bytes($sense, 8, 4);

        if ($over_under eq '00001500')
        {
            $msg = "Data underrun";
        }
        elsif ($over_under eq '00000700')
        {
            $msg = "Data overrun";
        }
        else
        {
            $msg = "Unknown error 0x4A subcode $over_under";
        }

        $msg .= " for $rnport";
    }
    elsif ($errnum eq '0000004B')
    {
        $msg = "Async event; P2P connection; Target port has changed during link transition";
    }
    elsif ($errnum eq '0000004E')
    {
        $msg = "PLOGI for device START found different target ";
        $msg .= "WWPN than expected"
    }
    elsif ($errnum eq '0000004E')
    {
        $msg = "Unknown IOCB reply status";
    }
    elsif ($errnum eq '00000050')
    {
        $msg  = "Adapter rejected ELS passthru for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000053')
    {
        $msg  = "ELS passthru failure for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000062')
    {
        $msg = "Task management IOCB error";
    }
    elsif ($errnum eq '0000006A')
    {
        $msg = "Adapter driver rejected I/O request for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '0000006B')
    {
        $msg = "Adapter driver rejected LUN cancel request for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '0000006C')
    {
        $msg  = "Adapter driver rejected target cancel for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '0000006D')
    {
        my $hstat = &bytes($sense, 8, 4);
        $msg  = "Adapter failed I/O for $rnport with non-zero header ";
                $msg .= "status ($hstat)";
    }
    elsif ($errnum eq '0000006F')
    {
        $msg  = "Adapter driver rejected login/logout/lookup ";
                $msg .= "for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000071')
    {
        $msg = "Timeout waiting for adapter driver to RESUME";
    }
    elsif ($errnum eq '0000009A')
    {
        $msg = "Bad eyecatcher preparing to start cmds for device";
    }
    elsif ($errnum eq '000000A0')
    {
        $msg = "Process login command failed";
    }
    elsif ($errnum eq '000000A1')
    {
        $msg = "Relogin failed for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000000A2')
    {
        my $ewwpn = &bytes($sense, 822, 8);
        my $ewwnn = &bytes($sense, 830, 8);
        my $fwwpn = &bytes($sense, 838, 8);
        my $fwwnn = &bytes($sense, 846, 8);

        $msg = "Relogin completed, but new WWPN\/WWNN; ";
        $msg .= "expected $ewwpn\/$ewwnn found $fwwpn\/$fwwnn";
    }
    elsif ($errnum eq '000000A3')
    {
        $msg  = "Reset adapter request failed";
    }
    elsif ($errnum eq '000000A4')
    {
        $msg  = "Unknown command type received in protocol driver";
    }
    elsif ($errnum eq '000000A5')
    {
        $msg = "CT_IU passthru failure; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000000AA')
    {
        $msg = "GID_PN failure; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000000AB')
    {
        $msg = "GID_PN failure; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000000AC')
    {
        $msg = "Name server query failure";
    }
    elsif ($errnum eq '000000AD')
    {
        $msg = "Dynamic tracking operation for $rnport failed; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000000AE')
    {
        $msg = "Cancel command failed";
    }
    elsif ($errnum eq '000000AF')
    {
        my $reason = &words($sense, 2, 1);
        $msg = "NS GID_PN reject " . $wwpn . "; ";
        $msg .= &lookup("", $reason, \%fc_nsrjt_lt);
    }
    elsif ($errnum eq '000000B0')
    {
        $msg = "Failed to issue adapter reset request";
    }
    elsif ($errnum eq '000000B1')
    {
        $msg = "Adapter driver rejected login for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000000B5')
    {
        $msg = "Failed to issue cancel request using admin cmd interface";
    }
    elsif ($errnum eq '000000B8')
    {
        $msg = "Adapter driver rejected CT_IU (regarding $rnport?); ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000000BC')
    {
        $msg = "Problem with move login; WWPN/WWNN mismatch";
    }
    elsif ($errnum eq '000000BD')
    {
        $msg = "Move login failure";
    }
    elsif ($errnum eq '000000C3')
    {
        my $ewwpn = &bytes($sense, 822, 8);
        $msg = "SCIOLSTART would duplicate WWPN ($ewwpn) in target ";
        $msg .= "hash; (dyntrk in progress during START?)"
    }
    elsif ($errnum eq '000000C8')
    {
        $msg = "Dynamic tracking failed (or not enabled) $wwpn";
    }
    elsif ($errnum eq '000000D0')
    {
        $msg = "Invalid scsi_buf request without valid CDB found in good IO path";
    }
        elsif ($errnum eq '000000D2')
        {
                my $pid  = &hex2int(&words($sense,  20, 1));
                $msg  = "dyntrk enabled, but version 0 ioctl requested by ";
                $msg .= "PID $pid";
        }
        elsif ($errnum eq '000000D3')
        {
                my $pid  = &hex2int(&words($sense,  20, 1));
                $msg  = "dyntrk enabled, but version 0 ioctl requested by ";
                $msg .= "PID $pid";
        }
    elsif ($errnum eq '000000DB')
    {
        $msg = "Not issuing relogin--target's scsi_id ($rnport) ";
        $msg .= "is STALE";
    }
    elsif ($errnum eq '000000E5')
    {
        $msg = "SCIOLSTART attempted for own scsi_id with dyntrk off ";
        $msg .= "and no WWPN supplied (debug)";
    }
    elsif ($errnum eq '000000F0')
    {
        $msg = "Invalid buf request in strategy; Failed it.";
    }
    elsif ($errnum eq '00000100')
    {
        $msg  = "Error during live dump; Failure returned by dmp_context call";
    }
    elsif ($errnum eq '00000101')
    {
        $msg  = "Error during live dump; Failure returned by dmp_kernext call";
    }
    elsif ($errnum eq '00000102')
    {
        $msg  = "Error during live dump; Failure returned by dmp_compspec call";
    }
    elsif ($errnum eq '00000103')
    {
        $msg  = "Error during live dump; Failure returned by livedump call";
    }
    elsif ($errnum eq '00000104')
    {
        $msg  = "Error during live dump; Failure returned by ldmp_setupparms call";
    }
    elsif ($errnum eq '00000133')
    {
        $msg  = "RFT ID command failed;";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000134')
    {
        my $hstat = &bytes($sense, 8, 4);
        $msg = "GID_PN failure;";
        $msg .= "Reason is $hstat";
    }
    elsif ($errnum eq '00000150')
    {
        $msg  = "INFO: conc. attr. change requested, but driver not ";
                $msg .= "in fit state";
    }
    elsif ($errnum eq '00000151')
    {
        $msg  = "INFO: dyntrk=yes requested, but not fabric attached";
    }
    elsif ($errnum eq '00000152')
    {
        $msg  = "INFO: dyntrk=no requested, but Target Mode started";
    }
    elsif ($errnum eq '00000153')
    {
                my $lun = &bytes($sense, 20, 8);
        $msg  = "INFO: dyntrk=yes requested, but V1 target has V0 ";
                $msg .= "LUNs ($wwpn, $lun)";
    }
    elsif ($errnum eq '00000154')
    {
                my $lun = &bytes($sense, 20, 8);
        $msg  = "INFO: dyntrk=yes requested, but LUN doesn't support ";
                $msg .= "concurrent changes ($wwpn, $lun)";
    }
    elsif ($errnum eq '00000155')
    {
        $msg  = "INFO: dyntrk=no requested, but target recovery is ";
                $msg .= "active ($wwpn)";
    }
    elsif ($errnum eq '00000156')
    {
                my $lun = &bytes($sense, 20, 8);
        $msg  = "INFO: dyntrk=no requested, but LUN doesn't support ";
                $msg .= "concurrent changes ($wwpn, $lun)";
    }
    elsif ($errnum eq '00000157')
    {
                my $lun = &bytes($sense, 20, 8);
        $msg  = "INFO: dyntrk=no requested, but LUN awaiting ";
                $msg .= "DEV_RESTART ($wwpn, $lun)";
    }
    elsif ($errnum eq '00000158')
    {
        $msg  = "INFO: fc_err_recov=fast_fail requested, but not ";
                $msg .= "fabric attached";
    }
    elsif ($errnum eq '0000015A')
    {
                my $lun = &bytes($sense, 20, 8);
        $msg  = "INFO: fc_err_recov=delayed_fail requested, but LUN ";
                $msg .= "has recovery pending ($wwpn, $lun)";
    }
    elsif ($errnum eq '0000015B')
    {
        $msg  = "INFO: dyntrk=yes succeeded, but target won't ";
                $msg .= "benefit due to V0 LUNs ($wwpn)";
    }
    elsif ($errnum eq '000001E4')
    {
        $msg = "Kernel extension SCIOLSTOP for app-STARTed device";
    }
    elsif ($errnum eq '000001E5')
    {
        $msg = "App SCIOLSTOP from kernel extension-STARTed device";
    }
    elsif ($errnum eq '000001E6')
    {
        $msg = "App SCIOLSTOPINITR for kernel extension-STARTed initr";
    }
    elsif ($errnum eq '000001E7')
    {
        $msg = "Kernel extension SCIOLSTOPINITR for app-STARTed initr";
    }
    elsif ($errnum eq '000001E8')
    {
        $msg = "SCIOLSTOPINITR: active cmds after NPIV_CLR; resetting adapter";
    }
    elsif ($errnum eq '000001E9')
    {
        $msg = "SCIOLSTOPINITR: active cmds after reset; continuing to wait";
    }
    elsif ($errnum eq '000001EA')
    {
        $msg  = "Target logout failure for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '000001EB')
    {
        $msg  = "SCIOLSTOP: active cmds after logout from $rnport; ";
        $msg .= "resetting adapter";
    }
    elsif ($errnum eq '000001EC')
    {
        $msg = "SCIOLSTOP: active cmds after reset; continuing to wait";
    }
    elsif ($errnum eq '000001ED')
    {
        $msg = "NPIV port logout for $rnport requested while NPIV client not ready";
    }
    elsif ($errnum eq '00000200')
    {
        $msg = "Kernel service registration failed (rc = $errno)";
    }
    elsif ($errnum eq '00000201')
    {
        $msg = "Kernel service unregistration failed (rc = $errno)";
    }
    elsif ($errnum eq '00000202')
    {
        $msg = "Kernel service couldn't be unregistered--busy";
    }
    elsif ($errnum eq '000002F1')
    {
        $msg = "Bad eyecatcher during SCIOLSTOP (errcheck only)";
    }
    elsif ($errnum eq '00000304')
    {
        $msg = "NPIV SCSI command build routine unexpected rc ($errno)";
    }
    elsif ($errnum eq '00000320')
    {
        $msg = "Adapter rejected NPIV SCSI IOCB for $rnport";
    }
    elsif ($errnum eq '00000321')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "DMA error";
    }
    elsif ($errnum eq '00000322')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "unspecified transport error";
    }
    elsif ($errnum eq '00000323')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "LIP reset";
    }
    elsif ($errnum eq '00000324')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "invalid exchange ID";
    }
    elsif ($errnum eq '00000325')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "overlapping, missing, or out of order frames";
    }
    elsif ($errnum eq '00000326')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "target aborted command";
    }
    elsif ($errnum eq '00000327')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "port not logged in";
    }
    elsif ($errnum eq '00000328')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "port logged out";
    }
    elsif ($errnum eq '00000329')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "new WWPN";
    }
    elsif ($errnum eq '0000032A')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "firmware out of resources";
    }
    elsif ($errnum eq '0000032B')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "task management resource shortage";
    }
    elsif ($errnum eq '0000032C')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "subcode error";
    }
    elsif ($errnum eq '0000032D')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "target aborted exchange";
    }
    elsif ($errnum eq '0000032E')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "unknown completion status";
    }
    elsif ($errnum eq '0000032F')
    {
        $msg  = "NPIV SCSI cmd for $rnport failed; ";
        $msg .= "adapter driver reports unknown status";
    }
    elsif ($errnum eq '00000330')
    {
        $msg  = "Adapter DD rejected NPIV Admin cmd for $rnport; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000334')
    {
        $msg = "NPIV Admin cmd failed; unknown failure_type ($errno)";
    }
    elsif ($errnum eq '00000335')
    {
        $msg = "NPIV SCSI PRLI failed; unknown failure_type ($errno)";
    }
    elsif ($errnum eq '00000336')
    {
        $msg  = "NPIV SCSI cmd returned to Admin return point ";
        $msg .= "(for $rnport)";
    }
    elsif ($errnum eq '00000337')
    {
        $msg = "Unknown NPIV Admin cmd received at return point";
    }
    elsif ($errnum eq '00000340')
    {
        $msg = "VIOS NPIV DD rejected completion of NPIV Admin cmd";
    }
    elsif ($errnum eq '00000341')
    {
        $msg  = "No function ptr to return NPIV Admin cmd to ";
        $msg .= "VIOS NPIV DD";
    }
    elsif ($errnum eq '00000348')
    {
        $msg = "VIOS NPIV DD rejected completion of NPIV SCSI cmd";
    }
    elsif ($errnum eq '00000349')
    {
        $msg  = "No functionp ptr to return NPIV SCSI cmd to ";
        $msg .= "VIOS NPIV DD";
    }
    elsif ($errnum eq '00000350')
    {
        $msg  = "NPIV async processing: unknown async status option ";
        $msg .= " ($errno)";
    }
    elsif ($errnum eq '00000351')
    {
        $msg  = "NPIV async processing: unknown async status code ";
        $msg .= " ($errno)";
    }
    elsif ($errnum eq '00000355')
    {
        $msg = "FCP_RSP IU build failure for response from $rnport";
    }
    elsif ($errnum eq '00000356')
    {
        $msg  = "NPIV PRLI (for $rnport) returned to ";
        $msg .= "NPIV SCSI return point";
    }
    elsif ($errnum eq '00000357')
    {
        $msg = "Unknown NPIV cmd returned to NPIV SCSI return point";
    }
    elsif ($errnum eq '00000358')
    {
        $msg = "Adapter rejected NPIV Marker for $rnport";
    }
    elsif ($errnum eq '00000359')
    {
        $msg = "NPIV Marker command for $rnport failed";
    }
    elsif ($errnum eq '00000360')
    {
        my $vwwn = &bytes($sense,  982, 8);
        $msg = "VIOS NPIV driver rejected async status for $vwwn; ";
        $msg .= "Client may have disconnected or rebooted";
    }
    elsif ($errnum eq '00000402')
    {
                my $reason = &bytes($sense, 8, 4);

                if ($reason eq '00000001')
                {
                    $msg = "Driver is closing with unlogged errors for link";
                }
                elsif ($reason eq '00000002')
                {
                    $msg = "Link has recovered";
                }
                else
                {
                    $msg = "Error counts reset for link (unknown reason)";
                }
        }
    elsif ($errnum eq '00000403')
    {
                my $reason = &bytes($sense, 8, 4);

                if ($reason eq '00000001')
                {
                    $msg  = "Driver is closing with unlogged errors for ";
                    $msg .= "target $rnport";
                }
                elsif ($reason eq '00000002')
                {
                    $msg = "Target $rnport has recovered";
                }
                else
                {
                    $msg  = "Error counts reset for target $rnport ";
                    $msg .= "(unknown reason)";
                }
    }
    elsif ($errnum eq '00000D01')
    {
        $msg = "Bad initiator eyecatcher during SCIOLSTOPINITR";
    }
    elsif ($errnum eq '00000D02')
    {
        $msg = "Invalid cmd in update vport request";
    }
    elsif ($errnum eq '00000D03')
    {
        $msg = "Update vport request failed";
    }
    elsif ($errnum eq '00000D07')
    {
        $msg = "NULL initiator during update vport operation";
    }
    elsif ($errnum eq '00000D08')
    {
        $msg = "Adapter driver rejected update vport request;";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000D15')
    {
        $msg = "Initiator cleanup called with invalid value (defect)";
    }
    elsif ($errnum eq '00000D16')
    {
        $msg = "Invalid eyecatcher while adding initiator for adapter";
    }
    elsif ($errnum eq '00000D17')
    {
        $msg  = "Adapter driver failed NPIV_CLR request; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);
    }
    elsif ($errnum eq '00000D19')
    {
        $msg = "Invalid eyecatcher while adding initiator (errcheck)";
    }
    elsif ($errnum eq '0000A103')
    {
        $msg = "Bad initiator eyecatcher during SCIOLSTART";
    }
    elsif ($errnum eq '0000A110')
    {
        $msg = "VIOS NPIV rejected completion of a flushed command";
    }
    else
    {
        $msg = "Unknown error number: " . $errnum;
    }

    if ($ERRNUMS)
    {
            $msg = "$errnum: $msg";
    }

    printf("%s", $msg);
}

# ---------------------------------------------------------------------------
# LABEL:          FCS_ERR2
# IDENTIFIER:     825849BF
# 
# [...]
# 
# VPD:             
# [...]
# 
# Detail Data
# SENSE DATA
# 0000 0000 0000 0027 ....
# [...]
# ---------------------------------------------------------------------------
sub FCS_ERR
{
	my @error = @_;

	my $sense  = &get_sense_data(@error);

	my $errnum = &bytes($sense,  4, 4);

	my $msg = "";

	if    ($errnum eq '00000001')
	{
		$msg = "mailbox failed with a link-type error";
	}
	elsif ($errnum eq '00000005')
	{
		my $mb = &bytes($sense, 105, 1);
		my $st = &byte_reverse(&bytes($sense, 106, 2));
		$msg = "Adapter mailbox request ($mb) failed with unexpected ";
		$msg .= "status $st";
	}
	elsif ($errnum eq '00000006')
	{
		my $st = &byte_reverse(&bytes($sense, 106, 2));
		my $mb = &bytes($sense, 105, 1);
		$msg = "Adapter mailbox request ($mb) failed with unknown ";
		$msg .= "status $st";
	}
	elsif ($errnum eq '00000007')
	{
		my $st = &byte_reverse(&bytes($sense, 106, 2));
		$msg = "Adapter configuration mailbox failed with status $st";
	}
	elsif ($errnum eq '0000000C')
	{
		my $els = &words($sense, 34, 1);
		$msg  = "Unsolicited unsupported ELS (";
		$msg .= &lookup("ELS ", $els, \%fc_payload_op_lt);
		$msg .= ") received";
	}
	elsif ($errnum eq '00000017')
	{
		my $pay_op	= &words($sense,  34, 1);
		my $rc		= &bytes($sense, 122, 1);
		my $re		= &bytes($sense, 121, 1);

		$msg = "(1 of 2) ELS failed with LS_RJT, ";
		$msg .= &lookup("payload opcode ", $pay_op, \%fc_payload_op_lt);
		$msg .= ", " . &lookup("Reason code ", $rc, \%fc_lsrjt_rc_lt);
		$msg .= ", " . &lookup("Explanation ", $re, \%fc_lsrjt_re_lt);
	}
	elsif ($errnum eq '0000001B')
	{
		$msg = "IOCB failed w/ Invalid RPI and retries exceeded";
	}
	elsif ($errnum eq '00000021')
	{
		my $els_op	= &words($sense, 34, 1);
		my $rport	= &byte_reverse(&bytes($sense, 124, 3));
		my $rc		= &bytes($sense, 120, 1);

		$msg  = "Adapter Local Reject (code $rc) for ";
		$msg .= &lookup("ELS ", $els_op, \%fc_payload_op_lt);
		$msg .= " to port 0x" . $rport;
	}
	elsif ($errnum eq '00000024')
	{
		$msg = "Adap DD generated IOCB has failed";
	}
	elsif ($errnum eq '00000026')
	{
		my $mb = &bytes($sense, 105, 1);
		my $st = &byte_reverse(&bytes($sense, 106, 2));
		$msg  = "Mailbox command ($mb) timed out (status $st)";
	}
	elsif ($errnum eq '00000027')
	{
		my $payload_op = &words($sense, 26, 1);
		$msg = "IOCB timeout, ";
		$msg .= &lookup("payload opcode ", $payload_op,
			\%fc_payload_op_lt);
	}
	elsif ($errnum eq '00000029')
	{
		my $size = &words($sense, 26, 1);
		my $rc   = &words($sense, 27, 1);

		$msg = "D_MAP_LIST failure; size 0x$size, ";
		$msg .= &lookup("rc ", $rc, \%aix_d_map_list_rc_lt);
	}
	elsif ($errnum eq '0000002E')
	{
		$msg = "Request to adapter to 'abort multiple' has timed out";
	}
	elsif ($errnum eq '00000030')
	{
		$msg = "Error attention";

		# Some of these have the SENSE DATA decorated with a
		# diagnostic analysis including an SRN.  Retrieve it if so.
		my $srn = "";
		for (my $i = 0; $i <= $#error; $i++)
		{
			if ($error[$i] =~ /^SRN:/)
			{
				$srn = $error[$i];
				chomp($srn);
				$srn =~ s/\s+/ /g;
				$msg = "$msg $srn";
				last;
			}
		}
	}
	elsif ($errnum eq '00000037')
	{
		$msg = "Adapter configuration/startup failed";
	}
	elsif ($errnum eq '00000038')
	{
		$msg = "No free command structure to reply to unsolicited ELS";
	}
	elsif ($errnum eq '0000003A')
	{
		$msg = "No buffers available to receive async sequence";
	}
	elsif ($errnum eq '00000041')
	{
		$msg = "Link is dead (has been down several seconds)";
	}
	elsif ($errnum eq '00000048')
	{
		$msg = "LOGO from remote port 0x000000";
	}
	elsif ($errnum eq '00000051')
	{
		$msg = "Error attention (continued from previous error)";
	}
	elsif ($errnum eq '00000053')
	{
		$msg = "(2 of 2) ELS failed with LS_RJT";
	}
	elsif ($errnum eq '0000005D')
	{
		$msg = "An unrecognized unsolicited IOCB was received";
	}
	elsif ($errnum eq '0000005E')
	{
		$msg = "Error detected in response to transmitted sequence";
	}
	elsif ($errnum eq '00000071')
	{
		$msg = "timeout waiting for adap quiesce for ucode download";
	}
	elsif ($errnum eq '000000C4')
	{
		my $rpi = &bytes($sense, 138, 2);
		$msg  = "Proto IOCB failed w/ Invalid RPI ($rpi); RPI not free";
	}
	elsif ($errnum eq '00000127')
	{
		$msg = "Kill board mailbox timeout";
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          FIRMWARE_EVENT
# IDENTIFIER:     A6D1BD62
# 
# [...]
# 
# Description
# Firmware Event
# 
# Detail Data
# Event Information
# 0124 0000 0000 0032 C600 8401 1614 5500 2010 0519 0000 626F 6F74 2D6D ...
# 0000 20A8 0110 0001 0000 0000 0000 0000 4942 4D00 0000 0000 0002 
# 
# Diagnostic Analysis
# Diagnostic Log sequence number: 6
# Resource tested:        sysplanar0
# Resource Description:   System Planar
# Location:               
# SRN:                    20A80110
# Description:            Refer to the Error Code to FRU Index in the system
#                         service guide.
# Possible FRUs:
#                      FRU:                                      
# and or 
#
# Supporting data:
#
# SRC: BA5400A5
# Additional Words: 2-00000000 3-00000000 4-00000000 5-00000000
#                   6-00000000 7-00000000 8-00000000 9-00000000
# Priority: H
# Location: U78D2.001.WZS0S0K-P1-C5-T2
# 
#
# ---------------------------------------------------------------------------
sub FIRMWARE_EVENT
{
	my @error	= @_;
	my $srn		= "(no SRN found)";
    my $src     = "(no SRC found)";
    my $msg     = "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^SRN:/)
		{
			$srn = $error[$i];
			chomp($srn);
			$srn =~ s/\s+/ /g;
			last;
		}

        if ($error[$i] =~ /^SRC:/)
        {
            $src = $error[$i];
            chomp($src);
            $src =~ s/^SRC://g;
            $src =~ s/\s+//g;
            $src =~ s/\s+$//g;
            last;
        }

    }

    if ($src && $src ne '(no SRC found)' )
    {
        $msg .= &lookup("", $src, \%scan_err_src_lt);
    }


	printf("%s %s", $srn, $msg );

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          FSCSI_ERR6
# IDENTIFIER:     B8FBD189
# 
# [...]
# 
# Detail Data
# SENSE DATA
# 0000 0000 0000 00A1 ....
# ---------------------------------------------------------------------------
sub FSCSI_ERR
{
	my @error = @_;

	my $sense  = &get_sense_data(@error);

	my $errnum = &bytes($sense,  4, 4);
	my $errno  = &hex2int(&bytes($sense, 8, 4));	# often an errno value
	my $rnport = "port 0x" . &bytes($sense,  65, 3);
	my $wwpn   = "wwpn 0x" . &bytes($sense, 188, 8);

	my $msg = "";

	if ($errnum eq '00000001')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg = "ioctl(SCIOLINQU) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000003')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg = "ioctl(SCIOLTUR) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000004')
	{
		my $lun = "lun 0x" . &bytes($sense, 20, 8);
		$msg = "ioctl(SCIOLREAD) timeout; $rnport $lun";
	}
	elsif ($errnum eq '00000007')
	{
		$msg = "Attempt to cancel a request to $rnport failed";
	}
	elsif ($errnum eq '0000000A')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "Name server rejected GID_PN, ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '0000000B')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "Name server rejected GCS_ID for $rnport, ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '0000000F')
	{
		$msg = "ioctl() WWPN\/WWNN does not match target";
	}
	elsif ($errnum eq '00000015')
	{
		my $rspiu = &words($sense, 45, 10);
		$msg = "Process level task management failed; ";
		$msg .= &FCP_RSP_IU($rspiu);
	}
	elsif ($errnum eq '00000017')
	{
		$msg = "Error on intr lvl TM; errno ";
		$msg .= &lookup("", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000001F')
	{
		$msg = "Data overrun (in FCP response)";
	}
	elsif ($errnum eq '00000023')
	{
		$msg = "Timeout for inactive command";
	}
	elsif ($errnum eq '00000025')
	{
		$msg = "Adapter driver rejected TM Abort Task Set for $rnport;";
		$msg .= " " . &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000026')
	{
		$msg = "Device cancel timeout";
	}
	elsif ($errnum eq '00000028')
	{
		$msg = "Target cancel for $rnport timed out";
	}
	elsif ($errnum eq '00000029')
	{
		$msg = "Relogin request timeout for $rnport";
	}
	elsif ($errnum eq '0000002A')
	{
		$msg = "PRLI or PDISC to $rnport timed out";
	}
	elsif ($errnum eq '0000002B')
	{
		$msg = "process lvl task mgt timeout";
	}
	elsif ($errnum eq '0000002C')
	{
		$msg = "Target reset to $rnport timed out";
	}
	elsif ($errnum eq '0000002E')
	{
		my $rspiu = &words($sense, 45, 10);
		$msg = "Data underrun receiving from $rnport ";
		$msg .= &FCP_RSP_IU($rspiu);
	}
	elsif ($errnum eq '00000030')
	{
		$msg = "Async status - NDD_HARD_FAIL";
	}
	elsif ($errnum eq '00000031')
	{
		$msg = "Async status - LINK_DOWN";
	}
	elsif ($errnum eq '00000032')
	{
		$msg = "Async status - LINK_UP";
	}
	elsif ($errnum eq '00000033')
	{
		$msg = "Async LOGO--target has a started LUN (debug)";
	}
	elsif ($errnum eq '00000035')
	{
		$msg = "Async adapter status--LIP or SCN (debug)";
	}
	elsif ($errnum eq '00000037')
	{
		$msg = "Async status--SCN received (debug)";
	}
	elsif ($errnum eq '0000003B')
	{
		$msg = "Async status--adapter halted";
	}
	elsif ($errnum eq '0000003C')
	{
		$msg = "Async status--adapter resumed";
	}
	elsif ($errnum eq '0000003E')
	{
		$msg = "Target SCIOLSTARTed as version 1, but received version 0 ioctl";
	}
	elsif ($errnum eq '00000041')
	{
		$msg = "Request failed--adapter reported HW failure";
	}
	elsif ($errnum eq '00000042')
	{
		$msg = "Request failed--adapter reported software error";
	}
	elsif ($errnum eq '00000049')
	{
		my $rc = &bytes($sense, 116, 1);
		$msg = "Adapter returned unexpected Local Reject status ";
		$msg .= "(code $rc)";
	}
	elsif ($errnum eq '0000004A')
	{
		$msg = "Error detected while receiving from $rnport ";
		$msg .= "(possible marginal link)";
	}
	elsif ($errnum eq '0000004B')
	{
		$msg = "Unknown IOCB status";
	}
	elsif ($errnum eq '0000004E')
	{
		$msg = "ioctl() WWPN\/WWNN doesn't match known $wwpn for $rnport";
	}
	elsif ($errnum eq '0000004F')
	{
		$msg = "Nameserver request regarding $rnport timed out";
	}
	elsif ($errnum eq '00000061')
	{
		$msg = "Device does not support FC classes we like";
	}
	elsif ($errnum eq '0000006A')
	{
		$msg = "Adapter driver rejected I/O request for $rnport; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006B')
	{
		$msg = "Cancel IOCB not accepted by output";
	}
	elsif ($errnum eq '0000006C')
	{
		$msg = "Cancel IOCB not accepted; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006E')
	{
		$msg = "Target reset IOCB not accepted; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '0000006F')
	{
		$msg = "Target cancel IOCB not accepted; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '00000070')
	{
		$msg = "Timeout waiting for link up";
	}
	elsif ($errnum eq '00000071')
	{
		$msg = "Timeout waiting for adapter to resume";
	}
	elsif ($errnum eq '00000073')
	{
		$msg = "Unsolicited IOCB received";
	}
	elsif ($errnum eq '0000007A')
	{
		$msg = "Async adapter status: adapter has been reset";
	}
	elsif ($errnum eq '0000007F')
	{
		$msg = "LUN reset not accepted; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A1')
	{
		$msg = "Relogin to $rnport failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000A2')
	{
		$msg = "Relogin completed, but new WWPN\/WWNN";
	}
	elsif ($errnum eq '000000A3')
	{
		$msg = "Reset ring for SCSI IOCB ring failed";
	}
	elsif ($errnum eq '000000A5')
	{
		$msg = "Send sequence failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AA')
	{
		$msg = "GID_PN nameserver request failed with ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AC')
	{
		my $reason = &words($sense, 2, 1);
		my $mynport = &bytes($sense, 57, 3);

		$msg = "Nameserver GID_PN or GPN_ID for 0x$mynport ";

		if ($reason =~ /00000000/)
		{
			$msg .= "failed by adapter driver";
		}
		else
		{
			$msg .= "rejected with ";
			$msg .= &lookup("reason code ", $reason, \%fc_nsrjt_lt);
		}
	}
	elsif ($errnum eq '000000AC')
	{
		$msg = "Name server query failed or rejected";
	}
	elsif ($errnum eq '000000AD')
	{
		$msg = "Dynamic tracking failed; $rnport/$wwpn ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000AF')
	{
		my $reason = &words($sense, 2, 1);
		$msg = "NS GID_PN reject " . $wwpn . "; ";
		$msg .= &lookup("", $reason, \%fc_nsrjt_lt);
	}
	elsif ($errnum eq '000000B0')
	{
		$msg = "Reset ring request not accepted; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B1')
	{
		my $retries = &bytes($sense, 136, 1);

		$msg = "Relogin to $rnport rejected; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
		$msg .= "; retries = $retries";
	}
	elsif ($errnum eq '000000B2')
	{
		$msg = "PDISC to $rnport failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B4')
	{
		$msg = "MOVE_LOGIN request refused by adap DD; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B5')
	{
		$msg = "Relogin with name server failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000B7')
	{
		$msg = "Adapter driver refused send sequence; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000BD')
	{
		$msg = "MOVE_LOGIN request failed; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000C0')
	{
		$msg = "PRLI failed";
	}
	elsif ($errnum eq '000000C3')
	{
		$msg = "target moved to new scsi_id, but tracking not complete";
	}
	elsif ($errnum eq '000000C7')
	{
		$msg  = "Issue MOVE_LOGIN failed for a target returning to orig scsi_id; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	elsif ($errnum eq '000000C8')
	{
		$msg = "dyntrk failure detected in ioctl() path " . $wwpn;
	}
	elsif ($errnum eq '000000D0')
	{
		$msg = "Request for zero-length SCSI cmd received";
	}
	elsif ($errnum eq '000000D1')
	{
		$msg = "Interrupt for inactive command";
	}
	elsif ($errnum eq '000000D2')
	{
		$msg = "Received I\/O request for invalid device";
	}
	elsif ($errnum eq '000000D3')
	{
		my $pid  = &hex2int(&words($sense,  20, 1));
		$msg  = "dyntrk enabled, but version 0 ioctl requested by ";
		$msg .= "PID $pid";
	}
	elsif ($errnum eq '000000D9')
	{
		my $conn = &bytes($sense, 12, 1);
		my $fw   = &hex2int(&bytes($sense, 68, 1));
		my $pid  = &hex2int(&words($sense, 20, 1));

		$msg = "PID $pid wants fast_fail/dyntrk; unsupported ";
		$msg .= "FW level ($fw) or conn (";
		if ($conn eq '01')
		{
			$msg .= "point to point";
		}
		elsif ($conn eq '02')
		{
			$msg .= "switch";
		}
		elsif ($conn eq '03')
		{
			$msg .= "loop";
		}
		else
		{
			$msg .= "unknown";
		}
		$msg .= ")";
		
	}
	elsif ($errnum eq '000000DB')
	{
		$msg = "issue_relogin abandoned; STALE scsi_id " . $wwpn;
	}
	elsif ($errnum eq '000000F0')
	{
		$msg = "strategy() received unsup. scsi buf";
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	if ($ERRNUMS)
	{
		$msg = "$errnum: $msg";
	}

	printf("%s", $msg);

	return;
}

sub FCA_ERR_Cavium_cvfc
{
    my @error  = @_;
    my $sense  = &get_sense_data(@error);
    my $errnum = &words($sense, 1, 1);
    my $msg    = "";

    if    ($errnum eq 'xxxxxxxx')
    {
        $msg = "huh?";
    }
    elsif ($errnum eq '00000000')
    {
        $msg  = "Unexpected mailbox completion received";
    }
    elsif ($errnum eq '00000001')
    {
        $msg  = "Verify Checksum MB failure";
    }
    elsif ($errnum eq '00000002')
    {
        $msg  = "Unable to read WWPN from NVRAM portion";
    }
    elsif ($errnum eq '00000003')
    {
        $msg  = "Adapter suffered an internal error";
    }
    elsif ($errnum eq '00000004')
    {
        $msg  = "MB failed with host error status";
    }
    elsif ($errnum eq '00000005')
    {
        $msg  = "LILO is failed; No IOCB/Exchange Ctrl Blocks available with FW";
    }
    elsif ($errnum eq '00000006')
    {
        $msg  = "Read/Write SFP MB failed";
    }
    elsif ($errnum eq '00000008')
    {
        $msg  = "Exceeded link re-tries; Currently not in link dead state";
    }
    elsif ($errnum eq '00000009')
    {
        $msg  = "LILO is failed; Fabric is not reachable";
    }
    elsif ($errnum eq '00000007')
    {
        $msg  = "LILO IOCB failed; FW is not ready";
    }
    elsif ($errnum eq '0000000A')
    {
        $msg  = "Cmd not found with handle found in response IOCB";
    }
    elsif ($errnum eq '0000000B')
    {
        $msg  = "DEFECT: Unexpected login request from adapter driver";
    }
    elsif ($errnum eq '0000000D')
    {
        $msg  = "LILO IOCB failed; Unkown error subcode1 received";
    }
    elsif ($errnum eq '0000000E')
    {
        $msg  = "Adapter failed login request with: No PCB";
    }
    elsif ($errnum eq '0000000F')
    {
        $msg  = "Received unknown entry_type in response IOCB";
    }
    elsif ($errnum eq '00000010')
    {
        $msg  = "Unable to connect; GET_ID mailbox failed at startup";
    }
    elsif ($errnum eq '00000011')
    {
        $msg  = "FLOGI is pending or ACC frame is not received for vport";
    }
    elsif ($errnum eq '00000012')
    {
        $msg  = "Registration for State Change Notifications failed";
    }
    elsif ($errnum eq '00000013')
    {
        $msg  = "ELS pass through failed with sub error codes";
    }
    elsif ($errnum eq '00000014')
    {
        $msg  = "Execute FW MB failed";
    }
    elsif ($errnum eq '00000015')
    {
        $msg  = "About FW MB failed";
    }
    elsif ($errnum eq '00000016')
    {
        my $rnport = &byte_reverse(&bytes($sense, 208, 3));

        $msg  = "Login to $rnport failed; not in correct state and retry count exceeded";
    }
    elsif ($errnum eq '00000017')
    {
        $msg  = "Modify VP cfg IOCB failed";
    }
    elsif ($errnum eq '00000018')
    {
        $msg  = "Get Data Rate MB failed";
    }
    elsif ($errnum eq '00000019')
    {
        $msg  = "Set FW options MB failed";
    }
    elsif ($errnum eq '0000001A')
    {
        $msg = "Async event with unknown AE-Code is received from adapter";
    }
    elsif ($errnum eq '0000001B')
    {
        $msg = "Mailbox cmd failure. Invalid MB cmd received";
    }
    elsif ($errnum eq '0000001C')
    {
        $msg = "LILO IOCB failed; No nport handles available with FW";
    }
    elsif ($errnum eq '0000001D')
    {
        $msg = "Failed to dump the RISC RAM";
    }
    elsif ($errnum eq '0000001E')
    {
        $msg = "Link is dead (has been down several seconds)";
    }
    elsif ($errnum eq '0000001F')
    {
        $msg = "Unknown mailbox command";
    }
    elsif ($errnum eq '00000020')
    {
        $msg  = "Failed to issue load RAM MB for FW download";
    }
    elsif ($errnum eq '00000021')
    {
        $msg  = "Can not find a vport during port db change event";
    }
    elsif ($errnum eq '00000022')
    {
        $msg  = "Can not find a vport during port db change event";
    }
    elsif ($errnum eq '00000023')
    {
        $msg  = "Adapter generated unknown interrupt type";
    }
    elsif ($errnum eq '00000025')
    {
        $msg  = "Passthrough MB failure; Host error or NPort hdl in use";
    }
    elsif ($errnum eq '00000026')
    {
        $msg  = "Mailbox timeout";
    }
    elsif ($errnum eq '00000027')
    {
        $msg  = "IOCB timeout";
    }
    elsif ($errnum eq '00000028')
    {
        $msg  = "Unknown watchdog timer type";
    }
    elsif ($errnum eq '00000029')
    {
        my $bytes = &bytes($sense, 148, 4);
        $msg  = "DMA map for $bytes bytes failed w/ DMA_NORES";
    }
    elsif ($errnum eq '0000002A')
    {
        $msg  = "Exceeded max adap restart re-tries";
    }
    elsif ($errnum eq '0000002B')
    {
        $msg  = "Login collision during login (address in use)";
    }
    elsif ($errnum eq '0000002C')
    {
        $msg  = "Failed to complete startup sequence after FW download";
                $msg .= "(process environment and run whole startup sequence)";
    }
    elsif ($errnum eq '0000002D')
    {
        $msg  = "Unknown interrupt status";
    }
    elsif ($errnum eq '0000002E')
    {
        $msg  = "Format 0 Rpt ID Acquisition mailbox received (info)";
    }
    elsif ($errnum eq '0000002F')
    {
        $msg  = "Error while processing admin response queue";
    }
    elsif ($errnum eq '00000030')
    {
        $msg  = "Couldn't find vport for Report ID Acquisition";
    }
    elsif ($errnum eq '00000031')
    {
        $msg  = "Unsupported adap_mb_opcode found while building CMD";
    }
    elsif ($errnum eq '00000032')
    {
        $msg  = "Unsupported cmd opcode found while building CMD";
    }
    elsif ($errnum eq '00000033')
    {
        $msg  = "Build IOCB routine received unknown adap_mb_opcode";
    }
    elsif ($errnum eq '00000034')
    {
        $msg  = "Build IOCB routine received unknown adap_opcode";
    }
    elsif ($errnum eq '00000035')
    {
        $msg  = "Admin IOCB failure; Rejected by adapter";
    }
    elsif ($errnum eq '00000037')
    {
        $msg  = "LILO IOCB failure with status (not logged in)";
    }
    elsif ($errnum eq '00000038')
    {
        $msg  = "LILO IOCB failed with unknown status";
    }
    elsif ($errnum eq '00000039')
    {
        my $rnport = &byte_reverse(&bytes($sense, 208, 3));

        $msg  = "Login to $rnport failed (usually timeout or LOGO ";
        $msg .= "received)";
    }
    elsif ($errnum eq '0000003A')
    {
        my $rnport = &byte_reverse(&bytes($sense, 208, 3));
        my $rc     =               &bytes($sense, 218, 1);
        my $re     =               &bytes($sense, 217, 1);

        my $rct = &lookup("", $rc, \%fc_lsrjt_rc_lt);
        my $ret = &lookup("", $re, \%fc_lsrjt_re_lt);

        $msg  = "Login to $rnport failed with LS_RJT ($rct/$ret)";
    }
    elsif ($errnum eq '0000003D')
    {
        $msg  = "DEFECT:Exceeded link max number of link retries";
    }
    elsif ($errnum eq '0000003C')
    {
        $msg  = "Initialize FW MB failure";
    }
    elsif ($errnum eq '0000003D')
    {
        $msg  = "Adapter driver IOCB failed at startup/shutdown; ";
        $msg .= "will reset at next open";
    }
    elsif ($errnum eq '0000003E')
    {
        $msg  = "Adapter driver IOCB failed at startup/shutdown; ";
        $msg .= "will reset at next open";
    }
    elsif ($errnum eq '0000003F')
    {
        $msg  = "Adapter driver startup sequence failed";
    }
    elsif ($errnum eq '00000040')
    {
        $msg  = "Unexpected continuation IOCB in admin response queue";
    }
    elsif ($errnum eq '00000041')
    {
        $msg  = "Adapter reset timeout; DMA wouldn't shut down";
    }
    elsif ($errnum eq '00000042')
    {
        $msg  = "Adapter link retries exceeded; Close in progress";
    }
    elsif ($errnum eq '00000044')
    {
        $msg  = "Inconsistent move login request received";
    }
    elsif ($errnum eq '00000045')
    {
        $msg  = "Invalid login correlator received in move_login request";
    }
    elsif ($errnum eq '00000047')
    {
        $msg  = "Unable to find an associated command;";
        $msg  .= "Processing proto queue";
    }
    elsif ($errnum eq '00000048')
    {
        $msg  = "Move_login received while connected in AL mode";
    }
    elsif ($errnum eq '00000049')
    {
        my $rnport = &byte_reverse(&bytes($sense, 208, 3));
        $msg  = "Login/logout request for $rnport failed due to ";
        $msg .= "link down";
    }
    elsif ($errnum eq '0000004A')
    {
        $msg  = "Adapter rejected IOCB due to invalid parameter";
    }
    elsif ($errnum eq '0000004B')
    {
        $msg  = "DMA initialization failed; check adapter tuning and ";
        $msg  .= "slot capability";
    }
    elsif ($errnum eq '0000004E')
    {
        $msg  = "Link retries exceeded; Close or Un-config in progress";
    }
    elsif ($errnum eq '0000004F')
    {
        $msg  = "Invalid entity id";
    }
    elsif ($errnum eq '00000050')
    {
        $msg  = "Unable to connect; GET_ID mailbox failed";
    }
    elsif ($errnum eq '00000051')
    {
        $msg  = "Unsupported buf_type received";
    }
    elsif ($errnum eq '00000052')
    {
        $msg  = "Failed to extract RISC code from FW image that is read from flash";
    }
    elsif ($errnum eq '00000053')
    {
        $msg  = "Failed to read the FW image from adapter flash";
    }
    elsif ($errnum eq '00000054')
    {
        $msg  = "Encountered a hard error; Moved the adapter into off-line state";
    }
    elsif ($errnum eq '00000055')
    {
        $msg  = "FW download failed";
    }
    elsif ($errnum eq '00000056')
    {
        $msg  = "Could not read flash layout table";
    }
    elsif ($errnum eq '00000057')
    {
        $msg  = "Invalid flash layout table; Either version or chksum has a problem";
    }
    elsif ($errnum eq '00000058')
    {
        $msg  = "Tried to restore PCI cfg space without being saved";
    }
    elsif ($errnum eq '0000005A')
    {
        $msg  = "Report ID Aquisition IOCB failed";
    }
    elsif ($errnum eq '0000005B')
    {
        $msg  = "Login collision occured; Max re-tries exceeded";
    }
    elsif ($errnum eq '0000005C')
    {
        $msg  = "Unable to read the flash information";
    }
    elsif ($errnum eq '0000005E')
    {
        $msg  = "Can't access the flash descriptor area in FW image";
    }
    elsif ($errnum eq '0000005F')
    {
        $msg  = "Invalid signature found in flash descriptor table";
    }
    elsif ($errnum eq '00000060')
    {
        $msg  = "No card type available in user supplied FW image;";
        $msg .= "Looks like a bad image";
    }
    elsif ($errnum eq '00000061')
    {
        $msg  = "Incorrect MPI FW region sizes found in FW image";
    }
    elsif ($errnum eq '00000062')
    {
        $msg  = "Incorrect Non-MPI region sizes found in FW image";
    }
    elsif ($errnum eq '00000063')
    {
        $msg  = "Bad FLT or FW Image. Did not find the required regions to download";
    }
    elsif ($errnum eq '00000064')
    {
        $msg  = "Failed to extract RISC code from FW image";
    }
    elsif ($errnum eq '00000065')
    {
        $msg  = "Couldn't read the VPD region from flash";
    }
    elsif ($errnum eq '00000066')
    {
        $msg  = "Failed to restore old FW image";
    }
    elsif ($errnum eq '0000006A')
    {
        $msg  = "Couldn't read NIC VPD0 region from flash";
    }
    elsif ($errnum eq '0000006C')
    {
        $msg  = "Failed init DMA handle for ctl requests";
    }
    elsif ($errnum eq '0000006B')
    {
        $msg  = "Partial FW download occurred; Moved back to old FW image";
    }
    elsif ($errnum eq '0000006D')
    {
        $msg  = "Couldn't read NIC VPD1 region from flash";
    }
    elsif ($errnum eq '0000006C')
    {
        $msg  = "Couldn't read FLT region from flash";
    }
    elsif ($errnum eq '0000006E')
    {
        $msg  = "Failed to find vport with given vp_index";
    }
    elsif ($errnum eq '0000006F')
    {
        $msg  = "DEFECT:Unexpected IOCB type found during update vport operation ";
    }
    elsif ($errnum eq '00000070')
    {
        $msg  = "Allocated less IO DMA size than the one requested";
    }
    elsif ($errnum eq '00000071')
    {
        $msg  = "Time-out waiting to quiesce IO during FW download";
    }
    elsif ($errnum eq '00000072')
    {
        $msg  = "Adapter driver detected login collision due to ";
                $msg .= "STALE target information";
    }
    elsif ($errnum eq '00000073')
    {
        $msg  = "NPort login received; Login to this target port is deleted;";
        $msg .= "May be due to a prior move_login request";
    }
    elsif ($errnum eq '00000074')
    {
        $msg  = "Re-Login received; Login to this target port is deleted;";
        $msg .= "May be due to a prior move_login request";
    }
    elsif ($errnum eq '00000075')
    {
        $msg  = "Timed out waiting for link to come up";
    }
    elsif ($errnum eq '00000078')
    {
        $msg  = "Restart MPI FW MB failed";
    }
    elsif ($errnum eq '00000079')
    {
        $msg  = "MPI Reg write failed due to semaphore contention in FW";
    }
    elsif ($errnum eq '0000007B')
    {
        $msg  = "Unable to get async queue element";
    }
    elsif ($errnum eq '0000007C')
    {
        $msg  = "Unexpected entry_count in Type7 IOCB";
    }
    elsif ($errnum eq '00000080')
    {
        $msg  = "Get Resource Count MB failure";
    }
    elsif ($errnum eq '00000081')
    {
        $msg  = "Get Position Map MB failure";
    }
    elsif ($errnum eq '00000082')
    {
        $msg  = "Verify checksum failed due to startup failure";
    }
    elsif ($errnum eq '00000083')
    {
        $msg  = "Unknown login state is reported in PDB cmd";
    }
    elsif ($errnum eq '00000084')
    {
        $msg  = "Failed to complete startup sequence after FW download";
                $msg .= "(process environment and run startup upto EXE FW)";
    }
    elsif ($errnum eq '00000085')
    {
        $msg  = "Get Port List MB failed during startup sequence";
    }
    elsif ($errnum eq '00000087')
    {
        $msg  = "SERDES XMIT Param MB failed";
    }
    elsif ($errnum eq '00000089')
    {
        $msg  = "Modify VP cfg IOCB cmd failed;";
    }
    elsif ($errnum eq '0000008E')
    {
        $msg  = "Vport info out of sync with FW";
    }
    elsif ($errnum eq '0000008F')
    {
        $msg  = "Adapter driver startup sequence failed";
    }
    elsif ($errnum eq '00000090')
    {
        $msg  = "Received async PRLI from unknown port";
    }
    elsif ($errnum eq '00000093')
    {
        $msg  = "Failed to shutdown DMA during adapter reset";
    }
    elsif ($errnum eq '00000094')
    {
        $msg  = "VP0 Enable Timeout; expecting Rpt ID Acq from adapter";
    }
    elsif ($errnum eq '000000A0')
    {
        $msg  = "Failed to set staging buffer for adap RAS block";
    }
    elsif ($errnum eq '000000A1')
    {
        $msg  = "Error during live dump; Failure returned by dmp_context call";
    }
    elsif ($errnum eq '000000A2')
    {
        $msg  = "Error during live dump; Failure returned by dmp_kernext call";
    }
    elsif ($errnum eq '000000A3')
    {
        $msg  = "Error during live dump; Failure returned by dmp_compspec call";
    }
    elsif ($errnum eq '000000A4')
    {
        $msg  = "Error during live dump; The livedump call returned error";
    }
    elsif ($errnum eq '000000A5')
    {
        $msg  = "Error during live dump; Failure returned by ldmp_setupparms call";
    }
    elsif ($errnum eq '000000A6')
    {
        $msg  = "Failed to initialize the interrupt";
    }
    elsif ($errnum eq '000000C0')
    {
        $msg  = "Faled to allocated DSD pool";
    }
    elsif ($errnum eq '000000C1')
    {
        $msg  = "Failed to allocate SGE resources for channels";
    }
    elsif ($errnum eq '000000C2')
    {
        $msg  = "Failed to init DMA vlist resources of channel";
    }
    elsif ($errnum eq '000000C3')
    {
        $msg  = "Failed to init DMA blist resources of channel";
    }
    elsif ($errnum eq '000000C4')
    {
        $msg  = "io_dma init failed";
    }
    elsif ($errnum eq '000000C5')
    {
        $msg  = "Failed to start kthread";
    }
    elsif ($errnum eq '00000100')
    {
        $msg  = "Fabric Name has changed";
    }
    elsif ($errnum eq '00000101')
    {
        $msg  = "Get FCF list MB failed";
    }
    elsif ($errnum eq '00000105')
    {
        $msg  = "Unexpected inter-driver message received";
    }
    elsif ($errnum eq '00000107')
    {
        $msg  = "Adapter reports FCF discovery timeout; advertising ";
                $msg .= "link down";
    }
    elsif ($errnum eq '0000010C')
    {
        $msg  = "DEFECT: Invalid mailbox resource-3 structure";
    }
    elsif ($errnum eq '0000010D')
    {
        $msg  = "DEFECT: Invalid mailbox resource-3 structure";
    }
    elsif ($errnum eq '0000010E')
    {
        $msg  = "DEFECT: Invalid mailbox resource-3 structure";
    }
    elsif ($errnum eq '00000110')
    {
        $msg  = "IDC Send message MB failed";
    }
    elsif ($errnum eq '00000111')
    {
        $msg  = "IDC Ack message MB failed";
    }
    elsif ($errnum eq '00000114')
    {
        $msg  = "FIP Clear VLink received for the physical link. ";
                $msg .= "This is typically associated with a lost link.";
    }
    elsif ($errnum eq '00000124')
    {
        $msg  = "Failed to allocate login table entry";
    }
    elsif ($errnum eq '00000125')
    {
        $msg  = "Failed to create requested number of IO channels";
    }
    elsif ($errnum eq '00000301')
    {
        $msg  = "Inconsistent LOGOUT request received";
    }
    elsif ($errnum eq '00000302')
    {
        $msg  = "Inconsistent PDISC/ADISC/RELOGIN request received";
    }
    elsif ($errnum eq '00000303')
    {
        $msg  = "Inconsistent RELOGIN request received";
    }
    elsif ($errnum eq '00000304')
    {
        $msg  = "Inconsistent Move_login request received";
    }
    elsif ($errnum eq '00000304')
    {
        $msg  = "Inconsistent cancel request received";
    }
    elsif ($errnum eq '00000306')
    {
        $msg  = "VP0 Enable failed; ";
                $msg .= "likely FLOGI, SCR, or SNS Login failure";
    }
    elsif ($errnum eq '00000801')
    {
        $msg  = "Dump template checksum failure; ";
    }
    elsif ($errnum eq '00000802')
    {
        $msg  = "Dump template parsing failure; ";
    }
    elsif ($errnum eq '00000D03')
    {
        $msg  = "DEFECT: Invalid eyecatcher ";
    }
    elsif ($errnum eq '00000D04')
    {
        $msg  = "NDD_NPIV_CLR request failed";
    }
    elsif ($errnum eq '00000D11')
    {
        $msg  = "Eye catcher failure on vport";
    }
    elsif ($errnum eq '00000130')
    {
        $msg  = "Watchdog timer invoked while in PERM slot error state";
    }
    elsif ($errnum eq '00000131')
    {
        $msg  = "Adapter FW dump failed";
    }
    elsif ($errnum eq '00000132')
    {
        $msg  = "Unknown PCI dev id found during FW dump";
    }
    elsif ($errnum eq '00000300')
    {
        $msg  = "Inconsistent FC_CMD_OP_NPORT_LOGIN cmd recved";
    }
    elsif ($errnum eq '00000801')
    {
        $msg  = "FW dump template checksum error";
    }
    elsif ($errnum eq '00000802')
    {
        $msg  = "Failed to parse FW dump template";
    }
    elsif ($errnum eq '00000803')
    {
        $msg  = "Failed to parse FW dump template;";
                $msg .= "Invalid entry type";
    }
    elsif ($errnum eq '00000804')
    {
        $msg  = "Invalid size found for reading IO bus type1 registers";
    }
    elsif ($errnum eq '00000805')
    {
        $msg  = "Invalid size found for reading IO bus type2 registers";
    }
    elsif ($errnum eq '00000806')
    {
        $msg  = "FW dump failure; Failed to dump RSIC RAM";
    }
    elsif ($errnum eq '00000934')
    {
        $msg  = "Conflict of DDW support from config method to driver";
    }
    elsif ($errnum eq '00000938')
    {
        $msg  = "Failed to query the DDW support from driver";
    }
    elsif ($errnum eq '00000958')
    {
        $msg  = "Failed to initialize DMA region for adapter queues";
    }
    elsif ($errnum eq '00000960')
    {
        $msg  = "Failed to allocate and map DMA region for adapter queues";
    }
    elsif ($errnum eq '00000968')
    {
        $msg  = "Failed to get contiguous DMA bus address region for adapter queues";
    }
    elsif ($errnum eq '000009A0')
    {
        $msg  = "D_MAP_LIST call failure";
    }
    elsif ($errnum eq '00000D01')
    {
        $msg  = "Failed to allocate VP index";
    }
    elsif ($errnum eq '00000D27')
    {
        $msg  = "Timed out waiting for the completion of cmds on admin channel";
    }
    elsif ($errnum eq '00000D28')
    {
        $msg  = "Timed out waiting for the completion of cmds on SCSI channels";
    }
    elsif ($errnum eq '00000D29')
    {
        $msg  = "Failed to write to MSI-X vector table";
    }
    else
    {
        $msg = "Unknown error number: " . $errnum;
    }

    if ($ERRNUMS)
    {
            $msg = "$errnum: $msg";
    }

    printf("%s", $msg);
}

# ---------------------------------------------------------------------------
# LABEL:          CFLASH_ERR3
# IDENTIFIER:     3A976A22
#
# [...]
#
# Detail Data
# SENSE DATA
# 0000 0001 0000 0101 [...]
# ---------------------------------------------------------------------------
sub CFLASH_ERR
{
    my @error = @_;
    my $sense = &get_sense_data(@error);
    my $driver = &bytes($sense, 3, 1);

    #
    # A few drivers use this error log, with different indicators:
    #
    # 0x01 - CAPI Flash adapter driver (cflashdd)
    #
    if ($driver eq '01')
    {
        &CFLASH_ERR_cflash_v0(@error)
    }
    else
    {
        printf("unknown driver type: " . $driver);
    }
}

sub CFLASH_ERR_cflash_v0
{
    my @error   = @_;
    my $sense   = &get_sense_data(@error);
    my $version = &bytes($sense, 3, 1);
    my $errnum  = &words($sense, 1, 1);
    my $msg     = "";

    if    ($errnum eq 'xxxxxxxx')
    {
        $msg  = "huh?";
    }
    elsif ($errnum eq '00000101')
    {
                $msg  = "No cmd room for master context. Failed to issue SYNC cmd";
    }
    elsif ($errnum eq '00000102')
    {
                my $fc_port = &bytes($sense, 260, 4);
                $msg  = "Link reset re-tries have exceeded, port ($fc_port) did not come online ";
    }
    elsif ($errnum eq '00000103')
    {
                my $fc_port = &bytes($sense, 260, 4);
                $msg  = "Failed to establish login for FC port $fc_port after link rst";
    }
    elsif ($errnum eq '00000104')
    {
                my $fc_port = &bytes($sense, 260, 4);
                $msg  = "Target WWPN has changed on port $fc_port";
    }
    elsif ($errnum eq '00000105')
    {
                my $fc_port = &bytes($sense, 260, 4);
                $msg  = "Link did not come up after adapter reset on port $fc_port";
    }
    elsif ($errnum eq '00000106')
    {
                my $fc_port = &bytes($sense, 260, 4);
                $msg  = "Failed to establish login for FC port $fc_port after adapter rst";
    }
    elsif ($errnum eq '00000201')
    {
                $msg  = "Failed to alloc DMA STAB";
    }
    elsif ($errnum eq '00000202')
    {
                $msg  = "Failed to initialize channel specific DMA resources";
    }
    elsif ($errnum eq '00000203')
    {
                $msg  = "Allocation of Channel DMA Memory failed.";
    }
    elsif ($errnum eq '00000204')
    {
                $msg  = "Failed to DMA map channel memory resources.";
    }
    elsif ($errnum eq '00000205')
    {
                $msg  = "DMA map resulted in discontiguous bus memory for can mem.";
    }
    elsif ($errnum eq '00000300')
    {
                my $afu_ver = &bytes($sense, 260, 8);
                $msg  = "Unsupported AFU intercace version : $afu_ver";
    }
    elsif ($errnum eq '00000301')
    {
                my $rc = &bytes($sense, 256, 4);
                $msg  = "Failed to init global DMA handle rc $rc";
    }
    elsif ($errnum eq '00000302')
    {
                $msg  = "Failed to alloc global mem pool.";
    }
    elsif ($errnum eq '00000303')
    {
                $msg  = "Failed to map DMA for mem pool.";
    }
    elsif ($errnum eq '00000304')
    {
                $msg  = "DMA map resulted in discontiguous bus memory for global mem.";
    }
    elsif ($errnum eq '00000506')
    {
                $msg  = "Detected a new EEH during the EEH recovery.";
    }
    elsif ($errnum eq '00000501')
    {
                $msg  = "Unknown EEH command received in callback";
    }
    elsif ($errnum eq '00000502')
    {
                $msg  = "Failed to log sysplanar EEH error";
    }
    elsif ($errnum eq '00000503')
    {
                $msg  = "Received EEH resume before getting an EEH active event";
    }
    elsif ($errnum eq '00000504')
    {
                $msg  = "Failed to re-attach kernel ctx after adapter reset";
    }
    elsif ($errnum eq '00000505')
    {
                $msg  = "Failed to re-attach chn ctx after adapter reset";
    }
    elsif ($errnum eq '00000507')
    {
                $msg  = "Rreset AFU failed";
    }
    elsif ($errnum eq '00000508')
    {
                $msg  = "Failed to reset AFU due to an EEH";
    }
    elsif ($errnum eq '0000060D')
    {
                my $fc_port = &bytes($sense, 263, 1) ;
                $msg  = "Link error on port $fc_port. Resetting the link.";
    }
    elsif ($errnum eq '00000601')
    {
                my $hrrqe = &bytes($sense, 260, 8);
                $msg  = "Invalid HRRQ entry $hrrqe found in master ctx";
    }
    elsif ($errnum eq '00000602')
    {
                $msg  = "DEFECT: Inactive cmd completion master ctx";
    }
    elsif ($errnum eq '00000603')
    {
                my $regval = &bytes($sense, 260, 8);
                $msg  = "Ctx syx failed with intr status $regval";
    }
    elsif ($errnum eq '00000604')
    {
                my $regval = &bytes($sense, 260, 8);
                $msg  = "Ctx syx failed with unknown status $regval";
    }
    elsif ($errnum eq '00000605')
    {
                my $eisnval = &bytes($sense, 260, 8);
                $msg  = "EISN received with invalid error value $eisnval";
    }
    elsif ($errnum eq '00000606')
    {
                my $hrrqe = &bytes($sense, 260, 8);
                $msg  = "Invalid HRRQ entry $hrrqe found in chn ctx";
    }
    elsif ($errnum eq '00000607')
    {
                my $hrrqe = &bytes($sense, 260, 8);
                $msg  = "Invalid HRRQ entry $hrrqe found in chn ctx during cmd proc";
    }
    elsif ($errnum eq '00000608')
    {
                $msg  = "Inactive cmd completion on chn";
    }
    elsif ($errnum eq '0000060A')
    {
                $msg  = "Invalid AFU RC in RCB status area";
    }
    elsif ($errnum eq '0000060B')
    {
                $msg  = "FC protocol error detected by AFU";
    }
    elsif ($errnum eq '0000060C')
    {
                $msg  = "Underrun error without any resid value";
    }
    elsif ($errnum eq '00000610')
    {
                my $eisnval = &bytes($sense, 260, 8);
                $msg  = "EISN called. Unkown error value $eisnval";
    }
    elsif ($errnum eq '00000611')
    {
                $msg  = "DEFECT: Bad Page Fault error on master ctx";
    }
    elsif ($errnum eq '00000612')
    {
                $msg  = "DEFECT: Bad Page Fault error chn ctx";
    }
    elsif ($errnum eq '00000613')
    {
                $msg  = "AFU Sync cmd failed";
    }
    elsif ($errnum eq '0000060D')
    {
                $msg  = "Other link status async event received during link reset";
    }
    elsif ($errnum eq '0000060E')
    {
                my $fc_port = &bytes($sense, 263, 1);
                $msg  = "Link DOWN on FC port $fc_port.";
    }
    elsif ($errnum eq '00000701')
    {
                $msg  = "IOCTL cmd timedout";
    }
    elsif ($errnum eq '00000702')
    {
                $msg  = "IOCTL cmd timedout";
    }
    elsif ($errnum eq '00000703')
    {
                $msg  = "IOCTL cmd timedout";
    }
    elsif ($errnum eq '00000704')
    {
                $msg  = "IOCTL cmd timedout";
    }
    elsif ($errnum eq '00000707')
    {
                $msg  = "Failed to detach user ctx";
    }
    elsif ($errnum eq '00000705')
    {
                $msg  = "Failed to recover user ctx";
    }
    elsif ($errnum eq '00000706')
    {
                $msg  = "Failed to attach user ctxs during recovery";
    }
    elsif ($errnum eq '00000802')
    {
                $msg  = "DEFECT: Found cmds on ped queue after a flush";
    }
    elsif ($errnum eq '00000D01')
    {
                $msg  = "DEFECT: Cmd timed out but no scsi_buf pointer in it";
    }
    elsif ($errnum eq '00000D02')
    {
                $msg  = "DEFECT: Cmd timed out but active cmds";
    }
    elsif ($errnum eq '00000D03')
    {
                $msg  = "Ctx reset timeout";
    }
    elsif ($errnum eq '00000D04')
    {
                $msg  = "AFU sync cmd timedout";
    }
    elsif ($errnum eq '00000D05')
    {
                my $fc_port = &bytes($sense, 263, 1) ;
                $msg  = "Timed out waiting for link up/login on port $fc_port";
    }
    elsif ($errnum eq '00000D06')
    {
                $msg  = "DEFECT: Watchdog called with incorrect timer type";
    }
    elsif ($errnum eq '00000E03')
    {
                my $krc = &bytes($sense, 260, 8);
                $msg  = "Ctx detach failed with krc = $krc";
    }
    elsif ($errnum eq '00000E02')
    {
                $msg  = "Adapter fatal error detected";
    }
    elsif ($errnum eq '0000060F')
    {
                my $fc_port = &bytes($sense, 263, 1);
                $msg  = "Async LOGO received on FC port $fc_port.";
    }
    elsif ($errnum eq '00000E03')
    {
                my $krc = &bytes($sense, 260, 8);
                $msg  = "Failed to detach kctx. krc is $krc";
    }
    elsif ($errnum eq '00000D02')
    {
                $msg  = "Command timeout";
    }
    else
    {
        $msg = "Unknown error number: " . $errnum;
    }

    if ($ERRNUMS)
    {
            $msg = "$errnum: $msg";
    }

    printf("%s", $msg);
}

# ---------------------------------------------------------------------------
# LABEL:          INIT_RAPID
# IDENTIFIER:     3A30359F
# 
# [...]
# 
# Detail Data
# SOFTWARE ERROR CODE
# Command is respawning too rapidly. Check for possible errors.
# COMMAND
# id:  tsm1 "/usr/bin/dsmc sched -optfile=/usr/tivoli/tsm/client/oracle/...
# ---------------------------------------------------------------------------
sub INIT_RAPID
{
	my @error	= @_;
	my $desc	= "unknown";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^COMMAND/)
		{
			$desc = $error[$i + 1];
			chomp($desc);
			last;
		}
	}

	printf("%s", $desc);
}


#---------------------------------------------------------------------------
#LABEL:          ISCSISW_ERR2
#
#[...]
#
#Detail Data
#SENSE DATA
#0000 0000 0000 40C6 0000 0302 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000
#0000 0000 0A0A 0101 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000 0000 0000
#0001 0204 0000 0000 0000 000A 0000 0000 0000 0030 0000 0000 0000 0000 0000 0000
#0000 0001 F100 0100 2D50 5000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#[...]

# New format
#Detail Data
#SENSE DATA
#0000 40C6 8704 0302 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 AC1B

#---------------------------------------------------------------------------
sub ISCSISW_ERR
{
	my @error = @_;

	my $sense   = &get_sense_data(@error);
	my $logtype = &nibbles(&shorts($sense, 3, 1), 0, 1);
	# my $errnum  = &nibbles(&shorts($sense, 3, 1), 1, 3);
    my $errnum  = &nibbles(&shorts($sense, 1, 1), 1, 3);


	my $msg = "";

	if    ($errnum eq '001')
	{
	}
	elsif ($errnum eq '0C6')
	{
        my $sc = &bytes($sense, 7, 1);
        my $sd = &bytes($sense, 6, 1);

		$msg = "Unknown status class ($sc) or detail ($sd) in ";
		$msg .= "login response";
	}
    elsif ($errnum eq '0C9')
    {
        $msg = "Debug: cmd does not exist in response processing; noop";
    }
    elsif ($errnum eq '0EB')
    {
        my $ae = &bytes($sense, 7, 1);
        $msg = "Unknown Asynchronous Message PDU recieved from the Target ($ae)";
    }
    elsif ($errnum eq '0EC')
    {
        # my $nip = &hex2ipaddr(&bytes($sense, 1, 2));
        $msg = "Relogin connection timeout to Target";
    }




	printf("%s", $msg);

	return;
}


#
# Filesystem error handling
#
# The various filesystem errors will log any of the data items below.
# The list was generated with the following command:
#
# $ errpt -a -t | awk '/^-----/       {f=0}
#                      /Label: J[F2]/ {f++; next}
#                      /Detail Data/  {f++; next}
#                      f==2           {print}' | sort -u
#
# -----------------------------------------
# ADDITIONAL INFORMATION
# BLOCK NUMBER
# BUF STRUCTURE B_FLAGS
# CALLER
# DETECTING MODULE
# DIRECTORY
# ERROR CODE
# FILE NAME
# FILE SYSTEM DEVICE
# FILE SYSTEM DEVICE AND MOUNT POINT
# INODE NUMBER
# JFS2 ERROR LOG FLAG
# JFS2 LOG MAJOR/MINOR DEVICE NUMBER
# JFS2 MAJOR/MINOR DEVICE NUMBER
# LINE NO.
# LINE NUMBER
# MAJOR/MINOR DEVICE NUMBER
# PROGRAM NAME
# RESOLUTION STATE
# SNAPSHOT MAJOR/MINOR DEVICE NUMBER
# Snapshot Major/Minor device number
# USER'S PROCESS ID:
# -----------------------------------------
sub JFS_general
{
	my @error	= @_;
	my $errno	= "";
	my $fs		= "";
	my $fn		= "";
	my $log		= "";
	my $mm		= "";
	my $snap	= "";
	my $msg		= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^ERROR CODE/)
		{
			my $e;
			$_ = $error[$i+1];
			s/\s//g;
			chomp;
			$e = &hex2int($_);
			$errno = &lookup("errno ", $e, \%aix_errno_lt);
		}

		if ($error[$i] =~ /^FILE NAME/)
		{
			$_ = $error[$i+1];
			s/^\s+//g;
			chomp;
			$fn = "Filename $_";
		}

		if ($error[$i] =~ /^FILE SYSTEM DEVICE/)
		{
			$_ = $error[$i+1];
			s/^\s+//g;
			chomp;
			$fs = "Filesystem $_";
		}

		if ($error[$i] =~ /^JFS2 LOG MAJOR/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$log = "Log device $_";
		}

		if ($error[$i] =~ /^JFS2 MAJOR/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$mm = "Device $_";
		}

		if ($error[$i] =~ /^MAJOR\/MINOR DEVICE/)
		{
			$_ = $error[$i+1];
			my ($maj,$min) = split /\s+/;
			$mm = "Device $maj$min";
			$mm .= " (" . hex2int($maj) . "," . hex2int($min) . ")";
		}

		if ($error[$i] =~ /^SNAPSHOT MAJOR/ ||
		    $error[$i] =~ /^Snapshot Major/)
		{
			$_ = $error[$i+1];
			s/\s+//g;
			chomp;
			$snap = "Snapshot device $_";
		}

	}

	$msg = "$fn $fs $log $mm $snap $errno";
	$msg =~ s/^\s+//g;
	$msg =~ s/\s+/ /g;
	printf("%s", $msg);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          KERNEL_ABEND
#
#[...]
#
#Detail Data
#ABEND CODE
#EEEE 0000 9627 B051 
#ABEND DETAIL
#0000 0000 0000 0000 
#ABEND CALLER
#0000 0000 000F 62C8 
#MACHINE STATE REGISTER, MSR
#8000 0000 0002 1032 
#---------------------------------------------------------------------------
sub KERNEL_ABEND
{
	my @error	= @_;
	my $krc		= "(unknown)";
    my $msg     = "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^ABEND CODE/)
		{
			$krc = $error[$i + 1];
			chomp($krc);
			$krc =~ s/\s+//g;
            $msg = &lookup("", $krc, \%kernel_abend_lt);
            if ($msg eq $krc)
            {
                $msg = ""
            }

			last;
		}
	}

	printf("%s %s", $krc, $msg);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          KERNEL_PANIC
#IDENTIFIER:     225E3B63
#Class:           S
#Type:            TEMP
#WPAR:            Global
#Resource Name:   PANIC
#Description
#SOFTWARE PROGRAM ABNORMALLY TERMINATED
#Detail Data
#ASSERT STRING
#PANIC STRING
#DMS occurred: cur time = 35403425s, last reset = 35403335s, reset interval = 90s
#---------------------------------------------------------------------------
sub KERNEL_PANIC
{
	my @error	= @_;
	my $panic	= "SOFTWARE PROGRAM ABNORMALLY TERMINATED";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^PANIC STRING/)
		{
			chomp($panic = $error[$i + 1]);
			last;
		}
	}

	printf("%s", $panic);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          LDMP_COMPLETE
#
#[...]
#
#Description      
#Live dump complete
#
#Detail Data      
#File name and message text
#/var/adm/ras/livedump/emfcdd.fcs1.202107120018.01.DZ
#emfcdd.fcs1:  data size was truncated to 0x800000
#
#---------------------------------------------------------------------------
sub LDMP_COMPLETE
{
	my @error	= @_;
	my $dmpfile	= "(unknown)";
    my $trunc   = "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^File name and message text/)
		{
			$dmpfile = $error[$i + 1];
			chomp($dmpfile);
		}

        if ($error[$i] =~ /truncated/)
        {
            $trunc = "data size was truncated";
        }
	}

	printf("%s %s", $dmpfile, $trunc);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          LDMP_DUMPERR
#
#[...]
#
#Detail Data
#Error code
#EEEE 0000 8C22 082E 
#Message text
#
#---------------------------------------------------------------------------
sub LDMP_DUMPERR
{
	my @error	= @_;
	my $krc		= "(unknown)";
	my $msg		= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^Error code/)
		{
			$krc = $error[$i + 1];
			chomp($krc);
			$krc =~ s/\s+//g;
		}

		if ($error[$i] =~ /^Message text/)
		{
			$msg = $error[$i + 1];
			chomp($msg);
		}
	}

	printf("%s %s", $krc, $msg);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          LDMP_PASSTIME
#
#[...]
#
#Description
#System freeze time advisory exceeded
#
#Detail Data
#Advisory value in milliseconds
#         100
#TIMEOUT
#           0
#COMPONENT ID
#emfcdd.fcs1_ct
#---------------------------------------------------------------------------
sub LDMP_PASSTIME
{
	my @error	= @_;
	my $comp	= "(unknown)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^COMPONENT ID/)
		{
			$comp = $error[$i + 1];
			chomp($comp);
			last;
		}
	}
	printf("Component %s exceeded freeze time", $comp);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          LOST_EVENTS
#
#[...]
#
#Detail Data
#ERROR ID OF FIRST EVENT DISCARDED
#D0EAC662
#ERROR ID OF LAST EVENT DISCARDED
#D0EAC662
#NUMBER OF EVENTS DISCARDED
#10
#---------------------------------------------------------------------------
sub LOST_EVENTS
{
	my @error	= @_;
	my $num_lost	= "(unknown)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^NUMBER OF EVENTS DISCARDED/)
		{
			$num_lost = $error[$i + 1];
			chomp($num_lost);
            $num_lost =~ s/\s+//g;
			last;
		}
	}
	printf("%s events lost", $num_lost);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          LVM_GS_RLEAVE
# IDENTIFIER:     AB59ABFF
# 
# [...]
# 
# Detail Data
# Remote Node Name
# t3scp01p
# Volume Group ID
# 0004 3BA2 0000 D900 0000 011C 9257 CF53 
# MAJOR/MINOR DEVICE NUMBER
# 01F5 0000 
# SENSE DATA
# 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ...
# ---------------------------------------------------------------------------
sub LVM_GS_RLEAVE
{
	my @error	= @_;
	my $remote	= "(unknown)";
	my $vgid	= "(unknown)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^Remote Node Name/)
		{
			$remote = $error[$i+1];
			chomp($remote);
			next;
		}

		if ($error[$i] =~ /^Volume Group ID/)
		{
			$vgid = $error[$i+1];
			chomp($vgid);
			$vgid =~ s/\s+//g;
			next;
		}
	}

	printf("Node: %s  VGID: %s", $remote, $vgid);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          LVM_IO_FAIL
#
#[...]
#
#Detail Data
#PHYSICAL VOLUME DEVICE MAJOR/MINOR
#8000 0028 0000 0052 
#ERROR CODE AS DEFINED IN sys/errno.h
#         110
#BLOCK NUMBER
#              95289488
#LOGICAL VOLUME DEVICE MAJOR/MINOR
#8000 0043 0000 0006 
#PHYSICAL BUFFER TRANSACTION TIME
#                     1
#RESIDUAL COUNT
#                  8192
#NUMBER OF BLOCKS
#                  8192
#I/O TYPE
#USER DATA     
#SENSE DATA
#0000 0000 0002 D700 0023 8BDB 0000 4C00 0000 0117 95F5 AEFC 00CD D08F 4837 5995
#0000 0000 0000 0000 
#---------------------------------------------------------------------------
sub LVM_ERR
{
	my @error = @_;
	my $pv    = "";
	my $lv    = "";
	my $dev   = "";
	my $errno = "";
	my $block = "";
	my $msg   = "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /PHYSICAL VOLUME DEVICE MAJOR/)
		{
			$_ = $error[$i+1];
			s/\s//g;
			chomp;
			$pv = "PV $_";
		}

		if ($error[$i] =~ /LOGICAL VOLUME DEVICE MAJOR/)
		{
			$_ = $error[$i+1];
			s/\s//g;
			chomp;
			$lv = "LV $_";
		}

		if ($error[$i] =~ /^MAJOR\/MINOR DEVICE NUMBER/)
		{
			$_ = $error[$i+1];
			s/\s//g;
			chomp;
			$dev = "Device $_";
		}

		if ($error[$i] =~ /^ERROR CODE/)
		{
			$_ = $error[$i+1];
			s/\s//g;
			chomp;
			$errno = &lookup("errno ", $_, \%aix_errno_lt);
#			$errno = "errno $_";
		}

		if ($error[$i] =~ /^BLOCK NUMBER/)
		{
			$_ = $error[$i+1];
			s/\s//g;
			chomp;
			$block = "Block " . &int2hex($_, 8);
		}
	}

	$msg = "$lv $pv $dev $block $errno";
	$msg =~ s/^\s+//g;
	$msg =~ s/\s+/ /g;
	printf("%s", $msg);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          OPMSG
# IDENTIFIER:     AA8AB241
# 
# [...]
# 
# Detail Data
# MESSAGE FROM ERRLOGGER COMMAND
# --- HTX Stopped ---
# ---------------------------------------------------------------------------
sub OPMSG
{
	my @error	= @_;

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^MESSAGE FROM ERRLOGGER COMMAND/)
		{
			$_ = $error[$i + 1];
			# Sometimes there is a blank line separator
			if ( /^\s*$/ )
			{
				$_ = $error[$i + 2];
				if ( /-{66}/ or /^LABEL/ )
				{
					# Went too far, message is blank
					$_ = "";
				}
			}
			chomp;
			printf("%s", $_);
			return
		}
	}
}


#---------------------------------------------------------------------------
#LABEL:          PCI_RECOVERABLE_ERR
#
#[...]
#
#Detail Data
#BID
#9000 00DF 
#DEVFUNC
#0000 0008 
#RTAS TOKEN
#0000 0036 
#ERROR CODE
#1100 0013 
#PROBLEM DATA
#0444 2201 0000 018A 8E00 8300 0842 1400 2007 0710 2000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 4942 4D00 5531 2E35 2D50 312D 4939 0000
#000C 4646 1802 1401 6000 D062 000C 4646 1802 1402 30C6 5200 000C 4646 1802 1404
#---------------------------------------------------------------------------
sub PCI_err
{
	my @error	= @_;
	my $msg		= "";
	my $bid		= "(unknown)";
	my $err		= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^BID/)
		{
			$bid = $error[$i + 1];
			chomp($bid);
			$bid =~ s/\s+//g;

			$msg = "Bus ID " . $bid;
			next;
		}

		if ($error[$i] =~ /^ERROR CODE/)
		{
			$err = $error[$i + 1];
			chomp($err);
			$err =~ s/\s+//g;

			$msg .= " " . &lookup("Error ", $err,
						\%plat_eeh_err_lt);
			next;
		}
	}
	printf("%s", $msg);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          PGSP_KILL
# IDENTIFIER:     C5C09FFA
# Description
# SOFTWARE PROGRAM ABNORMALLY TERMINATED
# Probable Causes
# SYSTEM RUNNING OUT OF PAGING SPACE
# Failure Causes
# INSUFFICIENT PAGING SPACE DEFINED FOR THE SYSTEM
# PROGRAM USING EXCESSIVE AMOUNT OF PAGING SPACE
#        Recommended Actions
#        DEFINE ADDITIONAL PAGING SPACE
#        REDUCE PAGING SPACE REQUIREMENTS OF PROGRAM(S)
# Detail Data
# PROGRAM
# lqueryvg
# USER'S PROCESS ID:
#              21823644
# PROGRAM'S PAGING SPACE USE IN 1KB BLOCKS
#         136
# ---------------------------------------------------------------------------
sub PGSP_KILL
{
	my @error	= @_;

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^PROGRAM$/)
		{
			$_ = $error[$i + 1];
			chomp;
			printf("%s", $_);
			return
		}
	}
}


#---------------------------------------------------------------------------
#LABEL:          REBOOT_ID
#IDENTIFIER:     2BFA76F6
#
#Description
#SYSTEM SHUTDOWN BY USER
#
#Probable Causes
#SYSTEM SHUTDOWN
#
#Detail Data
#USER ID
#           0
#0=SOFT IPL 1=HALT 2=TIME REBOOT
#           0
#TIME TO REBOOT (FOR TIMED REBOOT ONLY)
#           0
#---------------------------------------------------------------------------
sub REBOOT_ID
{
    my @error   = @_;
    my $userid  = "user unknown";
    my $ipltype = "type unknown";
    my $program = "";
    my $parent  = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^USER ID/)
        {
            chomp($userid = $error[$i + 1]);
        }
        elsif ($error[$i] =~ /^0=SOFT IPL/)
        {
            chomp($ipltype = $error[$i + 1]);

            if  ($ipltype == 0)
            {
                $ipltype = "SOFT IPL"
            }
            elsif ($ipltype == 1)
            {
                $ipltype = "HALT"
            }
            elsif ($ipltype == 2)
            {
                $ipltype = "TIME REBOOT"
            }
            else
            {
                $ipltype = "UNKNOWN"
            }
        }
        elsif ($error[$i] =~ /^PROGRAM NAME/)
        {
            chomp($program = $error[$i + 1]);
            $program =~ s/\s+//g;
        }
        elsif ($error[$i] =~ /^PARENT PROGRAM NAME/)
        {
            chomp($parent = $error[$i + 1]);
            $parent =~ s/\s+//g;
        }
    }
    printf("USERID=%d  (%s) %s %s", $userid, $ipltype, $program, $parent);

    return;
}

#---------------------------------------------------------------------------
#LABEL:          SAS_ERR4
#
#[...]
#
#Detail Data
#
#ADDITIONAL HEX DATA
#DD00 [...]
#[...]
#---------------------------------------------------------------------------
sub SAS_ERR
{
	my @error = @_;
	my $sense = &get_sense_data(@error);
	my $driver = &bytes($sense, 0, 2);

	#
	# A few drivers use this error log, with different indicators:
	#
	# DD00  - LSI SAS protocol driver
	# DD01  - LSA SAS adapter driver
	# other - SIS SAS protocol driver
	#

	if ($driver eq 'DD00')
	{
		&SAS_ERR_LSI_proto(@error);
	}
	elsif ($driver eq 'DD01')
	{
		&SAS_ERR_LSI_adap(@error);
	}
	else
	{
		&SAS_ERR_SIS_proto(@error);
	}

	return;
}


#---------------------------------------------------------------------------
#LABEL:          SAS_ERR4
#IDENTIFIER:     F3D304A2
#
#[...]
#
#Detail Data
#
#ADDITIONAL HEX DATA
#DD00 021B 0000 0030 [...]
#[...]
#---------------------------------------------------------------------------
sub SAS_ERR_LSI_proto
{
	my @error = @_;

	my $sense = &get_sense_data(@error);

	my $errnum = &bytes($sense,   4, 4);
	my $errno  = &hex2int(&bytes($sense, 8, 4));	# often an errno value
	my $ss     = &bytes($sense,  20,  1);		# SCSI status
	my $as     = &bytes($sense,  21,  1);		# Adapter status
	my $lun    = &bytes($sense,  24,  8);

	my $msg = "";

	if    ($errnum eq 'xxxxxxxx')
	{
		$msg = "Huh?";
	}
	elsif ($errnum eq '00000030')
	{
		$msg = "Request for LUN $lun finished w/ ";
		$msg .= &lookup("adapter status ", $as, \%aix_s3_adap_stat_lt);
	}
	elsif ($errnum eq '00000016')
	{
		$msg = "LUN $lun reset per head driver request";
	}
	elsif ($errnum eq '0000004C')
	{
		$msg = "Driver-issued task mgmt failure; ";
		$msg .= &lookup("errno ", $errno, \%aix_errno_lt);
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	printf("%s", $msg);

	return;
}


#---------------------------------------------------------------------------
#LABEL:          SAS_ERR4
#IDENTIFIER:     F3D304A2
#
#[...]
#
#Detail Data
#
#ADDITIONAL HEX DATA
#DD01 021B 0000 0030 [...]
#[...]
#---------------------------------------------------------------------------
sub SAS_ERR_LSI_adap
{
	my @error = @_;

	my $sense = &get_sense_data(@error);

	my $errnum = &bytes($sense, 4, 4);

	my $msg = "";

	if    ($errnum eq 'xxxxxxxx')
	{
		$msg = "Huh?";
	}
	else
	{
		$msg = "Unknown error number: " . $errnum;
	}

	printf("%s", $msg);

	return;
}


#LABEL:      SISSAS_ERR11TD
#IDENTIFIER: 54E8A127
#
#Detail Data
#PROBLEM DATA
#0000 0800 0004 0000 0000 0000 0000 0000 0000 0000 1910 00F0 0144 8100 0101 0000
#0422 0010 0000 0011 57B3 FFF6 5000 C500 1AB7 8223 0000 0000 0000 0000 0000 0000
#
#REASON FOR FAILURE
#Device detected hardware error
#
#DISK INFORMATION
#Resource  Vendor/Product ID S/N      World Wide ID
#00040000  IBM      ST930060 6SE07P8G 5000C5001AB78223
#
#SENSE DATA
#F000 0481 9D9E 0018 0000 0000 4200 1500 0000 0000 0442 0015 FFFF FFFF FFFF 0000
#
#ADDITIONAL HEX DATA
#E210 0080 1100 0000 0940 0003 0057 EDE0 0000 0000 0000 07E8 0144 8100 0004 0000
#FFFF FFFF 1105 0EA8 F000 0481 9D9E 0018 0000 0000 4200 1500 0000 0000 0442 0015



sub get_add_hex_data_sense
{
    my @error = @_;
    my $sense = "";

    my $done = 0;

    #
    # Search backwards from the bottom of the error so that we
    # find only the last batch of sense data.
    #
    for (my $i = $#error; $i >= 0; $i--)
    {
        if ($error[$i] =~ /^ADDITIONAL HEX DATA/ ) 
        {
            # Found the start of the SENSE DATA; grab it all
            # then get out.

            for (my $j = $i + 1; $j <= $#error; $j++)
            {
                $sense = $sense . $error[$j];
            }
            last;
        }
    }

    $sense =~ s/\s+//g;

    return $sense;
}

sub get_problem_data_sense
{
    my @error = @_;
    my $sense = "";

    #
    # Search backwards from the bottom of the error so that we
    # find only the last batch of sense data.
    #
    for (my $i = $#error; $i >= 0; $i--)
    {
        if ($error[$i] =~ /^PROBLEM DATA/)
        {
            # Found the start of the SENSE DATA; grab it all
            # then get out.

            for (my $j = $i + 1; $j <= $#error; $j++)
            {
                $sense = $sense . $error[$j];
            }
            last;
        }
    }

    $sense =~ s/\s+//g;

    return $sense;
}

sub get_disk_info
{
    my @error = @_;
    my $disk_info = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^DISK INFORMATION/)
        {
            $_ = $error[$i+2];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
                $fields[$i] =~ s/^F*(.)/$1/;
            }

            $disk_info = join(' ', @fields);
            $disk_info =~ s/^\s*//;
            $disk_info =~ s/\s*$//;
            $disk_info =~ s/0+$//;
        }
    }
    return $disk_info;
}


#---------------------------------------------------------------------------
# LABEL:          SAS_ERR3
# IDENTIFIER:     12296806
#
# [...]
#
# Detail Data
#
# ADDITIONAL HEX DATA
# 0000 019C 0000 4400 0000 0000 0000 0000 0000 0000 1910 0120 0405 0000 ....
# [...]
#
# or 
#
# ADDITIONAL HEX DATA
# 0001 0800 1910 0011 0444 8200 0101 0000 1951 2300 0000 0200 57B4 8150 0000 0000
#
# or 
#
# Detail Data
# PROBLEM DATA
# 0000 0800 0000 4500 0000 0000 0000 0000 0000 0000 1910 00F0 0144 8100 0101 0000
# 0420 003F 0000 0011 2BD9 FFF6 5000 C500 1722 67AF 0000 0000 0000 0000 0000 0000
#
# or
#
# ADDITIONAL HEX DATA
# 0001 01FC 1910 00D0 0000 0000 0101 0000 1651 9500 0000 0100 0000 0000 0000 0000
# FEFF FFFF FFFF FFFF 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#
# 
#---------------------------------------------------------------------------

sub SAS_ERR_SIS_proto
{
	my @error = @_;
	my $problem_data_sense  = &get_problem_data_sense(@error);
    my $hex_data_sense      = &get_add_hex_data_sense(@error);
    my $disk_info           = &get_disk_info(@error);


    my $resource = "";
    my $prc      = "";
    my $ioasc   = "";
    my $msg     = "";    
    my $ccin    = "";
    my $sense   = "";

    my $loc = 0;

    my $prc_loc_right   = "";
    my $prc_loc_left    = "";

    my ($cur, $sk, $ascq);

    my $pb_prc_loc_right = "";
    my $pb_prc_loc_left = "";

    # * 
    #   The PRC location can be in 2 different locations and under 
    #   either sense locations ADDITIONAL HEX DATA or PROBLEM DATA
    #   Lets figure that out first !
    # *

    if ($problem_data_sense )
    {
        $prc_loc_right = &bytes($problem_data_sense, 20, 2);
        $prc_loc_left = &bytes($problem_data_sense, 4, 2);

        if ($prc_loc_right eq '1910' )
        {
            $sense = $problem_data_sense ;
            $loc = 1;
        }
        elsif ($prc_loc_left eq '1910' )
        {
            $sense = $problem_data_sense ;
            $loc = 2;
        }
    }
    elsif(($hex_data_sense) && ($loc eq '0' ))
    {
        $prc_loc_right = &bytes($hex_data_sense, 20, 2);
        $prc_loc_left = &bytes($hex_data_sense, 4, 2);

        if ($prc_loc_right eq '1910' )
        {
            $sense = $hex_data_sense ;
            $loc = 1;
        }
        elsif ($prc_loc_left eq '1910' )
        {
            $sense = $hex_data_sense ;
            $loc = 2;
        }
    }
    else
    {
        # *
        #  Could not find the PRC. If possiable print out some useful info !
        # *

        if($disk_info)
        {
            $msg .= " $disk_info";
        }
        return;
    }

    # *  
    #  We must have found the PRC location in the sense data 
    #  Depending on location lest see if we can print more info
    # * 

    if ($loc eq '1')
    {
        $resource    = &bytes($sense,  4, 4);

        $prc     = &bytes($sense, 20, 4);
        $ioasc   = &bytes($sense, 24, 4);
        $ccin    = &bytes($sense,  40, 2);

        $msg = "Resource: $resource  ";

        $msg = "CCIN: $ccin ";
        $msg .= "PRC: $prc ";

    }
    elsif ($loc eq '2')
    {

	    $resource	= &bytes($sense,  4, 4);

	    $prc		= &bytes($sense, 4, 4);

	    $ioasc	= &bytes($sense, 8, 4);

	    $msg = "Resource: $resource  ";

        $ccin   = &bytes($sense,  24, 2);

        $msg = "CCIN: $ccin ";
        $msg .= "PRC: $prc ";

    }
    elsif ($loc eq '0')
    {

        # *
        #  Just in case we didnt catch it above we will here as well. 
        # *

        if($disk_info)
        {
            $msg .= " $disk_info";
        }
        return; 
    }


	if($ioasc eq '00000000')
	{
		# Zero IOASC means check PRC

		$msg .= "PRC: $prc";
	}
	elsif ($ioasc eq '01080000')
	{
		$msg .= "Soft device bus error recovered by adapter";
	}
	elsif ($ioasc eq '04050000')
	{
		$msg .= "Addressed device failed to respond to selection";
	}
    elsif ($ioasc eq '04080100')
    {
        $msg .= "Hardware error, IOA timed out the device / command";
    }
    elsif ($ioasc eq '04448200')
    {
        $msg .= "Hardware Error, IOA error; check for old FW level";
    }
	elsif ($ioasc eq '066B9100')
	{
		$msg .= "Multipath redundancy level got better";
	}
	elsif ($ioasc eq '066B9200')
	{
		$msg .= "Multipath redundancy level got worse";
	}


	if($ioasc ne '00000000')
	{
        # *
        #  Most of the ascq's are vendor unique. Try to decode what we can
        # *

		$msg .= " IOASC: $ioasc ";

        $cur  = &bytes($ioasc, 0, 1);
        $sk   = substr(&bytes($ioasc, 0, 1), 1, 1);
        $ascq = &bytes($ioasc, 2, 2);

        $msg .= " " . &lookup("Key ", $sk, \%scsi_skey_lt);

	}

    if($disk_info)
    {
        $msg .= " $disk_info";
    }

	printf("%s", $msg);

	return;
}


# ---------------------------------------------------------------------------
#LABEL:          SCAN_ERROR_CHRP
#IDENTIFIER:     BFE4C025
#[...]
#Description
#UNDETERMINED ERROR
#Failure Causes
#UNDETERMINED
#        Recommended Actions
#        RUN SYSTEM DIAGNOSTICS.
#Detail Data
#PROBLEM DATA
#0644 00E0 0000 066C 8E00 8E00 0000 0000 0000 0000 4942 4D00 5048 0030 0100 8B00 
#0000 8B00 3235 352E 3235 352E 3235 352E 3000 0000 
#Diagnostic Analysis
#Diagnostic Log sequence number: 1234
#Resource tested:        sysplanar0
#Resource Description:   System Planar
#Location:               
#SRC:                    B1A38B24
#Description:            External environment Predictive Error, general. Refer
#                        to the system service documentation for more
#                        information.
#Additional Words:       2-030000F0 3-2BAA1110 4-C1F720FF 5-400000FF
#                        6-0A000019 7-FFFFFF00 8-0A00001E 9-FFFFFF00
#Possible FRUs:
#    Priority: H Maintainence Procedure: FSPSP65 
#    Location: n/a
# ---------------------------------------------------------------------------
sub SCAN_ERROR_CHRP
{
	my @error	= @_;
	my $src		= "(no SRC found)";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^SRC:/)
		{
			$src = $error[$i];
			chomp($src);

            $src =~ s/^SRC://g;
    
			$src =~ s/\s+//g;
            $src =~ s/\s+$//g;

			last;
		}
	}

    if ($src && $src ne '(no SRC found)' )
    {
        $src = &lookup("", $src, \%scan_err_src_lt);
    }


	printf("SRC: %s", $src);

	return;
}

#---------------------------------------------------------------------------
#LABEL:          SC_DISK_ERR4
#
#[...]
#
#Detail Data
# PATH ID
#           0
#SENSE DATA
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 032A 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 B507 0006 3E40 0000 0002 0000 0000 0000 0000 0000 0003 0000
#---------------------------------------------------------------------------
sub SC_DISK_ERR
{
	my @error = @_;
	my $label  = &get_label(@error);
	my $path   = &get_path_id(@error);
	my $sense  = &get_sense_data(@error);
	
	if (defined($path))
	{
		printf("path %2s ", $path);
	}

	if ($label =~ /SC_DISK_ERR7/)
	{
		#
		# Earlier driver levels didn't include useful
		# information with this error, so we would just
		# print "path failure" and return.  But now the
		# drivers common in the field include normal SENSE
		# DATA, so continue processing after noting the
		# path failure.
		#
		printf("path failure; ");
	}

	#
	# Break out SC_DISK_PCM_ERR altogether someday
	#

	if ($label =~ /SC_DISK_PCM_ERR2 /) {
		printf("controller switch");
		return;
	}

	if ($label =~ /SC_DISK_PCM_ERR22/) {
		printf("path disabled");
		return;
	}

	if ($label =~ /SC_DISK_PCM_ERR8/) {
		printf("path failure");
		return;
	}

	if ($label =~ /SC_DISK_PCM_ERR9/) {
		printf("path recovered");
		return;
	}

	#
	# Extract and print the SCSI command information
	#

	my $cdb = &bytes($sense, 2, 16);

    my $scsi_cdb_len = &bytes($sense,  0,   1);

    my $sv  = &bytes($sense, 24, 1);

    if ($scsi_cdb_len eq '00' && $sv eq '03' )
    {
        #
        # All dk_driver errors should land here
        # 

        my $msg = "DK_DRIVER Error ";

        my $ss  = &bytes($sense, 25, 1);

        $msg .= &lookup("", $ss, \%aix_scdisk_stat_lt);

        if ( $ss eq '00' )
        {
            #
            # scsidisk ras errors land here
            # 

            my $cnt  = &bytes($sense, 228, 2);
            $msg .= "; " . &lookup("Ras Err", $cnt, \%aix_scdisk_ras_err_lt);
            print "$msg";

            return;
        }
        elsif ($ss eq '01' || $ss eq '08')
        {
            # 
            # Some mode sense corrupt errors we can print additional info
            # 

            my $page            = &bytes($cdb, 1, 1);
            my $page_length     = &bytes($cdb, 2, 2);
            my $offset          = &bytes($cdb, 4, 2);
            my $sense_length    = &bytes($cdb, 6, 2);

            my $sense_buf       = &bytes($sense, 28, 14);

            # CDB 0028160D000A00080000000000000000

            # page              = scsi_bytes[0]
            # p_length          = scsi_bytes[1]
            # offset            = scsi_bytes[3]
            # sense_length      = scsi_bytes[5]
            # autosense_buffer_ptr = sense_buf

            print &lookup("Driver status ", $ss , \%aix_scdisk_stat_lt );

            print " page "          .   $page;
            print " p_length "      .   $page_length;
            print " offset "        .   $offset;
            print " sense_length "  .   $sense_length;
            print " sense_buf "     .   $sense_buf ;

            return;
        }
        elsif ( $ss eq 'A9' )
        {
            #
            # scsidisk strat errors land here 
            #

            my $cnt  = &bytes($sense, 86, 1);

            $msg .= "; " . &lookup("Strat Err", $cnt, \%aix_scdisk_strat_err_lt);

            print "$msg";

            return;
        }
        else
        {
            #
            # No further decoding needed - End of driver errors 
            #

            print "$msg";

            return;
        }

        return;
    }

	print &sbc_command($cdb) . " ";

	#
	# Now the SS/VV/AA section
	#

	my $ss  = &bytes($sense, 25, 1);
	my $as  = &bytes($sense, 26, 1);
	my $r3	= &bytes($sense, 27, 1);
	my $lbac = &bytes($sense, 54, 2);

	if ($sv eq '01')
	{
		print &lookup("SCSI status ", $ss, \%scsi_status_lt);
	}
	elsif ($sv eq '02')
	{
		print &lookup("Adapter status ", $as, \%aix_s3_adap_stat_lt);
	}
	elsif ($sv eq '03' && $label =~ /^SC_DISK/)
	{
		print &lookup("Driver status ", $ss, \%aix_scdisk_stat_lt);
	}
	elsif ($sv eq '04' && $label =~ /^FCP_ARRAY/)
	{
		print &lookup("Driver status ", $r3, \%aix_rdac_stat_lt);
	}
	
	#
	# And the SCSI sense data if this was a CHECK or if a
	# REQUEST SENSE (CDB opcode 03) just finished.  In the
	# REQUEST SENSE case, only attempt the decode if the
	# Sense Data Response Code looks sane.
	#

	my $cdb_opcode = &bytes($cdb, 0, 1);
	my $autosense  = &bytes($sense, 28, 14);
	my $rsp_code   = &bytes($autosense, 0, 1);

	if (($sv eq '01' && $ss eq '02') ||
	   (($cdb_opcode eq '03') &&
	    ($rsp_code eq '70' ||
	     $rsp_code eq '71' ||
	     $rsp_code eq '72' ||
	     $rsp_code eq '73' ||
	     $rsp_code eq 'F0')))
	{
		print " " . &scsi_sense($autosense, $rsp_code);
	}

	# *
	#   If this is a serial number mismatch, then print the
	#   old and new serial numbers
	# *

	if ($sv eq '03' && $ss eq '0F')
	{
		my $LEN = 84;

		my $old = &bytes($sense, 28, $LEN);
		my $new = &bytes($sense, 28 + $LEN, $LEN);

		print "; Old: $old; New: $new"
	}


    # *
    #   Check to see if this errpt supports cmd_history 
    # *

    if ( $sense !~ /FFFFFFFF/)
    {
        return;
    }

    my $eos  = &bytes($sense, 230, 4);

    if (! defined $eos)
    {
         return;
    }

    if ( $eos eq 'FFFFFFFF' && $scsi_cdb_len ne '00' ) 
    {
        &process_dkcmd_history(@error)
    }

    return;
}


#######################################################
# 
# LABEL:          SC_DISK_ERR3
# IDENTIFIER:     C62E1EB7
# [ ... ]
#
# Detail Data
# PATH ID
#            5
# SENSE DATA
# 0600 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0200 0304 0000 0000
# 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
# 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
# 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
# 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
# 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
# 0000 0000 0000 0001 60FC 0004 5B00 0000 0000 0000 0000 0000 0000 0000 0187 0000
# 0012 0035 001A FFFF FFFF 0105 02C5 0203 0000 0501 02C5 0000 0000 0000 0000 0000
# 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
# 0000 0000 0000 0000 0000 0000 0000
#
########################################################

sub process_dkcmd_history
{

    my @error   = @_;
    my $sense  = &get_sense_data(@error);

    my $cmd_status      = 0;
    my $cmd_asc_ascq    = 0;
    my $cmd_path_a      = 0;
    my $cmd_count       = 0;
    my $cmd_time        = 0;


    # The index tells us how many errors we had in the past

    my $cmd_index       = &bytes($sense, 234, 1);

    #
    # This is the head element of the cmd_history array
    #

    if ( $cmd_index ne '00' )
    {
        # sv is our sanity check but we may need another
        my $cmd_sv          = &bytes($sense, 238, 1);

        if ( $cmd_sv eq '00' )
        {
            return;
        }

        #
        # The first 4 bytes define index, path and total cmd_time
        #

        my $last_path        = hex2int(&bytes($sense, 235, 1));
        my $cmd_tot_time    = &bytes($sense, 236, 2);

        $cmd_tot_time       = (hex2int($cmd_tot_time)/10);

        my $msg = "\n                                                 ";

        # debug
        # $msg .= "index $cmd_index last_path $last_path tot_time $cmd_tot_time" ;
        # print "$msg";

        #
        # Grab all 8 cmd history arrays
        #

        my $cmd_array_1     = &bytes($sense, 238, 8);
        my $cmd_array_2     = &bytes($sense, 246, 8);
        my $cmd_array_3     = &bytes($sense, 254, 8);
        my $cmd_array_4     = &bytes($sense, 262, 8);
        my $cmd_array_5     = &bytes($sense, 270, 8);
        my $cmd_array_6     = &bytes($sense, 278, 8);
        my $cmd_array_7     = &bytes($sense, 286, 8);
        my $cmd_array_8     = &bytes($sense, 294, 8);

        my $hist_cmd_arr = 0;

        # Assemble the array elements in rev order so we pull 
        # out the most recient one first.
        #

        my $arr_list = "$cmd_array_8 $cmd_array_7 $cmd_array_6 $cmd_array_5 $cmd_array_4 $cmd_array_3 $cmd_array_2 $cmd_array_1";
        my @hist_cmd_arr = split(' ', $arr_list);

        my $print_detail = 0;

        #
        # NOTE: cmd line option -c sets $CMD_HIST
        # 

        if ( $CMD_HIST )
        {
            $print_detail = 3;
        }

        # *
        #   Verbosity is controlled by using the -c option          
        #   Default output is 0 and will not produce any additional lines
        #   but rather will add only total time. 
        #   Adding the -c flag will produce full cmd history failure 
        #   output adding an additional line for each failure / retry. 
        # *

        if ( $print_detail eq '0' )
        {
            print " ($cmd_tot_time Sec rtry $cmd_index)" ;
            return;
        }
        elsif ( $print_detail eq '1' )
        {
            $msg .= " index $cmd_index path $last_path tot_time $cmd_tot_time sv $cmd_sv status $cmd_status asc $cmd_asc_ascq $cmd_path_a cmd_cnt $cmd_count time $cmd_time" ;
            print "$msg";
            return;
        }
        elsif ( $print_detail eq '2' )
        {
            $msg .= " num indexes $cmd_index retry1 $cmd_array_1 retry2 $cmd_array_2 retry3 $cmd_array_3 retry4 $cmd_array_4"; 
            $msg .= " retry5 $cmd_array_5 retry6 $cmd_array_6 retry7 $cmd_array_7 retry8 $cmd_array_8";
            print "$msg";
            return;
        }
        elsif ( $print_detail eq '3' )
        {
            my $elem = 0000000000000000;

            print " ($cmd_tot_time Sec rtry $cmd_index)" ;

            # *
            #   Emumerate over the array of cmd_history elements and ignore the empty ones.
            #   The index does define how many array elements there are but the unused ones are null.
            #   if this ever changes the approach we use here will need to change. 
            # *

            foreach $elem (@hist_cmd_arr)
            {
                if ( $elem ne '0000000000000000' )
                {
                    $cmd_sv          = &bytes($elem, 0, 1);
                    $cmd_status      = &bytes($elem, 1, 1);
                        
                    # *
                    #   Combining the asc and ascq fields into 1
                    # *

                    $cmd_asc_ascq    = &bytes($elem, 2, 2);

                    $cmd_path_a      = hex2int(&bytes($elem, 4, 1));

                    # *
                    #   Strip out leading 0 in path id and replace with a space
                    #   if this is a single character path id. 
                    # *

                    if ($cmd_path_a =~ m/^[0-9]$/)
                    {
                        $cmd_path_a      =~ s/^0*(.)/ $1/;
                    }

                    $cmd_count       =  hex2int(&bytes($elem, 5, 1));
                    $cmd_time        =  &bytes($elem, 6, 2);
                    $cmd_time        =  (hex2int($cmd_time)/10);

                    my $msg = "\n                                                 ";

                    #
                    # debug
                    # $msg .= "path $cmd_path_a cmd_failure_history: sv $cmd_sv cmd_status $cmd_status /
                    #          asc/ascq $cmd_asc_ascq count $cmd_count time $cmd_time calc_time $calc_cmd_time";
                    #

                    if ( $cmd_sv eq '01' ) # (scsi status)
                    {
                        if ( $cmd_status eq '04' || $cmd_status eq '08' || $cmd_status eq '18' ||
                             $cmd_status eq '28' || $cmd_status eq '30' || $cmd_status eq '40' )
                            {
                                # * 
                                #   Anything other than (scsi check condition), such as scsi busy 
                                #   or aca active (should land here).
                                # *

                                $cmd_status = &lookup("Scsi Status ", $cmd_status, \%scsi_status_lt);

                                $msg        .= "path $cmd_path_a cmd_history: $cmd_status count $cmd_count time $cmd_time";
                            }
                            else # (check condition)
                            {
                                # * 
                                #   This (should) be a (check condition), decode the sense key and asc/ascq
                                #   Note: the asc and ascq fields are combined for lookup.
                                # *

                                $cmd_status     =~ s/^0*(.)/$1/;
                                $cmd_status     = &lookup("sense key", $cmd_status, \%scsi_skey_lt);
                                $cmd_asc_ascq   = &lookup("ascq ", $cmd_asc_ascq, \%scsi_ascq_lt );

                                $msg .= "path $cmd_path_a cmd_history: $cmd_status $cmd_asc_ascq count $cmd_count time $cmd_time";
                            }

                    }
                    elsif ($cmd_sv eq '02') # (adapter status)
                    {
                        # * 
                        #   Only (adapter status) should land here 
                        # * 

                        $cmd_status = &lookup("adap_stat=", $cmd_status, \%aix_s3_adap_stat_lt);
                        $msg .= "path $cmd_path_a cmd_history: $cmd_status count $cmd_count time $cmd_time";

                    }
                    elsif ($cmd_sv eq '03') # (driver status)
                    {
                        # *
                        #   Only (driver status) should land here
                        # *

                        $cmd_status = &lookup("driver_stat=", $cmd_status, \%aix_scdisk_stat_lt);
                        $msg .= "path $cmd_path_a cmd_history: $cmd_status count $cmd_count time $cmd_time";

                    }
                    else # (unknown / unexpected) 
                    {
                        # *
                        #   We should not be here, yet we are ! Display some useful info for debugging.
                        # *

                        $msg .= "path $cmd_path_a cmd_history: status_validity ($cmd_sv) status $cmd_status count $cmd_count time $cmd_time";

                    }

                    print "$msg";
                }

            }

        }
        else # Not a valid verbosity level
        {
            return;
        }

    }

    # Final Exit 
    return;
}

#---------------------------------------------------------------------------
#LABEL:          PHAKE_KENEXT
#
#[...]
#Detail Data
#MINOR DEVICE NUMBER
#Failed to process Auto resync request for MG[ABSDB_mg 9]. rc=11. We may attempt it later.
#
#---------------------------------------------------------------------------
sub PHAKE_KENEXT
{
    my @error = @_;
    my $label  = &get_label(@error);
    my $detail = ""; 

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Detail Data/)
        {
            $_ = $error[$i+2];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
                last;
            }

            $detail = join(' ', @fields);
            $detail =~ s/^\s*//;
            $detail =~ s/\s*$//;
        }
    }


    printf("%s", $detail );

    return;
}


#---------------------------------------------------------------------------
#LABEL:          SC_DISK_PPRC_ERR[1..15]
#
#[...]
#Detail Data
#DEVICE NAME
#hdisk15
#GROUP NAME
#pha_116528110rdg5
#ERROR CODE
#0000 0000 0000 0000 0000 0000 0000 0000
#SENSE DATA
#0000 0000 FFFF 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0001 580C 0000 0000 0001 488C 0000 0000 0000
#0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#...
#---------------------------------------------------------------------------
sub SC_DISK_PPRC_ERR
{
	my @error = @_;
    my $sense  = &get_sense_data(@error);

	my $label  = &get_label(@error);
	my $desc   = &get_description(@error);
	my $group  = &get_group_name(@error);

    my $loc = &bytes($sense, 582, 4);

    my $location = &lookup("", $loc, \%pprc_loc_lt);

    my $ver = &bytes($sense, 2, 2);

    if ( $ver eq  '0101' ) # Group Data 
    {

        my $path_id = &bytes($sense, 6, 2);
        my $path_gpr_id = &bytes($sense, 8, 2);
 
        my $cdb = &bytes($sense, 10, 16);

        my $pprc_dev_state = &bytes($sense, 26, 8);

        my $pprc_grp_state = &bytes($sense, 42, 8);

        my $berror = &bytes($sense, 58, 1);
        my $sv = &bytes($sense, 59, 1);
        my $ss = &bytes($sense, 60, 1);
        my $adp_status = &bytes($sense, 61, 1);
        
	    printf("Grp %s %s %s ", $location, $desc, $group );
        printf(" dev_state %s grp_state %s errno %s ss %s", $pprc_dev_state, $pprc_grp_state, $berror, $ss );        

        # printf("Grp %s %s path_gpr_id %s cdb %s dev_state %s grp_state %s loc %s", $desc, $group, $path_gpr_id, $cdb, $pprc_dev_state, $pprc_grp_state, $location );
    }
    elsif ( $ver eq  '0100' )
    {
        printf("%s %s %s ", $location, $desc, $group );

        #printf("%s %s %s", $desc, $group, $location );

    }
    elsif ( $ver eq  '0000' ) # Dev Data
    {
        printf("%s %s %s ", $location, $desc, $group );

        #printf("Dev %s %s %s", $desc, $group, $location  );
    }
    else
    {
        printf("%s %s %s ", $location, $desc, $group );
        # printf("%s %s loc %s", $desc, $group, $location );

    }


	return;
}

sub SC_TAPE_ERR
{
	my @error = @_;
	my $sense  = &get_sense_data(@error);

    my $rsp_code   = &bytes($sense, 0, 1);

	#
	# Extract and print the SCSI command information
	#

	my $cdb = &bytes($sense, 2, 16);
	print &ssc_command($cdb) . " ";

	#
	# Now the SS/VV/AA section
	#

	my $sv  = &bytes($sense, 24, 1);
	my $ss  = &bytes($sense, 25, 1);
	my $as  = &bytes($sense, 26, 1);

	if ($sv eq '01')
	{
		print &lookup("SCSI status ", $ss, \%scsi_status_lt);
	}
	elsif ($sv eq '02')
	{
		print &lookup("adap_stat=", $as, \%aix_s3_adap_stat_lt);
	}
	
	#
	# And the SCSI sense data if this was a CHECK or if a
	# REQUEST SENSE just finished
	#

	if (($sv eq '01' && $ss eq '02') || (substr($cdb, 0, 2) eq '03'))
	{
        print " " . &scsi_sense(&bytes($sense, 28, 14), $rsp_code);
	}

	return;
}

sub SDDPCM
{
	my @error	= @_;
	my $path	= &get_path_id(@error);

	printf("Path ID %s", $path);

	return;
}

# ---------------------------------------------------------------------------
# LABEL:          SH_LOST_IO
# 
# [...]
# 
# Detail Data
# MAJOR/MINOR DEVICE NUMBER
# 8000 0025 0000 0003 
# TIME STAMP
# 0000 0000 000E 2027 
# NUMBER OF LOST I/O ON DEVICES
#           32
# ---------------------------------------------------------------------------
sub SH_LOST_IO
{
	my @error	= @_;
	my $devno	= "";
	my $timestamp	= "";
	my $num_lost	= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^MAJOR\/MINOR DEVICE NUMBER/)
		{
			$devno = $error[$i + 1];
			chomp($devno);
			$devno =~ s/\s+//g;
		}

		if ($error[$i] =~ /^TIME STAMP/)
		{
			$timestamp = $error[$i + 1];
			chomp($timestamp);
			$timestamp =~ s/\s+//g;

			#
			# Strip leading zeros. Be sure to leave
			# at least one character in the string;
			# i.e. don't strip the whole string if
			# it's all zeros.
			#

			$timestamp =~ s/^0*(.)/$1/;
		}

		if ($error[$i] =~ /^NUMBER OF LOST I\/O ON DEVICES/)
		{
			$num_lost = $error[$i + 1];
			chomp($num_lost);
			$num_lost =~ s/\s+//g;
		}
	}

	printf("devno: %s  Timestamp: %s  Num lost: %s",
		$devno, $timestamp, $num_lost);

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          SRC_RSTRT    -or-
# LABEL:          SRC_SVKO     -or-
# LABEL:          SRC_TRYX
#
# [...]
#
# Detail Data
# SYMPTOM CODE
#          256
# SOFTWARE ERROR CODE
#        -9035
# ERROR CODE
#            0
# DETECTING MODULE
# 'srchevn.c'@line:'222'
# FAILING MODULE
# rpc.lockd
# ---------------------------------------------------------------------------
sub SRC_general
{
	my @error	= @_;
	my $module	= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^FAILING MODULE/)
		{
			$module = $error[$i + 1];
			chomp($module);
			last;
		}
	}

	printf("%s", $module);

	return;
}


sub TAPE_ERR
{
	my @error = @_;
	my $sense  = &get_sense_data(@error);

    my $rsp_code   = &bytes($sense, 0, 1);

	#
	# Extract and print the SCSI command information
	#

	my $cdb = &bytes($sense, 4, 12);
	print &ssc_command($cdb) . " ";

	#
	# Now the SS/VV/AA section
	#

	my $sv  = &bytes($sense, 16, 1);
	my $ss  = &bytes($sense, 17, 1);
	my $as  = &bytes($sense, 18, 1);

	if ($sv eq '01')
	{
		print &lookup("SCSI status ", $ss, \%scsi_status_lt);
	}
	elsif ($sv eq '02')
	{
		# Don't try to decode the adapter status here.  If _AIX_
		# logs the error then it'll be a general_card_status as
		# defined in scsi.h.  But if _Atape_ logs the error then
		# this may be a SCSI-3 device using the adapter_status
		# values in scsi_buf.h.  We can't easily distinguish between
		# the two from the data in the error, so just print the
		# raw value.
		#
		# print &lookup("adap_stat=", $as, \%aix_s2_adap_stat_lt);
		#
		print "Adapter status $as";
	}
	

	#
	# And the SCSI sense data if this was a CHECK or if a
	# REQUEST SENSE just finished
	#
	if (($sv eq '01' && $ss eq '02') || (substr($cdb, 0, 2) eq '03'))
	{
		print " " . &scsi_sense(&bytes($sense, 20, 14), $rsp_code);
	}

	return;
}


# ---------------------------------------------------------------------------
# LABEL:          VFC_CLIENT_FAILURE
# IDENTIFIER:     88E96781
# 
# Date/Time:       Wed Nov  7 06:31:55 CST 2012
# Sequence Number: 4683
# Machine Id:      00F7BD3C4C00
# Class:           S
# Type:            TEMP
# WPAR:            Global
# Resource Name:   vfchost0
#[...]
# Detail Data
# ADDITIONAL INFORMATION
#    module: npiv_do_async %I%    rc: 00000000FFFFFFF5    location: 00001300
#    data:  10000015 13000015 2001 2001 2F
# 
# ---------------------------------------------------------------------------
sub VFC_CLIENT_FAILURE
{
	my @error	= @_;
	my $addinfo	= "unknown";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^ADDITIONAL INFORMATION/)
		{
			$_ = $error[$i+1];

			my @fields = split(/\s+/, $_);

			for (my $i = 0; $i < @fields; $i++)
			{
				#
				# Strip leading zeros. Be sure to leave
				# at least one character in the string;
				# i.e. don't strip the whole string if
				# it's all zeros.
				#

				$fields[$i] =~ s/^0*(.)/$1/;
			}

			$addinfo = join(' ', @fields);
			$addinfo =~ s/^\s*//;
			$addinfo =~ s/\s*$//;
		}
	}

	printf("%s", $addinfo);

	return
}


# ---------------------------------------------------------------------------
# LABEL:          VFC_ERR2
# IDENTIFIER:     D712FEAE
# 
# [...]
# 
# Description
# LINK_DEAD events reported by the VIOS
# 
# [...]
# 
# Detail Data
# Error Location
# 0000 007C 
# Error Type
# 00
# RC
# 0000 0000 0000 0014 
# VIO Server Partition Name
# fvt-vios2
# Host Adapter Instance Name
# vfchost3
# Physical Adapter Location Code
# U789C.001.DQD2272-P1-C2-T2
# Physical Adapter DRC Name
# U8203.E4A.10DBAA1-V2-C15
# N Port ID of this adapter
# 0000 0000 0001 0C01 
# ---------------------------------------------------------------------------
sub VFC_ERR
{
	my @error	= @_;
	my $desc	= "unknown";
	my $vios	= "unknown";
	my $vhost	= "unknown";
	my $errnum		= "unknown";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^Description/)
		{
			$_ = $error[$i+1];
			chomp;
			$desc = $_ if length($_) > 0;
		}

		if ($error[$i] =~ /^VIO Server Partition Name/)
		{
			$_ = $error[$i+1];
			chomp;
			$vios = $_ if length($_) > 0;
		}

		if ($error[$i] =~ /^Host Adapter Instance Name/)
		{
			$_ = $error[$i+1];
			chomp;
			$vhost = $_ if length($_) > 0;
		}

		if ($error[$i] =~ /^Error Location/)
		{
			$_ = $error[$i+1];
			chomp;
			$errnum = $_ if length($_) > 0;
			$errnum =~ s/^0*//;
			$errnum =~ s/\s*$//;
			$errnum =~ s/^\s*//;
		}
	}

    if($errnum eq '0000')
    {

    }
    elsif ($errnum eq '0047')
    {
        $errnum = "no dma resource";
        $desc   = "";
    }
    elsif ($errnum eq '007C')
    {
        $errnum = "LINK_DEAD event reported by the VIOS";
        $desc   = "";
    }
    elsif ($errnum eq '0080')
    {
        $errnum = "Probable VFC_HOST: driver bug; cmd_elem state is inactive or cmd not for this fcs instance";
        $desc   = "return cmd's with link_dead; IJ31936";
    }

	printf("VIOS %s, vfc_host %s; %s; %s", $vios, $vhost, $errnum, $desc);

	return
}


# ---------------------------------------------------------------------------
# LABEL:          VFC_HOST 		-OR-
# LABEL:          VSCSI_HOST
#
# [...]
# 
# Detail Data
# ADDITIONAL INFORMATION
#         module: npiv_startinitr rc: 0000000000000045    location: 00000586
#         data:  0 0 0 0
# ---------------------------------------------------------------------------
sub Vxx_HOST
{
	my @error	= @_;
	my $addinfo	= "";

	for (my $i = 0; $i <= $#error; $i++)
	{
		if ($error[$i] =~ /^ADDITIONAL INFORMATION/)
		{
			$_ = $error[$i+1];

			my @fields = split(/\s+/, $_);

			for (my $i = 0; $i < @fields; $i++)
			{
				#
				# Strip leading zeros. Be sure to leave
				# at least one character in the string;
				# i.e. don't strip the whole string if
				# it's all zeros.
				#

				$fields[$i] =~ s/^0*(.)/$1/;
			}

			$addinfo = join(' ', @fields);
			$addinfo =~ s/^\s*//;
			$addinfo =~ s/\s*$//;
		}
	}

	printf("%s", $addinfo);

	return
}

# ---------------------------------------------------------------------------
# LABEL:          VIOS_VFC_HOST      
#
# [...]

# ERNUM
# 0000 0102
# ABSTRACT
# command response code is failed
# AREA
# Internal
# BUILD INFO
# BLD: 1802 12-13:56:38 p2018_07A1
# LOCATION
# Filename:npiv_mads.c Function:npiv_query_target_done Line:3271
# DATA
# cmd_rsp_code = 0x8001    reason_code = 0x09
# reason_code_exp = 0x02

# ---------------------------------------------------------------------------

sub VIOS_VFC_HOST
{
    my @error       = @_;
    my $errnum      = "unknown";
    my $abstract    = "unknown";
    my $location    = "unknown";
    my $data1       = "";
    my $data2       = "";
    my $msg         = "";
    
    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^ABSTRACT/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $abstract = join(' ', @fields);
            $abstract =~ s/^\s*//;
            $abstract =~ s/\s*$//;

        }

        if ($error[$i] =~ /^LOCATION/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $location = join(' ', @fields);
            $location =~ s/^\s*//;
            $location =~ s/\s*$//;
            $location =~ s/Filename://;
            $location =~ s/Function://;
            $location =~ s/Line://;
        }

        if ($error[$i] =~ /^ERNUM/)
        {
            $_ = $error[$i+1];
            chomp;
            $errnum = $_ if length($_) > 0;
            $errnum =~ s/^0*//;
            $errnum =~ s/\s*$//;
            $errnum =~ s/^\s*//;
        }

        if ($error[$i] =~ /^DATA/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0x*(.)/$1/;
                #$fields[$i] =~ s/^0*(.)/$1/;
            }

            $data1 = join(' ', @fields);
            $data1 =~ s/^\s*//;
            $data1 =~ s/\s*$//;

            $_ = $error[$i+2];
            if (! $_ =~/^$/)
            {
                chomp;

                my @fields2 = split(/\s+/, $_);

                for (my $i = 0; $i < @fields2; $i++)
                {
                    $fields2[$i] =~ s/^0x*(.)/$1/;
                }

                $data2 = join(' ', @fields2);
                $data2 =~ s/^\s*//;
                $data2 =~ s/\s*$//;
            }
        }
    }

    # added the most used fields under DATA
    # DATA
    # rc = 0x00000010  state = 0x0008

    my @dataA = split(/\s+/, $data1);
    my $dataA2 = $dataA[2];
    my $dataA5 = $dataA[5];
    my $dataA6 = $dataA[6];
    my $dataA7 = $dataA[7];
    my $dataA8 = $dataA[8];
    my $dataA9 = $dataA[9];
    my $dataA11 = $dataA[11];

    my @dataB = split(/\s+/, $data2);
    my $dataB2 = $dataB[2];
    my $dataB5 = $dataB[5];
    my $dataB8 = $dataB[8];


    if($errnum eq '0000')
    {

    }
    elsif ($errnum eq '0039')
    {
        $msg = "$abstract $location $data1";
    }
    elsif ($errnum eq '006E')
    {
        $dataA2 =~ s/^0*(.)/$1/;
        $dataA5 =~ s/x\s*$//;

        my $errno = &hex2int($dataA2);
        my $rc = &lookup("", $errno, \%aix_errno_lt);
        my $wwn = $dataA5;

        $msg = "(startinitr / fabric login) failed for $wwn; ";
        $msg .= "with $rc";
    }
    elsif ($errnum eq '0089')
    {
        $dataA2  =~ s/^0*(.)/$1/;

        my $errno           = &hex2int($dataA2);
        my $ft              = $dataA5;
        my $rc              = $dataA8;
        my $re              = $dataB2; 
        my $einval_arg      = $dataB5;
        my $scsi_id         = $dataB8;

        $scsi_id  =~ s/^0*(.)/$1/;

        $msg = "ioctl SCIOLSTART plogi failed; ";
        $msg .= &lookup("errno ", $errno, \%aix_errno_lt);

        my $errno_2 = &lookup("", $errno, \%aix_errno_lt);

        $msg .= " -> 0x$scsi_id; ";

        # Only LS_RJT's are allowed here 

        if ( $ft ne '00' && $errno_2 eq 'ECONNREFUSED') 
        {
            $msg .=" " . &lookup(" ", $ft, \%fc_failure_type_lt);
            $msg .=", " . &lookup("Reason code ", $rc, \%fc_lsrjt_rc_lt);
            $msg .=", " . &lookup("Explanation ", $re, \%fc_lsrjt_re_lt);
        }
        elsif ( $errno_2 ne 'ENODEV' )
        {
            # ENODEV is not an LS_RJT
            if ( $ft ne '00' )
            {
                $msg .= "failure_type $ft ";
            }

            if ( $rc  eq '25' && $re eq '00' )
            {
                $msg .= "Aborted by host due to timeout "; 
            }
            elsif ($rc ne '00' )
            {
                $msg .= "Reason code $rc ";
                $msg .= "Explanation $re ";
            }
        }

        if ( $einval_arg ne '00' )
        { 
            $msg .= " inv_args $einval_arg"
        }

    }
    elsif ($errnum eq '00A9')
    {
        my $kerror = &kerrno_to_errno($dataA2);

        $msg    = "Relogin to nameserver or target port failed; ";
        $msg    .= "$kerror";
    }
    elsif ($errnum eq '0102') 
    {
        $msg  = "NPIV_ERR_$errnum GID_PN failed by directory server; ";

        my @field = split(/\s+/, $data1);
        my $rsp_code = $field[2];
        my $reason_code = $field[5];

        my @field1 = split(/\s+/, $data2);
        my $reason_exp = $field1[2];

        my $reason  = "0000$reason_code$reason_exp";

        $msg .= &lookup("", $reason, \%fc_nsrjt_lt);

    }
    elsif ($errnum eq '0103')
    {
        # remove leading zeros 
        $dataA5 =~ s/^0*//;

        $msg  = "Process Login failed with cmd_status ($dataA5) ";
        $msg .= &lookup(" ", $dataA5, \%com_scsi_status_lt);
        $msg .= "; flags ($dataA2)";

    }
    elsif ($errnum eq '0112')
    {
        # remove leading zeros
        $dataA2 =~ s/^0*//;
        $dataA8 =~ s/^0*//; 

        $msg  = "NPIV_ERR_$errnum non Linux Client requested logo with pending i/o's for Target fcid 0x$dataA8 $dataA5 " ;
        $msg .= "Returning logo with mad status ";
        $msg .= &lookup("", $dataA2, \%npiv_mad_status_lt);
        
    }
    else
    {
        $msg = "NPIV_ERR_$errnum $abstract $data1";
    }

    if ($ERRNUMS)
    {
        $msg = "$errnum: $msg";
    }

    printf("%s", $msg);

    return;
}

# ---------------------------------------------------------------------------
# LABEL:          VIOS_CLIENT_FAILURE
#
# [...]

# ERNUM
# 0000 0102
# ABSTRACT
# command response code is failed
# AREA
# Internal
# BUILD INFO
# BLD: 1802 12-13:56:38 p2018_07A1
# LOCATION
# Filename:npiv_mads.c Function:npiv_query_target_done Line:3271
# DATA
# cmd_rsp_code = 0x8001    reason_code = 0x09
# reason_code_exp = 0x02

# ---------------------------------------------------------------------------
# 

sub VIOS_CLIENT_FAILURE
{
    my @error       = @_;
    my $errnum      = "unknown";
    my $abstract    = "unknown";
    my $location    = "unknown";
    my $data1       = "unknown";
    my $data2       = "unknown";
    my $msg =       "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^ABSTRACT/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $abstract = join(' ', @fields);
            $abstract =~ s/^\s*//;
            $abstract =~ s/\s*$//;
        }

        if ($error[$i] =~ /^LOCATION/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $location = join(' ', @fields);
            $location =~ s/^\s*//;
            $location =~ s/\s*$//;
            $location =~ s/Filename://;
            $location =~ s/Function://;
            $location =~ s/Line://;
        }

        if ($error[$i] =~ /^ERNUM/)
        {
            $_ = $error[$i+1];
            chomp;
            $errnum = $_ if length($_) > 0;
            $errnum =~ s/^0*//;
            $errnum =~ s/\s*$//;
            $errnum =~ s/^\s*//;
        }

        if ($error[$i] =~ /^DATA/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                 $fields[$i] =~ s/^0x*(.)/$1/;
                 $fields[$i] =~ s/^0*//;
            }

            $data1 = join(' ', @fields);
            $data1 =~ s/^\s*//;
            $data1 =~ s/\s*$//;

            $_ = $error[$i+2];
            
            # This could be the last line, check now
            if (! $_ =~/^$/)        
            {
                chomp;

                my @fields2 = split(/\s+/, $_);

                for (my $i = 0; $i < @fields2; $i++)
                {
                    $fields2[$i] =~ s/^0x*(.)/$1/;
                    $fields2[$i] =~ s/^0*(.)/$1/;
                }

                $data2 = join(' ', @fields2);
                $data2 =~ s/^\s*//;
                $data2 =~ s/\s*$//;
            } 
        }

    }

    # added the most used fields under DATA
    my @dataA = split(/\s+/, $data1);
    my $dataA2 = $dataA[2];
    my $dataA5 = $dataA[5];
    my $dataA6 = $dataA[8];

    my @dataB = split(/\s+/, $data2);
    my $dataB2 = $dataB[2];
    my $dataB5 = $dataB[5];
    my $dataB8 = $dataB[8];


    if ($errnum eq '0001')
    {
        $msg = "INFO: Not reporting LUN due to current state; ";
        $msg .= "$data1";
    }
    elsif ($errnum eq '0019')
    {
        $msg = "H_COPY_RDMA() failed while copying MAD payload; vios sending disconnect";
    }
    elsif ($errnum eq '0040')
    {
        my $cli_max = &int2hex($dataA6, 1);
        my $vhost_max = &int2hex($dataB2, 1);

        $msg = "Client max_xfer_size 0x$cli_max exceeded vscsi_host max_xfer_size 0x$vhost_max";
    }
    elsif ($errnum eq '0048')
    {
        $msg = "Unknown SCSI ID specified; frame->targetSCSIid 0x$dataA5; $location";
    }
    elsif ($errnum eq '1000 0080')
    {
        my $debit = &hex2int($dataA5);
        my $rsp   = $dataB2;
        my $cmd   = $dataB5;

        $msg = "Connection lost with outstanding commands; cmds_out ($debit) resp ($rsp) cmd ($cmd)";
    }
    elsif ($errnum eq '0089')
    {
        $msg = "SCIOLSTART failed; ";
        $msg .= "$data2";
    }
    elsif ($errnum eq '002D')
    {
        $msg = "Client is inaccessible due to TCE's permission bit; vios sending disconnect";
    }
    elsif ($errnum eq '0058')
    {
        $msg = "INFO: Failing NPIV Login due to current adapter state";
    }
    elsif ($errnum eq '005B')
    {
        $msg = "H_COPY_RDMA() failed ";
        $msg .= "$data2";
    }
    elsif ($errnum eq '00D2')
    {
        $msg = "d_map_init failure in vl_init_lun; ";
        $msg .= "$data2";
    }
    elsif ($errnum eq '0102')
    {
        $msg  = "GID_PN failed by directory server; ";
        $msg .= "$data1 $data2";
    }
    elsif ($errnum eq '0114')
    {
        $msg  = "H_COPY_RDMA() failed; client's queue is down; ";
        $msg .= "$data1 disconnected from VIOS from Timed out I/O or moved to another server during LPM";
    }
    else
    {
        $msg = "$errnum $abstract $data1";
    }

    if ($ERRNUMS)
    {
        $msg = "$errnum: $msg";
    }

    printf("%s", $msg);

    return;

}

#
# get_detail_sense_data - Retrieve and return the SENSE DATA section from an
# error entry.  Assumes the sense data follows the LAST line starting with
# "SENSE DATA" or "ADDITIONAL HEX DATA" and spans to the end of the error
# entry.
#
# The return is a hexstring (ASCII-encoded hex digits, e.g. "DEADBEEF")
# with no whitespace.
#
# TODO: Note that the returned string may contain non-hex characters if,
# say, other text follows the actual SENSE DATA.  Perhaps we should stop
# gathering at the first non-hex digit, or at the first line that contains
# a non-hex digit.
#

sub get_detail_sense_data
{
    my @error = @_;
    my $sense = "";

    #
    # Search backwards from the bottom of the error so that we
    # find only the last batch of sense data.
    #
    for (my $i = $#error; $i >= 0; $i--)
    {
        if ($error[$i] =~ /^Detailed Data/)
        {
            for (my $j = $i + 1; $j <= $#error; $j++)
            {
                $sense = $sense . $error[$j];
            }
            last;
        }
    }

    $sense =~ s/\s+//g;

    return $sense;
}


# 
# Error Location
# Filename:vfc_sm.c  Error Number:VFC_ERR_LOC_26C  Function:vfc_log_info_err_msg  Line:2956  RC:10
#


sub get_error_location
{
    my @error = @_;
    my $data = "";
    my $vfc_err = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Error Location/)
        {
            $data = $error[$i+1];
            $vfc_err = (split /\s+/, $data)[2];
        }    
        $vfc_err =~ s/Number://;
    }
    return $vfc_err;
}

sub get_vios_part_name
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^VIO Server Partition Name/)
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
        }
    }
    return $data;
}

sub get_virt_host_adapter
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Virtual Host Adapter/)
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
        }
    }
    return $data;
}

# ---------------------------------------------------------------------------
# LABEL:          VFC4_ERR
#
# [...]

# Description
# Error during MADS/IO Transportation

# Detail Data
# Error Location
# Filename:vfc_admin.c  Error Number:VFC_ERR_LOC_18E  Function:vfc_parse_passthru  Line:1699  RC:F7
#
# Detailed Data
# 0000 0100 0000 018E 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 1990 0000
#
# ---------------------------------------------------------------------------

sub VFC4_ERR
{
    my @error           = @_;
    my $sense           = &get_detail_sense_data(@error);
    my $error_location  = &get_error_location(@error);
    my $vios_name       = &get_vios_part_name(@error);
    my $vios_host_adap  = &get_virt_host_adapter(@error);
    my $description     = &get_DESCRIPTION(@error);
    my $prob_cause      = &get_PROBABLE_CAUSE(@error);


    my $errnum      = "unknown";
    my $errno       = "unknown";
    my $msg         = "";

    if ($sense)
    {
        $errnum = &bytes($sense,  4, 4);
        $errno  = &hex2int(&bytes($sense, 8, 4));    # often an errno value    
    }

    if ($error_location)
    {
        $msg = "$error_location ";
    }
    else
    {
        $msg = "$errnum ";
    } 

    if ($vios_name)
    {
        $msg .= "$vios_name ";
    }

    if ($vios_host_adap)
    {
        $msg .= "$vios_host_adap ";
    }



    if ($errnum eq '00000001')
    {
        $msg .= "INFO: Not reporting LUN due to current state";
    }
    elsif ($errnum eq '00000242')
    {
        $msg .= "vfc transport failed or de-registered; sending async link_down";
    }
    elsif ($errnum eq '00000243')
    {
        $msg .= "recieved async link up from VIOS; setting link down to force re-login";
    }
    elsif ($errnum eq '00000244')
    {
        $msg .= "recieved async link down from VIOS";
    }
    elsif ($errnum eq '00000249')
    {
        $msg .= "vfc_login_timeout sending ring_reset / disconnect";
    }
    elsif ($errnum eq '0000026C')
    {
        $msg .= "INFO: no channel support from host";
    }
    elsif ($description)
    {
        $msg .= "$description";
    }
    elsif ($prob_cause)
    {
        $msg .= "$prob_cause";
    }

    printf("%s", $msg);

    return;

}

# -----------------------------------------------------------------------

sub get_LOCATION
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Error Location/ )
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
            $data =~ s/Error Number://;
            $data =~ s/Function://;
            $data =~ s/Filename://;
        }
    }
    return $data;
}



sub get_ERNUM
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^ERNUM/ )
        {
            $_ = $error[$i+1];
            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #
            }

            $data = join('', @fields);
        }
    }
    return $data;
}

sub get_ABSTRACT
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^ABSTRACT/ )
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
            $data =~ s/Error Number://;
            $data =~ s/Function://;
            $data =~ s/Filename://;
        }
    }
    return $data;
}

sub get_DATA
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^DATA/ )
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #
                
                $fields[$i] =~ s/^0x*(.)/$1/;
                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
            $data =~ s/Error Number://;
            $data =~ s/Function://;
            $data =~ s/Filename://;
            $data =~ s/->/ /;
        }
    }
    return $data;
}

sub get_AREA
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^AREA/ )
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0x*(.)/$1/;
                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
            $data =~ s/Error Number://;
            $data =~ s/Function://;
            $data =~ s/Filename://;
            $data =~ s/->/ /;
        }
    }
    return $data;
}

##################################################################
#
# 
#
# LABEL:      VIOS_SEAHA_BACKUP
# IDENTIFIER: 1FE2DD91
#
# [ .... ]
#
# Description
# BECOME BACKUP
#
# Probable Causes
# BECOME BACKUP
#
# Failure Causes
# BECOME BACKUP
#
#    Recommended Actions
#    BECOME BACKUP
#
# Detail Data
# ERNUM
# 0000 0008
# ABSTRACT
# Transition from INIT to BACKUP
# AREA
# SEA HA state notification
# BUILD INFO
# BLD: 2012 03-09:18:29 v2020_49A9
# LOCATION
# Filename:sea_ha.c Function:seaha_ctlrecv Line:1216
# DATA
# seahap->state= 0x00000003
# Become the Backup SEA
#
#
##################################################################

sub VIOS_SEAHA
{
    my @error           = @_;
    my $errnum          = &get_ERNUM(@error);
    my $location        = &get_LOCATION(@error);
    my $abstract        = &get_ABSTRACT(@error);
    my $data            = &get_DATA(@error);

    my $msg         = "";


    if ($errnum eq '00000001')
    {
        $msg = "$errnum; ";
    }
    elsif ($errnum eq '00000243')
    {
        $msg = "$errnum; ";
    }
    else
    {
        $msg = "$errnum ";
    }


    if ($abstract )
    {
        $msg .= "$abstract ";
    }

    if ($location)
    {
        $msg .= "$location ";
    }

    if ($data)
    {
        $msg .= "$data";
    }


    printf("%s", $msg);

    return;

}

# -----------------------------------------------------------------------------------------------------------------

sub get_DESCRIPTION
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Description/ )
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0x*(.)/$1/;
                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
            $data =~ s/Error Number://;
            $data =~ s/Function://;
            $data =~ s/Filename://;
            $data =~ s/->/ /;
        }
    }
    return $data;
}

sub get_PROBABLE_CAUSE
{
    my @error = @_;
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Probable Causes/ )
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0x*(.)/$1/;
                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
            $data =~ s/Error Number://;
            $data =~ s/Function://;
            $data =~ s/Filename://;
            $data =~ s/->/ /;
        }
    }
    return $data;
}



sub get_EVENT_DATA
{
    my @error = @_;
    my $label  = &get_label(@error);
    my $data = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^EVENT \DATA/ )
        {
            $_ = $error[$i+1];

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                #
                # Strip leading zeros. Be sure to leave
                # at least one character in the string;
                # i.e. don't strip the whole string if
                # it's all zeros.
                #

                $fields[$i] =~ s/^0x*(.)/$1/;
                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $data = join(' ', @fields);
            $data =~ s/^\s*//;
            $data =~ s/\s*$//;
        }
    }
    return $data;
}

sub POOL
{
    my @error           = @_;
    my $label  = &get_label(@error);

    if    ($label =~ /POOL_CLUSTER_STATE_/)      { &POOL_CLUSTER_STATE(@error) }
    elsif ($label =~ /POOL_CHALLENGE/)           { &POOL_CHALLENGE(@error) }
    elsif ($label =~ /POOL_EXPEL_NODE_REQ/)           { &POOL_CHALLENGE(@error) }
    elsif ($label =~ /POOL_EXPEL_NODE_TAR/)           { &POOL_EXPEL_NODE_TAR(@error) }
    elsif ($label =~ /POOL_EXPEL_NODE_FAI/)           { &POOL_EXPEL_NODE_FAI(@error) }
    elsif ($label =~ /POOL_PDISK_FAILED/)           { &POOL_PDISK_FAILED(@error) }
    elsif ($label =~ /POOL_STALE_PP/)           { &POOL_STALE_PP(@error) }
    elsif ($label =~ /POOL_SLOW_DISK_IO/)           { &POOL_SLOW_DISK_IO(@error) }
    elsif ($label =~ /POOL_LOST_CONNECTIO/)           { &POOL_LOST_CONNECTIO(@error) }
    
    else                { &POOL_GENERAL(@error) }

    return;

}

########################################################################
#
# LABEL:          POOL_ESTABLISHED_CO
# IDENTIFIER:     9F4E98DF
#
# [ ... ]
#
# Description
# This node established connection with server node.
#
# Probable Causes
# NONE
#
# Failure Causes
# NONE
#
#        Recommended Actions
#        NONE
#
# Detail Data
# LINE NUMBER:
#         769
# DETECTING MODULE
# tmleaseexpiry.c,Oct 28 2019 16:59:48 q2019_44A2
# EVENT DATA:
# This node established TCP/IP connection with server vioxxx.xxxx.com over 99.99.99.120.
# Number of valid lease connections=1
#
##########################################################################

sub POOL_GENERAL
{
    my @error           = @_;
    my $description     = &get_DESCRIPTION(@error);
    my $event_data      = &get_EVENT_DATA(@error);

    my $msg         = "";


    if ($description )
    {
        $msg .= "$description ";
    }

    if ($event_data)
    {
        $msg .= "$event_data ";
    }


    printf("%s", $msg);

    return;

}

sub POOL_CLUSTER_STATE
{
    my @error = @_;
    my $msg   = "";
    my $leader = "";

    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /Leader/)
        {
            $_ = $error[$i];
            s/\s//g;
            chomp;
            s/Leader=//;
            $leader=$_;
            #printf("(Leader:%s)",$_);
        }

        if ($error[$i] =~ /Node bringing pool online/)
        {
            $_ = $error[$i+2];
            s/MFS Manager Node=//;
            s/ ServerNo=.*//;
            chomp;
            printf("Pool online (MFS=%s)",$_);
        }

        if ($error[$i] =~ /Establishing new MFS manager/)
        {
            $_ = $error[$i+2];
            s/MFS Manager Node=//;
            s/ ServerNo=.*//;
            chomp;
            printf("New MFS (MFS=%s)",$_);
        }

        if ($error[$i] =~ /Joining Nodes/)
        {
            my $j=1; my $nodes="";
            while ($error[$i+$j] && $error[$i+$j] !~ /^----/ ) {
                $_ = $error[$i+$j];
                s/\s//g;
                chomp;
                $nodes="$nodes $_";
                $j += 1;
            }
            printf("Joining:%s (Leader=%s)",$nodes,$leader);
        }

        if ($error[$i] =~ /Leaving Nodes/)
        {
            my $j=1; my $nodes="";
            while ($error[$i+$j] && $error[$i+$j] =~ /\S/ ) {
                $_ = $error[$i+$j];
                s/\s//g;
                chomp;
                $nodes="$nodes $_";
                $j += 1;
            }
            if($nodes) {
                printf("Leaving:%s (Leader=%s)",$nodes,$leader);
            }
        }
        if ($error[$i] =~ /Resigning Nodes/)
        {
            my $j=1; my $nodes="";
            while ($error[$i+$j] && $error[$i+$j] =~ /\S/ ) {
                $_ = $error[$i+$j];
                s/\s//g;
                chomp;
                $nodes="$nodes $_";
                $j += 1;
            }
            if($nodes) {
                printf("MFS Mgr Resigning:%s",$nodes);
            }
        }
        if ($error[$i] =~ /Node is crippled/) {
            chomp($error[$i]);
            print "$error[$i]";
        }

    }

    return;
}

sub POOL_CHALLENGE
{
    my @error=@_;
    for (my $i = 0; $i <= $#error; $i++) {
        if ($error[$i] =~ /EVENT DATA/) {
            chomp($error[$i+1]);
            printf("%s",$error[$i+1]);
            if($error[$i+1] =~ /responder is not reacting quickly enough/){
                my @times=split(' ',$error[$i+4]);
                printf("(%s,%s,%s,%s)",$times[1],$times[2],$times[3],$times[4]);
            }
        }
    }
}

sub POOL_EXPEL_NODE_REQ
{
    my @error = @_;
    my $msg   = "";

    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /Expelled Nodes/)
        {
            my $j=1; my $nodes="";
            while ($error[$i+$j] && $error[$i+$j] =~ /\S/ ) {
                $_ = $error[$i+$j];
                s/\s//g;
                chomp;
                $nodes="$nodes $_";
                $j += 1;
            }
            if($nodes) {
                printf("Expelling:%s",$nodes);
            }
        }
    }

    return;
}

sub POOL_EXPEL_NODE_TAR
{
    my @error = @_;
    my $msg   = "";


    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /EVENT DATA/)
        {
            my $err=$error[$i+1];
            $err=~s/Node expel target/Expelled/;
            chomp($err);
            printf("$err");
        }
    }

    return;
}

sub POOL_EXPEL_NODE_FAI
{
    my @error = @_;
    my $msg   = "";


    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /EVENT DATA/)
        {
            my $err=$error[$i+1];
            $err=~s/Node expel failure/Expel failed/;
            chomp($err);
            printf("$err");
        }
    }

    return;
}

sub POOL_PDISK_FAILED
{
    my @error = @_;
    my $msg   = "";
    my $diskId = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /diskId/)
        {
            $_ = $error[$i];
            s/\s//g;
            chomp;
            $diskId = "$_";
        }
    }

    $msg = "$diskId";
    $msg =~ s/^\s+//g;
    $msg =~ s/\s+/ /g;
    printf("%s", $msg);

    return;
}

sub POOL_STALE_PP
{
    my @error = @_;
    my $msg   = "";
    my $diskId = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /fgIndex|pgIndex|diskIndex/) {
            chomp($error[$i]);
            $msg = $msg.$error[$i]." ";
        }
    }
    printf("%s", $msg);

    return;
}

sub POOL_SLOW_DISK_IO
{
    my @error = @_;
    my $msg   = "";


    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /EVENT DATA/)
        {
            chomp($error[$i+1]);
            chomp($error[$i+2]); $error[$i+2]=~s/=/ /g;
            my ($h1,$obj)=split(/ /,$error[$i+2]);
            chomp($error[$i+3]); $error[$i+3]=~s/=/ /g;
            my ($h2,$h3,$off,$h35,$len,$h4,$rw)=split(/ /,$error[$i+3]);
            chomp($error[$i+4]); $error[$i+4]=~s/=/ /g;
            my ($h5,$h6,$dev,$h7,$blk,$h8,$bytes)=split(/ /,$error[$i+4]);
            chomp($error[$i+5]); $error[$i+5]=~s/=/ /g;
            my ($h9,$ttot,$h10,$h11,$tdisk,$h12)=split(/ /,$error[$i+5]);
            print "$obj ($rw,$off,$len,$rw) -> $dev ($blk,$bytes) : total=${ttot}s disk=${tdisk}s";
        }
    }

    return;
}

sub POOL_LOST_CONNECTIO
{
    my @error = @_;
    my $msg   = "";


    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /EVENT DATA/)
        {
            my $err=$error[$i+1];
            chomp($err);
            printf("$err");
        }
    }

    return;
}


sub VIO_ALERT_EVENT
{
    my @error = @_;
    my $msg   = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        chomp($error[$i]);

        if ($error[$i] =~ /A Storage Pool Threshold alert event occurred/) {
            my $alert=$error[$i];
            $alert =~ s/^.*The alert event received is:\s*//;
            printf("%s",$alert);
            return;
        } elsif ($error[$i] =~ /A Storage Pool alert event occurred/) {
            my $alert=$error[$i];
            $alert =~ s/^.*The alert received is:\s*//;
            printf("$alert");
            return;
        } elsif ($error[$i] =~ /Tier Threshold alert event occurred/) {
            my $alert=$error[$i];
            $alert =~ s/^.*The alert event received is:\s*//;
            my $tier=$error[$i];
            $tier =~ s/^.*?tier *([^\s]*).*$/$1/;
            printf("$tier $alert");
            return;
        } elsif ($error[$i] =~ /Tier Mirror alert event occurred/) {
            my $alert=$error[$i];
            $alert =~ s/^.*The alert event received is:\s*//;
            my $tier=$error[$i];
            $tier =~ s/^.*Tier *([^\s]*).*$/$1/;
            printf("$tier $alert");
            return;
        } elsif ($error[$i] =~ /File System alert event occurred/) {
            my $fs=$error[$i];
            $fs =~ s/^.*?occurred on [^\s]* *(.*),.*$/$1/;
            printf("%s",$fs);
            return;
        } elsif ($error[$i] =~ /Storage Pool Mirror alert/) {
            printf("Storage Pool Mirror alert");
            return;
        }
    }
}

sub VKE_INFO
{
    my @error = @_;
    my $msg   = "";

    for (my $i = 0; $i <= $#error; $i++) {
        chomp($error[$i]);
        if ($error[$i] =~ /ABSTRACT/) {
            chomp($error[$i+1]);
            printf("%s",$error[$i+1]);
        }
        if ($error[$i] =~ /file :/) {
            $error[$i]=~s/file ://;
            printf("%s",$error[$i]);
        }
    }
}


sub CL_FFDC
{
    my @error = @_;
    my $msg   = "";

    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /^Description/)
        {
            chomp($error[$i+1]);
            $msg=sprintf("%-16.16s", $error[$i+1]);
        }

        if ($error[$i] =~ /^Detail Data/){
            chomp($error[$i+2]); $msg="$msg$error[$i+2]";
            chomp($error[$i+4]); $msg="$msg$error[$i+4]";
            if(defined($error[$i+10])) { #location, success only
                chomp($error[$i+10]); $msg="$msg$error[$i+10]";
            }
            print ($msg);
        }
    }

    return;
}


# ---------------------------------------------------------------------------
# LABEL:          VIO_ERR
#
# [...]

# Detail Data
# ERNUM
# 1000 0022
# ABSTRACT
# rules file could not be deployed
# AREA
# RULES DEPLOY
# VIO BUILD
# SSP BLD: 19/10/14-11:04:46 q2019_42A1 build@builder720
# CMD: 1.41
# LOCATION
# vioRulesDeploy-libRulesDeploy.c
# DATA
# rules_file=CURRENT_RULES rc=6

# ---------------------------------------------------------------------------

sub VIO_ERR
{
    my @error       = @_;
    my $errnum      = "unknown";
    my $abstract    = "unknown";
    my $location    = "unknown";
    my $data1       = "unknown";
    my $data2       = "unknown";
    my $msg         = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^ABSTRACT/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);
            for (my $i = 0; $i < @fields; $i++)
            {
                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $abstract = join(' ', @fields);
            $abstract =~ s/^\s*//;
            $abstract =~ s/\s*$//;
        }

        if ($error[$i] =~ /^LOCATION/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                $fields[$i] =~ s/^0*(.)/$1/;
            }

            $location = join(' ', @fields);
            $location =~ s/^\s*//;
            $location =~ s/\s*$//;
            $location =~ s/Filename://;
            $location =~ s/Function://;
            $location =~ s/Line://;
        }

        if ($error[$i] =~ /^ERNUM/)
        {
            $_ = $error[$i+1];
            chomp;
            $errnum = $_ if length($_) > 0;
            $errnum =~ s/^0*//;
            $errnum =~ s/\s*$//;
            $errnum =~ s/^\s*//;
        }

        if ($error[$i] =~ /^DATA/)
        {
            $_ = $error[$i+1];
            chomp;

            my @fields = split(/\s+/, $_);

            for (my $i = 0; $i < @fields; $i++)
            {
                $fields[$i] =~ s/^0x*(.)/$1/;
            }

            $data1 = join(' ', @fields);
            $data1 =~ s/^\s*//;
            $data1 =~ s/\s*$//;

            $_ = $error[$i+2];

            if (! $_ =~/^$/)
            {
                chomp;

                my @fields2 = split(/\s+/, $_);

                for (my $i = 0; $i < @fields2; $i++)
                {
                    $fields2[$i] =~ s/^0x*(.)/$1/;
                }

                $data2 = join(' ', @fields2);
                $data2 =~ s/^\s*//;
                $data2 =~ s/\s*$//;
            }
        }

    }

    if ($errnum eq '0001')
    {
        $msg = "INFO: Not reporting LUN due to current state; ";
        $msg .= "$data1"
    }
    elsif ($errnum eq '0040')
    {
        $msg = "Client req exceeded vhost max_xfer_size; ";
        $msg .= "$data2"
    }
    else
    {
        $msg = "$errnum $abstract $data1";
    }

    if ($ERRNUMS)
    {
        $msg = "$errnum: $msg";
    }

    printf("%s", $msg);

    return;

}

# ---------------------------------------------------------------------------
# LABEL:          DELAYED_INTS
# [..]
# Resource Name:   SYSPROC
# [..]
# Description
# Excessive interrupt disablement time
#
# [..]
#
# Detail Data
#
# TICKS 13 (1) i/o, IAR 9450 i_enable+150, LR 423523C eeh_configure_pe+5FC
# trb_called.func 4239380 trb_eeh_phase2
# stkp F1000816B016E770
# i_enable+150
# eeh_configure_pe+5F8
# eeh_configure_bridge+7E0
# trb_eeh_phase2+28
# clock+30C
# i_softmod+538
# flih_util+258
# ---------------------------------------------------------------------------

sub DELAYED_INTS
{
    my @error   = @_;
    my $desc    = "unknown";
    my $tics    = "unknown";

    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /^Description/)
        {
            $_ = $error[$i+1];
            chomp;
            $desc = $_ if length($_) > 0;
        }

        if ($error[$i] =~ /^Detail Data/)
        {
            $_ = $error[$i+2];
            chomp;
            $tics = $_ if length($_) > 0;
        }

    }

    printf("%s; %s",  $desc, $tics);

    return
}

sub VNIC_SERVER
{
    my @error   = @_;
    my $desc    = "unknown";
    my $fcause  = "unknown";
    my $fname   = "unknown";
    my $state   = "unknown";
    my $crqste  = "unknown";
    my $status  = "unknown";


    for (my $i = 0; $i <= $#error; $i++)
    {

        if ($error[$i] =~ /^Description/)
        {
            $_ = $error[$i+1];
            chomp;
            $desc = $_ if length($_) > 0;
        }

        if ($error[$i] =~ /^Failure/)
        {
            $_ = $error[$i+1];
            chomp;
            $fcause = $_ if length($_) > 0;
        }

        if ($error[$i] =~ /^Detail Data/)
        {
            $_ = $error[$i+2];
            if (! $_ =~/^$/)
            {
                chomp;

                my @fields = split(/\s+/, $_);

                for (my $i = 0; $i < @fields; $i++)
                {
                    $fields[$i] =~ s/^0*(.)/$1/;
                }

                $fname = join(' ', @fields);
                $fname =~ s/^\s+|\s+$//g;
                $fname =~ s/^\s*//;
                $fname =~ s/\s*$//;
                $fname =~ s/file: //;
                $fname =~ s/line:/num/;
            }
        }

        if ($error[$i] =~ /^DEVICE/)
        {
            $_ = $error[$i+1];
            if (! $_ =~/^$/)
            {
                chomp;

                my @fields1 = split(/\s+/, $_);

                for (my $i = 0; $i < @fields1; $i++)
                {
                    $fields1[$i] =~ s/^0*(.)/$1/;
                    $fields1[$i] =~ s/^\s+|\s+$//g;
                }

                $state = join('', @fields1);
                $state =~ s/^\s*//;
                $state =~ s/\s*$//;
                $state = substr($state, 3, 1)
            }
        }

        if ($error[$i] =~ /^CRQ/)
        {
            $_ = $error[$i+1];
            if (! $_ =~/^$/)
            {
                chomp;

                my @fields1 = split(/\s+/, $_);

                for (my $i = 0; $i < @fields1; $i++)
                {
                    $fields1[$i] =~ s/^0*(.)/$1/;
                    $fields1[$i] =~ s/^\s+|\s+$//g;
                }

                $crqste = join('', @fields1);
                $crqste =~ s/^\s*//;
                $crqste =~ s/\s*$//;
                $crqste = substr($crqste, 3, 1)
            }
        }

        if ($error[$i] =~ /^ERROR/)
        {
            $_ = $error[$i+1];
            if (! $_ =~/^$/)
            {
                chomp;

                my @fields1 = split(/\s+/, $_);

                for (my $i = 0; $i < @fields1; $i++)
                {
                    $fields1[$i] =~ s/^0*(.)/$1/;
                    $fields1[$i] =~ s/^\s+|\s+$//g;
                }

                $status = join('', @fields1);
                $status =~ s/^\s*//;
                $status =~ s/\s*$//;
                $status = substr($status, 3, 1)
            }
        }
    }

    printf("%s; %s; %s; state %s crqstate %s status %s", 
         $desc, $fcause, $fname, $state, $crqste, $status);

    return
}

# ---------------------------------------------------------------------------
# LABEL:  MVR_MIG_COMPLETED
# LABEL:  MVR_FORCE_SUSPEND
#
# Detail Data

sub MVR_
{
    my @error   = @_;
    my $strid    = "";
    my $service    = "";
    my $errornum    = "";
    my $errordesc    = "";
    my $label  = &get_label(@error);

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^STREAM ID/)
        {
            $_ = $error[$i+1];
            chomp;
            $strid = $_ if length($_) > 0;
        }
        if ($error[$i] =~ /^SERVICES/)
        {
            $_ = $error[$i+1];
            chomp;
            $service = $_ if length($_) > 0;
        }
        if ($error[$i] =~ /^ERROR NUM/)
        {
            $_ = $error[$i+1];
            chomp;
            $errornum = $_ if length($_) > 0;
            $_ = $error[$i+3];
            chomp;
            $errordesc = $_ if length($_) > 0;

        }
    }

    if ($label =~ /MVR_MIG_ERROR/ || $label =~ /MVR_MIG_ABORTED/) {
        printf("STREAM ID: %s %s ERROR_NUM: %s %s", $strid,$service,$errornum,$errordesc);
    }
    else {
        printf("STREAM ID: %s %s", $strid,$service);
    }
}

# ---------------------------------------------------------------------------
# LABEL: CL_NETWORK_ISSUE
# Description
# Node is heartbeating solely over disk or FC for more than 15 minutes

sub CL_NETWORK_ISSUE
{
    my @error   = @_;
    my $desc    = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Description/)
        {
            $_ = $error[$i+1];
            chomp;
            $desc = $_ if length($_) > 0;
        }
    }
        printf("%s", $desc);
}

# ---------------------------------------------------------------------------
# LABEL: SEAHA_PRIMARY
# LABEL: SEAHA_BACKUP
# LABEL: ECH_MAIN_CHAN_FAIL
#
# Detail Data
# Become the Primary SEA

sub SEA_
{
    my @error   = @_;
    my $desc    = "";

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /^Detail Data/)
        {
            $_ = $error[$i+1];
            chomp;
            $desc = $_ if length($_) > 0;
        }
    }
        printf("%s", $desc);
}


sub emfc_print_cmd_err
{
    # SFL

    my @cmd   = @_;
    my $sense   = &get_sense_data(@error);
    my $msg = "";


    my $cmd = &words($sense, 96, 8);
    my $status = &bytes($cmd, 11, 1);

    my $failure_type = &bytes($cmd, 15, 1);
    my $fail_rc = &bytes($cmd, 16, 1);
    my $fail_exp = &bytes($cmd, 17, 1);

    if ( $failure_type eq '01' ) # LS_RJT
    {
        $msg .= " " .  &lookup(" ", $failure_type, \%fc_failure_type_lt);
        $msg .= ", " . &lookup("Reason code ", $fail_rc, \%fc_lsrjt_rc_lt);
        $msg .= ", " . &lookup("Explanation ", $fail_exp, \%fc_lsrjt_re_lt);
    }


    return $msg;
}

#---------------------------------------------------------------------------
#LABEL:          NVME_*
#
#---------------------------------------------------------------------------
sub nvme_decode
{
    my @error = @_;
    my $label = &get_label(@error);
    my $msg;

#    my $flags  = &bytes($sense, 0, 2);
#    my $reason = &bytes($sense, 2, 2);

#    if ($flags & 0x8000) {print "REMOTE ";}
#    printf("%x ", $reason);

    for (my $i = 0; $i <= $#error; $i++)
    {
        if ($error[$i] =~ /ADDITIONAL INFORMATION/)
        {
            my $nl=0;
            for (my $j = $i+1; $j <= $#error; $j++)
            {
                if ($error[$j] =~ /uplicate/) {return;}
                if ($nl == 1) {printf("\n                                                 ");}
                $msg = $error[$j];
                $msg =~ s/^\s+//;
                chomp($msg);
                print $msg;
                $nl=1;
            }
        }
    }
    return;
}


#######################################################################
##
#  Lookup table initialization
##
#######################################################################

sub initialize_lookup_tables
{
	$aix_d_map_list_rc_lt{'00000000'} = 'DMA_SUCC';
	$aix_d_map_list_rc_lt{'FFFFFFFF'} = 'DMA_FAIL';
	$aix_d_map_list_rc_lt{'FFFFFFFE'} = 'DMA_NOACC';
	$aix_d_map_list_rc_lt{'FFFFFFFD'} = 'DMA_NORES';
	$aix_d_map_list_rc_lt{'FFFFFFFC'} = 'DMA_DIOFULL';
	$aix_d_map_list_rc_lt{'FFFFFFFB'} = 'DMA_TC_NOTREACHED';
	$aix_d_map_list_rc_lt{'FFFFFFFA'} = 'DMA_BAD_MODE';
	$aix_d_map_list_rc_lt{'FFFFFFF9'} = 'DMA_R_FAIL';
	$aix_d_map_list_rc_lt{'FFFFFFF8'} = 'DMA_R_NORES';

	$aix_errno_lt{1}   = 'EPERM';
	$aix_errno_lt{2}   = 'ENOENT';
	$aix_errno_lt{3}   = 'ESRCH';
	$aix_errno_lt{4}   = 'EINTR';
	$aix_errno_lt{5}   = 'EIO';
	$aix_errno_lt{6}   = 'ENXIO';
	$aix_errno_lt{7}   = 'E2BIG';
	$aix_errno_lt{8}   = 'ENOEXEC';
	$aix_errno_lt{9}   = 'EBADF';
	$aix_errno_lt{10}  = 'ECHILD';
	$aix_errno_lt{11}  = 'EAGAIN';
	$aix_errno_lt{12}  = 'ENOMEM';
	$aix_errno_lt{13}  = 'EACCES';
	$aix_errno_lt{14}  = 'EFAULT';
	$aix_errno_lt{15}  = 'ENOTBLK';
	$aix_errno_lt{16}  = 'EBUSY';
	$aix_errno_lt{17}  = 'EEXIST';
	$aix_errno_lt{18}  = 'EXDEV';
	$aix_errno_lt{19}  = 'ENODEV';
	$aix_errno_lt{20}  = 'ENOTDIR';
	$aix_errno_lt{21}  = 'EISDIR';
	$aix_errno_lt{22}  = 'EINVAL';
	$aix_errno_lt{23}  = 'ENFILE';
	$aix_errno_lt{24}  = 'EMFILE';
	$aix_errno_lt{25}  = 'ENOTTY';
	$aix_errno_lt{26}  = 'ETXTBSY';
	$aix_errno_lt{27}  = 'EFBIG';
	$aix_errno_lt{28}  = 'ENOSPC';
	$aix_errno_lt{29}  = 'ESPIPE';
	$aix_errno_lt{30}  = 'EROFS';
	$aix_errno_lt{31}  = 'EMLINK';
	$aix_errno_lt{32}  = 'EPIPE';
	$aix_errno_lt{33}  = 'EDOM';
	$aix_errno_lt{34}  = 'ERANGE';
	$aix_errno_lt{35}  = 'ENOMSG';
	$aix_errno_lt{36}  = 'EIDRM';
	$aix_errno_lt{37}  = 'ECHRNG';
	$aix_errno_lt{38}  = 'EL2NSYNC';
	$aix_errno_lt{39}  = 'EL3HLT';
	$aix_errno_lt{40}  = 'EL3RST';
	$aix_errno_lt{41}  = 'ELNRNG';
	$aix_errno_lt{42}  = 'EUNATCH';
	$aix_errno_lt{43}  = 'ENOCSI';
	$aix_errno_lt{44}  = 'EL2HLT';
	$aix_errno_lt{45}  = 'EDEADLK';
	$aix_errno_lt{46}  = 'ENOTREADY';
	$aix_errno_lt{47}  = 'EWRPROTECT';
	$aix_errno_lt{48}  = 'EFORMAT';
	$aix_errno_lt{49}  = 'ENOLCK';
	$aix_errno_lt{50}  = 'ENOCONNECT';
	$aix_errno_lt{52}  = 'ESTALE';
	$aix_errno_lt{53}  = 'EDIST';
	$aix_errno_lt{55}  = 'EINPROGRESS';
	$aix_errno_lt{56}  = 'EALREADY';
	$aix_errno_lt{57}  = 'ENOTSOCK';
	$aix_errno_lt{58}  = 'EDESTADDRREQ';
	$aix_errno_lt{59}  = 'EMSGSIZE';
	$aix_errno_lt{60}  = 'EPROTOTYPE';
	$aix_errno_lt{61}  = 'ENOPROTOOPT';
	$aix_errno_lt{62}  = 'EPROTONOSUPPORT';
	$aix_errno_lt{63}  = 'ESOCKTNOSUPPORT';
	$aix_errno_lt{64}  = 'EOPNOTSUPP';
	$aix_errno_lt{65}  = 'EPFNOSUPPORT';
	$aix_errno_lt{66}  = 'EAFNOSUPPORT';
	$aix_errno_lt{67}  = 'EADDRINUSE';
	$aix_errno_lt{68}  = 'EADDRNOTAVAIL';
	$aix_errno_lt{69}  = 'ENETDOWN';
	$aix_errno_lt{70}  = 'ENETUNREACH';
	$aix_errno_lt{71}  = 'ENETRESET';
	$aix_errno_lt{72}  = 'ECONNABORTED';
	$aix_errno_lt{73}  = 'ECONNRESET';
	$aix_errno_lt{74}  = 'ENOBUFS';
	$aix_errno_lt{75}  = 'EISCONN';
	$aix_errno_lt{76}  = 'ENOTCONN';
	$aix_errno_lt{77}  = 'ESHUTDOWN';
	$aix_errno_lt{78}  = 'ETIMEDOUT';
	$aix_errno_lt{79}  = 'ECONNREFUSED';
	$aix_errno_lt{80}  = 'EHOSTDOWN';
	$aix_errno_lt{81}  = 'EHOSTUNREACH';
	$aix_errno_lt{82}  = 'ERESTART';
	$aix_errno_lt{83}  = 'EPROCLIM';
	$aix_errno_lt{84}  = 'EUSERS';
	$aix_errno_lt{85}  = 'ELOOP';
	$aix_errno_lt{86}  = 'ENAMETOOLONG';
	$aix_errno_lt{88}  = 'EDQUOT';
	$aix_errno_lt{89}  = 'ECORRUPT';
	$aix_errno_lt{93}  = 'EREMOTE';
	$aix_errno_lt{109} = 'ENOSYS';
	$aix_errno_lt{110} = 'EMEDIA';
	$aix_errno_lt{111} = 'ESOFT';
	$aix_errno_lt{112} = 'ENOATTR';
	$aix_errno_lt{113} = 'ESAD';
	$aix_errno_lt{114} = 'ENOTRUST';
	$aix_errno_lt{115} = 'ETOOMANYREFS';
	$aix_errno_lt{116} = 'EILSEQ';
	$aix_errno_lt{117} = 'ECANCELED';
	$aix_errno_lt{118} = 'ENOSR';
	$aix_errno_lt{119} = 'ETIME';
	$aix_errno_lt{120} = 'EBADMSG';
	$aix_errno_lt{121} = 'EPROTO';
	$aix_errno_lt{122} = 'ENODATA';
	$aix_errno_lt{123} = 'ENOSTR';
	$aix_errno_lt{124} = 'ENOTSUP';
	$aix_errno_lt{125} = 'EMULTIHOP';
	$aix_errno_lt{126} = 'ENOLINK';
	$aix_errno_lt{127} = 'EOVERFLOW';

	$aix_rdac_stat_lt{'9C'} = 'Read-only reservation encountered';
	$aix_rdac_stat_lt{'AA'} = 'Failed to start command';
	$aix_rdac_stat_lt{'CC'} = 'Exceeded allowed retries for ENXIO';
	$aix_rdac_stat_lt{'D1'} = 'LUN not configured';
	$aix_rdac_stat_lt{'DD'} = 'Exceeded allowed retries for ACA ACTIVE';
	$aix_rdac_stat_lt{'EE'} = 'LUN ownership change';

	$aix_s2_adap_stat_lt{'01'} = 'host I/O bus error';
	$aix_s2_adap_stat_lt{'02'} = 'transport fault';
	$aix_s2_adap_stat_lt{'04'} = 'command timeout';
	$aix_s2_adap_stat_lt{'08'} = 'no response from device';
	$aix_s2_adap_stat_lt{'0E'} = 'error, do not retry';
	$aix_s2_adap_stat_lt{'0F'} = 'error, delay logging';
	$aix_s2_adap_stat_lt{'10'} = 'adapter HW failure';
	$aix_s2_adap_stat_lt{'20'} = 'adapter SW failure';
	$aix_s2_adap_stat_lt{'40'} = 'bad fuse or termination';
	$aix_s2_adap_stat_lt{'80'} = 'external bus reset';

	$aix_s3_adap_stat_lt{'01'} = 'host I/O bus error';
	$aix_s3_adap_stat_lt{'02'} = 'transport fault';
	$aix_s3_adap_stat_lt{'03'} = 'command timeout';
	$aix_s3_adap_stat_lt{'04'} = 'no response from device';
	$aix_s3_adap_stat_lt{'05'} = 'adapter HW failure';
	$aix_s3_adap_stat_lt{'06'} = 'adapter SW failure';
	$aix_s3_adap_stat_lt{'07'} = 'WW name change';
	$aix_s3_adap_stat_lt{'08'} = 'bad fuse or termination';
	$aix_s3_adap_stat_lt{'09'} = 'external bus reset';
	$aix_s3_adap_stat_lt{'0A'} = 'transport busy';
	$aix_s3_adap_stat_lt{'0B'} = 'transport dead';
	$aix_s3_adap_stat_lt{'0C'} = 'driver should redrive open seq';
	$aix_s3_adap_stat_lt{'0D'} = 'transport migrated';
	$aix_s3_adap_stat_lt{'0E'} = 'do not retry';
	$aix_s3_adap_stat_lt{'0F'} = 'max retry attempts exceeded';

    $aix_scdisk_stat_lt{'00'} = 'RAS Error';
	$aix_scdisk_stat_lt{'01'} = 'Mode Sense Data Corrupted 1 (Formatting mode sense data failed)';
	$aix_scdisk_stat_lt{'02'} = 'Mode Sense Data Corrupted 2 (index beyond the changable mode sense data for this page)';
	$aix_scdisk_stat_lt{'03'} = 'Mode Sense Data Corrupted 3 (index beyond the changable mode sense data for this page)';
	$aix_scdisk_stat_lt{'04'} = 'Mode Sense Data Corrupted 4 (Changable mode sense data is less than what we asked for 255)';
	$aix_scdisk_stat_lt{'05'} = 'Mode Sense Data Corrupted 5 (Changable mode sense length is less than what we asked for 255)';
	$aix_scdisk_stat_lt{'06'} = 'Mode Sense Data Corrupted 6 (Changable mode sense length is less than what we asked for 255)';
	$aix_scdisk_stat_lt{'07'} = 'Mode Sense Data Corrupted 7 (Changable mode sense length is less than what we asked for 255)';
	$aix_scdisk_stat_lt{'08'} = 'Mode Sense Data Corrupted 8 (Formatting mode sense data failed)';
	$aix_scdisk_stat_lt{'09'} = 'MPIO path selection failed';
	$aix_scdisk_stat_lt{'0A'} = 'SCSI sense data is corrupted';
	$aix_scdisk_stat_lt{'0B'} = 'Corrupted descriptor data';
	$aix_scdisk_stat_lt{'0C'} = 'Corrupted descriptor data';
	$aix_scdisk_stat_lt{'0D'} = 'READ CAPACITY does not match blocksize';
	$aix_scdisk_stat_lt{'0E'} = 'READ CAPACITY does not match blocksize';
	$aix_scdisk_stat_lt{'0F'} = 'Serial number mismatch';
	$aix_scdisk_stat_lt{'10'} = 'Software issue with loop';
	$aix_scdisk_stat_lt{'11'} = 'Header Transfer Failed';
	$aix_scdisk_stat_lt{'12'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'13'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'14'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'15'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'16'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'17'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'18'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'19'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'1A'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'1B'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'1C'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'1D'} = 'Header Transfer Failed';
	$aix_scdisk_stat_lt{'1E'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'1F'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'20'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'21'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'22'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'23'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'24'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'25'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'26'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'27'} = 'MPIO cannot get path-private sense buffer';
	$aix_scdisk_stat_lt{'28'} = 'dev restart failed for non-MPIO device';
	$aix_scdisk_stat_lt{'29'} = 'dev restart failed for MPIO device';
	$aix_scdisk_stat_lt{'2A'} = 'queue recovery command allocation failure';
	$aix_scdisk_stat_lt{'2B'} = 'max retry delay exceeded';
    $aix_scdisk_stat_lt{'80'} = 'Serial Number malloc failed';
    $aix_scdisk_stat_lt{'81'} = 'Serial Number copyin failed';
    $aix_scdisk_stat_lt{'82'} = 'Serial Number malloc failed';
	$aix_scdisk_stat_lt{'84'} = 'FC driver supports dyntrk, disk does not';
    $aix_scdisk_stat_lt{'85'} = 'SCSI_ERR_LOG_KEY registration err';
    $aix_scdisk_stat_lt{'86'} = 'Part.Key. service register failed';
    $aix_scdisk_stat_lt{'A8'} = 'Raw Serial Number invalid';
	$aix_scdisk_stat_lt{'A9'} = 'scsi disk detected invalid buf in strat';
    $aix_scdisk_stat_lt{'AA'} = 'scsi driver timedout expired buf';

    $aix_scdisk_ras_err_lt{'008C'} = 'DEBUG: scsidisk_dkaudio path_attr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'008D'} = 'DEBUG: scsidisk_dk_cd_mode path_attr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'0094'} = 'DEBUG: scsidisk_close_adapter path_attr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'0095'} = 'DEBUG: scsidisk_spindown path_attr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'00A1'} = 'attempted to start cmd but found we are out of resources with no act cmds';
    $aix_scdisk_ras_err_lt{'00A2'} = 'recieved unexpected check condition on TM cmd';
    $aix_scdisk_ras_err_lt{'00A3'} = 'error getting pvt_path single path reserve info while processing reset';
    $aix_scdisk_ras_err_lt{'00B0'} = 'DEBUG: scsidisk_test_unit_ready path_attr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'00B1'} = 'DEBUG: scsidisk_open_path path_attr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'00D9'} = 'DEBUG: iodone path writev cmd_ptr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'00DA'} = 'DEBUG: iodone path reassign cmd_ptr eyecatcher invalid';
    $aix_scdisk_ras_err_lt{'00DB'} = 'DEBUG: req sense pvt_path checked cmd not null';
    $aix_scdisk_ras_err_lt{'00E2'} = 'DEBUG: failure to allocate cmd for write verify';
    $aix_scdisk_ras_err_lt{'00E8'} = 'livedump dmp_context failed - continuing with livedump';
    $aix_scdisk_ras_err_lt{'00E9'} = 'livedump dmp_kernext failed - continuing with livedump';
    $aix_scdisk_ras_err_lt{'00EA'} = 'livedump dmp_compspec failed - continuing with livedump';
    $aix_scdisk_ras_err_lt{'00EB'} = 'livedump failed';
    $aix_scdisk_ras_err_lt{'00EC'} = 'livedump setupparms failed, livedump failed'; 
    $aix_scdisk_ras_err_lt{'00F2'} = 'failure to retrieve pvt path list while setting all paths to reset failed';
    $aix_scdisk_ras_err_lt{'00F6'} = 'failed to get pvt_path possiable bad address detected';
    $aix_scdisk_ras_err_lt{'00F8'} = 'failed to get pvt_path for this path_id in scsidisk_select_path';
    $aix_scdisk_ras_err_lt{'0100'} = 'during config while in cfgterm failed to get list of private path';
    $aix_scdisk_ras_err_lt{'0101'} = 'failed to retrieve pvt_paths; cleanup and fail open';
    $aix_scdisk_ras_err_lt{'0103'} = 'while closing failed to get path private list';
    $aix_scdisk_ras_err_lt{'0104'} = 'while closing failed to get path private for the reserved path';
    $aix_scdisk_ras_err_lt{'0108'} = 'failed to retrieve list of pvt_paths in scsidisk_dkaudio';
    $aix_scdisk_ras_err_lt{'0109'} = 'failed to retrieve list of pvt_paths in dk_cd_mode';
    $aix_scdisk_ras_err_lt{'010A'} = 'failed to retrieve list of pvt_paths in scsidisk_dk_pres_register';
    $aix_scdisk_ras_err_lt{'010C'} = 'failed to retrieve list of pvt_paths in scsidisk_open_path';
    $aix_scdisk_ras_err_lt{'010D'} = 'failed to retrieve list of pvt_paths in scsidisk_close_path';
    $aix_scdisk_ras_err_lt{'010E'} = 'failed to retrieve list of pvt_paths in scsidisk_check_adapter';
    $aix_scdisk_ras_err_lt{'010F'} = 'failed to retrieve list of pvt_paths in scsidisk_check_adapter'; 
    $aix_scdisk_ras_err_lt{'0112'} = 'pvt_path passed to scsidisk_open_adapter is null';
    $aix_scdisk_ras_err_lt{'0113'} = 'while closing found active dump device';


	$aix_scdisk_strat_err_lt{'00'} = 'Strat err 0: Request does not start on device block boundary';
	$aix_scdisk_strat_err_lt{'01'} = 'Strat err 1: Buf is greater than our maximum transfer size';
	$aix_scdisk_strat_err_lt{'02'} = 'Strat err 2: Device is in diag mode';
	$aix_scdisk_strat_err_lt{'03'} = 'Strat err 3: blkno exceeds last LBA';
	$aix_scdisk_strat_err_lt{'04'} = 'Strat err 4: blkno exceeds last LBA ';
	$aix_scdisk_strat_err_lt{'05'} = 'Strat err 5: Request is a zero length read or write';
	$aix_scdisk_strat_err_lt{'06'} = 'Strat err 6: Device is either off line or not opened';
	$aix_scdisk_strat_err_lt{'07'} = 'Strat err 7: Block size incorrect or HWRELOC on a read ';
	$aix_scdisk_strat_err_lt{'09'} = 'Strat err 9: sfw fence set to read only';

	$scsi_sbcop_lt{'00'} = 'TEST UNIT READY';
	$scsi_sbcop_lt{'01'} = 'REZERO UNIT';
	$scsi_sbcop_lt{'03'} = 'REQUEST SENSE';
	$scsi_sbcop_lt{'04'} = 'FORMAT UNIT';
	$scsi_sbcop_lt{'07'} = 'REASSIGN BLOCKS';
	$scsi_sbcop_lt{'08'} = 'READ(6)';
	$scsi_sbcop_lt{'0A'} = 'WRITE(6)';
	$scsi_sbcop_lt{'0B'} = 'SEEK(6)';
	$scsi_sbcop_lt{'12'} = 'INQUIRY';
	$scsi_sbcop_lt{'15'} = 'MODE SELECT(6)';
	$scsi_sbcop_lt{'16'} = 'RESERVE(6)';
	$scsi_sbcop_lt{'17'} = 'RELEASE(6)';
	$scsi_sbcop_lt{'18'} = 'COPY';
	$scsi_sbcop_lt{'1A'} = 'MODE SENSE(6)';
	$scsi_sbcop_lt{'1B'} = 'START STOP UNIT';
	$scsi_sbcop_lt{'1C'} = 'RECEIVE DIAGNOSTIC RESULTS';
	$scsi_sbcop_lt{'1D'} = 'SEND DIAGNOSTIC';
	$scsi_sbcop_lt{'1E'} = 'PREVENT ALLOW MEDIUM REMOVAL';
	$scsi_sbcop_lt{'25'} = 'READ CAPACITY(10)';
	$scsi_sbcop_lt{'28'} = 'READ(10)';
	$scsi_sbcop_lt{'2A'} = 'WRITE(10)';
	$scsi_sbcop_lt{'2B'} = 'SEEK(10)';
	$scsi_sbcop_lt{'2E'} = 'WRITE AND VERIFY(10)';
	$scsi_sbcop_lt{'2F'} = 'VERIFY(10)';
	$scsi_sbcop_lt{'30'} = 'SEARCH DATA HIGH(10)';
	$scsi_sbcop_lt{'31'} = 'SEARCH DATA EQUAL(10)';
	$scsi_sbcop_lt{'32'} = 'SEARCH DATA LOW(10)';
	$scsi_sbcop_lt{'33'} = 'SET LIMITS(10)';
	$scsi_sbcop_lt{'34'} = 'PRE-FETCH(10)';
	$scsi_sbcop_lt{'35'} = 'SYNCHRONIZE CACHE(10)';
	$scsi_sbcop_lt{'36'} = 'LOCK UNLOCK CACHE(10)';
	$scsi_sbcop_lt{'37'} = 'READ DEFECT DATA(10)';
	$scsi_sbcop_lt{'39'} = 'COMPARE';
	$scsi_sbcop_lt{'3A'} = 'COPY AND VERIFY';
	$scsi_sbcop_lt{'3B'} = 'WRITE BUFFER';
	$scsi_sbcop_lt{'3C'} = 'READ BUFFER';
	$scsi_sbcop_lt{'3E'} = 'READ LONG(10)';
	$scsi_sbcop_lt{'3F'} = 'WRITE LONG(10)';
	$scsi_sbcop_lt{'40'} = 'CHANGE DEFINITION';
	$scsi_sbcop_lt{'41'} = 'WRITE SAME(10)';
	$scsi_sbcop_lt{'4C'} = 'LOG SELECT';
	$scsi_sbcop_lt{'4D'} = 'LOG SENSE';
	$scsi_sbcop_lt{'50'} = 'XDWRITE(10)';
	$scsi_sbcop_lt{'51'} = 'XPWRITE(10)';
	$scsi_sbcop_lt{'52'} = 'XDREAD(10)';
	$scsi_sbcop_lt{'55'} = 'MODE SELECT(10)';
	$scsi_sbcop_lt{'56'} = 'RESERVE(10)';
	$scsi_sbcop_lt{'57'} = 'RELEASE(10)';
	$scsi_sbcop_lt{'5A'} = 'MODE SENSE(10)';
	$scsi_sbcop_lt{'5E'} = 'PERSISTENT RESERVE IN';
	$scsi_sbcop_lt{'5F'} = 'PERSISTENT RESERVE OUT';
	$scsi_sbcop_lt{'7F'} = 'variable length CDB (more than 16 bytes)';
	$scsi_sbcop_lt{'80'} = 'XDWRITE EXTENDED(16)';
	$scsi_sbcop_lt{'81'} = 'REBUILD(16)';
	$scsi_sbcop_lt{'82'} = 'REGENERATE(16)';
	$scsi_sbcop_lt{'83'} = 'EXTENDED COPY';
	$scsi_sbcop_lt{'84'} = 'RECEIVE COPY RESULTS';
	$scsi_sbcop_lt{'85'} = 'ATA COMMAND PASS THROUGH(16)';
	$scsi_sbcop_lt{'86'} = 'ACCESS CONTROL IN';
	$scsi_sbcop_lt{'87'} = 'ACCESS CONTROL OUT';
	$scsi_sbcop_lt{'88'} = 'READ(16)';
	$scsi_sbcop_lt{'8A'} = 'WRITE(16)';
	$scsi_sbcop_lt{'8C'} = 'READ ATTRIBUTE';
	$scsi_sbcop_lt{'8D'} = 'WRITE ATTRIBUTE';
	$scsi_sbcop_lt{'8E'} = 'WRITE AND VERIFY(16)';
	$scsi_sbcop_lt{'8F'} = 'VERIFY(16)';
	$scsi_sbcop_lt{'90'} = 'PRE-FETCH(16)';
	$scsi_sbcop_lt{'91'} = 'SYNCHRONIZE CACHE(16)';
	$scsi_sbcop_lt{'92'} = 'LOCK UNLOCK CACHE(16)';
	$scsi_sbcop_lt{'93'} = 'WRITE SAME(16)';
	$scsi_sbcop_lt{'9E'} = 'READ CAPACITY(16)';
	$scsi_sbcop_lt{'A0'} = 'REPORT LUNS';
	$scsi_sbcop_lt{'A1'} = 'ATA COMMAND PASS THROUGH(12)';
	$scsi_sbcop_lt{'A2'} = 'SECURITY PROTOCOL IN';
	$scsi_sbcop_lt{'A3'} = 'MAINTENANCE (IN)';
	$scsi_sbcop_lt{'A4'} = 'MAINTENANCE (OUT)';
	$scsi_sbcop_lt{'A7'} = 'MOVE MEDIUM ATTACHED';
	$scsi_sbcop_lt{'A8'} = 'READ(12)';
	$scsi_sbcop_lt{'AA'} = 'WRITE(12)';
	$scsi_sbcop_lt{'AE'} = 'WRITE AND VERIFY(12)';
	$scsi_sbcop_lt{'AF'} = 'VERIFY(12)';
	$scsi_sbcop_lt{'B3'} = 'SET LIMITS(12)';
	$scsi_sbcop_lt{'B4'} = 'READ ELEMENT STATUS ATTACHED';
	$scsi_sbcop_lt{'B5'} = 'SECURITY PROTOCOL OUT';
	$scsi_sbcop_lt{'B7'} = 'READ DEFECT DATA(12)';
	$scsi_sbcop_lt{'BA'} = 'REDUNDANCY GROUP (IN)';
	$scsi_sbcop_lt{'BB'} = 'REDUNDANCY GROUP (OUT)';
	$scsi_sbcop_lt{'BC'} = 'SPARE (IN)';
	$scsi_sbcop_lt{'BD'} = 'SPARE (OUT)';
	$scsi_sbcop_lt{'BE'} = 'VOLUME SET (IN)';
	$scsi_sbcop_lt{'BF'} = 'VOLUME SET (OUT)';
	$scsi_sscop_lt{'00'} = 'TEST UNIT READY';
	$scsi_sscop_lt{'01'} = 'REWIND';
	$scsi_sscop_lt{'03'} = 'REQUEST SENSE';
	$scsi_sscop_lt{'04'} = 'FORMAT MEDIUM';
	$scsi_sscop_lt{'05'} = 'READ BLOCK LIMITS';
	$scsi_sscop_lt{'08'} = 'READ(6)';
	$scsi_sscop_lt{'0A'} = 'WRITE(6)';
	$scsi_sscop_lt{'0B'} = 'SET CAPACITY';
	$scsi_sscop_lt{'0F'} = 'READ REVERSE(6)';
	$scsi_sscop_lt{'10'} = 'WRITE FILEMARKS(6)';
	$scsi_sscop_lt{'11'} = 'SPACE(6)';
	$scsi_sscop_lt{'12'} = 'INQUIRY';
	$scsi_sscop_lt{'13'} = 'VERIFY(6)';
	$scsi_sscop_lt{'14'} = 'RECOVER BUFFERED DATA';
	$scsi_sscop_lt{'15'} = 'MODE SELECT(6)';
	$scsi_sscop_lt{'16'} = 'RESERVE(6)';
	$scsi_sscop_lt{'17'} = 'RELEASE(6)';
	$scsi_sscop_lt{'18'} = 'COPY';
	$scsi_sscop_lt{'19'} = 'ERASE(6)';
	$scsi_sscop_lt{'1A'} = 'MODE SENSE(6)';
	$scsi_sscop_lt{'1B'} = 'LOAD UNLOAD';
	$scsi_sscop_lt{'1C'} = 'RECEIVE DIAGNOSTIC RESULTS';
	$scsi_sscop_lt{'1D'} = 'SEND DIAGNOSTIC';
	$scsi_sscop_lt{'1E'} = 'PREVENT ALLOW MEDIUM REMOVAL';
    $scsi_sscop_lt{'28'} = 'READ(10)';
    $scsi_sscop_lt{'2A'} = 'WRITE(10)';
	$scsi_sscop_lt{'2B'} = 'LOCATE(10)';
	$scsi_sscop_lt{'34'} = 'READ POSITION';
	$scsi_sscop_lt{'39'} = 'COMPARE';
	$scsi_sscop_lt{'3A'} = 'COPY AND VERIFY';
	$scsi_sscop_lt{'3B'} = 'WRITE BUFFER';
	$scsi_sscop_lt{'3C'} = 'READ BUFFER';
	$scsi_sscop_lt{'40'} = 'CHANGE DEFINITION';
	$scsi_sscop_lt{'44'} = 'REPORT DENSITY SUPPORT';
	$scsi_sscop_lt{'4C'} = 'LOG SELECT';
	$scsi_sscop_lt{'4D'} = 'LOG SENSE';
	$scsi_sscop_lt{'55'} = 'MODE SELECT(10)';
	$scsi_sscop_lt{'56'} = 'RESERVE(10)';
	$scsi_sscop_lt{'57'} = 'RELEASE(10)';
	$scsi_sscop_lt{'5A'} = 'MODE SENSE(10)';
	$scsi_sscop_lt{'5E'} = 'PERSISTENT RESERVE IN';
	$scsi_sscop_lt{'5F'} = 'PERSISTENT RESERVE OUT';
	$scsi_sscop_lt{'80'} = 'WRITE FILEMARKS(16)';
	$scsi_sscop_lt{'81'} = 'READ REVERSE(16)';
	$scsi_sscop_lt{'83'} = 'EXTENDED COPY';
	$scsi_sscop_lt{'84'} = 'RECEIVE COPY RESULTS';
	$scsi_sscop_lt{'86'} = 'ACCESS CONTROL IN';
	$scsi_sscop_lt{'87'} = 'ACCESS CONTROL OUT';
	$scsi_sscop_lt{'88'} = 'READ(16)';
	$scsi_sscop_lt{'8A'} = 'WRITE(16)';
	$scsi_sscop_lt{'8C'} = 'READ ATTRIBUTE';
	$scsi_sscop_lt{'8D'} = 'WRITE ATTRIBUTE';
	$scsi_sscop_lt{'8F'} = 'VERIFY(16)';
	$scsi_sscop_lt{'91'} = 'SPACE(16)';
	$scsi_sscop_lt{'92'} = 'LOCATE(16)';
	$scsi_sscop_lt{'93'} = 'ERASE(16)';
	$scsi_sscop_lt{'A0'} = 'REPORT LUNS';
	$scsi_sscop_lt{'A2'} = 'SECURITY PROTOCOL IN';
	$scsi_sscop_lt{'A3'} = 'MAINTENANCE (IN)';
	$scsi_sscop_lt{'A4'} = 'MAINTENANCE (OUT)';
	$scsi_sscop_lt{'A5'} = 'MOVE MEDIUM';
	$scsi_sscop_lt{'A7'} = 'MOVE MEDIUM ATTACHED';
	$scsi_sscop_lt{'B4'} = 'READ ELEMENT STATUS ATTACHED';
	$scsi_sscop_lt{'B5'} = 'SECURITY PROTOCOL OUT';
	$scsi_sscop_lt{'B8'} = 'READ ELEMENT STATUS';

	$scsi_status_lt{'00'} = 'GOOD';
	$scsi_status_lt{'02'} = 'CHECK';
	$scsi_status_lt{'08'} = 'BUSY';
	$scsi_status_lt{'18'} = 'RESERVATION CONFLICT';
	$scsi_status_lt{'28'} = 'TASK SET FULL';
	$scsi_status_lt{'30'} = 'ACA ACTIVE';
	$scsi_status_lt{'40'} = 'TASK ABORTED';

	$scsi_skey_lt{'0'} = 'NO SENSE';
	$scsi_skey_lt{'1'} = 'RECOVERED ERROR';
	$scsi_skey_lt{'2'} = 'NOT READY';
	$scsi_skey_lt{'3'} = 'MEDIUM ERROR';
	$scsi_skey_lt{'4'} = 'HARDWARE ERROR';
	$scsi_skey_lt{'5'} = 'ILLEGAL REQUEST';
	$scsi_skey_lt{'6'} = 'UNIT ATTENTION';
	$scsi_skey_lt{'7'} = 'DATA PROTECT';
	$scsi_skey_lt{'8'} = 'BLANK CHECK';
	$scsi_skey_lt{'9'} = 'VENDOR SPECIFIC';
	$scsi_skey_lt{'A'} = 'COPY ABORTED';
	$scsi_skey_lt{'B'} = 'ABORTED COMMAND';
	$scsi_skey_lt{'C'} = '(obsolete)';
	$scsi_skey_lt{'D'} = 'VOLUME OVERFLOW';
	$scsi_skey_lt{'E'} = 'MISCOMPARE';
	$scsi_skey_lt{'F'} = '(reserved)';

	$scsi_ascq_lt{'0000'} = 'NO ADDITIONAL SENSE INFORMATION';
	$scsi_ascq_lt{'0001'} = 'FILEMARK DETECTED';
	$scsi_ascq_lt{'0002'} = 'END-OF-PARTITION/MEDIUM DETECTED';
	$scsi_ascq_lt{'0003'} = 'SETMARK DETECTED';
	$scsi_ascq_lt{'0004'} = 'BEGINNING-OF-PARTITION/MEDIUM DETECTED';
	$scsi_ascq_lt{'0005'} = 'END-OF-DATA DETECTED';
	$scsi_ascq_lt{'0006'} = 'I/O PROCESS TERMINATED';
	$scsi_ascq_lt{'0011'} = 'AUDIO PLAY OPERATION IN PROGRESS';
	$scsi_ascq_lt{'0012'} = 'AUDIO PLAY OPERATION PAUSED';
	$scsi_ascq_lt{'0013'} = 'AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED';
	$scsi_ascq_lt{'0014'} = 'AUDIO PLAY OPERATION STOPPED DUE TO ERROR';
	$scsi_ascq_lt{'0015'} = 'NO CURRENT AUDIO STATUS TO RETURN';
	$scsi_ascq_lt{'0016'} = 'OPERATION IN PROGRESS';
	$scsi_ascq_lt{'0017'} = 'CLEANING REQUESTED';
	$scsi_ascq_lt{'0018'} = 'ERASE OPERATION IN PROGRESS';
	$scsi_ascq_lt{'0019'} = 'LOCATE OPERATION IN PROGRESS';
	$scsi_ascq_lt{'001A'} = 'REWIND OPERATION IN PROGRESS';
	$scsi_ascq_lt{'001B'} = 'SET CAPACITY OPERATION IN PROGRESS';
	$scsi_ascq_lt{'001C'} = 'VERIFY OPERATION IN PROGRESS';
	$scsi_ascq_lt{'001D'} = 'ATA PASS THROUGH INFORMATION AVAILABLE';
	$scsi_ascq_lt{'0100'} = 'NO INDEX/SECTOR SIGNAL';
	$scsi_ascq_lt{'0200'} = 'NO SEEK COMPLETE';
	$scsi_ascq_lt{'0300'} = 'PERIPHERAL DEVICE WRITE FAULT';
	$scsi_ascq_lt{'0301'} = 'NO WRITE CURRENT';
	$scsi_ascq_lt{'0302'} = 'EXCESSIVE WRITE ERRORS';
	$scsi_ascq_lt{'0400'} = 'LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE';
	$scsi_ascq_lt{'0401'} = 'LOGICAL UNIT IS IN PROCESS OF BECOMING READY';
	$scsi_ascq_lt{'0402'} = 'LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED';
	$scsi_ascq_lt{'0403'} = 'LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED';
	$scsi_ascq_lt{'0404'} = 'LOGICAL UNIT NOT READY, FORMAT IN PROGRESS';
	$scsi_ascq_lt{'0405'} = 'LOGICAL UNIT NOT READY, REBUILD IN PROGRESS';
	$scsi_ascq_lt{'0406'} = 'LOGICAL UNIT NOT READY, RECALCULATION IN PROGRESS';
	$scsi_ascq_lt{'0407'} = 'LOGICAL UNIT NOT READY, OPERATION IN PROGRESS';
	$scsi_ascq_lt{'0408'} = 'LOGICAL UNIT NOT READY, LONG WRITE IN PROGRESS';
	$scsi_ascq_lt{'0409'} = 'LOGICAL UNIT NOT READY, SELF-TEST IN PROGRESS';
	$scsi_ascq_lt{'040A'} = 'LOGICAL UNIT NOT ACCESSIBLE, ASYMMETRIC ACCESS STATE TRANSITION';
	$scsi_ascq_lt{'040B'} = 'LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN STANDBY STATE';
	$scsi_ascq_lt{'040C'} = 'LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN UNAVAILABLE STATE';
	$scsi_ascq_lt{'0410'} = 'LOGICAL UNIT NOT READY, AUXILIARY MEMORY NOT ACCESSIBLE';
	$scsi_ascq_lt{'0411'} = 'LOGICAL UNIT NOT READY, NOTIFY (ENABLE SPINUP) REQUIRED';
	$scsi_ascq_lt{'0412'} = 'LOGICAL UNIT NOT READY, OFFLINE';
	$scsi_ascq_lt{'0500'} = 'LOGICAL UNIT DOES NOT RESPOND TO SELECTION';
	$scsi_ascq_lt{'0600'} = 'NO REFERENCE POSITION FOUND';
	$scsi_ascq_lt{'0700'} = 'MULTIPLE PERIPHERAL DEVICES SELECTED';
	$scsi_ascq_lt{'0800'} = 'LOGICAL UNIT COMMUNICATION FAILURE';
	$scsi_ascq_lt{'0801'} = 'LOGICAL UNIT COMMUNICATION TIME-OUT';
	$scsi_ascq_lt{'0802'} = 'LOGICAL UNIT COMMUNICATION PARITY ERROR';
	$scsi_ascq_lt{'0803'} = 'LOGICAL UNIT COMMUNICATION CRC ERROR (ULTRA-DMA/32)';
	$scsi_ascq_lt{'0804'} = 'UNREACHABLE COPY TARGET';
	$scsi_ascq_lt{'0900'} = 'TRACK FOLLOWING ERROR';
	$scsi_ascq_lt{'0901'} = 'TRACKING SERVO FAILURE';
	$scsi_ascq_lt{'0902'} = 'FOCUS SERVO FAILURE';
	$scsi_ascq_lt{'0903'} = 'SPINDLE SERVO FAILURE';
	$scsi_ascq_lt{'0904'} = 'HEAD SELECT FAULT';
	$scsi_ascq_lt{'0A00'} = 'ERROR LOG OVERFLOW';
	$scsi_ascq_lt{'0B00'} = 'WARNING';
	$scsi_ascq_lt{'0B01'} = 'WARNING - SPECIFIED TEMPERATURE EXCEEDED';
	$scsi_ascq_lt{'0B02'} = 'WARNING - ENCLOSURE DEGRADED';
	$scsi_ascq_lt{'0B03'} = 'WARNING - BACKGROUND SELF-TEST FAILED';
	$scsi_ascq_lt{'0B04'} = 'WARNING - BACKGROUND PRE-SCAN DETECTED MEDIUM ERROR';
	$scsi_ascq_lt{'0B05'} = 'WARNING - BACKGROUND MEDIUM SCAN DETECTED MEDIUM ERROR';
	$scsi_ascq_lt{'0C00'} = 'WRITE ERROR';
	$scsi_ascq_lt{'0C01'} = 'WRITE ERROR - RECOVERED WITH AUTO REALLOCATION';
	$scsi_ascq_lt{'0C02'} = 'WRITE ERROR - AUTO REALLOCATION FAILED';
	$scsi_ascq_lt{'0C03'} = 'WRITE ERROR - RECOMMEND REASSIGNMENT';
	$scsi_ascq_lt{'0C04'} = 'COMPRESSION CHECK MISCOMPARE ERROR';
	$scsi_ascq_lt{'0C05'} = 'DATA EXPANSION OCCURRED DURING COMPRESSION';
	$scsi_ascq_lt{'0C06'} = 'BLOCK NOT COMPRESSIBLE';
	$scsi_ascq_lt{'0C07'} = 'WRITE ERROR - RECOVERY NEEDED';
	$scsi_ascq_lt{'0C08'} = 'WRITE ERROR - RECOVERY FAILED';
	$scsi_ascq_lt{'0C09'} = 'WRITE ERROR - LOSS OF STREAMING';
	$scsi_ascq_lt{'0C0A'} = 'WRITE ERROR - PADDING BLOCKS ADDED';
	$scsi_ascq_lt{'0C0B'} = 'AUXILIARY MEMORY WRITE ERROR';
	$scsi_ascq_lt{'0C0C'} = 'WRITE ERROR - UNEXPECTED UNSOLICITED DATA';
	$scsi_ascq_lt{'0C0D'} = 'WRITE ERROR - NOT ENOUGH UNSOLICITED DATA';
	$scsi_ascq_lt{'0C0F'} = 'DEFECTS IN ERROR WINDOW';
	$scsi_ascq_lt{'0D00'} = 'ERROR DETECTED BY THIRD PARTY TEMPORARY INITIATOR';
	$scsi_ascq_lt{'0D01'} = 'THIRD PARTY DEVICE FAILURE';
	$scsi_ascq_lt{'0D02'} = 'COPY TARGET DEVICE NOT REACHABLE';
	$scsi_ascq_lt{'0D03'} = 'INCORRECT COPY TARGET DEVICE TYPE';
	$scsi_ascq_lt{'0D04'} = 'COPY TARGET DEVICE DATA UNDERRUN';
	$scsi_ascq_lt{'0D05'} = 'COPY TARGET DEVICE DATA OVERRUN';
	$scsi_ascq_lt{'0E00'} = 'INVALID INFORMATION UNIT';
	$scsi_ascq_lt{'0E01'} = 'INFORMATION UNIT TOO SHORT';
	$scsi_ascq_lt{'0E02'} = 'INFORMATION UNIT TOO LONG';
	$scsi_ascq_lt{'0E03'} = 'INVALID FIELD IN COMMAND INFORMATION UNIT';
	$scsi_ascq_lt{'0F00'} = '(none)';
	$scsi_ascq_lt{'1000'} = 'ID CRC OR ECC ERROR';
	$scsi_ascq_lt{'1001'} = 'LOGICAL BLOCK GUARD CHECK FAILED';
	$scsi_ascq_lt{'1002'} = 'LOGICAL BLOCK APPLICATION TAG CHECK FAILED';
	$scsi_ascq_lt{'1003'} = 'LOGICAL BLOCK REFERENCE TAG CHECK FAILED';
	$scsi_ascq_lt{'1100'} = 'UNRECOVERED READ ERROR';
	$scsi_ascq_lt{'1101'} = 'READ RETRIES EXHAUSTED';
	$scsi_ascq_lt{'1102'} = 'ERROR TOO LONG TO CORRECT';
	$scsi_ascq_lt{'1103'} = 'MULTIPLE READ ERRORS';
	$scsi_ascq_lt{'1104'} = 'UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED';
	$scsi_ascq_lt{'1105'} = 'L-EC UNCORRECTABLE ERROR';
	$scsi_ascq_lt{'1106'} = 'CIRC UNRECOVERED ERROR';
	$scsi_ascq_lt{'1107'} = 'DATA RE-SYNCHRONIZATION ERROR';
	$scsi_ascq_lt{'1108'} = 'INCOMPLETE BLOCK READ';
	$scsi_ascq_lt{'1109'} = 'NO GAP FOUND';
	$scsi_ascq_lt{'110A'} = 'MISCORRECTED ERROR';
	$scsi_ascq_lt{'110B'} = 'UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT';
	$scsi_ascq_lt{'110C'} = 'UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA';
	$scsi_ascq_lt{'110D'} = 'DE-COMPRESSION CRC ERROR';
	$scsi_ascq_lt{'110E'} = 'CANNOT DECOMPRESS USING DECLARED ALGORITHM';
	$scsi_ascq_lt{'110F'} = 'ERROR READING UPC/EAN NUMBER';
	$scsi_ascq_lt{'1110'} = 'ERROR READING ISRC NUMBER';
	$scsi_ascq_lt{'1111'} = 'READ ERROR - LOSS OF STREAMING';
	$scsi_ascq_lt{'1112'} = 'AUXILIARY MEMORY READ ERROR';
	$scsi_ascq_lt{'1113'} = 'READ ERROR - FAILED RETRANSMISSION REQUEST';
	$scsi_ascq_lt{'1114'} = 'READ ERROR - LBA MARKED BAD BY APPLICATION CLIENT';
	$scsi_ascq_lt{'1200'} = 'ADDRESS MARK NOT FOUND FOR ID FIELD';
	$scsi_ascq_lt{'1300'} = 'ADDRESS MARK NOT FOUND FOR DATA FIELD';
	$scsi_ascq_lt{'1400'} = 'RECORDED ENTITY NOT FOUND';
	$scsi_ascq_lt{'1401'} = 'RECORD NOT FOUND';
	$scsi_ascq_lt{'1402'} = 'FILEMARK OR SETMARK NOT FOUND';
	$scsi_ascq_lt{'1403'} = 'END-OF-DATA NOT FOUND';
	$scsi_ascq_lt{'1404'} = 'BLOCK SEQUENCE ERROR';
	$scsi_ascq_lt{'1405'} = 'RECORD NOT FOUND - RECOMMEND REASSIGNMENT';
	$scsi_ascq_lt{'1406'} = 'RECORD NOT FOUND - DATA AUTO-REALLOCATED';
	$scsi_ascq_lt{'1407'} = 'LOCATE OPERATION FAILURE';
	$scsi_ascq_lt{'1500'} = 'RANDOM POSITIONING ERROR';
	$scsi_ascq_lt{'1501'} = 'MECHANICAL POSITIONING ERROR';
	$scsi_ascq_lt{'1502'} = 'POSITIONING ERROR DETECTED BY READ OF MEDIUM';
	$scsi_ascq_lt{'1600'} = 'DATA SYNCHRONIZATION MARK ERROR';
	$scsi_ascq_lt{'1601'} = 'DATA SYNC ERROR - DATA REWRITTEN';
	$scsi_ascq_lt{'1602'} = 'DATA SYNC ERROR - RECOMMEND REWRITE';
	$scsi_ascq_lt{'1603'} = 'DATA SYNC ERROR - DATA AUTO-REALLOCATED';
	$scsi_ascq_lt{'1604'} = 'DATA SYNC ERROR - RECOMMEND REASSIGNMENT';
	$scsi_ascq_lt{'1700'} = 'RECOVERED DATA WITH NO ERROR CORRECTION APPLIED';
	$scsi_ascq_lt{'1701'} = 'RECOVERED DATA WITH RETRIES';
	$scsi_ascq_lt{'1702'} = 'RECOVERED DATA WITH POSITIVE HEAD OFFSET';
	$scsi_ascq_lt{'1703'} = 'RECOVERED DATA WITH NEGATIVE HEAD OFFSET';
	$scsi_ascq_lt{'1704'} = 'RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED';
	$scsi_ascq_lt{'1705'} = 'RECOVERED DATA USING PREVIOUS SECTOR ID';
	$scsi_ascq_lt{'1706'} = 'RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED';
	$scsi_ascq_lt{'1707'} = 'RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT';
	$scsi_ascq_lt{'1708'} = 'RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE';
	$scsi_ascq_lt{'1709'} = 'RECOVERED DATA WITHOUT ECC - DATA REWRITTEN';
	$scsi_ascq_lt{'1800'} = 'RECOVERED DATA WITH ERROR CORRECTION APPLIED';
	$scsi_ascq_lt{'1801'} = 'RECOVERED DATA WITH ERROR CORR. & RETRIES APPLIED';
	$scsi_ascq_lt{'1802'} = 'RECOVERED DATA - DATA AUTO-REALLOCATED';
	$scsi_ascq_lt{'1803'} = 'RECOVERED DATA WITH CIRC';
	$scsi_ascq_lt{'1804'} = 'RECOVERED DATA WITH L-EC';
	$scsi_ascq_lt{'1805'} = 'RECOVERED DATA - RECOMMEND REASSIGNMENT';
	$scsi_ascq_lt{'1806'} = 'RECOVERED DATA - RECOMMEND REWRITE';
	$scsi_ascq_lt{'1807'} = 'RECOVERED DATA WITH ECC - DATA REWRITTEN';
	$scsi_ascq_lt{'1808'} = 'RECOVERED DATA WITH LINKING';
	$scsi_ascq_lt{'1900'} = 'DEFECT LIST ERROR';
	$scsi_ascq_lt{'1901'} = 'DEFECT LIST NOT AVAILABLE';
	$scsi_ascq_lt{'1902'} = 'DEFECT LIST ERROR IN PRIMARY LIST';
	$scsi_ascq_lt{'1903'} = 'DEFECT LIST ERROR IN GROWN LIST';
	$scsi_ascq_lt{'1A00'} = 'PARAMETER LIST LENGTH ERROR';
	$scsi_ascq_lt{'1B00'} = 'SYNCHRONOUS DATA TRANSFER ERROR';
	$scsi_ascq_lt{'1C00'} = 'DEFECT LIST NOT FOUND';
	$scsi_ascq_lt{'1C01'} = 'PRIMARY DEFECT LIST NOT FOUND';
	$scsi_ascq_lt{'1C02'} = 'GROWN DEFECT LIST NOT FOUND';
	$scsi_ascq_lt{'1D00'} = 'MISCOMPARE DURING VERIFY OPERATION';
	$scsi_ascq_lt{'1E00'} = 'RECOVERED ID WITH ECC CORRECTION';
	$scsi_ascq_lt{'1F00'} = 'PARTIAL DEFECT LIST TRANSFER';
	$scsi_ascq_lt{'2000'} = 'INVALID COMMAND OPERATION CODE';
	$scsi_ascq_lt{'2001'} = 'ACCESS DENIED - INITIATOR PENDING-ENROLLED';
	$scsi_ascq_lt{'2002'} = 'ACCESS DENIED - NO ACCESS RIGHTS';
	$scsi_ascq_lt{'2003'} = 'ACCESS DENIED - INVALID MGMT ID KEY';
	$scsi_ascq_lt{'2004'} = 'ILLEGAL COMMAND WHILE IN WRITE CAPABLE STATE';
	$scsi_ascq_lt{'2005'} = 'Obsolete';
	$scsi_ascq_lt{'2006'} = 'ILLEGAL COMMAND WHILE IN EXPLICIT ADDRESS MODE';
	$scsi_ascq_lt{'2007'} = 'ILLEGAL COMMAND WHILE IN IMPLICIT ADDRESS MODE';
	$scsi_ascq_lt{'2008'} = 'ACCESS DENIED - ENROLLMENT CONFLICT';
	$scsi_ascq_lt{'2009'} = 'ACCESS DENIED - INVALID LU IDENTIFIER';
	$scsi_ascq_lt{'200A'} = 'ACCESS DENIED - INVALID PROXY TOKEN';
	$scsi_ascq_lt{'200B'} = 'ACCESS DENIED - ACL LUN CONFLICT';
	$scsi_ascq_lt{'2100'} = 'LOGICAL BLOCK ADDRESS OUT OF RANGE';
	$scsi_ascq_lt{'2101'} = 'INVALID ELEMENT ADDRESS';
	$scsi_ascq_lt{'2102'} = 'INVALID ADDRESS FOR WRITE';
	$scsi_ascq_lt{'2103'} = 'INVALID WRITE CROSSING LAYER JUMP';
	$scsi_ascq_lt{'2200'} = 'ILLEGAL FUNCTION (USE 20 00, 24 00, OR 26 00)';
	$scsi_ascq_lt{'2400'} = 'INVALID FIELD IN CDB';
	$scsi_ascq_lt{'2401'} = 'CDB DECRYPTION ERROR';
	$scsi_ascq_lt{'2402'} = 'Obsolete';
	$scsi_ascq_lt{'2403'} = 'Obsolete';
	$scsi_ascq_lt{'2404'} = 'SECURITY AUDIT VALUE FROZEN';
	$scsi_ascq_lt{'2405'} = 'SECURITY WORKING KEY FROZEN';
	$scsi_ascq_lt{'2406'} = 'NONCE NOT UNIQUE';
	$scsi_ascq_lt{'2407'} = 'NONCE TIMESTAMP OUT OF RANGE';
	$scsi_ascq_lt{'2500'} = 'LOGICAL UNIT NOT SUPPORTED';
	$scsi_ascq_lt{'2600'} = 'INVALID FIELD IN PARAMETER LIST';
	$scsi_ascq_lt{'2601'} = 'PARAMETER NOT SUPPORTED';
	$scsi_ascq_lt{'2602'} = 'PARAMETER VALUE INVALID';
	$scsi_ascq_lt{'2603'} = 'THRESHOLD PARAMETERS NOT SUPPORTED';
	$scsi_ascq_lt{'2604'} = 'INVALID RELEASE OF PERSISTENT RESERVATION';
	$scsi_ascq_lt{'2605'} = 'DATA DECRYPTION ERROR';
	$scsi_ascq_lt{'2606'} = 'TOO MANY TARGET DESCRIPTORS';
	$scsi_ascq_lt{'2607'} = 'UNSUPPORTED TARGET DESCRIPTOR TYPE CODE';
	$scsi_ascq_lt{'2608'} = 'TOO MANY SEGMENT DESCRIPTORS';
	$scsi_ascq_lt{'2609'} = 'UNSUPPORTED SEGMENT DESCRIPTOR TYPE CODE';
	$scsi_ascq_lt{'260A'} = 'UNEXPECTED INEXACT SEGMENT';
	$scsi_ascq_lt{'260B'} = 'INLINE DATA LENGTH EXCEEDED';
	$scsi_ascq_lt{'260C'} = 'INVALID OPERATION FOR COPY SOURCE OR DESTINATION';
	$scsi_ascq_lt{'260D'} = 'COPY SEGMENT GRANULARITY VIOLATION';
	$scsi_ascq_lt{'260E'} = 'INVALID PARAMETER WHILE PORT IS ENABLED';
	$scsi_ascq_lt{'260F'} = 'INVALID DATA-OUT BUFFER INTEGRITY CHECK VALUE';
	$scsi_ascq_lt{'2610'} = 'DATA DECRYPTION KEY FAIL LIMIT REACHED';
	$scsi_ascq_lt{'2611'} = 'INCOMPLETE KEY-ASSOCIATED DATA SET';
	$scsi_ascq_lt{'2612'} = 'VENDOR SPECIFIC KEY REFERENCE NOT FOUND';
	$scsi_ascq_lt{'2700'} = 'WRITE PROTECTED';
	$scsi_ascq_lt{'2701'} = 'HARDWARE WRITE PROTECTED';
	$scsi_ascq_lt{'2702'} = 'LOGICAL UNIT SOFTWARE WRITE PROTECTED';
	$scsi_ascq_lt{'2703'} = 'ASSOCIATED WRITE PROTECT';
	$scsi_ascq_lt{'2704'} = 'PERSISTENT WRITE PROTECT';
	$scsi_ascq_lt{'2705'} = 'PERMANENT WRITE PROTECT';
	$scsi_ascq_lt{'2706'} = 'CONDITIONAL WRITE PROTECT';
	$scsi_ascq_lt{'2800'} = 'NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED';
	$scsi_ascq_lt{'2801'} = 'IMPORT OR EXPORT ELEMENT ACCESSED';
	$scsi_ascq_lt{'2802'} = 'FORMAT-LAYER MAY HAVE CHANGED';
	$scsi_ascq_lt{'2900'} = 'POWER ON, RESET, OR BUS DEVICE RESET OCCURRED';
	$scsi_ascq_lt{'2901'} = 'POWER ON OCCURRED';
	$scsi_ascq_lt{'2902'} = 'SCSI BUS RESET OCCURRED';
	$scsi_ascq_lt{'2903'} = 'BUS DEVICE RESET FUNCTION OCCURRED';
	$scsi_ascq_lt{'2904'} = 'DEVICE INTERNAL RESET';
	$scsi_ascq_lt{'2905'} = 'TRANSCEIVER MODE CHANGED TO SINGLE-ENDED';
	$scsi_ascq_lt{'2906'} = 'TRANSCEIVER MODE CHANGED TO LVD';
	$scsi_ascq_lt{'2907'} = 'I_T NEXUS LOSS OCCURRED';
	$scsi_ascq_lt{'2A00'} = 'PARAMETERS CHANGED';
	$scsi_ascq_lt{'2A01'} = 'MODE PARAMETERS CHANGED';
	$scsi_ascq_lt{'2A02'} = 'LOG PARAMETERS CHANGED';
	$scsi_ascq_lt{'2A03'} = 'RESERVATIONS PREEMPTED';
	$scsi_ascq_lt{'2A04'} = 'RESERVATIONS RELEASED';
	$scsi_ascq_lt{'2A05'} = 'REGISTRATIONS PREEMPTED';
	$scsi_ascq_lt{'2A06'} = 'ASYMMETRIC ACCESS STATE CHANGED';
	$scsi_ascq_lt{'2A07'} = 'IMPLICIT ASYMMETRIC ACCESS STATE TRANSITION FAILED';
	$scsi_ascq_lt{'2A08'} = 'PRIORITY CHANGED';
	$scsi_ascq_lt{'2A09'} = 'CAPACITY DATA HAS CHANGED';
	$scsi_ascq_lt{'2A10'} = 'TIMESTAMP CHANGED';
	$scsi_ascq_lt{'2A11'} = 'DATA ENCRYPTION PARAMETERS CHANGED BY ANOTHER I_T NEXUS';
	$scsi_ascq_lt{'2A12'} = 'DATA ENCRYPTION PARAMETERS CHANGED BY VENDOR SPECIFIC EVENT';
	$scsi_ascq_lt{'2A13'} = 'DATA ENCRYPTION KEY INSTANCE COUNTER HAS CHANGED';
	$scsi_ascq_lt{'2B00'} = 'COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT';
	$scsi_ascq_lt{'2C00'} = 'COMMAND SEQUENCE ERROR';
	$scsi_ascq_lt{'2C01'} = 'TOO MANY WINDOWS SPECIFIED';
	$scsi_ascq_lt{'2C02'} = 'INVALID COMBINATION OF WINDOWS SPECIFIED';
	$scsi_ascq_lt{'2C03'} = 'CURRENT PROGRAM AREA IS NOT EMPTY';
	$scsi_ascq_lt{'2C04'} = 'CURRENT PROGRAM AREA IS EMPTY';
	$scsi_ascq_lt{'2C05'} = 'ILLEGAL POWER CONDITION REQUEST';
	$scsi_ascq_lt{'2C06'} = 'PERSISTENT PREVENT CONFLICT';
	$scsi_ascq_lt{'2C07'} = 'PREVIOUS BUSY STATUS';
	$scsi_ascq_lt{'2C08'} = 'PREVIOUS TASK SET FULL STATUS';
	$scsi_ascq_lt{'2C09'} = 'PREVIOUS RESERVATION CONFLICT STATUS';
	$scsi_ascq_lt{'2C0A'} = 'PARTITION OR COLLECTION CONTAINS USER OBJECTS';
	$scsi_ascq_lt{'2C0B'} = 'NOT RESERVED';
	$scsi_ascq_lt{'2D00'} = 'OVERWRITE ERROR ON UPDATE IN PLACE';
	$scsi_ascq_lt{'2E00'} = 'INSUFFICIENT TIME FOR OPERATION';
	$scsi_ascq_lt{'2F00'} = 'COMMANDS CLEARED BY ANOTHER INITIATOR';
	$scsi_ascq_lt{'2F01'} = 'COMMANDS CLEARED BY POWER LOSS NOTIFICATION';
	$scsi_ascq_lt{'2F02'} = 'COMMANDS CLEARED BY DEVICE SERVER';
	$scsi_ascq_lt{'3000'} = 'INCOMPATIBLE MEDIUM INSTALLED';
	$scsi_ascq_lt{'3001'} = 'CANNOT READ MEDIUM - UNKNOWN FORMAT';
	$scsi_ascq_lt{'3002'} = 'CANNOT READ MEDIUM - INCOMPATIBLE FORMAT';
	$scsi_ascq_lt{'3003'} = 'CLEANING CARTRIDGE INSTALLED';
	$scsi_ascq_lt{'3004'} = 'CANNOT WRITE MEDIUM - UNKNOWN FORMAT';
	$scsi_ascq_lt{'3005'} = 'CANNOT WRITE MEDIUM - INCOMPATIBLE FORMAT';
	$scsi_ascq_lt{'3006'} = 'CANNOT FORMAT MEDIUM - INCOMPATIBLE MEDIUM';
	$scsi_ascq_lt{'3007'} = 'CLEANING FAILURE';
	$scsi_ascq_lt{'3008'} = 'CANNOT WRITE - APPLICATION CODE MISMATCH';
	$scsi_ascq_lt{'3009'} = 'CURRENT SESSION NOT FIXATED FOR APPEND';
	$scsi_ascq_lt{'300A'} = 'CLEANING REQUEST REJECTED';
	$scsi_ascq_lt{'300C'} = 'WORM MEDIUM - OVERWRITE ATTEMPTED';
	$scsi_ascq_lt{'300D'} = 'WORM MEDIUM - INTEGRITY CHECK';
	$scsi_ascq_lt{'3010'} = 'MEDIUM NOT FORMATTED';
	$scsi_ascq_lt{'3100'} = 'MEDIUM FORMAT CORRUPTED';
	$scsi_ascq_lt{'3101'} = 'FORMAT COMMAND FAILED';
	$scsi_ascq_lt{'3102'} = 'ZONED FORMATTING FAILED DUE TO SPARE LINKING';
	$scsi_ascq_lt{'3200'} = 'NO DEFECT SPARE LOCATION AVAILABLE';
	$scsi_ascq_lt{'3201'} = 'DEFECT LIST UPDATE FAILURE';
	$scsi_ascq_lt{'3300'} = 'TAPE LENGTH ERROR';
	$scsi_ascq_lt{'3400'} = 'ENCLOSURE FAILURE';
	$scsi_ascq_lt{'3500'} = 'ENCLOSURE SERVICES FAILURE';
	$scsi_ascq_lt{'3501'} = 'UNSUPPORTED ENCLOSURE FUNCTION';
	$scsi_ascq_lt{'3502'} = 'ENCLOSURE SERVICES UNAVAILABLE';
	$scsi_ascq_lt{'3503'} = 'ENCLOSURE SERVICES TRANSFER FAILURE';
	$scsi_ascq_lt{'3504'} = 'ENCLOSURE SERVICES TRANSFER REFUSED';
	$scsi_ascq_lt{'3505'} = 'ENCLOSURE SERVICES CHECKSUM ERROR';
	$scsi_ascq_lt{'3600'} = 'RIBBON, INK, OR TONER FAILURE';
	$scsi_ascq_lt{'3700'} = 'ROUNDED PARAMETER';
	$scsi_ascq_lt{'3800'} = 'EVENT STATUS NOTIFICATION';
	$scsi_ascq_lt{'3802'} = 'ESN - POWER MANAGEMENT CLASS EVENT';
	$scsi_ascq_lt{'3804'} = 'ESN - MEDIA CLASS EVENT';
	$scsi_ascq_lt{'3806'} = 'ESN - DEVICE BUSY CLASS EVENT';
	$scsi_ascq_lt{'3900'} = 'SAVING PARAMETERS NOT SUPPORTED';
	$scsi_ascq_lt{'3A00'} = 'MEDIUM NOT PRESENT';
	$scsi_ascq_lt{'3A01'} = 'MEDIUM NOT PRESENT - TRAY CLOSED';
	$scsi_ascq_lt{'3A02'} = 'MEDIUM NOT PRESENT - TRAY OPEN';
	$scsi_ascq_lt{'3A03'} = 'MEDIUM NOT PRESENT - LOADABLE';
	$scsi_ascq_lt{'3A04'} = 'MEDIUM NOT PRESENT - MEDIUM AUXILIARY MEMORY ACCESSIBLE';
	$scsi_ascq_lt{'3B00'} = 'SEQUENTIAL POSITIONING ERROR';
	$scsi_ascq_lt{'3B01'} = 'TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM';
	$scsi_ascq_lt{'3B02'} = 'TAPE POSITION ERROR AT END-OF-MEDIUM';
	$scsi_ascq_lt{'3B03'} = 'TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY';
	$scsi_ascq_lt{'3B04'} = 'SLEW FAILURE';
	$scsi_ascq_lt{'3B05'} = 'PAPER JAM';
	$scsi_ascq_lt{'3B06'} = 'FAILED TO SENSE TOP-OF-FORM';
	$scsi_ascq_lt{'3B07'} = 'FAILED TO SENSE BOTTOM-OF-FORM';
	$scsi_ascq_lt{'3B08'} = 'REPOSITION ERROR';
	$scsi_ascq_lt{'3B09'} = 'READ PAST END OF MEDIUM';
	$scsi_ascq_lt{'3B0A'} = 'READ PAST BEGINNING OF MEDIUM';
	$scsi_ascq_lt{'3B0B'} = 'POSITION PAST END OF MEDIUM';
	$scsi_ascq_lt{'3B0C'} = 'POSITION PAST BEGINNING OF MEDIUM';
	$scsi_ascq_lt{'3B0D'} = 'MEDIUM DESTINATION ELEMENT FULL';
	$scsi_ascq_lt{'3B0E'} = 'MEDIUM SOURCE ELEMENT EMPTY';
	$scsi_ascq_lt{'3B0F'} = 'END OF MEDIUM REACHED';
	$scsi_ascq_lt{'3B11'} = 'MEDIUM MAGAZINE NOT ACCESSIBLE';
	$scsi_ascq_lt{'3B12'} = 'MEDIUM MAGAZINE REMOVED';
	$scsi_ascq_lt{'3B13'} = 'MEDIUM MAGAZINE INSERTED';
	$scsi_ascq_lt{'3B14'} = 'MEDIUM MAGAZINE LOCKED';
	$scsi_ascq_lt{'3B15'} = 'MEDIUM MAGAZINE UNLOCKED';
	$scsi_ascq_lt{'3B16'} = 'MECHANICAL POSITIONING OR CHANGER ERROR';
	$scsi_ascq_lt{'3B17'} = 'READ PAST END OF USER OBJECT';
	$scsi_ascq_lt{'3D00'} = 'INVALID BITS IN IDENTIFY MESSAGE';
	$scsi_ascq_lt{'3E00'} = 'LOGICAL UNIT HAS NOT SELF-CONFIGURED YET';
	$scsi_ascq_lt{'3E01'} = 'LOGICAL UNIT FAILURE';
	$scsi_ascq_lt{'3E02'} = 'TIMEOUT ON LOGICAL UNIT';
	$scsi_ascq_lt{'3E03'} = 'LOGICAL UNIT FAILED SELF-TEST';
	$scsi_ascq_lt{'3E04'} = 'LOGICAL UNIT UNABLE TO UPDATE SELF-TEST LOG';
	$scsi_ascq_lt{'3F00'} = 'TARGET OPERATING CONDITIONS HAVE CHANGED';
	$scsi_ascq_lt{'3F01'} = 'MICROCODE HAS BEEN CHANGED';
	$scsi_ascq_lt{'3F02'} = 'CHANGED OPERATING DEFINITION';
	$scsi_ascq_lt{'3F03'} = 'INQUIRY DATA HAS CHANGED';
	$scsi_ascq_lt{'3F04'} = 'COMPONENT DEVICE ATTACHED';
	$scsi_ascq_lt{'3F05'} = 'DEVICE IDENTIFIER CHANGED';
	$scsi_ascq_lt{'3F06'} = 'REDUNDANCY GROUP CREATED OR MODIFIED';
	$scsi_ascq_lt{'3F07'} = 'REDUNDANCY GROUP DELETED';
	$scsi_ascq_lt{'3F08'} = 'SPARE CREATED OR MODIFIED';
	$scsi_ascq_lt{'3F09'} = 'SPARE DELETED';
	$scsi_ascq_lt{'3F0A'} = 'VOLUME SET CREATED OR MODIFIED';
	$scsi_ascq_lt{'3F0B'} = 'VOLUME SET DELETED';
	$scsi_ascq_lt{'3F0C'} = 'VOLUME SET DEASSIGNED';
	$scsi_ascq_lt{'3F0D'} = 'VOLUME SET REASSIGNED';
	$scsi_ascq_lt{'3F0E'} = 'REPORTED LUNS DATA HAS CHANGED';
	$scsi_ascq_lt{'3F0F'} = 'ECHO BUFFER OVERWRITTEN';
	$scsi_ascq_lt{'3F10'} = 'MEDIUM LOADABLE';
	$scsi_ascq_lt{'3F11'} = 'MEDIUM AUXILIARY MEMORY ACCESSIBLE';
	$scsi_ascq_lt{'3F12'} = 'iSCSI IP ADDRESS ADDED';
	$scsi_ascq_lt{'3F13'} = 'iSCSI IP ADDRESS REMOVED';
	$scsi_ascq_lt{'3F14'} = 'iSCSI IP ADDRESS CHANGED';
	$scsi_ascq_lt{'4000'} = 'RAM FAILURE (SHOULD USE 40 NN)';
	$scsi_ascq_lt{'40NN'} = 'DIAGNOSTIC FAILURE ON COMPONENT NN (80h-FFh)';
	$scsi_ascq_lt{'4100'} = 'DATA PATH FAILURE (SHOULD USE 40 NN)';
	$scsi_ascq_lt{'4200'} = 'POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN)';
	$scsi_ascq_lt{'4300'} = 'MESSAGE ERROR';
	$scsi_ascq_lt{'4400'} = 'INTERNAL TARGET FAILURE';
	$scsi_ascq_lt{'4471'} = 'ATA DEVICE FAILED SET FEATURES';
	$scsi_ascq_lt{'4500'} = 'SELECT OR RESELECT FAILURE';
	$scsi_ascq_lt{'4600'} = 'UNSUCCESSFUL SOFT RESET';
	$scsi_ascq_lt{'4700'} = 'SCSI PARITY ERROR';
	$scsi_ascq_lt{'4701'} = 'DATA PHASE CRC ERROR DETECTED';
	$scsi_ascq_lt{'4702'} = 'SCSI PARITY ERROR DETECTED DURING ST DATA PHASE';
	$scsi_ascq_lt{'4703'} = 'INFORMATION UNIT iuCRC ERROR DETECTED';
	$scsi_ascq_lt{'4704'} = 'ASYNCHRONOUS INFORMATION PROTECTION ERROR DETECTED';
	$scsi_ascq_lt{'4705'} = 'PROTOCOL SERVICE CRC ERROR';
	$scsi_ascq_lt{'4706'} = 'PHY TEST FUNCTION IN PROGRESS';
	$scsi_ascq_lt{'477F'} = 'SOME COMMANDS CLEARED BY ISCSI PROTOCOL EVENT';
	$scsi_ascq_lt{'4800'} = 'INITIATOR DETECTED ERROR MESSAGE RECEIVED';
	$scsi_ascq_lt{'4900'} = 'INVALID MESSAGE ERROR';
	$scsi_ascq_lt{'4A00'} = 'COMMAND PHASE ERROR';
	$scsi_ascq_lt{'4B00'} = 'DATA PHASE ERROR';
	$scsi_ascq_lt{'4B01'} = 'INVALID TARGET PORT TRANSFER TAG RECEIVED';
	$scsi_ascq_lt{'4B02'} = 'TOO MUCH WRITE DATA';
	$scsi_ascq_lt{'4B03'} = 'ACK/NAK TIMEOUT';
	$scsi_ascq_lt{'4B04'} = 'NAK RECEIVED';
	$scsi_ascq_lt{'4B05'} = 'DATA OFFSET ERROR';
	$scsi_ascq_lt{'4B06'} = 'INITIATOR RESPONSE TIMEOUT';
	$scsi_ascq_lt{'4C00'} = 'LOGICAL UNIT FAILED SELF-CONFIGURATION';
	$scsi_ascq_lt{'4DNN'} = 'TAGGED OVERLAPPED COMMANDS (NN = TASK TAG)';
	$scsi_ascq_lt{'4E00'} = 'OVERLAPPED COMMANDS ATTEMPTED';
	$scsi_ascq_lt{'5000'} = 'WRITE APPEND ERROR';
	$scsi_ascq_lt{'5001'} = 'WRITE APPEND POSITION ERROR';
	$scsi_ascq_lt{'5002'} = 'POSITION ERROR RELATED TO TIMING';
	$scsi_ascq_lt{'5100'} = 'ERASE FAILURE';
	$scsi_ascq_lt{'5101'} = 'ERASE FAILURE - INCOMPLETE ERASE OPERATION DETECTED';
	$scsi_ascq_lt{'5200'} = 'CARTRIDGE FAULT';
	$scsi_ascq_lt{'5300'} = 'MEDIA LOAD OR EJECT FAILED';
	$scsi_ascq_lt{'5301'} = 'UNLOAD TAPE FAILURE';
	$scsi_ascq_lt{'5302'} = 'MEDIUM REMOVAL PREVENTED';
	$scsi_ascq_lt{'5303'} = 'MEDIUM REMOVAL PREVENTED BY DATA TRANSFER ELEMENT';
	$scsi_ascq_lt{'5304'} = 'MEDIUM THREAD OR UNTHREAD FAILURE';
	$scsi_ascq_lt{'5400'} = 'SCSI TO HOST SYSTEM INTERFACE FAILURE';
	$scsi_ascq_lt{'5500'} = 'SYSTEM RESOURCE FAILURE';
	$scsi_ascq_lt{'5501'} = 'SYSTEM BUFFER FULL';
	$scsi_ascq_lt{'5502'} = 'INSUFFICIENT RESERVATION RESOURCES';
	$scsi_ascq_lt{'5503'} = 'INSUFFICIENT RESOURCES';
	$scsi_ascq_lt{'5504'} = 'INSUFFICIENT REGISTRATION RESOURCES';
	$scsi_ascq_lt{'5505'} = 'INSUFFICIENT ACCESS CONTROL RESOURCES';
	$scsi_ascq_lt{'5506'} = 'AUXILIARY MEMORY OUT OF SPACE';
	$scsi_ascq_lt{'5507'} = 'QUOTA ERROR';
	$scsi_ascq_lt{'5508'} = 'MAXIMUM NUMBER OF SUPPLEMENTAL DECRYPTION KEYS EXCEEDED';
	$scsi_ascq_lt{'5700'} = 'UNABLE TO RECOVER TABLE-OF-CONTENTS';
	$scsi_ascq_lt{'5800'} = 'GENERATION DOES NOT EXIST';
	$scsi_ascq_lt{'5900'} = 'UPDATED BLOCK READ';
	$scsi_ascq_lt{'5A00'} = 'OPERATOR REQUEST OR STATE CHANGE INPUT';
	$scsi_ascq_lt{'5A01'} = 'OPERATOR MEDIUM REMOVAL REQUEST';
	$scsi_ascq_lt{'5A02'} = 'OPERATOR SELECTED WRITE PROTECT';
	$scsi_ascq_lt{'5A03'} = 'OPERATOR SELECTED WRITE PERMIT';
	$scsi_ascq_lt{'5B00'} = 'LOG EXCEPTION';
	$scsi_ascq_lt{'5B01'} = 'THRESHOLD CONDITION MET';
	$scsi_ascq_lt{'5B02'} = 'LOG COUNTER AT MAXIMUM';
	$scsi_ascq_lt{'5B03'} = 'LOG LIST CODES EXHAUSTED';
	$scsi_ascq_lt{'5C00'} = 'RPL STATUS CHANGE';
	$scsi_ascq_lt{'5C01'} = 'SPINDLES SYNCHRONIZED';
	$scsi_ascq_lt{'5C02'} = 'SPINDLES NOT SYNCHRONIZED';
	$scsi_ascq_lt{'5D00'} = 'FAILURE PREDICTION THRESHOLD EXCEEDED';
	$scsi_ascq_lt{'5D01'} = 'MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED';
	$scsi_ascq_lt{'5D02'} = 'LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED';
	$scsi_ascq_lt{'5D03'} = 'SPARE AREA EXHAUSTION PREDICTION THRESHOLD EXCEEDED';
	$scsi_ascq_lt{'5D10'} = 'HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE';
	$scsi_ascq_lt{'5D11'} = 'HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D12'} = 'HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D13'} = 'HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D14'} = 'HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS';
	$scsi_ascq_lt{'5D15'} = 'HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH';
	$scsi_ascq_lt{'5D16'} = 'HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH';
	$scsi_ascq_lt{'5D17'} = 'HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS';
	$scsi_ascq_lt{'5D18'} = 'HARDWARE IMPENDING FAILURE CONTROLLER DETECTED';
	$scsi_ascq_lt{'5D19'} = 'HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE';
	$scsi_ascq_lt{'5D1A'} = 'HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE';
	$scsi_ascq_lt{'5D1B'} = 'HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT';
	$scsi_ascq_lt{'5D1C'} = 'HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT';
	$scsi_ascq_lt{'5D20'} = 'CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE';
	$scsi_ascq_lt{'5D21'} = 'CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D22'} = 'CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D23'} = 'CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D24'} = 'CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS';
	$scsi_ascq_lt{'5D25'} = 'CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH';
	$scsi_ascq_lt{'5D26'} = 'CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH';
	$scsi_ascq_lt{'5D27'} = 'CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS';
	$scsi_ascq_lt{'5D28'} = 'CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED';
	$scsi_ascq_lt{'5D29'} = 'CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE';
	$scsi_ascq_lt{'5D2A'} = 'CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE';
	$scsi_ascq_lt{'5D2B'} = 'CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT';
	$scsi_ascq_lt{'5D2C'} = 'CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT';
	$scsi_ascq_lt{'5D30'} = 'DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE';
	$scsi_ascq_lt{'5D31'} = 'DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D32'} = 'DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D33'} = 'DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D34'} = 'DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS';
	$scsi_ascq_lt{'5D35'} = 'DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH';
	$scsi_ascq_lt{'5D36'} = 'DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH';
	$scsi_ascq_lt{'5D37'} = 'DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS';
	$scsi_ascq_lt{'5D38'} = 'DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED';
	$scsi_ascq_lt{'5D39'} = 'DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE';
	$scsi_ascq_lt{'5D3A'} = 'DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE';
	$scsi_ascq_lt{'5D3B'} = 'DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT';
	$scsi_ascq_lt{'5D3C'} = 'DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT';
	$scsi_ascq_lt{'5D40'} = 'SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE';
	$scsi_ascq_lt{'5D41'} = 'SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D42'} = 'SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D43'} = 'SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D44'} = 'SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS';
	$scsi_ascq_lt{'5D45'} = 'SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH';
	$scsi_ascq_lt{'5D46'} = 'SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH';
	$scsi_ascq_lt{'5D47'} = 'SERVO IMPENDING FAILURE CHANNEL PARAMETRICS';
	$scsi_ascq_lt{'5D48'} = 'SERVO IMPENDING FAILURE CONTROLLER DETECTED';
	$scsi_ascq_lt{'5D49'} = 'SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE';
	$scsi_ascq_lt{'5D4A'} = 'SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE';
	$scsi_ascq_lt{'5D4B'} = 'SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT';
	$scsi_ascq_lt{'5D4C'} = 'SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT';
	$scsi_ascq_lt{'5D50'} = 'SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE';
	$scsi_ascq_lt{'5D51'} = 'SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D52'} = 'SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D53'} = 'SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D54'} = 'SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS';
	$scsi_ascq_lt{'5D55'} = 'SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH';
	$scsi_ascq_lt{'5D56'} = 'SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH';
	$scsi_ascq_lt{'5D57'} = 'SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS';
	$scsi_ascq_lt{'5D58'} = 'SPINDLE IMPENDING FAILURE CONTROLLER DETECTED';
	$scsi_ascq_lt{'5D59'} = 'SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE';
	$scsi_ascq_lt{'5D5A'} = 'SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE';
	$scsi_ascq_lt{'5D5B'} = 'SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT';
	$scsi_ascq_lt{'5D5C'} = 'SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT';
	$scsi_ascq_lt{'5D60'} = 'FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE';
	$scsi_ascq_lt{'5D61'} = 'FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D62'} = 'FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D63'} = 'FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH';
	$scsi_ascq_lt{'5D64'} = 'FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS';
	$scsi_ascq_lt{'5D65'} = 'FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH';
	$scsi_ascq_lt{'5D66'} = 'FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH';
	$scsi_ascq_lt{'5D67'} = 'FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS';
	$scsi_ascq_lt{'5D68'} = 'FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED';
	$scsi_ascq_lt{'5D69'} = 'FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE';
	$scsi_ascq_lt{'5D6A'} = 'FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE';
	$scsi_ascq_lt{'5D6B'} = 'FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT';
	$scsi_ascq_lt{'5D6C'} = 'FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT';
	$scsi_ascq_lt{'5DFF'} = 'FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE)';
	$scsi_ascq_lt{'5E00'} = 'LOW POWER CONDITION ON';
	$scsi_ascq_lt{'5E01'} = 'IDLE CONDITION ACTIVATED BY TIMER';
	$scsi_ascq_lt{'5E02'} = 'STANDBY CONDITION ACTIVATED BY TIMER';
	$scsi_ascq_lt{'5E03'} = 'IDLE CONDITION ACTIVATED BY COMMAND';
	$scsi_ascq_lt{'5E04'} = 'STANDBY CONDITION ACTIVATED BY COMMAND';
	$scsi_ascq_lt{'5E41'} = 'POWER STATE CHANGE TO ACTIVE';
	$scsi_ascq_lt{'5E42'} = 'POWER STATE CHANGE TO IDLE';
	$scsi_ascq_lt{'5E43'} = 'POWER STATE CHANGE TO STANDBY';
	$scsi_ascq_lt{'5E45'} = 'POWER STATE CHANGE TO SLEEP';
	$scsi_ascq_lt{'5E47'} = 'POWER STATE CHANGE TO DEVICE CONTROL';
	$scsi_ascq_lt{'6000'} = 'LAMP FAILURE';
	$scsi_ascq_lt{'6100'} = 'VIDEO ACQUISITION ERROR';
	$scsi_ascq_lt{'6101'} = 'UNABLE TO ACQUIRE VIDEO';
	$scsi_ascq_lt{'6102'} = 'OUT OF FOCUS';
	$scsi_ascq_lt{'6200'} = 'SCAN HEAD POSITIONING ERROR';
	$scsi_ascq_lt{'6300'} = 'END OF USER AREA ENCOUNTERED ON THIS TRACK';
	$scsi_ascq_lt{'6301'} = 'PACKET DOES NOT FIT IN AVAILABLE SPACE';
	$scsi_ascq_lt{'6400'} = 'ILLEGAL MODE FOR THIS TRACK';
	$scsi_ascq_lt{'6401'} = 'INVALID PACKET SIZE';
	$scsi_ascq_lt{'6500'} = 'VOLTAGE FAULT';
	$scsi_ascq_lt{'6600'} = 'AUTOMATIC DOCUMENT FEEDER COVER UP';
	$scsi_ascq_lt{'6601'} = 'AUTOMATIC DOCUMENT FEEDER LIFT UP';
	$scsi_ascq_lt{'6602'} = 'DOCUMENT JAM IN AUTOMATIC DOCUMENT FEEDER';
	$scsi_ascq_lt{'6603'} = 'DOCUMENT MISS FEED AUTOMATIC IN DOCUMENT FEEDER';
	$scsi_ascq_lt{'6700'} = 'CONFIGURATION FAILURE';
	$scsi_ascq_lt{'6701'} = 'CONFIGURATION OF INCAPABLE LOGICAL UNITS FAILED';
	$scsi_ascq_lt{'6702'} = 'ADD LOGICAL UNIT FAILED';
	$scsi_ascq_lt{'6703'} = 'MODIFICATION OF LOGICAL UNIT FAILED';
	$scsi_ascq_lt{'6704'} = 'EXCHANGE OF LOGICAL UNIT FAILED';
	$scsi_ascq_lt{'6705'} = 'REMOVE OF LOGICAL UNIT FAILED';
	$scsi_ascq_lt{'6706'} = 'ATTACHMENT OF LOGICAL UNIT FAILED';
	$scsi_ascq_lt{'6707'} = 'CREATION OF LOGICAL UNIT FAILED';
	$scsi_ascq_lt{'6708'} = 'ASSIGN FAILURE OCCURRED';
	$scsi_ascq_lt{'6709'} = 'MULTIPLY ASSIGNED LOGICAL UNIT';
	$scsi_ascq_lt{'670A'} = 'SET TARGET PORT GROUPS COMMAND FAILED';
	$scsi_ascq_lt{'670B'} = 'ATA DEVICE FEATURE NOT ENABLED';
	$scsi_ascq_lt{'6800'} = 'LOGICAL UNIT NOT CONFIGURED';
	$scsi_ascq_lt{'6900'} = 'DATA LOSS ON LOGICAL UNIT';
	$scsi_ascq_lt{'6901'} = 'MULTIPLE LOGICAL UNIT FAILURES';
	$scsi_ascq_lt{'6902'} = 'PARITY/DATA MISMATCH';
	$scsi_ascq_lt{'6A00'} = 'INFORMATIONAL, REFER TO LOG';
	$scsi_ascq_lt{'6B00'} = 'STATE CHANGE HAS OCCURRED';
	$scsi_ascq_lt{'6B01'} = 'REDUNDANCY LEVEL GOT BETTER';
	$scsi_ascq_lt{'6B02'} = 'REDUNDANCY LEVEL GOT WORSE';
	$scsi_ascq_lt{'6C00'} = 'REBUILD FAILURE OCCURRED';
	$scsi_ascq_lt{'6D00'} = 'RECALCULATE FAILURE OCCURRED';
	$scsi_ascq_lt{'6E00'} = 'COMMAND TO LOGICAL UNIT FAILED';
	$scsi_ascq_lt{'6F00'} = 'COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE';
	$scsi_ascq_lt{'6F01'} = 'COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT PRESENT';
	$scsi_ascq_lt{'6F02'} = 'COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED';
	$scsi_ascq_lt{'6F03'} = 'READ OF SCRAMBLED SECTOR WITHOUT AUTHENTICATION';
	$scsi_ascq_lt{'6F04'} = 'MEDIA REGION CODE IS MISMATCHED TO LOGICAL UNIT REGION';
	$scsi_ascq_lt{'6F05'} = 'DRIVE REGION MUST BE PERMANENT/REGION RESET COUNT ERROR';
	$scsi_ascq_lt{'6F06'} = 'INSUFFICIENT BLOCK COUNT FOR BINDING NONCE RECORDING';
	$scsi_ascq_lt{'6F07'} = 'CONFLICT IN BINDING NONCE RECORDING';
	$scsi_ascq_lt{'70NN'} = 'DECOMPRESSION EXCEPTION SHORT ALGORITHM ID OF NN';
	$scsi_ascq_lt{'7100'} = 'DECOMPRESSION EXCEPTION LONG ALGORITHM ID';
	$scsi_ascq_lt{'7200'} = 'SESSION FIXATION ERROR';
	$scsi_ascq_lt{'7201'} = 'SESSION FIXATION ERROR WRITING LEAD-IN';
	$scsi_ascq_lt{'7202'} = 'SESSION FIXATION ERROR WRITING LEAD-OUT';
	$scsi_ascq_lt{'7203'} = 'SESSION FIXATION ERROR - INCOMPLETE TRACK IN SESSION';
	$scsi_ascq_lt{'7204'} = 'EMPTY OR PARTIALLY WRITTEN RESERVED TRACK';
	$scsi_ascq_lt{'7205'} = 'NO MORE TRACK RESERVATIONS ALLOWED';
	$scsi_ascq_lt{'7206'} = 'RMZ EXTENSION IS NOT ALLOWED';
	$scsi_ascq_lt{'7207'} = 'NO MORE TEST ZONE EXTENSIONS ARE ALLOWED';
	$scsi_ascq_lt{'7300'} = 'CD CONTROL ERROR';
	$scsi_ascq_lt{'7301'} = 'POWER CALIBRATION AREA ALMOST FULL';
	$scsi_ascq_lt{'7302'} = 'POWER CALIBRATION AREA IS FULL';
	$scsi_ascq_lt{'7303'} = 'POWER CALIBRATION AREA ERROR';
	$scsi_ascq_lt{'7304'} = 'PROGRAM MEMORY AREA UPDATE FAILURE';
	$scsi_ascq_lt{'7305'} = 'PROGRAM MEMORY AREA IS FULL';
	$scsi_ascq_lt{'7306'} = 'RMA/PMA IS ALMOST FULL';
	$scsi_ascq_lt{'7310'} = 'CURRENT POWER CALIBRATION AREA ALMOST FULL';
	$scsi_ascq_lt{'7311'} = 'CURRENT POWER CALIBRATION AREA IS FULL';
	$scsi_ascq_lt{'7317'} = 'RDZ IS FULL';
	$scsi_ascq_lt{'7400'} = 'SECURITY ERROR';
	$scsi_ascq_lt{'7401'} = 'UNABLE TO DECRYPT DATA';
	$scsi_ascq_lt{'7402'} = 'UNENCRYPTED DATA ENCOUNTERED WHILE DECRYPTING';
	$scsi_ascq_lt{'7403'} = 'INCORRECT DATA ENCRYPTION KEY';
	$scsi_ascq_lt{'7404'} = 'CRYPTOGRAPHIC INTEGRITY VALIDATION FAILED';
	$scsi_ascq_lt{'7405'} = 'ERROR DECRYPTING DATA';
	$scsi_ascq_lt{'7471'} = 'LOGICAL UNIT ACCESS NOT AUTHORIZED';

	$fc_payload_op_lt{'00000000'} = '(0x00; non-ELS)';
	$fc_payload_op_lt{'01000000'} = 'LS_RJT (or NS req?)';
	$fc_payload_op_lt{'02000000'} = 'LS_ACC';
	$fc_payload_op_lt{'03000000'} = 'PLOGI';
	$fc_payload_op_lt{'04000000'} = 'FLOGI';
	$fc_payload_op_lt{'05000000'} = 'LOGO';
	$fc_payload_op_lt{'06000000'} = 'ABTX';
	$fc_payload_op_lt{'07000000'} = 'RCS';
	$fc_payload_op_lt{'08000000'} = 'RES';
	$fc_payload_op_lt{'09000000'} = 'RSS';
	$fc_payload_op_lt{'0A000000'} = 'RSI';
	$fc_payload_op_lt{'0B000000'} = 'ESTS';
	$fc_payload_op_lt{'0C000000'} = 'ESTC';
	$fc_payload_op_lt{'0D000000'} = 'ADVC';
	$fc_payload_op_lt{'0E000000'} = 'RTV';
	$fc_payload_op_lt{'0F000000'} = 'RLS';
	$fc_payload_op_lt{'10000000'} = 'ECHO';
	$fc_payload_op_lt{'11000000'} = 'TEST';
	$fc_payload_op_lt{'12000000'} = 'RRQ';
	$fc_payload_op_lt{'13000000'} = 'REC';
	$fc_payload_op_lt{'14000000'} = 'for';
	$fc_payload_op_lt{'20000000'} = 'PRLI';
	$fc_payload_op_lt{'21000000'} = 'PRLO';
	$fc_payload_op_lt{'22000000'} = 'SCN';
	$fc_payload_op_lt{'23000000'} = 'TPLS';
	$fc_payload_op_lt{'24000000'} = 'TPRLO';
	$fc_payload_op_lt{'25000000'} = 'LCLM';
	$fc_payload_op_lt{'30000000'} = 'GAID';
	$fc_payload_op_lt{'31000000'} = 'FACT';
	$fc_payload_op_lt{'32000000'} = 'FDACT';
	$fc_payload_op_lt{'33000000'} = 'NACT';
	$fc_payload_op_lt{'34000000'} = 'NDACT';
	$fc_payload_op_lt{'40000000'} = 'QoSR';
	$fc_payload_op_lt{'41000000'} = 'RVCS';
	$fc_payload_op_lt{'50000000'} = 'PDISC';
	$fc_payload_op_lt{'51000000'} = 'FDISC';
	$fc_payload_op_lt{'52000000'} = 'ADISC';
	$fc_payload_op_lt{'53000000'} = 'RNC';
	$fc_payload_op_lt{'54000000'} = 'FARP_REQ';
	$fc_payload_op_lt{'55000000'} = 'FARP_REPLY';
	$fc_payload_op_lt{'56000000'} = 'RPS';
	$fc_payload_op_lt{'57000000'} = 'RPL';
	$fc_payload_op_lt{'58000000'} = 'RPBC';
	$fc_payload_op_lt{'60000000'} = 'FAN';
	$fc_payload_op_lt{'61000000'} = 'RSCN';
	$fc_payload_op_lt{'62000000'} = 'SCR';
	$fc_payload_op_lt{'63000000'} = 'RNFT';
	$fc_payload_op_lt{'68000000'} = 'CSR';
	$fc_payload_op_lt{'69000000'} = 'CSU';
	$fc_payload_op_lt{'70000000'} = 'LINIT';
	$fc_payload_op_lt{'71000000'} = 'LPC';
	$fc_payload_op_lt{'72000000'} = 'LSTS';
	$fc_payload_op_lt{'77000000'} = '(Vendor Specific)';
	$fc_payload_op_lt{'78000000'} = 'RNID';
	$fc_payload_op_lt{'79000000'} = 'RLIR';
	$fc_payload_op_lt{'7A000000'} = 'LIRR';
	$fc_payload_op_lt{'7B000000'} = 'SRL';
	$fc_payload_op_lt{'7C000000'} = 'SBRP';
	$fc_payload_op_lt{'7D000000'} = 'RPSC';
	$fc_payload_op_lt{'7E000000'} = 'FC-SP';
	$fc_payload_op_lt{'7F000000'} = 'EVFP';
	$fc_payload_op_lt{'80000000'} = 'LKA';
	$fc_payload_op_lt{'90000000'} = 'FC-SP';
	$fc_payload_op_lt{'97000000'} = 'FC-SP';
	$fc_payload_op_lt{'A0000000'} = 'FFI_DTM';
	$fc_payload_op_lt{'A1000000'} = 'FFI_RTM';
	$fc_payload_op_lt{'A2000000'} = 'FFI_PSS';
	$fc_payload_op_lt{'A3000000'} = 'FFI_MUR';
	$fc_payload_op_lt{'A4000000'} = 'FFI_RMUN';
	$fc_payload_op_lt{'A5000000'} = 'FFI_SMU';
	$fc_payload_op_lt{'A6000000'} = 'FFI_RMU';

	$fc_nsrjt_lt{'00000900'} = 'No additional explanation';
	$fc_nsrjt_lt{'00000901'} = 'Port Identifier not registered';
	$fc_nsrjt_lt{'00000902'} = 'Port Name not registered';
	$fc_nsrjt_lt{'00000903'} = 'Node Name not registered';
	$fc_nsrjt_lt{'00000904'} = 'Class of Service not registered';
	$fc_nsrjt_lt{'00000905'} = 'IP Address (Node) not registered';
	$fc_nsrjt_lt{'00000906'} = 'Initial Process Associator not registered';
	$fc_nsrjt_lt{'00000907'} = 'FC-4 TYPEs not registered';
	$fc_nsrjt_lt{'00000908'} = 'Sybolic Port Name not registered';
	$fc_nsrjt_lt{'00000909'} = 'Symbolic Node Name not registered';
	$fc_nsrjt_lt{'0000090A'} = 'Port Type not registered';
	$fc_nsrjt_lt{'0000090B'} = 'IP Address (Port) not registered';
	$fc_nsrjt_lt{'0000090C'} = 'Fabric Port Name not registered';
	$fc_nsrjt_lt{'0000090D'} = 'Host Address not registered';
	$fc_nsrjt_lt{'0000090E'} = 'FC-4 Descriptor not registered';
	$fc_nsrjt_lt{'0000090F'} = 'FC-4 Features not registered';
	$fc_nsrjt_lt{'00000910'} = 'Access denied';
	$fc_nsrjt_lt{'00000911'} = 'Unacceptable Port Identifier';
	$fc_nsrjt_lt{'00000912'} = 'Data base empty';
	$fc_nsrjt_lt{'00000913'} = 'No object registered in the specified scope';
	$fc_nsrjt_lt{'00000914'} = 'Domain ID not present';
	$fc_nsrjt_lt{'00000915'} = 'Port number not present';
	$fc_nsrjt_lt{'00000916'} = 'No device attached';

	$fc_lsrjt_rc_lt{'01'} = 'Invalid LA_Command code';
	$fc_lsrjt_rc_lt{'03'} = 'Logical error';
	$fc_lsrjt_rc_lt{'05'} = 'Logical busy';
	$fc_lsrjt_rc_lt{'07'} = 'Protocol error';
	$fc_lsrjt_rc_lt{'09'} = 'Unable to perform command request';
	$fc_lsrjt_rc_lt{'0B'} = 'Command not supported';
	$fc_lsrjt_rc_lt{'0E'} = 'Command lready in progress';

	$fc_lsrjt_re_lt{'00'} = 'No additional explanation';
	$fc_lsrjt_re_lt{'01'} = 'Service Parm error - Options';
	$fc_lsrjt_re_lt{'03'} = 'Service Parm error - Initiator Ctl';
	$fc_lsrjt_re_lt{'05'} = 'Service Parm error - Recieient Ctl';
	$fc_lsrjt_re_lt{'07'} = 'Service Parm error - Rec Data Field Size';
	$fc_lsrjt_re_lt{'09'} = 'Service Parm error - Concurrent Seq';
	$fc_lsrjt_re_lt{'0B'} = 'Service Parm error - Credit';
	$fc_lsrjt_re_lt{'0D'} = 'Invalid N_Port/F_Port Name';
	$fc_lsrjt_re_lt{'0E'} = 'Invalid Node/Fabric Name';
	$fc_lsrjt_re_lt{'0F'} = 'Invalid Common Service Parameters';
	$fc_lsrjt_re_lt{'11'} = 'Invalid Association Header';
	$fc_lsrjt_re_lt{'13'} = 'Association Header required';
	$fc_lsrjt_re_lt{'15'} = 'Invalid Originator S_ID';
	$fc_lsrjt_re_lt{'17'} = 'Invalid OS_ID-RX_ID combination';
	$fc_lsrjt_re_lt{'19'} = 'Command (request) already in progress';
	$fc_lsrjt_re_lt{'1E'} = 'N_Port Login required';
	$fc_lsrjt_re_lt{'1F'} = 'Invalid N_Port Identifier';
	$fc_lsrjt_re_lt{'21'} = 'Invalid SEQ_ID';
	$fc_lsrjt_re_lt{'23'} = 'Attempt to abort invalid Exchange';
	$fc_lsrjt_re_lt{'25'} = 'Attempt to abort inactive Exchange';
	$fc_lsrjt_re_lt{'27'} = 'Recovery_Qualifier required';
	$fc_lsrjt_re_lt{'29'} = 'Insufficient resources to support Login';
	$fc_lsrjt_re_lt{'2A'} = 'Unable to supply requested data';
	$fc_lsrjt_re_lt{'2C'} = 'Request not supported';
	$fc_lsrjt_re_lt{'2D'} = 'Invalid Payload length';
	$fc_lsrjt_re_lt{'46'} = 'Login Extnesion not supported';
	$fc_lsrjt_re_lt{'48'} = 'Authentication required (see FC-SP)';

	$fcp_rsp_code_lt{'00'} = 'Task Management function complete';
	$fcp_rsp_code_lt{'01'} = 'FCP_DATA length different than FCP_BURST_LEN';
	$fcp_rsp_code_lt{'02'} = 'FCP_CMND fields invalid';
	$fcp_rsp_code_lt{'03'} = 'FCP_DATA parameter mismatch with FCP_DATA_RO';
	$fcp_rsp_code_lt{'04'} = 'Task Management function rejected';
	$fcp_rsp_code_lt{'05'} = 'Task Management function failed';
	$fcp_rsp_code_lt{'09'} = 'Task Management function incorrect logical unit number';

	$plat_eeh_err_lt{'10000006'} = "slot Unavailable or Reset active";
	$plat_eeh_err_lt{'10000007'} = "could not xmalloc() EEH handle";
	$plat_eeh_err_lt{'10000008'} = "Bad BUS ID";
	$plat_eeh_err_lt{'11000009'} = "could not xmalloc EADS handle";
	$plat_eeh_err_lt{'11000010'} = "could not talloc EADS TRB";
	$plat_eeh_err_lt{'11000011'} = "RTAS Hardware Error";
	$plat_eeh_err_lt{'11000012'} = "EEH permanent error";
	$plat_eeh_err_lt{'11000013'} = "EEH temporary error";
	$plat_eeh_err_lt{'11000014'} = "EADS xalloc failure";

	$fc_cmd_op_lt{'0D'} =  'move_login';

    $kernel_abend_lt{'BADF00DBADF00D01'} = 'driver q_list_head_bad_list_type';
    $kernel_abend_lt{'BADF00DBADF00D02'} = 'driver q_list_tail_bad_list_type';
    $kernel_abend_lt{'BADF00DBADF00D03'} = 'driver dq_list_bad_list_type';
    $kernel_abend_lt{'BADF00DBADF00D04'} = 'driver dq_list_type_mismatch check IJ17157';
    $kernel_abend_lt{'EEEE000085350019'} = 'sli3_fc_driver login_table_crash';
    $kernel_abend_lt{'EEEE000096408063'} = 'ql_fc_driver cmd_not_queued_bad_adp_fw_level';
    $kernel_abend_lt{'EEEE0000DA278030'} = 'RECURLOCK; same thread that is currently disable_lock attempted to take the same lock';
    $kernel_abend_lt{'EEEE0000DA5190B8'} = 'XMFREE_NOTINHEAP; request to unpin pinned memory failed due to not pinned';

    $fc_failure_type_lt{'01'} = 'LS_RJT';
    $fc_failure_type_lt{'02'} = 'P_RJT';
    $fc_failure_type_lt{'03'} = 'F_RJT';
    $fc_failure_type_lt{'04'} = 'BA_RJT';
    $fc_failure_type_lt{'05'} = 'F_BSY';
    $fc_failure_type_lt{'06'} = 'P_BSY';

    $com_scsi_status_lt{'1'} = 'FCP status returned';
    $com_scsi_status_lt{'2'} = 'Host I/O Bus error';
    $com_scsi_status_lt{'3'} = 'Adapter Hardware error';
    $com_scsi_status_lt{'4'} = 'Adapter Software error';
    $com_scsi_status_lt{'5'} = 'Link Dead';
    $com_scsi_status_lt{'6'} = 'Link Down';
    $com_scsi_status_lt{'7'} = 'cmd was aborted';
    $com_scsi_status_lt{'8'} = 'Target Error';
    $com_scsi_status_lt{'9'} = 'Target/Fabric cmd returned LS_RJT';
    $com_scsi_status_lt{'A'} = 'Target/Fabric cmd returned Busy';
    $com_scsi_status_lt{'B'} = 'Command timeout';
    $com_scsi_status_lt{'C'} = 'Transport Error';
    $com_scsi_status_lt{'D'} = 'Invalid Field in cmd';
    $com_scsi_status_lt{'E'} = 'Client Port login needed';
    $com_scsi_status_lt{'F'} = 'Target Stale';

    $npiv_mad_status_lt{'00'} = 'SUCCESS';
    $npiv_mad_status_lt{'F1'} = 'NOT_SUPPORTED';
    $npiv_mad_status_lt{'F7'} = 'FAILED';

    $kerrno_lt{'000'} = 'artic_sw';
    $kerrno_lt{'008'} = 'atmif';
    $kerrno_lt{'010'} = 'atmle';
    $kerrno_lt{'018'} = 'atmsvc';
    $kerrno_lt{'020'} = 'autofs';
    $kerrno_lt{'028'} = 'bbldd';
    $kerrno_lt{'030'} = 'bluedd';
    $kerrno_lt{'038'} = 'cachefskern';
    $kerrno_lt{'040'} = 'cdide';
    $kerrno_lt{'048'} = 'cfg_nls';
    $kerrno_lt{'050'} = 'cifs_fs';
    $kerrno_lt{'058'} = 'cmdmirror';
    $kerrno_lt{'060'} = 'diagddent';
    $kerrno_lt{'068'} = 'diagddfddi';
    $kerrno_lt{'070'} = 'diagddient';
    $kerrno_lt{'078'} = 'diagddtok';
    $kerrno_lt{'080'} = 'diskide';
    $kerrno_lt{'088'} = 'dispccm';
    $kerrno_lt{'090'} = 'dmxhdlc';
    $kerrno_lt{'098'} = 'gxme';
    $kerrno_lt{'0A0'} = 'ica';
    $kerrno_lt{'0A8'} = 'inputdd';
    $kerrno_lt{'0B0'} = 'ips_tun';
    $kerrno_lt{'0B8'} = 'isafd';
    $kerrno_lt{'0C0'} = 'isamouse';
    $kerrno_lt{'0C8'} = 'isatty';
    $kerrno_lt{'0D0'} = 'kauaidd';
    $kerrno_lt{'0D8'} = 'lanaidd';
    $kerrno_lt{'0E0'} = 'lftdd';
    $kerrno_lt{'0E8'} = 'magdd';
    $kerrno_lt{'0F0'} = 'mauidd';
    $kerrno_lt{'0F8'} = 'mintdd';
    $kerrno_lt{'100'} = 'miragedd';
    $kerrno_lt{'108'} = 'mpiopcm';
    $kerrno_lt{'110'} = 'mrcdd';
    $kerrno_lt{'118'} = 'mtndd';
    $kerrno_lt{'120'} = 'onckern';
    $kerrno_lt{'128'} = 'paud';
    $kerrno_lt{'130'} = 'pci4758';
    $kerrno_lt{'138'} = 'pcibatm';
    $kerrno_lt{'140'} = 'pcibent';
    $kerrno_lt{'148'} = 'pciccmdd';
    $kerrno_lt{'150'} = 'pcichatm';
    $kerrno_lt{'158'} = 'pcictok';
    $kerrno_lt{'160'} = 'pcient';
    $kerrno_lt{'168'} = 'pcigoent';
    $kerrno_lt{'170'} = 'pcigxent';
    $kerrno_lt{'178'} = 'pciiga';
    $kerrno_lt{'180'} = 'pcijatm';
    $kerrno_lt{'188'} = 'pcimga';
    $kerrno_lt{'190'} = 'pciphxent';
    $kerrno_lt{'198'} = 'pciraid';
    $kerrno_lt{'1A0'} = 'pciscent';
    $kerrno_lt{'1A8'} = 'pciscsi';
    $kerrno_lt{'1B0'} = 'pcitok';
    $kerrno_lt{'1B8'} = 'pcivent';
    $kerrno_lt{'1C0'} = 'peddd';
    $kerrno_lt{'1C8'} = 'perfstat';
    $kerrno_lt{'1D0'} = 'pmapi';
    $kerrno_lt{'1D8'} = 'procfs';
    $kerrno_lt{'1E0'} = 'rcm';
    $kerrno_lt{'1E8'} = 'rspcios';
    $kerrno_lt{'1E9'} = 'rspcios';
    $kerrno_lt{'1F0'} = 'rspcpal';
    $kerrno_lt{'1F8'} = 'sgadd';
    $kerrno_lt{'200'} = 'sisadd';
    $kerrno_lt{'208'} = 'sonoradd';
    $kerrno_lt{'210'} = 'ssaadapdd';
    $kerrno_lt{'218'} = 'ssadiskdd';
    $kerrno_lt{'21C'} = 'stnfs';
    $kerrno_lt{'220'} = 'sysdump';
    $kerrno_lt{'228'} = 'syserrlg';
    $kerrno_lt{'230'} = 'sysient';
    $kerrno_lt{'238'} = 'sysios';
    $kerrno_lt{'240'} = 'sysipc_H_kipc';
    $kerrno_lt{'248'} = 'sysj2';
    $kerrno_lt{'249'} = 'sysj2';
    $kerrno_lt{'24A'} = 'sysj2';
    $kerrno_lt{'24B'} = 'sysj2';
    $kerrno_lt{'24C'} = 'sysj2';
    $kerrno_lt{'24D'} = 'sysj25';
    $kerrno_lt{'24E'} = 'sysj26';
    $kerrno_lt{'24F'} = 'sysj27';
    $kerrno_lt{'250'} = 'sysldr';
    $kerrno_lt{'258'} = 'syslfs';
    $kerrno_lt{'260'} = 'sysmobip6';
    $kerrno_lt{'268'} = 'sysnet';
    $kerrno_lt{'270'} = 'syspfs';
    $kerrno_lt{'278'} = 'sysproc';
    $kerrno_lt{'279'} = 'sysproc';
    $kerrno_lt{'27A'} = 'sysproc';
    $kerrno_lt{'27B'} = 'sysproc';
    $kerrno_lt{'27C'} = 'sysproc';
    $kerrno_lt{'27D'} = 'sysproc_C_tmm_except';
    $kerrno_lt{'27E'} = 'sysproc6';
    $kerrno_lt{'27F'} = 'sysproc_C_migrate';
    $kerrno_lt{'280'} = 'sysras';
    $kerrno_lt{'281'} = 'sysras';
    $kerrno_lt{'282'} = 'sysras';
    $kerrno_lt{'283'} = 'sysras';
    $kerrno_lt{'284'} = 'sysras';
    $kerrno_lt{'285'} = 'sysras5';
    $kerrno_lt{'286'} = 'sysras6';
    $kerrno_lt{'287'} = 'sysras7';
    $kerrno_lt{'288'} = 'syssec';
    $kerrno_lt{'290'} = 'syssi';
    $kerrno_lt{'298'} = 'syssrng';
    $kerrno_lt{'2A0'} = 'systrace';
    $kerrno_lt{'2B0'} = 'sysvmm';
    $kerrno_lt{'2B1'} = 'sysvmm';
    $kerrno_lt{'2B2'} = 'sysvmm';
    $kerrno_lt{'2B3'} = 'sysvmm';
    $kerrno_lt{'2B4'} = 'sysvmm';
    $kerrno_lt{'2B5'} = 'sysvmm5';
    $kerrno_lt{'2B8'} = 'sysx327';
    $kerrno_lt{'2C0'} = 'sysxaio';
    $kerrno_lt{'2C8'} = 'sysxaixif';
    $kerrno_lt{'2D0'} = 'sysxarray';
    $kerrno_lt{'2D8'} = 'sysxatm';
    $kerrno_lt{'2E0'} = 'sysxbpf';
    $kerrno_lt{'2E8'} = 'sysxcat';
    $kerrno_lt{'2F0'} = 'sysxcfs';
    $kerrno_lt{'2F8'} = 'sysxcie';
    $kerrno_lt{'300'} = 'sysxdlc';
    $kerrno_lt{'308'} = 'sysxdisk';
    $kerrno_lt{'310'} = 'sysxdispgem';
    $kerrno_lt{'318'} = 'sysxdispsky';
    $kerrno_lt{'320'} = 'sysxdlpi';
    $kerrno_lt{'328'} = 'sysxdmx';
    $kerrno_lt{'330'} = 'sysxdpmp';
    $kerrno_lt{'338'} = 'sysxent';
    $kerrno_lt{'340'} = 'sysxentchan';
    $kerrno_lt{'348'} = 'sysxewlm';
    $kerrno_lt{'350'} = 'sysxfc';
    $kerrno_lt{'358'} = 'sysxfcp';
    $kerrno_lt{'360'} = 'sysxfd';
    $kerrno_lt{'368'} = 'sysxfddi';
    $kerrno_lt{'370'} = 'sysxfrca';
    $kerrno_lt{'378'} = 'sysxide';
    $kerrno_lt{'398'} = 'sysxintf';
    $kerrno_lt{'3A0'} = 'sysxiocp';
    $kerrno_lt{'3A8'} = 'sysxipfc';
    $kerrno_lt{'3B0'} = 'sysxiscsi_sw';
    $kerrno_lt{'3B8'} = 'sysxlce';
    $kerrno_lt{'3C0'} = 'sysxldbg';
    $kerrno_lt{'3C8'} = 'sysxlvm';
    $kerrno_lt{'3D0'} = 'sysxmpa';
    $kerrno_lt{'3D8'} = 'sysxmpqp';
    $kerrno_lt{'3E0'} = 'sysxpciaudio';
    $kerrno_lt{'3E8'} = 'sysxppp';
    $kerrno_lt{'3F0'} = 'sysxprnt';
    $kerrno_lt{'3F8'} = 'sysxpse';
    $kerrno_lt{'400'} = 'sysxpty';
    $kerrno_lt{'408'} = 'sysxqfc';
    $kerrno_lt{'410'} = 'sysxqfcp';
    $kerrno_lt{'418'} = 'sysxqliscsi';
    $kerrno_lt{'420'} = 'sysxqlto';
    $kerrno_lt{'430'} = 'sysxramd';
    $kerrno_lt{'438'} = 'sysxrif';
    $kerrno_lt{'440'} = 'sysxs128';
    $kerrno_lt{'448'} = 'sysxscie';
    $kerrno_lt{'450'} = 'sysxsea';
    $kerrno_lt{'458'} = 'sysxses';
    $kerrno_lt{'460'} = 'sysxsol';
    $kerrno_lt{'468'} = 'sysxtape';
    $kerrno_lt{'470'} = 'sysxtm';
    $kerrno_lt{'478'} = 'sysxtok';
    $kerrno_lt{'480'} = 'sysxts';
    $kerrno_lt{'488'} = 'sysxtty';
    $kerrno_lt{'490'} = 'sysxudf';
    $kerrno_lt{'498'} = 'sysxusb';
    $kerrno_lt{'4A0'} = 'sysxusb_cdrom';
    $kerrno_lt{'4A8'} = 'sysxusb_kbd';
    $kerrno_lt{'4B0'} = 'sysxusb_mse';
    $kerrno_lt{'4B8'} = 'sysxusb_ufd';
    $kerrno_lt{'4C0'} = 'sysxvio';
    $kerrno_lt{'4C8'} = 'sysxvonc';
    $kerrno_lt{'4D0'} = 'sysxx25';
    $kerrno_lt{'4D8'} = 'sysxxns';
    $kerrno_lt{'4E0'} = 'tmssadd';
    $kerrno_lt{'4E8'} = 'vddrby';
    $kerrno_lt{'4F0'} = 'vioent';
    $kerrno_lt{'4F8'} = 'vlan';
    $kerrno_lt{'500'} = 'wgadd';
    $kerrno_lt{'508'} = 'sysml';
    $kerrno_lt{'509'} = 'sysml';
    $kerrno_lt{'510'} = 'mstcheck';
    $kerrno_lt{'518'} = 'sysalloc';
    $kerrno_lt{'519'} = 'sysalloc';
    $kerrno_lt{'51A'} = 'sysalloc';
    $kerrno_lt{'51B'} = 'sysalloc';
    $kerrno_lt{'51C'} = 'sysalloc';
    $kerrno_lt{'520'} = 'sysras8';
    $kerrno_lt{'521'} = 'sysras9';
    $kerrno_lt{'522'} = 'sysras10';
    $kerrno_lt{'600'} = 'sysnfs';
    $kerrno_lt{'601'} = 'sysnfs4';
    $kerrno_lt{'602'} = 'sysnfs4';
    $kerrno_lt{'603'} = 'sysnfs4';
    $kerrno_lt{'604'} = 'sysnfs';
    $kerrno_lt{'605'} = 'sysnfs5';
    $kerrno_lt{'606'} = 'sysnfs6';
    $kerrno_lt{'607'} = 'sysnfs7';
    $kerrno_lt{'620'} = 'sysvcm';
    $kerrno_lt{'630'} = 'sysxemfc';
    $kerrno_lt{'638'} = 'sysxemfcp';
    $kerrno_lt{'640'} = 'sysxemfcnvme';
    $kerrno_lt{'650'} = 'sysxfpga';
    $kerrno_lt{'651'} = 'sysxfpga';
    $kerrno_lt{'660'} = 'flashsysdisk';
    $kerrno_lt{'680'} = 'sysipc_C_bsr_shm';
    $kerrno_lt{'681'} = 'sysipc_C_shm_mem64';
    $kerrno_lt{'700'} = 'sysvmm_C_userio';
    $kerrno_lt{'701'} = 'sysvmm_C_v_alloc';
    $kerrno_lt{'702'} = 'sysvmm_C_v_aptsubs';
    $kerrno_lt{'703'} = 'sysvmm_C_v_compsubs';
    $kerrno_lt{'704'} = 'sysvmm_C_v_cpfsubs';
    $kerrno_lt{'705'} = 'sysvmm_C_v_diosubs';
    $kerrno_lt{'706'} = 'sysvmm_C_v_disksubs';
    $kerrno_lt{'707'} = 'sysvmm_C_v_dps';
    $kerrno_lt{'708'} = 'sysvmm_C_v_dr';
    $kerrno_lt{'709'} = 'sysvmm_C_v_exception';
    $kerrno_lt{'70A'} = 'sysvmm_C_v_fragsubs';
    $kerrno_lt{'70B'} = 'sysvmm_C_v_freelist';
    $kerrno_lt{'70C'} = 'sysvmm_C_v_fssubs';
    $kerrno_lt{'70D'} = 'sysvmm_C_v_galloc';
    $kerrno_lt{'70E'} = 'sysvmm_C_v_getsubs';
    $kerrno_lt{'70F'} = 'sysvmm_C_v_getsubs1';
    $kerrno_lt{'710'} = 'sysvmm_C_v_getsubs64';
    $kerrno_lt{'711'} = 'sysvmm_C_v_interrupt';
    $kerrno_lt{'712'} = 'sysvmm_C_v_lgpg';
    $kerrno_lt{'713'} = 'sysvmm_C_v_lists';
    $kerrno_lt{'714'} = 'sysvmm_C_v_lookup';
    $kerrno_lt{'715'} = 'sysvmm_C_v_lru';
    $kerrno_lt{'716'} = 'sysvmm_C_v_lrubylist';
    $kerrno_lt{'717'} = 'sysvmm_C_v_lrulist';
    $kerrno_lt{'718'} = 'sysvmm_C_v_lruphys';
    $kerrno_lt{'719'} = 'sysvmm_C_v_map';
    $kerrno_lt{'71A'} = 'sysvmm_C_v_mapsubs';
    $kerrno_lt{'71B'} = 'sysvmm_C_v_mpsubs';
    $kerrno_lt{'71C'} = 'sysvmm_C_v_mvfork';
    $kerrno_lt{'71D'} = 'sysvmm_C_v_numa';
    $kerrno_lt{'71E'} = 'sysvmm_C_v_patch';
    $kerrno_lt{'71F'} = 'sysvmm_C_v_pdtsubs';
    $kerrno_lt{'720'} = 'sysvmm_C_v_pfend';
    $kerrno_lt{'721'} = 'sysvmm_C_v_pinsubs';
    $kerrno_lt{'722'} = 'sysvmm_C_v_protsubs';
    $kerrno_lt{'723'} = 'sysvmm_C_v_psgc';
    $kerrno_lt{'724'} = 'sysvmm_C_v_putsubs';
    $kerrno_lt{'725'} = 'sysvmm_C_v_relsubs';
    $kerrno_lt{'726'} = 'sysvmm_C_v_scblist';
    $kerrno_lt{'727'} = 'sysvmm_C_v_scbsubs';
    $kerrno_lt{'728'} = 'sysvmm_C_v_segsubs';
    $kerrno_lt{'729'} = 'sysvmm_C_v_spaceok';
    $kerrno_lt{'72A'} = 'sysvmm_C_v_thrpgio';
    $kerrno_lt{'72B'} = 'sysvmm_C_v_trackp';
    $kerrno_lt{'72C'} = 'sysvmm_C_v_wlm';
    $kerrno_lt{'97F'} = 'ofed_END';
    $kerrno_lt{'980'} = 'sysxsfw';
    $kerrno_lt{'981'} = 'sysxsfw';
    $kerrno_lt{'982'} = 'sysxsfw';
    $kerrno_lt{'983'} = 'sysxsfw';
    $kerrno_lt{'984'} = 'sysxsfw';
    $kerrno_lt{'985'} = 'sysxsfw5';
    $kerrno_lt{'986'} = 'sysxsfw6';
    $kerrno_lt{'987'} = 'sysxsfw7';
    $kerrno_lt{'988'} = 'pcilncent';
    $kerrno_lt{'989'} = 'pcilncent';
    $kerrno_lt{'98A'} = 'pcilncent';
    $kerrno_lt{'98B'} = 'syswpar';
    $kerrno_lt{'98C'} = 'acf';
    $kerrno_lt{'98D'} = 'acf';
    $kerrno_lt{'990'} = 'ofed';
    $kerrno_lt{'9AE'} = 'ofed_END';
    $kerrno_lt{'9B0'} = 'pcimlxent';
    $kerrno_lt{'9B1'} = 'pcimlxent';
    $kerrno_lt{'9B2'} = 'pcimlxent';
    $kerrno_lt{'9B3'} = 'pcimlxent';
    $kerrno_lt{'9B4'} = 'pcimlxent';
    $kerrno_lt{'9B5'} = 'pcimlxent5';
    $kerrno_lt{'9B6'} = 'pcimlxent6';
    $kerrno_lt{'9B7'} = 'pcimlxent7';
    $kerrno_lt{'9B8'} = 'pcimlxent8';
    $kerrno_lt{'9B9'} = 'entcore_v1';
    $kerrno_lt{'9BA'} = 'entcore_v1';
    $kerrno_lt{'9BB'} = 'entcore_v1';
    $kerrno_lt{'9BC'} = 'entcore_v1';
    $kerrno_lt{'9BD'} = 'entcore_v1';
    $kerrno_lt{'9BE'} = 'entcore_v15';
    $kerrno_lt{'9BF'} = 'entcore_v16';
    $kerrno_lt{'9C0'} = 'entcore_v17';
    $kerrno_lt{'9C1'} = 'entcore_v2';
    $kerrno_lt{'9C2'} = 'entcore_v2';
    $kerrno_lt{'9C3'} = 'entcore_v2';
    $kerrno_lt{'9C4'} = 'entcore_v2';
    $kerrno_lt{'9c5'} = 'musent';
    $kerrno_lt{'9C6'} = 'vnicserver';
    $kerrno_lt{'9C7'} = 'vnicserver';
    $kerrno_lt{'9C8'} = 'pcimlxcent';
    $kerrno_lt{'9C9'} = 'pcimlxcent';
    $kerrno_lt{'9D0'} = 'vrtcore';
    $kerrno_lt{'9D4'} = 'vrtscsi';
    $kerrno_lt{'9D8'} = 'vrtent';
    $kerrno_lt{'9E0'} = 'sysxcvfc';
    $kerrno_lt{'9E1'} = 'sysxcvfcp';
    $kerrno_lt{'A00'} = 'sysios_C_caccelinit';
    $kerrno_lt{'A01'} = 'sysios_C_caccel';
    $kerrno_lt{'A02'} = 'sysios_C_caccelutil';
    $kerrno_lt{'A03'} = 'sysios_C_caccelstat';
    $kerrno_lt{'A10'} = 'sysmemcopy_C_memcopy';
    $kerrno_lt{'A20'} = 'sysios_N_nxutil';
    $kerrno_lt{'A21'} = 'sysios_N_nxinit';
    $kerrno_lt{'A22'} = 'sysios_N_nxserv';
    $kerrno_lt{'A80'} = 'sysios_C_selnotify';
    $kerrno_lt{'A90'} = 'cormob_C_pmemfstranstbl';

    $scan_err_src_lt{'11001510'} = 'Detected AC loss';
    $scan_err_src_lt{'10001520'} = 'Detected AC loss';
    $scan_err_src_lt{'A7004761'} = 'The update access key has expired. Only firmware updates with a date prior to the expiration date are allowed';
    $scan_err_src_lt{'B150493F'} = 'SMP cable waiting for backend power';
    $scan_err_src_lt{'B175F1381'} = 'Gard records found during periodic check';
    $scan_err_src_lt{'B7006971'} = 'PCI secondary bus failure';
    $scan_err_src_lt{'B7006A72'} = 'IO downstream from a PCI Host Bridge (PHB) has been experiencing recoverable errors in a volume which exceeds an expected threshold';
    $scan_err_src_lt{'BA180010'} = 'PCI probe error, bridge in freeze state';
    $scan_err_src_lt{'BA180020'} = 'No response was received from a PCI slot during probing';
    $scan_err_src_lt{'BA180030'} = 'A PHB reset/recovery was successful';
    $scan_err_src_lt{'BA090007'} = 'System fw switched paths due to scsi reservation';
    $scan_err_src_lt{'BA09000B'} = 'System fw: Generic SCSI sense error';
    $scan_err_src_lt{'B200A101'} = 'partition ended abnormally. The partition could not stay running and shut itself down';
    $scan_err_src_lt{'BA5400A5'} = 'Firmware device driver has failed Secure Boot validation. Trusted substitute loaded in its place';
    $scan_err_src_lt{'BA5400A6'} = 'Firmware device driver has failed Secure Boot validation. Trusted substitute loaded in its place';
    $scan_err_src_lt{'BC23E504'} = 'A hardware failure was detected in the central electronics complex (CEC)';
    $scan_err_src_lt{'B150F138'} = 'Firmware detected either a FRU deconfiguration record or an improper Cabling';

    $fcp_tm_flags_lt{'02'} = 'ABORT_TASK_SET';
    $fcp_tm_flags_lt{'04'} = 'CLEAR_TASK_SET';
    $fcp_tm_flags_lt{'10'} = 'LUN_RESET';
    $fcp_tm_flags_lt{'20'} = 'TARGET_RESET';
    $fcp_tm_flags_lt{'40'} = 'CLEAR_ACA';

    $pprc_loc_lt{'0001'} = 'EST_PPRC_DONE'; 
    $pprc_loc_lt{'0002'} = 'FAILOVER_DONE';     
    $pprc_loc_lt{'0003'} = 'FAILBACK_DONE';     
    $pprc_loc_lt{'0004'} = 'QUERY_PPRC_DONE';   
    $pprc_loc_lt{'0005'} = 'STD_INQ_DONE';      
    $pprc_loc_lt{'0006'} = 'INQ_83_DONE';       
    $pprc_loc_lt{'0007'} = 'INQ_C0_DONE';       
    $pprc_loc_lt{'0008'} = 'INQ_C0_FO_DONE';    
    $pprc_loc_lt{'0009'} = 'INQ_C0_FB_DONE';    
    $pprc_loc_lt{'000A'} = 'ABORT_OP';            
    $pprc_loc_lt{'000B'} = 'FAIL_PATH_GRP';       
    $pprc_loc_lt{'000C'} = 'RECOV_PATH_GRP';      
    $pprc_loc_lt{'000D'} = 'GRP_STATE_MACHINE';   
    $pprc_loc_lt{'000E'} = 'GRP_JOB_END';         
    $pprc_loc_lt{'000F'} = 'INQ_C0_SYNC_DONE';  
    $pprc_loc_lt{'0010'} = 'SETGRP_STATE';        
    $pprc_loc_lt{'0011'} = 'MKREPPATH_DONE';    
    $pprc_loc_lt{'0012'} = 'FREEZE_DONE';       
    $pprc_loc_lt{'0013'} = 'UNFREEZE_DONE';    
}

