-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * Private data...
- */
-static ASCQ_Table_t *mptscsih_ASCQ_TablePtr;
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* old symsense.c stuff... */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * Private data...
- * To protect ourselves against those that would pass us bogus pointers
- */
-static u8 dummyInqData[SCSI_STD_INQUIRY_BYTES]
- = { 0x1F, 0x00, 0x00, 0x00,
- 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static u8 dummySenseData[SCSI_STD_SENSE_BYTES]
- = { 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00 };
-static u8 dummyCDB[16]
- = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static u8 dummyScsiData[16]
- = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static char *ScsiStatusString[] = {
- "GOOD", /* 00h */
- NULL, /* 01h */
- "CHECK CONDITION", /* 02h */
- NULL, /* 03h */
- "CONDITION MET", /* 04h */
- NULL, /* 05h */
- NULL, /* 06h */
- NULL, /* 07h */
- "BUSY", /* 08h */
- NULL, /* 09h */
- NULL, /* 0Ah */
- NULL, /* 0Bh */
- NULL, /* 0Ch */
- NULL, /* 0Dh */
- NULL, /* 0Eh */
- NULL, /* 0Fh */
- "INTERMEDIATE", /* 10h */
- NULL, /* 11h */
- NULL, /* 12h */
- NULL, /* 13h */
- "INTERMEDIATE-CONDITION MET", /* 14h */
- NULL, /* 15h */
- NULL, /* 16h */
- NULL, /* 17h */
- "RESERVATION CONFLICT", /* 18h */
- NULL, /* 19h */
- NULL, /* 1Ah */
- NULL, /* 1Bh */
- NULL, /* 1Ch */
- NULL, /* 1Dh */
- NULL, /* 1Eh */
- NULL, /* 1Fh */
- NULL, /* 20h */
- NULL, /* 21h */
- "COMMAND TERMINATED", /* 22h */
- NULL, /* 23h */
- NULL, /* 24h */
- NULL, /* 25h */
- NULL, /* 26h */
- NULL, /* 27h */
- "TASK SET FULL", /* 28h */
- NULL, /* 29h */
- NULL, /* 2Ah */
- NULL, /* 2Bh */
- NULL, /* 2Ch */
- NULL, /* 2Dh */
- NULL, /* 2Eh */
- NULL, /* 2Fh */
- "ACA ACTIVE", /* 30h */
- NULL
-};
-
-static const char *ScsiCommonOpString[] = {
- "TEST UNIT READY", /* 00h */
- "REZERO UNIT (REWIND)", /* 01h */
- NULL, /* 02h */
- "REQUEST_SENSE", /* 03h */
- "FORMAT UNIT (MEDIUM)", /* 04h */
- "READ BLOCK LIMITS", /* 05h */
- NULL, /* 06h */
- "REASSIGN BLOCKS", /* 07h */
- "READ(6)", /* 08h */
- NULL, /* 09h */
- "WRITE(6)", /* 0Ah */
- "SEEK(6)", /* 0Bh */
- NULL, /* 0Ch */
- NULL, /* 0Dh */
- NULL, /* 0Eh */
- "READ REVERSE", /* 0Fh */
- "WRITE_FILEMARKS", /* 10h */
- "SPACE(6)", /* 11h */
- "INQUIRY", /* 12h */
- NULL
-};
-
-static const char *SenseKeyString[] = {
- "NO SENSE", /* 0h */
- "RECOVERED ERROR", /* 1h */
- "NOT READY", /* 2h */
- "MEDIUM ERROR", /* 3h */
- "HARDWARE ERROR", /* 4h */
- "ILLEGAL REQUEST", /* 5h */
- "UNIT ATTENTION", /* 6h */
- "DATA PROTECT", /* 7h */
- "BLANK CHECK", /* 8h */
- "VENDOR-SPECIFIC", /* 9h */
- "ABORTED COPY", /* Ah */
- "ABORTED COMMAND", /* Bh */
- "EQUAL (obsolete)", /* Ch */
- "VOLUME OVERFLOW", /* Dh */
- "MISCOMPARE", /* Eh */
- "RESERVED", /* Fh */
- NULL
-};
-
-#define SPECIAL_ASCQ(c,q) \
- (((c) == 0x40 && (q) != 0x00) || ((c) == 0x4D) || ((c) == 0x70))
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int dump_cdb(char *foo, unsigned char *cdb)
-{
- int i, grpCode, cdbLen;
- int l = 0;
-
- grpCode = cdb[0] >> 5;
- if (grpCode < 1)
- cdbLen = 6;
- else if (grpCode < 3)
- cdbLen = 10;
- else if (grpCode == 5)
- cdbLen = 12;
- else
- cdbLen = 16;
-
- for (i=0; i < cdbLen; i++)
- l += sprintf(foo+l, " %02X", cdb[i]);
-
- return l;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Do ASC/ASCQ lookup/grindage to English readable string(s) */
-static const char * ascq_set_strings_4max(
- u8 ASC, u8 ASCQ,
- const char **s1, const char **s2, const char **s3, const char **s4)
-{
- static const char *asc_04_part1_string = "LOGICAL UNIT ";
- static const char *asc_04_part2a_string = "NOT READY, ";
- static const char *asc_04_part2b_string = "IS ";
- static const char *asc_04_ascq_NN_part3_strings[] = { /* ASC ASCQ (hex) */
- "CAUSE NOT REPORTABLE", /* 04 00 */
- "IN PROCESS OF BECOMING READY", /* 04 01 */
- "INITIALIZING CMD. REQUIRED", /* 04 02 */
- "MANUAL INTERVENTION REQUIRED", /* 04 03 */
- /* Add " IN PROGRESS" to all the following... */
- "FORMAT", /* 04 04 */
- "REBUILD", /* 04 05 */
- "RECALCULATION", /* 04 06 */
- "OPERATION", /* 04 07 */
- "LONG WRITE", /* 04 08 */
- "SELF-TEST", /* 04 09 */
- NULL
- };
- static char *asc_04_part4_string = " IN PROGRESS";
-
- static char *asc_29_ascq_NN_strings[] = { /* ASC ASCQ (hex) */
- "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED", /* 29 00 */
- "POWER ON OCCURRED", /* 29 01 */
- "SCSI BUS RESET OCCURRED", /* 29 02 */
- "BUS DEVICE RESET FUNCTION OCCURRED", /* 29 03 */
- "DEVICE INTERNAL RESET", /* 29 04 */
- "TRANSCEIVER MODE CHANGED TO SINGLE-ENDED", /* 29 05 */
- "TRANSCEIVER MODE CHANGED TO LVD", /* 29 06 */
- NULL
- };
- static char *ascq_vendor_uniq = "(Vendor Unique)";
- static char *ascq_noone = "(no matching ASC/ASCQ description found)";
- int idx;
-
- *s1 = *s2 = *s3 = *s4 = ""; /* set'em all to the empty "" string */
-
- /* CHECKME! Need lock/sem?
- * Update and examine for isense module presense.
- */
- mptscsih_ASCQ_TablePtr = (ASCQ_Table_t *)mpt_v_ASCQ_TablePtr;
-
- if (mptscsih_ASCQ_TablePtr == NULL) {
- /* 2nd chances... */
- if (ASC == 0x04 && (ASCQ < sizeof(asc_04_ascq_NN_part3_strings)/sizeof(char*)-1)) {
- *s1 = asc_04_part1_string;
- *s2 = (ASCQ == 0x01) ? asc_04_part2b_string : asc_04_part2a_string;
- *s3 = asc_04_ascq_NN_part3_strings[ASCQ];
- /* check for " IN PROGRESS" ones */
- if (ASCQ >= 0x04)
- *s4 = asc_04_part4_string;
- } else if (ASC == 0x29 && (ASCQ < sizeof(asc_29_ascq_NN_strings)/sizeof(char*)-1))
- *s1 = asc_29_ascq_NN_strings[ASCQ];
- /*
- * Else { leave all *s[1-4] values pointing to the empty "" string }
- */
- return *s1;
- }
-
- /*
- * Need to check ASC here; if it is "special," then
- * the ASCQ is variable, and indicates failed component number.
- * We must treat the ASCQ as a "don't care" while searching the
- * mptscsih_ASCQ_Table[] by masking it off, and then restoring it later
- * on when we actually need to identify the failed component.
- */
- if (SPECIAL_ASCQ(ASC,ASCQ))
- ASCQ = 0xFF;
-
- /* OK, now search mptscsih_ASCQ_Table[] for a matching entry */
- for (idx = 0; mptscsih_ASCQ_TablePtr && idx < mpt_ASCQ_TableSz; idx++)
- if ((ASC == mptscsih_ASCQ_TablePtr[idx].ASC) && (ASCQ == mptscsih_ASCQ_TablePtr[idx].ASCQ)) {
- *s1 = mptscsih_ASCQ_TablePtr[idx].Description;
- return *s1;
- }
-
- if ((ASC >= 0x80) || (ASCQ >= 0x80))
- *s1 = ascq_vendor_uniq;
- else
- *s1 = ascq_noone;
-
- return *s1;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * SCSI Information Report; desired output format...
- *---
-SCSI Error: (iocnum:target_id:LUN) Status=02h (CHECK CONDITION)
- Key=6h (UNIT ATTENTION); FRU=03h
- ASC/ASCQ=29h/00h, "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED"
- CDB: 00 00 00 00 00 00 - TestUnitReady
- *---
- */
-/*
- * SCSI Error Report; desired output format...
- *---
-SCSI Error Report =-=-=-=-=-=-=-=-=-=-=-=-=-= (ioc0,scsi0:0)
- SCSI_Status=02h (CHECK CONDITION)
- Original_CDB[]: 00 00 00 00 00 00 - TestUnitReady
- SenseData[12h]: 70 00 06 00 00 00 00 0A 00 00 00 00 29 00 03 00 00 00
- SenseKey=6h (UNIT ATTENTION); FRU=03h
- ASC/ASCQ=29h/00h, "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED"
- *---
- */
-
-int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop)
-{
- char foo[512];
- char buf2[32];
- char *statstr;
- const char *opstr;
- int sk = SD_Sense_Key(ioop->sensePtr);
- const char *skstr = SenseKeyString[sk];
- unsigned char asc = SD_ASC(ioop->sensePtr);
- unsigned char ascq = SD_ASCQ(ioop->sensePtr);
- int l;
-
- /* Change the error logging to only report errors on
- * read and write commands. Ignore errors on other commands.
- * Should this be configurable via proc?
- */
- switch (ioop->cdbPtr[0]) {
- case READ_6:
- case WRITE_6:
- case READ_10:
- case WRITE_10:
- case READ_12:
- case WRITE_12:
- case READ_16:
- case WRITE_16:
- break;
- default:
- return 0;
- }
-
- /*
- * More quiet mode.
- * Filter out common, repetitive, warning-type errors... like:
- * POWER ON (06,29/00 or 06,29/01),
- * SPINNING UP (02,04/01),
- * LOGICAL UNIT NOT SUPPORTED (05,25/00), etc.
- */
- if (sk == SK_NO_SENSE) {
- return 0;
- }
-
- if ( (sk==SK_UNIT_ATTENTION && asc==0x29 && (ascq==0x00 || ascq==0x01))
- || (sk==SK_NOT_READY && asc==0x04 && (ascq==0x01 || ascq==0x02))
- || (sk==SK_ILLEGAL_REQUEST && asc==0x25 && ascq==0x00)
- )
- {
- /* Do nothing! */
- return 0;
- }
-
- /* Prevent the system from continually writing to the log
- * if a medium is not found: 02 3A 00
- * Changer issues: TUR, Read Capacity, Table of Contents continually
- */
- if (sk==SK_NOT_READY && asc==0x3A) {
- if (ioop->cdbPtr == NULL) {
- return 0;
- } else if ((ioop->cdbPtr[0] == CMD_TestUnitReady) ||
- (ioop->cdbPtr[0] == CMD_ReadCapacity) ||
- (ioop->cdbPtr[0] == 0x43)) {
- return 0;
- }
- }
- if (sk==SK_UNIT_ATTENTION) {
- if (ioop->cdbPtr == NULL)
- return 0;
- else if (ioop->cdbPtr[0] == CMD_TestUnitReady)
- return 0;
- }
-
- /*
- * Protect ourselves...
- */
- if (ioop->cdbPtr == NULL)
- ioop->cdbPtr = dummyCDB;
- if (ioop->sensePtr == NULL)
- ioop->sensePtr = dummySenseData;
- if (ioop->inqPtr == NULL)
- ioop->inqPtr = dummyInqData;
- if (ioop->dataPtr == NULL)
- ioop->dataPtr = dummyScsiData;
-
- statstr = NULL;
- if ((ioop->SCSIStatus >= sizeof(ScsiStatusString)/sizeof(char*)-1) ||
- ((statstr = (char*)ScsiStatusString[ioop->SCSIStatus]) == NULL)) {
- (void) sprintf(buf2, "Bad-Reserved-%02Xh", ioop->SCSIStatus);
- statstr = buf2;
- }
-
- opstr = NULL;
- if (1+ioop->cdbPtr[0] <= sizeof(ScsiCommonOpString)/sizeof(char*))
- opstr = ScsiCommonOpString[ioop->cdbPtr[0]];
- else if (mpt_ScsiOpcodesPtr)
- opstr = mpt_ScsiOpcodesPtr[ioop->cdbPtr[0]];
-
- l = sprintf(foo, "SCSI Error: (%s) Status=%02Xh (%s)\n",
- ioop->DevIDStr,
- ioop->SCSIStatus,
- statstr);
- l += sprintf(foo+l, " Key=%Xh (%s); FRU=%02Xh\n ASC/ASCQ=%02Xh/%02Xh",
- sk, skstr, SD_FRU(ioop->sensePtr), asc, ascq );
- {
- const char *x1, *x2, *x3, *x4;
- x1 = x2 = x3 = x4 = "";
- x1 = ascq_set_strings_4max(asc, ascq, &x1, &x2, &x3, &x4);
- if (x1 != NULL) {
- if (x1[0] != '(')
- l += sprintf(foo+l, " \"%s%s%s%s\"", x1,x2,x3,x4);
- else
- l += sprintf(foo+l, " %s%s%s%s", x1,x2,x3,x4);
- }
- }
- l += sprintf(foo+l, "\n CDB:");
- l += dump_cdb(foo+l, ioop->cdbPtr);
- if (opstr)
- l += sprintf(foo+l, " - \"%s\"", opstr);
- l += sprintf(foo+l, "\n");
-
- PrintF(("%s\n", foo));
-
- return l;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-