Commit dd424b0a authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

MPT Fusion driver 3.01.15 update

Highlights of this release:
- Patch provided by Christoph Hellwig to remove the isense code.
- Fix compile errors when CONFIG_PROC_FS=n.
- A fix for the module parameter "mptscsih" which was not being exported.
- The port of the 2.05.17 thru 2.05.23 of the lk 2.4 mpt driver.
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 8069f5cd
......@@ -27,39 +27,6 @@ config FUSION_MAX_SGE
necessary (or recommended) unless the user will be running
large I/O's via the raw interface.
config FUSION_ISENSE
tristate "Enhanced SCSI error reporting"
depends on MODULES && FUSION && m
---help---
The isense module (roughly stands for Interpret SENSE data) is
completely optional. It simply provides extra English readable
strings in SCSI Error Report(s) that might be generated from the
Fusion MPT SCSI Host driver, for example when a target device
returns a SCSI check condition on a I/O. Without this module
loaded you might see:
SCSI Error Report =-=-= (ioc0,scsi5:0)
SCSI_Status=02h (CHECK_CONDITION)
Original_CDB[]: 2A 00 00 00 00 41 00 00 02 00
SenseData[12h]: 70 00 02 00 00 00 00 0A 00 00 00 00 04 02 02 00 00 00
SenseKey=2h (NOT READY); FRU=02h
ASC/ASCQ=29h/00h
Where otherwise, if this module had been loaded, you would see:
SCSI Error Report =-=-= (ioc0,scsi5:0)
SCSI_Status=02h (CHECK_CONDITION)
Original_CDB[]: 2A 00 00 00 00 41 00 00 02 00 - "WRITE(10)"
SenseData[12h]: 70 00 02 00 00 00 00 0A 00 00 00 00 04 02 02 00 00 00
SenseKey=2h (NOT READY); FRU=02h
ASC/ASCQ=29h/00h "LOGICAL UNIT NOT READY, INITIALIZING CMD. REQUIRED"
Say M for "Enhanced SCSI error reporting" to compile this optional module,
creating a driver named: isense.
NOTE: Support for building this feature into the kernel is not
available, due to kernel size considerations.
config FUSION_CTL
tristate "Fusion MPT misc device (ioctl) driver"
depends on MODULES && FUSION && m
......
......@@ -2,7 +2,7 @@
# Makefile for the LSI Logic Fusion MPT (Message Passing Technology) drivers.
#
# Note! If you want to turn on various debug defines for an extended period of
# time but don't want them lingering around in the Makefile when you pass it on
# time but don't want them lingering around in the Makefile when you pass it on
# to someone else, use the MPT_CFLAGS env variable (thanks Steve). -nromer
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-{ LSI_LOGIC
......@@ -48,6 +48,5 @@ EXTRA_CFLAGS += ${MPT_CFLAGS}
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
obj-$(CONFIG_FUSION) += mptbase.o mptscsih.o
obj-$(CONFIG_FUSION_ISENSE) += isense.o
obj-$(CONFIG_FUSION_CTL) += mptctl.o
obj-$(CONFIG_FUSION_LAN) += mptlan.o
#ifndef SCSI_ASCQ_TBL_C_INCLUDED
#define SCSI_ASCQ_TBL_C_INCLUDED
/* AuToMaGiCaLlY generated from: "t10.org/asc-num.txt"
*******************************************************************************
* File: ASC-NUM.TXT
*
* SCSI ASC/ASCQ Assignments
* Numeric Sorted Listing
* as of 5/18/00
*
* D - DIRECT ACCESS DEVICE (SBC-2) device column key
* .T - SEQUENTIAL ACCESS DEVICE (SSC) -------------------
* . L - PRINTER DEVICE (SSC) blank = reserved
* . P - PROCESSOR DEVICE (SPC) not blank = allowed
* . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC-2)
* . . R - CD DEVICE (MMC)
* . . S - SCANNER DEVICE (SCSI-2)
* . . .O - OPTICAL MEMORY DEVICE (SBC-2)
* . . . M - MEDIA CHANGER DEVICE (SMC)
* . . . C - COMMUNICATION DEVICE (SCSI-2)
* . . . .A - STORAGE ARRAY DEVICE (SCC)
* . . . . E - ENCLOSURE SERVICES DEVICE (SES)
* . . . . B - SIMPLIFIED DIRECT-ACCESS DEVICE (RBC)
* . . . . .K - OPTICAL CARD READER/WRITER DEVICE (OCRW)
* ASC/ASCQ DTLPWRSOMCAEBK Description
* ------- -------------- ----------------------------------------------------
*/
static char SenseDevTypes001[] = "DTLPWRSOMCAEBK";
static char SenseDevTypes002[] = ".T............";
static char SenseDevTypes003[] = ".T....S.......";
static char SenseDevTypes004[] = ".TL...S.......";
static char SenseDevTypes005[] = ".....R........";
static char SenseDevTypes006[] = "DTL.WRSOM.AEBK";
static char SenseDevTypes007[] = "D...W..O....BK";
static char SenseDevTypes008[] = "D...WR.OM...BK";
static char SenseDevTypes009[] = "DTL.W.SO....BK";
static char SenseDevTypes010[] = "DTL..R.O....B.";
static char SenseDevTypes011[] = "DT..W..OMCA.BK";
static char SenseDevTypes012[] = "..............";
static char SenseDevTypes013[] = "DTL.WRSOMCAEBK";
static char SenseDevTypes014[] = "DTL.WRSOM...BK";
static char SenseDevTypes015[] = "DT...R.OM...BK";
static char SenseDevTypes016[] = "DTLPWRSO.C...K";
static char SenseDevTypes017[] = "DT..WR.O....B.";
static char SenseDevTypes018[] = "....WR.O.....K";
static char SenseDevTypes019[] = "....WR.O......";
static char SenseDevTypes020[] = ".T...RS.......";
static char SenseDevTypes021[] = ".............K";
static char SenseDevTypes022[] = "DT..W..O....B.";
static char SenseDevTypes023[] = "DT..WRSO....BK";
static char SenseDevTypes024[] = "DT..W.SO....BK";
static char SenseDevTypes025[] = "....WR.O....B.";
static char SenseDevTypes026[] = "....W..O....B.";
static char SenseDevTypes027[] = "DT.....O....BK";
static char SenseDevTypes028[] = "DTL.WRSO....BK";
static char SenseDevTypes029[] = "DT..WR.O....BK";
static char SenseDevTypes030[] = "DT..W..O....BK";
static char SenseDevTypes031[] = "D...WR.O....BK";
static char SenseDevTypes032[] = "D......O.....K";
static char SenseDevTypes033[] = "D......O....BK";
static char SenseDevTypes034[] = "DT..WR.OM...BK";
static char SenseDevTypes035[] = "D.............";
static char SenseDevTypes036[] = "DTLPWRSOMCAE.K";
static char SenseDevTypes037[] = "DTLPWRSOMCA.BK";
static char SenseDevTypes038[] = ".T...R........";
static char SenseDevTypes039[] = "DT..WR.OM...B.";
static char SenseDevTypes040[] = "DTL.WRSOMCAE.K";
static char SenseDevTypes041[] = "DTLPWRSOMCAE..";
static char SenseDevTypes042[] = "......S.......";
static char SenseDevTypes043[] = "............B.";
static char SenseDevTypes044[] = "DTLPWRSO.CA..K";
static char SenseDevTypes045[] = "DT...R.......K";
static char SenseDevTypes046[] = "D.L..R.O....B.";
static char SenseDevTypes047[] = "..L...........";
static char SenseDevTypes048[] = ".TL...........";
static char SenseDevTypes049[] = "DTLPWRSOMC..BK";
static char SenseDevTypes050[] = "DT..WR.OMCAEBK";
static char SenseDevTypes051[] = "DT..WR.OMCAEB.";
static char SenseDevTypes052[] = ".T...R.O......";
static char SenseDevTypes053[] = "...P..........";
static char SenseDevTypes054[] = "DTLPWRSOM.AE.K";
static char SenseDevTypes055[] = "DTLPWRSOM.AE..";
static char SenseDevTypes056[] = ".......O......";
static char SenseDevTypes057[] = "DTLPWRSOM...BK";
static char SenseDevTypes058[] = "DT..WR.O..A.BK";
static char SenseDevTypes059[] = "DTLPWRSOM....K";
static char SenseDevTypes060[] = "D......O......";
static char SenseDevTypes061[] = ".....R......B.";
static char SenseDevTypes062[] = "D...........B.";
static char SenseDevTypes063[] = "............BK";
static char SenseDevTypes064[] = "..........A...";
static ASCQ_Table_t ASCQ_Table[] = {
{
0x00, 0x00,
SenseDevTypes001,
"NO ADDITIONAL SENSE INFORMATION"
},
{
0x00, 0x01,
SenseDevTypes002,
"FILEMARK DETECTED"
},
{
0x00, 0x02,
SenseDevTypes003,
"END-OF-PARTITION/MEDIUM DETECTED"
},
{
0x00, 0x03,
SenseDevTypes002,
"SETMARK DETECTED"
},
{
0x00, 0x04,
SenseDevTypes003,
"BEGINNING-OF-PARTITION/MEDIUM DETECTED"
},
{
0x00, 0x05,
SenseDevTypes004,
"END-OF-DATA DETECTED"
},
{
0x00, 0x06,
SenseDevTypes001,
"I/O PROCESS TERMINATED"
},
{
0x00, 0x11,
SenseDevTypes005,
"AUDIO PLAY OPERATION IN PROGRESS"
},
{
0x00, 0x12,
SenseDevTypes005,
"AUDIO PLAY OPERATION PAUSED"
},
{
0x00, 0x13,
SenseDevTypes005,
"AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED"
},
{
0x00, 0x14,
SenseDevTypes005,
"AUDIO PLAY OPERATION STOPPED DUE TO ERROR"
},
{
0x00, 0x15,
SenseDevTypes005,
"NO CURRENT AUDIO STATUS TO RETURN"
},
{
0x00, 0x16,
SenseDevTypes001,
"OPERATION IN PROGRESS"
},
{
0x00, 0x17,
SenseDevTypes006,
"CLEANING REQUESTED"
},
{
0x01, 0x00,
SenseDevTypes007,
"NO INDEX/SECTOR SIGNAL"
},
{
0x02, 0x00,
SenseDevTypes008,
"NO SEEK COMPLETE"
},
{
0x03, 0x00,
SenseDevTypes009,
"PERIPHERAL DEVICE WRITE FAULT"
},
{
0x03, 0x01,
SenseDevTypes002,
"NO WRITE CURRENT"
},
{
0x03, 0x02,
SenseDevTypes002,
"EXCESSIVE WRITE ERRORS"
},
{
0x04, 0x00,
SenseDevTypes001,
"LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE"
},
{
0x04, 0x01,
SenseDevTypes001,
"LOGICAL UNIT IS IN PROCESS OF BECOMING READY"
},
{
0x04, 0x02,
SenseDevTypes001,
"LOGICAL UNIT NOT READY, INITIALIZING CMD. REQUIRED"
},
{
0x04, 0x03,
SenseDevTypes001,
"LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED"
},
{
0x04, 0x04,
SenseDevTypes010,
"LOGICAL UNIT NOT READY, FORMAT IN PROGRESS"
},
{
0x04, 0x05,
SenseDevTypes011,
"LOGICAL UNIT NOT READY, REBUILD IN PROGRESS"
},
{
0x04, 0x06,
SenseDevTypes011,
"LOGICAL UNIT NOT READY, RECALCULATION IN PROGRESS"
},
{
0x04, 0x07,
SenseDevTypes001,
"LOGICAL UNIT NOT READY, OPERATION IN PROGRESS"
},
{
0x04, 0x08,
SenseDevTypes005,
"LOGICAL UNIT NOT READY, LONG WRITE IN PROGRESS"
},
{
0x04, 0x09,
SenseDevTypes001,
"LOGICAL UNIT NOT READY, SELF-TEST IN PROGRESS"
},
{
0x04, 0x10,
SenseDevTypes012,
"auxiliary memory code 2 (99-148) [proposed]"
},
{
0x05, 0x00,
SenseDevTypes013,
"LOGICAL UNIT DOES NOT RESPOND TO SELECTION"
},
{
0x06, 0x00,
SenseDevTypes008,
"NO REFERENCE POSITION FOUND"
},
{
0x07, 0x00,
SenseDevTypes014,
"MULTIPLE PERIPHERAL DEVICES SELECTED"
},
{
0x08, 0x00,
SenseDevTypes013,
"LOGICAL UNIT COMMUNICATION FAILURE"
},
{
0x08, 0x01,
SenseDevTypes013,
"LOGICAL UNIT COMMUNICATION TIME-OUT"
},
{
0x08, 0x02,
SenseDevTypes013,
"LOGICAL UNIT COMMUNICATION PARITY ERROR"
},
{
0x08, 0x03,
SenseDevTypes015,
"LOGICAL UNIT COMMUNICATION CRC ERROR (ULTRA-DMA/32)"
},
{
0x08, 0x04,
SenseDevTypes016,
"UNREACHABLE COPY TARGET"
},
{
0x09, 0x00,
SenseDevTypes017,
"TRACK FOLLOWING ERROR"
},
{
0x09, 0x01,
SenseDevTypes018,
"TRACKING SERVO FAILURE"
},
{
0x09, 0x02,
SenseDevTypes018,
"FOCUS SERVO FAILURE"
},
{
0x09, 0x03,
SenseDevTypes019,
"SPINDLE SERVO FAILURE"
},
{
0x09, 0x04,
SenseDevTypes017,
"HEAD SELECT FAULT"
},
{
0x0A, 0x00,
SenseDevTypes001,
"ERROR LOG OVERFLOW"
},
{
0x0B, 0x00,
SenseDevTypes001,
"WARNING"
},
{
0x0B, 0x01,
SenseDevTypes001,
"WARNING - SPECIFIED TEMPERATURE EXCEEDED"
},
{
0x0B, 0x02,
SenseDevTypes001,
"WARNING - ENCLOSURE DEGRADED"
},
{
0x0C, 0x00,
SenseDevTypes020,
"WRITE ERROR"
},
{
0x0C, 0x01,
SenseDevTypes021,
"WRITE ERROR - RECOVERED WITH AUTO REALLOCATION"
},
{
0x0C, 0x02,
SenseDevTypes007,
"WRITE ERROR - AUTO REALLOCATION FAILED"
},
{
0x0C, 0x03,
SenseDevTypes007,
"WRITE ERROR - RECOMMEND REASSIGNMENT"
},
{
0x0C, 0x04,
SenseDevTypes022,
"COMPRESSION CHECK MISCOMPARE ERROR"
},
{
0x0C, 0x05,
SenseDevTypes022,
"DATA EXPANSION OCCURRED DURING COMPRESSION"
},
{
0x0C, 0x06,
SenseDevTypes022,
"BLOCK NOT COMPRESSIBLE"
},
{
0x0C, 0x07,
SenseDevTypes005,
"WRITE ERROR - RECOVERY NEEDED"
},
{
0x0C, 0x08,
SenseDevTypes005,
"WRITE ERROR - RECOVERY FAILED"
},
{
0x0C, 0x09,
SenseDevTypes005,
"WRITE ERROR - LOSS OF STREAMING"
},
{
0x0C, 0x0A,
SenseDevTypes005,
"WRITE ERROR - PADDING BLOCKS ADDED"
},
{
0x0C, 0x0B,
SenseDevTypes012,
"auxiliary memory code 4 (99-148) [proposed]"
},
{
0x10, 0x00,
SenseDevTypes007,
"ID CRC OR ECC ERROR"
},
{
0x11, 0x00,
SenseDevTypes023,
"UNRECOVERED READ ERROR"
},
{
0x11, 0x01,
SenseDevTypes023,
"READ RETRIES EXHAUSTED"
},
{
0x11, 0x02,
SenseDevTypes023,
"ERROR TOO LONG TO CORRECT"
},
{
0x11, 0x03,
SenseDevTypes024,
"MULTIPLE READ ERRORS"
},
{
0x11, 0x04,
SenseDevTypes007,
"UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED"
},
{
0x11, 0x05,
SenseDevTypes025,
"L-EC UNCORRECTABLE ERROR"
},
{
0x11, 0x06,
SenseDevTypes025,
"CIRC UNRECOVERED ERROR"
},
{
0x11, 0x07,
SenseDevTypes026,
"DATA RE-SYNCHRONIZATION ERROR"
},
{
0x11, 0x08,
SenseDevTypes002,
"INCOMPLETE BLOCK READ"
},
{
0x11, 0x09,
SenseDevTypes002,
"NO GAP FOUND"
},
{
0x11, 0x0A,
SenseDevTypes027,
"MISCORRECTED ERROR"
},
{
0x11, 0x0B,
SenseDevTypes007,
"UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT"
},
{
0x11, 0x0C,
SenseDevTypes007,
"UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA"
},
{
0x11, 0x0D,
SenseDevTypes017,
"DE-COMPRESSION CRC ERROR"
},
{
0x11, 0x0E,
SenseDevTypes017,
"CANNOT DECOMPRESS USING DECLARED ALGORITHM"
},
{
0x11, 0x0F,
SenseDevTypes005,
"ERROR READING UPC/EAN NUMBER"
},
{
0x11, 0x10,
SenseDevTypes005,
"ERROR READING ISRC NUMBER"
},
{
0x11, 0x11,
SenseDevTypes005,
"READ ERROR - LOSS OF STREAMING"
},
{
0x11, 0x12,
SenseDevTypes012,
"auxiliary memory code 3 (99-148) [proposed]"
},
{
0x12, 0x00,
SenseDevTypes007,
"ADDRESS MARK NOT FOUND FOR ID FIELD"
},
{
0x13, 0x00,
SenseDevTypes007,
"ADDRESS MARK NOT FOUND FOR DATA FIELD"
},
{
0x14, 0x00,
SenseDevTypes028,
"RECORDED ENTITY NOT FOUND"
},
{
0x14, 0x01,
SenseDevTypes029,
"RECORD NOT FOUND"
},
{
0x14, 0x02,
SenseDevTypes002,
"FILEMARK OR SETMARK NOT FOUND"
},
{
0x14, 0x03,
SenseDevTypes002,
"END-OF-DATA NOT FOUND"
},
{
0x14, 0x04,
SenseDevTypes002,
"BLOCK SEQUENCE ERROR"
},
{
0x14, 0x05,
SenseDevTypes030,
"RECORD NOT FOUND - RECOMMEND REASSIGNMENT"
},
{
0x14, 0x06,
SenseDevTypes030,
"RECORD NOT FOUND - DATA AUTO-REALLOCATED"
},
{
0x15, 0x00,
SenseDevTypes014,
"RANDOM POSITIONING ERROR"
},
{
0x15, 0x01,
SenseDevTypes014,
"MECHANICAL POSITIONING ERROR"
},
{
0x15, 0x02,
SenseDevTypes029,
"POSITIONING ERROR DETECTED BY READ OF MEDIUM"
},
{
0x16, 0x00,
SenseDevTypes007,
"DATA SYNCHRONIZATION MARK ERROR"
},
{
0x16, 0x01,
SenseDevTypes007,
"DATA SYNC ERROR - DATA REWRITTEN"
},
{
0x16, 0x02,
SenseDevTypes007,
"DATA SYNC ERROR - RECOMMEND REWRITE"
},
{
0x16, 0x03,
SenseDevTypes007,
"DATA SYNC ERROR - DATA AUTO-REALLOCATED"
},
{
0x16, 0x04,
SenseDevTypes007,
"DATA SYNC ERROR - RECOMMEND REASSIGNMENT"
},
{
0x17, 0x00,
SenseDevTypes023,
"RECOVERED DATA WITH NO ERROR CORRECTION APPLIED"
},
{
0x17, 0x01,
SenseDevTypes023,
"RECOVERED DATA WITH RETRIES"
},
{
0x17, 0x02,
SenseDevTypes029,
"RECOVERED DATA WITH POSITIVE HEAD OFFSET"
},
{
0x17, 0x03,
SenseDevTypes029,
"RECOVERED DATA WITH NEGATIVE HEAD OFFSET"
},
{
0x17, 0x04,
SenseDevTypes025,
"RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED"
},
{
0x17, 0x05,
SenseDevTypes031,
"RECOVERED DATA USING PREVIOUS SECTOR ID"
},
{
0x17, 0x06,
SenseDevTypes007,
"RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED"
},
{
0x17, 0x07,
SenseDevTypes031,
"RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT"
},
{
0x17, 0x08,
SenseDevTypes031,
"RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE"
},
{
0x17, 0x09,
SenseDevTypes031,
"RECOVERED DATA WITHOUT ECC - DATA REWRITTEN"
},
{
0x18, 0x00,
SenseDevTypes029,
"RECOVERED DATA WITH ERROR CORRECTION APPLIED"
},
{
0x18, 0x01,
SenseDevTypes031,
"RECOVERED DATA WITH ERROR CORR. & RETRIES APPLIED"
},
{
0x18, 0x02,
SenseDevTypes031,
"RECOVERED DATA - DATA AUTO-REALLOCATED"
},
{
0x18, 0x03,
SenseDevTypes005,
"RECOVERED DATA WITH CIRC"
},
{
0x18, 0x04,
SenseDevTypes005,
"RECOVERED DATA WITH L-EC"
},
{
0x18, 0x05,
SenseDevTypes031,
"RECOVERED DATA - RECOMMEND REASSIGNMENT"
},
{
0x18, 0x06,
SenseDevTypes031,
"RECOVERED DATA - RECOMMEND REWRITE"
},
{
0x18, 0x07,
SenseDevTypes007,
"RECOVERED DATA WITH ECC - DATA REWRITTEN"
},
{
0x19, 0x00,
SenseDevTypes032,
"DEFECT LIST ERROR"
},
{
0x19, 0x01,
SenseDevTypes032,
"DEFECT LIST NOT AVAILABLE"
},
{
0x19, 0x02,
SenseDevTypes032,
"DEFECT LIST ERROR IN PRIMARY LIST"
},
{
0x19, 0x03,
SenseDevTypes032,
"DEFECT LIST ERROR IN GROWN LIST"
},
{
0x1A, 0x00,
SenseDevTypes001,
"PARAMETER LIST LENGTH ERROR"
},
{
0x1B, 0x00,
SenseDevTypes001,
"SYNCHRONOUS DATA TRANSFER ERROR"
},
{
0x1C, 0x00,
SenseDevTypes033,
"DEFECT LIST NOT FOUND"
},
{
0x1C, 0x01,
SenseDevTypes033,
"PRIMARY DEFECT LIST NOT FOUND"
},
{
0x1C, 0x02,
SenseDevTypes033,
"GROWN DEFECT LIST NOT FOUND"
},
{
0x1D, 0x00,
SenseDevTypes029,
"MISCOMPARE DURING VERIFY OPERATION"
},
{
0x1E, 0x00,
SenseDevTypes007,
"RECOVERED ID WITH ECC CORRECTION"
},
{
0x1F, 0x00,
SenseDevTypes032,
"PARTIAL DEFECT LIST TRANSFER"
},
{
0x20, 0x00,
SenseDevTypes001,
"INVALID COMMAND OPERATION CODE"
},
{
0x20, 0x01,
SenseDevTypes012,
"access controls code 1 (99-314) [proposed]"
},
{
0x20, 0x02,
SenseDevTypes012,
"access controls code 2 (99-314) [proposed]"
},
{
0x20, 0x03,
SenseDevTypes012,
"access controls code 3 (99-314) [proposed]"
},
{
0x21, 0x00,
SenseDevTypes034,
"LOGICAL BLOCK ADDRESS OUT OF RANGE"
},
{
0x21, 0x01,
SenseDevTypes034,
"INVALID ELEMENT ADDRESS"
},
{
0x22, 0x00,
SenseDevTypes035,
"ILLEGAL FUNCTION (USE 20 00, 24 00, OR 26 00)"
},
{
0x24, 0x00,
SenseDevTypes001,
"INVALID FIELD IN CDB"
},
{
0x24, 0x01,
SenseDevTypes001,
"CDB DECRYPTION ERROR"
},
{
0x25, 0x00,
SenseDevTypes001,
"LOGICAL UNIT NOT SUPPORTED"
},
{
0x26, 0x00,
SenseDevTypes001,
"INVALID FIELD IN PARAMETER LIST"
},
{
0x26, 0x01,
SenseDevTypes001,
"PARAMETER NOT SUPPORTED"
},
{
0x26, 0x02,
SenseDevTypes001,
"PARAMETER VALUE INVALID"
},
{
0x26, 0x03,
SenseDevTypes036,
"THRESHOLD PARAMETERS NOT SUPPORTED"
},
{
0x26, 0x04,
SenseDevTypes001,
"INVALID RELEASE OF PERSISTENT RESERVATION"
},
{
0x26, 0x05,
SenseDevTypes037,
"DATA DECRYPTION ERROR"
},
{
0x26, 0x06,
SenseDevTypes016,
"TOO MANY TARGET DESCRIPTORS"
},
{
0x26, 0x07,
SenseDevTypes016,
"UNSUPPORTED TARGET DESCRIPTOR TYPE CODE"
},
{
0x26, 0x08,
SenseDevTypes016,
"TOO MANY SEGMENT DESCRIPTORS"
},
{
0x26, 0x09,
SenseDevTypes016,
"UNSUPPORTED SEGMENT DESCRIPTOR TYPE CODE"
},
{
0x26, 0x0A,
SenseDevTypes016,
"UNEXPECTED INEXACT SEGMENT"
},
{
0x26, 0x0B,
SenseDevTypes016,
"INLINE DATA LENGTH EXCEEDED"
},
{
0x26, 0x0C,
SenseDevTypes016,
"INVALID OPERATION FOR COPY SOURCE OR DESTINATION"
},
{
0x26, 0x0D,
SenseDevTypes016,
"COPY SEGMENT GRANULARITY VIOLATION"
},
{
0x27, 0x00,
SenseDevTypes029,
"WRITE PROTECTED"
},
{
0x27, 0x01,
SenseDevTypes029,
"HARDWARE WRITE PROTECTED"
},
{
0x27, 0x02,
SenseDevTypes029,
"LOGICAL UNIT SOFTWARE WRITE PROTECTED"
},
{
0x27, 0x03,
SenseDevTypes038,
"ASSOCIATED WRITE PROTECT"
},
{
0x27, 0x04,
SenseDevTypes038,
"PERSISTENT WRITE PROTECT"
},
{
0x27, 0x05,
SenseDevTypes038,
"PERMANENT WRITE PROTECT"
},
{
0x28, 0x00,
SenseDevTypes001,
"NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED"
},
{
0x28, 0x01,
SenseDevTypes039,
"IMPORT OR EXPORT ELEMENT ACCESSED"
},
{
0x29, 0x00,
SenseDevTypes001,
"POWER ON, RESET, OR BUS DEVICE RESET OCCURRED"
},
{
0x29, 0x01,
SenseDevTypes001,
"POWER ON OCCURRED"
},
{
0x29, 0x02,
SenseDevTypes001,
"SCSI BUS RESET OCCURRED"
},
{
0x29, 0x03,
SenseDevTypes001,
"BUS DEVICE RESET FUNCTION OCCURRED"
},
{
0x29, 0x04,
SenseDevTypes001,
"DEVICE INTERNAL RESET"
},
{
0x29, 0x05,
SenseDevTypes001,
"TRANSCEIVER MODE CHANGED TO SINGLE-ENDED"
},
{
0x29, 0x06,
SenseDevTypes001,
"TRANSCEIVER MODE CHANGED TO LVD"
},
{
0x2A, 0x00,
SenseDevTypes013,
"PARAMETERS CHANGED"
},
{
0x2A, 0x01,
SenseDevTypes013,
"MODE PARAMETERS CHANGED"
},
{
0x2A, 0x02,
SenseDevTypes040,
"LOG PARAMETERS CHANGED"
},
{
0x2A, 0x03,
SenseDevTypes036,
"RESERVATIONS PREEMPTED"
},
{
0x2A, 0x04,
SenseDevTypes041,
"RESERVATIONS RELEASED"
},
{
0x2A, 0x05,
SenseDevTypes041,
"REGISTRATIONS PREEMPTED"
},
{
0x2B, 0x00,
SenseDevTypes016,
"COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT"
},
{
0x2C, 0x00,
SenseDevTypes001,
"COMMAND SEQUENCE ERROR"
},
{
0x2C, 0x01,
SenseDevTypes042,
"TOO MANY WINDOWS SPECIFIED"
},
{
0x2C, 0x02,
SenseDevTypes042,
"INVALID COMBINATION OF WINDOWS SPECIFIED"
},
{
0x2C, 0x03,
SenseDevTypes005,
"CURRENT PROGRAM AREA IS NOT EMPTY"
},
{
0x2C, 0x04,
SenseDevTypes005,
"CURRENT PROGRAM AREA IS EMPTY"
},
{
0x2C, 0x05,
SenseDevTypes043,
"ILLEGAL POWER CONDITION REQUEST"
},
{
0x2D, 0x00,
SenseDevTypes002,
"OVERWRITE ERROR ON UPDATE IN PLACE"
},
{
0x2E, 0x00,
SenseDevTypes044,
"ERROR DETECTED BY THIRD PARTY TEMPORARY INITIATOR"
},
{
0x2E, 0x01,
SenseDevTypes044,
"THIRD PARTY DEVICE FAILURE"
},
{
0x2E, 0x02,
SenseDevTypes044,
"COPY TARGET DEVICE NOT REACHABLE"
},
{
0x2E, 0x03,
SenseDevTypes044,
"INCORRECT COPY TARGET DEVICE TYPE"
},
{
0x2E, 0x04,
SenseDevTypes044,
"COPY TARGET DEVICE DATA UNDERRUN"
},
{
0x2E, 0x05,
SenseDevTypes044,
"COPY TARGET DEVICE DATA OVERRUN"
},
{
0x2F, 0x00,
SenseDevTypes001,
"COMMANDS CLEARED BY ANOTHER INITIATOR"
},
{
0x30, 0x00,
SenseDevTypes034,
"INCOMPATIBLE MEDIUM INSTALLED"
},
{
0x30, 0x01,
SenseDevTypes029,
"CANNOT READ MEDIUM - UNKNOWN FORMAT"
},
{
0x30, 0x02,
SenseDevTypes029,
"CANNOT READ MEDIUM - INCOMPATIBLE FORMAT"
},
{
0x30, 0x03,
SenseDevTypes045,
"CLEANING CARTRIDGE INSTALLED"
},
{
0x30, 0x04,
SenseDevTypes029,
"CANNOT WRITE MEDIUM - UNKNOWN FORMAT"
},
{
0x30, 0x05,
SenseDevTypes029,
"CANNOT WRITE MEDIUM - INCOMPATIBLE FORMAT"
},
{
0x30, 0x06,
SenseDevTypes017,
"CANNOT FORMAT MEDIUM - INCOMPATIBLE MEDIUM"
},
{
0x30, 0x07,
SenseDevTypes006,
"CLEANING FAILURE"
},
{
0x30, 0x08,
SenseDevTypes005,
"CANNOT WRITE - APPLICATION CODE MISMATCH"
},
{
0x30, 0x09,
SenseDevTypes005,
"CURRENT SESSION NOT FIXATED FOR APPEND"
},
{
0x31, 0x00,
SenseDevTypes029,
"MEDIUM FORMAT CORRUPTED"
},
{
0x31, 0x01,
SenseDevTypes046,
"FORMAT COMMAND FAILED"
},
{
0x32, 0x00,
SenseDevTypes007,
"NO DEFECT SPARE LOCATION AVAILABLE"
},
{
0x32, 0x01,
SenseDevTypes007,
"DEFECT LIST UPDATE FAILURE"
},
{
0x33, 0x00,
SenseDevTypes002,
"TAPE LENGTH ERROR"
},
{
0x34, 0x00,
SenseDevTypes001,
"ENCLOSURE FAILURE"
},
{
0x35, 0x00,
SenseDevTypes001,
"ENCLOSURE SERVICES FAILURE"
},
{
0x35, 0x01,
SenseDevTypes001,
"UNSUPPORTED ENCLOSURE FUNCTION"
},
{
0x35, 0x02,
SenseDevTypes001,
"ENCLOSURE SERVICES UNAVAILABLE"
},
{
0x35, 0x03,
SenseDevTypes001,
"ENCLOSURE SERVICES TRANSFER FAILURE"
},
{
0x35, 0x04,
SenseDevTypes001,
"ENCLOSURE SERVICES TRANSFER REFUSED"
},
{
0x36, 0x00,
SenseDevTypes047,
"RIBBON, INK, OR TONER FAILURE"
},
{
0x37, 0x00,
SenseDevTypes013,
"ROUNDED PARAMETER"
},
{
0x38, 0x00,
SenseDevTypes043,
"EVENT STATUS NOTIFICATION"
},
{
0x38, 0x02,
SenseDevTypes043,
"ESN - POWER MANAGEMENT CLASS EVENT"
},
{
0x38, 0x04,
SenseDevTypes043,
"ESN - MEDIA CLASS EVENT"
},
{
0x38, 0x06,
SenseDevTypes043,
"ESN - DEVICE BUSY CLASS EVENT"
},
{
0x39, 0x00,
SenseDevTypes040,
"SAVING PARAMETERS NOT SUPPORTED"
},
{
0x3A, 0x00,
SenseDevTypes014,
"MEDIUM NOT PRESENT"
},
{
0x3A, 0x01,
SenseDevTypes034,
"MEDIUM NOT PRESENT - TRAY CLOSED"
},
{
0x3A, 0x02,
SenseDevTypes034,
"MEDIUM NOT PRESENT - TRAY OPEN"
},
{
0x3A, 0x03,
SenseDevTypes039,
"MEDIUM NOT PRESENT - LOADABLE"
},
{
0x3A, 0x04,
SenseDevTypes039,
"MEDIUM NOT PRESENT - MEDIUM AUXILIARY MEMORY ACCESSIBLE"
},
{
0x3B, 0x00,
SenseDevTypes048,
"SEQUENTIAL POSITIONING ERROR"
},
{
0x3B, 0x01,
SenseDevTypes002,
"TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM"
},
{
0x3B, 0x02,
SenseDevTypes002,
"TAPE POSITION ERROR AT END-OF-MEDIUM"
},
{
0x3B, 0x03,
SenseDevTypes047,
"TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY"
},
{
0x3B, 0x04,
SenseDevTypes047,
"SLEW FAILURE"
},
{
0x3B, 0x05,
SenseDevTypes047,
"PAPER JAM"
},
{
0x3B, 0x06,
SenseDevTypes047,
"FAILED TO SENSE TOP-OF-FORM"
},
{
0x3B, 0x07,
SenseDevTypes047,
"FAILED TO SENSE BOTTOM-OF-FORM"
},
{
0x3B, 0x08,
SenseDevTypes002,
"REPOSITION ERROR"
},
{
0x3B, 0x09,
SenseDevTypes042,
"READ PAST END OF MEDIUM"
},
{
0x3B, 0x0A,
SenseDevTypes042,
"READ PAST BEGINNING OF MEDIUM"
},
{
0x3B, 0x0B,
SenseDevTypes042,
"POSITION PAST END OF MEDIUM"
},
{
0x3B, 0x0C,
SenseDevTypes003,
"POSITION PAST BEGINNING OF MEDIUM"
},
{
0x3B, 0x0D,
SenseDevTypes034,
"MEDIUM DESTINATION ELEMENT FULL"
},
{
0x3B, 0x0E,
SenseDevTypes034,
"MEDIUM SOURCE ELEMENT EMPTY"
},
{
0x3B, 0x0F,
SenseDevTypes005,
"END OF MEDIUM REACHED"
},
{
0x3B, 0x11,
SenseDevTypes034,
"MEDIUM MAGAZINE NOT ACCESSIBLE"
},
{
0x3B, 0x12,
SenseDevTypes034,
"MEDIUM MAGAZINE REMOVED"
},
{
0x3B, 0x13,
SenseDevTypes034,
"MEDIUM MAGAZINE INSERTED"
},
{
0x3B, 0x14,
SenseDevTypes034,
"MEDIUM MAGAZINE LOCKED"
},
{
0x3B, 0x15,
SenseDevTypes034,
"MEDIUM MAGAZINE UNLOCKED"
},
{
0x3B, 0x16,
SenseDevTypes005,
"MECHANICAL POSITIONING OR CHANGER ERROR"
},
{
0x3D, 0x00,
SenseDevTypes036,
"INVALID BITS IN IDENTIFY MESSAGE"
},
{
0x3E, 0x00,
SenseDevTypes001,
"LOGICAL UNIT HAS NOT SELF-CONFIGURED YET"
},
{
0x3E, 0x01,
SenseDevTypes001,
"LOGICAL UNIT FAILURE"
},
{
0x3E, 0x02,
SenseDevTypes001,
"TIMEOUT ON LOGICAL UNIT"
},
{
0x3E, 0x03,
SenseDevTypes001,
"LOGICAL UNIT FAILED SELF-TEST"
},
{
0x3E, 0x04,
SenseDevTypes001,
"LOGICAL UNIT UNABLE TO UPDATE SELF-TEST LOG"
},
{
0x3F, 0x00,
SenseDevTypes001,
"TARGET OPERATING CONDITIONS HAVE CHANGED"
},
{
0x3F, 0x01,
SenseDevTypes001,
"MICROCODE HAS BEEN CHANGED"
},
{
0x3F, 0x02,
SenseDevTypes049,
"CHANGED OPERATING DEFINITION"
},
{
0x3F, 0x03,
SenseDevTypes001,
"INQUIRY DATA HAS CHANGED"
},
{
0x3F, 0x04,
SenseDevTypes050,
"COMPONENT DEVICE ATTACHED"
},
{
0x3F, 0x05,
SenseDevTypes050,
"DEVICE IDENTIFIER CHANGED"
},
{
0x3F, 0x06,
SenseDevTypes051,
"REDUNDANCY GROUP CREATED OR MODIFIED"
},
{
0x3F, 0x07,
SenseDevTypes051,
"REDUNDANCY GROUP DELETED"
},
{
0x3F, 0x08,
SenseDevTypes051,
"SPARE CREATED OR MODIFIED"
},
{
0x3F, 0x09,
SenseDevTypes051,
"SPARE DELETED"
},
{
0x3F, 0x0A,
SenseDevTypes050,
"VOLUME SET CREATED OR MODIFIED"
},
{
0x3F, 0x0B,
SenseDevTypes050,
"VOLUME SET DELETED"
},
{
0x3F, 0x0C,
SenseDevTypes050,
"VOLUME SET DEASSIGNED"
},
{
0x3F, 0x0D,
SenseDevTypes050,
"VOLUME SET REASSIGNED"
},
{
0x3F, 0x0E,
SenseDevTypes041,
"REPORTED LUNS DATA HAS CHANGED"
},
{
0x3F, 0x0F,
SenseDevTypes001,
"ECHO BUFFER OVERWRITTEN"
},
{
0x3F, 0x10,
SenseDevTypes039,
"MEDIUM LOADABLE"
},
{
0x3F, 0x11,
SenseDevTypes039,
"MEDIUM AUXILIARY MEMORY ACCESSIBLE"
},
{
0x40, 0x00,
SenseDevTypes035,
"RAM FAILURE (SHOULD USE 40 NN)"
},
{
0x40, 0xFF,
SenseDevTypes001,
"DIAGNOSTIC FAILURE ON COMPONENT NN (80H-FFH)"
},
{
0x41, 0x00,
SenseDevTypes035,
"DATA PATH FAILURE (SHOULD USE 40 NN)"
},
{
0x42, 0x00,
SenseDevTypes035,
"POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN)"
},
{
0x43, 0x00,
SenseDevTypes001,
"MESSAGE ERROR"
},
{
0x44, 0x00,
SenseDevTypes001,
"INTERNAL TARGET FAILURE"
},
{
0x45, 0x00,
SenseDevTypes001,
"SELECT OR RESELECT FAILURE"
},
{
0x46, 0x00,
SenseDevTypes049,
"UNSUCCESSFUL SOFT RESET"
},
{
0x47, 0x00,
SenseDevTypes001,
"SCSI PARITY ERROR"
},
{
0x47, 0x01,
SenseDevTypes001,
"DATA PHASE CRC ERROR DETECTED"
},
{
0x47, 0x02,
SenseDevTypes001,
"SCSI PARITY ERROR DETECTED DURING ST DATA PHASE"
},
{
0x47, 0x03,
SenseDevTypes001,
"INFORMATION UNIT CRC ERROR DETECTED"
},
{
0x47, 0x04,
SenseDevTypes001,
"ASYNCHRONOUS INFORMATION PROTECTION ERROR DETECTED"
},
{
0x48, 0x00,
SenseDevTypes001,
"INITIATOR DETECTED ERROR MESSAGE RECEIVED"
},
{
0x49, 0x00,
SenseDevTypes001,
"INVALID MESSAGE ERROR"
},
{
0x4A, 0x00,
SenseDevTypes001,
"COMMAND PHASE ERROR"
},
{
0x4B, 0x00,
SenseDevTypes001,
"DATA PHASE ERROR"
},
{
0x4C, 0x00,
SenseDevTypes001,
"LOGICAL UNIT FAILED SELF-CONFIGURATION"
},
{
0x4D, 0xFF,
SenseDevTypes001,
"TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG)"
},
{
0x4E, 0x00,
SenseDevTypes001,
"OVERLAPPED COMMANDS ATTEMPTED"
},
{
0x50, 0x00,
SenseDevTypes002,
"WRITE APPEND ERROR"
},
{
0x50, 0x01,
SenseDevTypes002,
"WRITE APPEND POSITION ERROR"
},
{
0x50, 0x02,
SenseDevTypes002,
"POSITION ERROR RELATED TO TIMING"
},
{
0x51, 0x00,
SenseDevTypes052,
"ERASE FAILURE"
},
{
0x52, 0x00,
SenseDevTypes002,
"CARTRIDGE FAULT"
},
{
0x53, 0x00,
SenseDevTypes014,
"MEDIA LOAD OR EJECT FAILED"
},
{
0x53, 0x01,
SenseDevTypes002,
"UNLOAD TAPE FAILURE"
},
{
0x53, 0x02,
SenseDevTypes034,
"MEDIUM REMOVAL PREVENTED"
},
{
0x54, 0x00,
SenseDevTypes053,
"SCSI TO HOST SYSTEM INTERFACE FAILURE"
},
{
0x55, 0x00,
SenseDevTypes053,
"SYSTEM RESOURCE FAILURE"
},
{
0x55, 0x01,
SenseDevTypes033,
"SYSTEM BUFFER FULL"
},
{
0x55, 0x02,
SenseDevTypes054,
"INSUFFICIENT RESERVATION RESOURCES"
},
{
0x55, 0x03,
SenseDevTypes041,
"INSUFFICIENT RESOURCES"
},
{
0x55, 0x04,
SenseDevTypes055,
"INSUFFICIENT REGISTRATION RESOURCES"
},
{
0x55, 0x05,
SenseDevTypes012,
"access controls code 4 (99-314) [proposed]"
},
{
0x55, 0x06,
SenseDevTypes012,
"auxiliary memory code 1 (99-148) [proposed]"
},
{
0x57, 0x00,
SenseDevTypes005,
"UNABLE TO RECOVER TABLE-OF-CONTENTS"
},
{
0x58, 0x00,
SenseDevTypes056,
"GENERATION DOES NOT EXIST"
},
{
0x59, 0x00,
SenseDevTypes056,
"UPDATED BLOCK READ"
},
{
0x5A, 0x00,
SenseDevTypes057,
"OPERATOR REQUEST OR STATE CHANGE INPUT"
},
{
0x5A, 0x01,
SenseDevTypes034,
"OPERATOR MEDIUM REMOVAL REQUEST"
},
{
0x5A, 0x02,
SenseDevTypes058,
"OPERATOR SELECTED WRITE PROTECT"
},
{
0x5A, 0x03,
SenseDevTypes058,
"OPERATOR SELECTED WRITE PERMIT"
},
{
0x5B, 0x00,
SenseDevTypes059,
"LOG EXCEPTION"
},
{
0x5B, 0x01,
SenseDevTypes059,
"THRESHOLD CONDITION MET"
},
{
0x5B, 0x02,
SenseDevTypes059,
"LOG COUNTER AT MAXIMUM"
},
{
0x5B, 0x03,
SenseDevTypes059,
"LOG LIST CODES EXHAUSTED"
},
{
0x5C, 0x00,
SenseDevTypes060,
"RPL STATUS CHANGE"
},
{
0x5C, 0x01,
SenseDevTypes060,
"SPINDLES SYNCHRONIZED"
},
{
0x5C, 0x02,
SenseDevTypes060,
"SPINDLES NOT SYNCHRONIZED"
},
{
0x5D, 0x00,
SenseDevTypes001,
"FAILURE PREDICTION THRESHOLD EXCEEDED"
},
{
0x5D, 0x01,
SenseDevTypes061,
"MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED"
},
{
0x5D, 0x02,
SenseDevTypes005,
"LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED"
},
{
0x5D, 0x10,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE"
},
{
0x5D, 0x11,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH"
},
{
0x5D, 0x12,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH"
},
{
0x5D, 0x13,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH"
},
{
0x5D, 0x14,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS"
},
{
0x5D, 0x15,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH"
},
{
0x5D, 0x16,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH"
},
{
0x5D, 0x17,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS"
},
{
0x5D, 0x18,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE CONTROLLER DETECTED"
},
{
0x5D, 0x19,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE"
},
{
0x5D, 0x1A,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE"
},
{
0x5D, 0x1B,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT"
},
{
0x5D, 0x1C,
SenseDevTypes062,
"HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"
},
{
0x5D, 0x20,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE"
},
{
0x5D, 0x21,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH"
},
{
0x5D, 0x22,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH"
},
{
0x5D, 0x23,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH"
},
{
0x5D, 0x24,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS"
},
{
0x5D, 0x25,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH"
},
{
0x5D, 0x26,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH"
},
{
0x5D, 0x27,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS"
},
{
0x5D, 0x28,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED"
},
{
0x5D, 0x29,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE"
},
{
0x5D, 0x2A,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE"
},
{
0x5D, 0x2B,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT"
},
{
0x5D, 0x2C,
SenseDevTypes062,
"CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"
},
{
0x5D, 0x30,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE"
},
{
0x5D, 0x31,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH"
},
{
0x5D, 0x32,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH"
},
{
0x5D, 0x33,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH"
},
{
0x5D, 0x34,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS"
},
{
0x5D, 0x35,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH"
},
{
0x5D, 0x36,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH"
},
{
0x5D, 0x37,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS"
},
{
0x5D, 0x38,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED"
},
{
0x5D, 0x39,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE"
},
{
0x5D, 0x3A,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE"
},
{
0x5D, 0x3B,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT"
},
{
0x5D, 0x3C,
SenseDevTypes062,
"DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"
},
{
0x5D, 0x40,
SenseDevTypes062,
"SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE"
},
{
0x5D, 0x41,
SenseDevTypes062,
"SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH"
},
{
0x5D, 0x42,
SenseDevTypes062,
"SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH"
},
{
0x5D, 0x43,
SenseDevTypes062,
"SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH"
},
{
0x5D, 0x44,
SenseDevTypes062,
"SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS"
},
{
0x5D, 0x45,
SenseDevTypes062,
"SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH"
},
{
0x5D, 0x46,
SenseDevTypes062,
"SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH"
},
{
0x5D, 0x47,
SenseDevTypes062,
"SERVO IMPENDING FAILURE CHANNEL PARAMETRICS"
},
{
0x5D, 0x48,
SenseDevTypes062,
"SERVO IMPENDING FAILURE CONTROLLER DETECTED"
},
{
0x5D, 0x49,
SenseDevTypes062,
"SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE"
},
{
0x5D, 0x4A,
SenseDevTypes062,
"SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE"
},
{
0x5D, 0x4B,
SenseDevTypes062,
"SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT"
},
{
0x5D, 0x4C,
SenseDevTypes062,
"SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"
},
{
0x5D, 0x50,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE"
},
{
0x5D, 0x51,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH"
},
{
0x5D, 0x52,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH"
},
{
0x5D, 0x53,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH"
},
{
0x5D, 0x54,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS"
},
{
0x5D, 0x55,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH"
},
{
0x5D, 0x56,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH"
},
{
0x5D, 0x57,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS"
},
{
0x5D, 0x58,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE CONTROLLER DETECTED"
},
{
0x5D, 0x59,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE"
},
{
0x5D, 0x5A,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE"
},
{
0x5D, 0x5B,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT"
},
{
0x5D, 0x5C,
SenseDevTypes062,
"SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"
},
{
0x5D, 0x60,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE"
},
{
0x5D, 0x61,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH"
},
{
0x5D, 0x62,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH"
},
{
0x5D, 0x63,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH"
},
{
0x5D, 0x64,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS"
},
{
0x5D, 0x65,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH"
},
{
0x5D, 0x66,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH"
},
{
0x5D, 0x67,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS"
},
{
0x5D, 0x68,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED"
},
{
0x5D, 0x69,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE"
},
{
0x5D, 0x6A,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE"
},
{
0x5D, 0x6B,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT"
},
{
0x5D, 0x6C,
SenseDevTypes062,
"FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"
},
{
0x5D, 0xFF,
SenseDevTypes001,
"FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE)"
},
{
0x5E, 0x00,
SenseDevTypes044,
"LOW POWER CONDITION ON"
},
{
0x5E, 0x01,
SenseDevTypes044,
"IDLE CONDITION ACTIVATED BY TIMER"
},
{
0x5E, 0x02,
SenseDevTypes044,
"STANDBY CONDITION ACTIVATED BY TIMER"
},
{
0x5E, 0x03,
SenseDevTypes044,
"IDLE CONDITION ACTIVATED BY COMMAND"
},
{
0x5E, 0x04,
SenseDevTypes044,
"STANDBY CONDITION ACTIVATED BY COMMAND"
},
{
0x5E, 0x41,
SenseDevTypes043,
"POWER STATE CHANGE TO ACTIVE"
},
{
0x5E, 0x42,
SenseDevTypes043,
"POWER STATE CHANGE TO IDLE"
},
{
0x5E, 0x43,
SenseDevTypes043,
"POWER STATE CHANGE TO STANDBY"
},
{
0x5E, 0x45,
SenseDevTypes043,
"POWER STATE CHANGE TO SLEEP"
},
{
0x5E, 0x47,
SenseDevTypes063,
"POWER STATE CHANGE TO DEVICE CONTROL"
},
{
0x60, 0x00,
SenseDevTypes042,
"LAMP FAILURE"
},
{
0x61, 0x00,
SenseDevTypes042,
"VIDEO ACQUISITION ERROR"
},
{
0x61, 0x01,
SenseDevTypes042,
"UNABLE TO ACQUIRE VIDEO"
},
{
0x61, 0x02,
SenseDevTypes042,
"OUT OF FOCUS"
},
{
0x62, 0x00,
SenseDevTypes042,
"SCAN HEAD POSITIONING ERROR"
},
{
0x63, 0x00,
SenseDevTypes005,
"END OF USER AREA ENCOUNTERED ON THIS TRACK"
},
{
0x63, 0x01,
SenseDevTypes005,
"PACKET DOES NOT FIT IN AVAILABLE SPACE"
},
{
0x64, 0x00,
SenseDevTypes005,
"ILLEGAL MODE FOR THIS TRACK"
},
{
0x64, 0x01,
SenseDevTypes005,
"INVALID PACKET SIZE"
},
{
0x65, 0x00,
SenseDevTypes001,
"VOLTAGE FAULT"
},
{
0x66, 0x00,
SenseDevTypes042,
"AUTOMATIC DOCUMENT FEEDER COVER UP"
},
{
0x66, 0x01,
SenseDevTypes042,
"AUTOMATIC DOCUMENT FEEDER LIFT UP"
},
{
0x66, 0x02,
SenseDevTypes042,
"DOCUMENT JAM IN AUTOMATIC DOCUMENT FEEDER"
},
{
0x66, 0x03,
SenseDevTypes042,
"DOCUMENT MISS FEED AUTOMATIC IN DOCUMENT FEEDER"
},
{
0x67, 0x00,
SenseDevTypes064,
"CONFIGURATION FAILURE"
},
{
0x67, 0x01,
SenseDevTypes064,
"CONFIGURATION OF INCAPABLE LOGICAL UNITS FAILED"
},
{
0x67, 0x02,
SenseDevTypes064,
"ADD LOGICAL UNIT FAILED"
},
{
0x67, 0x03,
SenseDevTypes064,
"MODIFICATION OF LOGICAL UNIT FAILED"
},
{
0x67, 0x04,
SenseDevTypes064,
"EXCHANGE OF LOGICAL UNIT FAILED"
},
{
0x67, 0x05,
SenseDevTypes064,
"REMOVE OF LOGICAL UNIT FAILED"
},
{
0x67, 0x06,
SenseDevTypes064,
"ATTACHMENT OF LOGICAL UNIT FAILED"
},
{
0x67, 0x07,
SenseDevTypes064,
"CREATION OF LOGICAL UNIT FAILED"
},
{
0x67, 0x08,
SenseDevTypes064,
"ASSIGN FAILURE OCCURRED"
},
{
0x67, 0x09,
SenseDevTypes064,
"MULTIPLY ASSIGNED LOGICAL UNIT"
},
{
0x68, 0x00,
SenseDevTypes064,
"LOGICAL UNIT NOT CONFIGURED"
},
{
0x69, 0x00,
SenseDevTypes064,
"DATA LOSS ON LOGICAL UNIT"
},
{
0x69, 0x01,
SenseDevTypes064,
"MULTIPLE LOGICAL UNIT FAILURES"
},
{
0x69, 0x02,
SenseDevTypes064,
"PARITY/DATA MISMATCH"
},
{
0x6A, 0x00,
SenseDevTypes064,
"INFORMATIONAL, REFER TO LOG"
},
{
0x6B, 0x00,
SenseDevTypes064,
"STATE CHANGE HAS OCCURRED"
},
{
0x6B, 0x01,
SenseDevTypes064,
"REDUNDANCY LEVEL GOT BETTER"
},
{
0x6B, 0x02,
SenseDevTypes064,
"REDUNDANCY LEVEL GOT WORSE"
},
{
0x6C, 0x00,
SenseDevTypes064,
"REBUILD FAILURE OCCURRED"
},
{
0x6D, 0x00,
SenseDevTypes064,
"RECALCULATE FAILURE OCCURRED"
},
{
0x6E, 0x00,
SenseDevTypes064,
"COMMAND TO LOGICAL UNIT FAILED"
},
{
0x6F, 0x00,
SenseDevTypes005,
"COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE"
},
{
0x6F, 0x01,
SenseDevTypes005,
"COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT PRESENT"
},
{
0x6F, 0x02,
SenseDevTypes005,
"COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED"
},
{
0x6F, 0x03,
SenseDevTypes005,
"READ OF SCRAMBLED SECTOR WITHOUT AUTHENTICATION"
},
{
0x6F, 0x04,
SenseDevTypes005,
"MEDIA REGION CODE IS MISMATCHED TO LOGICAL UNIT REGION"
},
{
0x6F, 0x05,
SenseDevTypes005,
"DRIVE REGION MUST BE PERMANENT/REGION RESET COUNT ERROR"
},
{
0x70, 0xFF,
SenseDevTypes002,
"DECOMPRESSION EXCEPTION SHORT ALGORITHM ID OF NN"
},
{
0x71, 0x00,
SenseDevTypes002,
"DECOMPRESSION EXCEPTION LONG ALGORITHM ID"
},
{
0x72, 0x00,
SenseDevTypes005,
"SESSION FIXATION ERROR"
},
{
0x72, 0x01,
SenseDevTypes005,
"SESSION FIXATION ERROR WRITING LEAD-IN"
},
{
0x72, 0x02,
SenseDevTypes005,
"SESSION FIXATION ERROR WRITING LEAD-OUT"
},
{
0x72, 0x03,
SenseDevTypes005,
"SESSION FIXATION ERROR - INCOMPLETE TRACK IN SESSION"
},
{
0x72, 0x04,
SenseDevTypes005,
"EMPTY OR PARTIALLY WRITTEN RESERVED TRACK"
},
{
0x72, 0x05,
SenseDevTypes005,
"NO MORE TRACK RESERVATIONS ALLOWED"
},
{
0x73, 0x00,
SenseDevTypes005,
"CD CONTROL ERROR"
},
{
0x73, 0x01,
SenseDevTypes005,
"POWER CALIBRATION AREA ALMOST FULL"
},
{
0x73, 0x02,
SenseDevTypes005,
"POWER CALIBRATION AREA IS FULL"
},
{
0x73, 0x03,
SenseDevTypes005,
"POWER CALIBRATION AREA ERROR"
},
{
0x73, 0x04,
SenseDevTypes005,
"PROGRAM MEMORY AREA UPDATE FAILURE"
},
{
0x73, 0x05,
SenseDevTypes005,
"PROGRAM MEMORY AREA IS FULL"
},
{
0x73, 0x06,
SenseDevTypes005,
"RMA/PMA IS FULL"
},
};
static int ASCQ_TableSize = 463;
#endif
#!/bin/sh
#
# ascq_tbl.sh - Translate SCSI t10.org's "asc-num.txt" file of
# SCSI Additional Sense Code & Qualifiers (ASC/ASCQ's)
# into something useful in C, creating "ascq_tbl.c" file.
#
#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
PREF_INFILE="t10.org/asc-num.txt" # From SCSI t10.org
PREF_OUTFILE="ascq_tbl.c"
#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
xlate_ascq() {
cat | awk '
BEGIN {
DQ = "\042";
OUTFILE = "'"${PREF_OUTFILE}"'";
TRUE = 1;
FALSE = 0;
#debug = TRUE;
# read and discard all lines up to and including the one that begins
# with the "magic token" of "------- -------------- ---"...
headers_gone = FALSE;
while (!headers_gone) {
if (getline <= 0)
exit 1;
header_line[++hdrs] = $0;
if (debug)
printf("header_line[%d] = :%s:\n", ++hdrs, $0);
if ($0 ~ /^------- -------------- ---/) {
headers_gone = TRUE;
}
}
outcount = 0;
}
(NF > 1) {
++outcount;
if (debug)
printf( "DBG: %s\n", $0 );
ASC[outcount] = substr($0,1,2);
ASCQ[outcount] = substr($0,5,2);
devtypes = substr($0,10,14);
gsub(/ /, ".", devtypes);
DESCRIP[outcount] = substr($0,26);
if (!(devtypes in DevTypesVoodoo)) {
DevTypesVoodoo[devtypes] = ++voodoo;
DevTypesIdx[voodoo] = devtypes;
}
DEVTYPES[outcount] = DevTypesVoodoo[devtypes];
# Handle 0xNN exception stuff...
if (ASCQ[outcount] == "NN" || ASCQ[outcount] == "nn")
ASCQ[outcount] = "FF";
}
END {
printf("#ifndef SCSI_ASCQ_TBL_C_INCLUDED\n") > OUTFILE;
printf("#define SCSI_ASCQ_TBL_C_INCLUDED\n") >> OUTFILE;
printf("\n/* AuToMaGiCaLlY generated from: %s'"${FIN}"'%s\n", DQ, DQ) >> OUTFILE;
printf(" *******************************************************************************\n") >> OUTFILE;
for (i=1; i<=hdrs; i++) {
printf(" * %s\n", header_line[i]) >> OUTFILE;
}
printf(" */\n") >> OUTFILE;
printf("\n") >> OUTFILE;
for (i=1; i<=voodoo; i++) {
printf("static char SenseDevTypes%03d[] = %s%s%s;\n", i, DQ, DevTypesIdx[i], DQ) >> OUTFILE;
}
printf("\nstatic ASCQ_Table_t ASCQ_Table[] = {\n") >> OUTFILE;
for (i=1; i<=outcount; i++) {
printf(" {\n") >> OUTFILE;
printf(" 0x%s, 0x%s,\n", ASC[i], ASCQ[i]) >> OUTFILE;
printf(" SenseDevTypes%03d,\n", DEVTYPES[i]) >> OUTFILE;
printf(" %s%s%s\n", DQ, DESCRIP[i], DQ) >> OUTFILE;
printf(" },\n") >> OUTFILE;
}
printf( "};\n\n" ) >> OUTFILE;
printf( "static int ASCQ_TableSize = %d;\n\n", outcount ) >> OUTFILE;
printf( "Total of %d ASC/ASCQ records generated\n", outcount );
printf("\n#endif\n") >> OUTFILE;
close(OUTFILE);
}'
return
}
#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
# main()
if [ $# -lt 1 ]; then
echo "INFO: No input filename supplied - using: $PREF_INFILE" >&2
FIN=$PREF_INFILE
else
FIN="$1"
if [ "$FIN" != "$PREF_INFILE" ]; then
echo "INFO: Ok, I'll try chewing on '$FIN' for SCSI ASC/ASCQ combos..." >&2
fi
shift
fi
cat $FIN | xlate_ascq
exit 0
/*
* linux/drivers/message/fusion/isense.c
* Little linux driver / shim that interfaces with the Fusion MPT
* Linux base driver to provide english readable strings in SCSI
* Error Report logging output. This module implements SCSI-3
* Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings.
*
* Copyright (c) 1991-2004 Steven J. Ralston
* Written By: Steven J. Ralston
* (yes I wrote some of the orig. code back in 1991!)
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
*
* $Id: isense.c,v 1.33 2002/02/27 18:44:19 sralston Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
NO WARRANTY
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
solely responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement, including but not limited to
the risks and costs of program errors, damage to or loss of data,
programs or equipment, and unavailability or interruption of operations.
DISCLAIMER OF LIABILITY
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <asm/io.h>
#define MODULEAUTHOR "Steven J. Ralston"
#define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR
#include "mptbase.h"
#include "isense.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Private data...
*/
/*
* YIKES! I don't usually #include C source files, but..
* The following #include's pulls in our needed ASCQ_Table[] array,
* ASCQ_TableSz integer, and ScsiOpcodeString[] array!
*/
#include "ascq_tbl.c"
#include "scsiops.c"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define my_NAME "SCSI-3 Opcodes & ASC/ASCQ Strings"
#define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "isense"
MODULE_AUTHOR(MODULEAUTHOR);
MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int __init isense_init(void)
{
show_mptmod_ver(my_NAME, my_VERSION);
/*
* Install our handler
*/
if (mpt_register_ascqops_strings(&ASCQ_Table[0], ASCQ_TableSize, ScsiOpcodeString) != 1)
{
printk(KERN_ERR MYNAM ": ERROR: Can't register with Fusion MPT base driver!\n");
return -EBUSY;
}
printk(KERN_INFO MYNAM ": Registered SCSI-3 Opcodes & ASC/ASCQ Strings\n");
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void isense_exit(void)
{
#ifdef MODULE
mpt_deregister_ascqops_strings();
#endif
printk(KERN_INFO MYNAM ": Deregistered SCSI-3 Opcodes & ASC/ASCQ Strings\n");
}
module_init(isense_init);
module_exit(isense_exit);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#ifndef ISENSE_H_INCLUDED
#define ISENSE_H_INCLUDED
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#ifdef __KERNEL__
#include <linux/types.h> /* needed for u8, etc. */
#include <linux/string.h> /* needed for strcat */
#include <linux/kernel.h> /* needed for sprintf */
#else
#ifndef U_STUFF_DEFINED
#define U_STUFF_DEFINED
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#endif
#endif
#include "scsi3.h" /* needed for all things SCSI */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Defines and typedefs...
*/
#ifdef __KERNEL__
#define PrintF(x) printk x
#else
#define PrintF(x) printf x
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define RETRY_STATUS ((int) 1)
#define PUT_STATUS ((int) 0)
/*
* A generic structure to hold info about IO request that caused
* a Request Sense to be performed, and the resulting Sense Data.
*/
typedef struct IO_Info
{
char *DevIDStr; /* String of chars which identifies the device. */
u8 *cdbPtr; /* Pointer (Virtual/Logical addr) to CDB bytes of
IO request that caused ContAllegianceCond. */
u8 *sensePtr; /* Pointer (Virtual/Logical addr) to Sense Data
returned by Request Sense operation. */
u8 *dataPtr; /* Pointer (Virtual/Logical addr) to Data buffer
of IO request caused ContAllegianceCondition. */
u8 *inqPtr; /* Pointer (Virtual/Logical addr) to Inquiry Data for
IO *Device* that caused ContAllegianceCondition. */
u8 SCSIStatus; /* SCSI status byte of IO request that caused
Contingent Allegiance Condition. */
u8 DoDisplay; /* Shall we display any messages? */
u16 rsvd_align1;
u32 ComplCode; /* Four-byte OS-dependent completion code. */
u32 NotifyL; /* Four-byte OS-dependent notification field. */
} IO_Info_t;
/*
* SCSI Additional Sense Code and Additional Sense Code Qualifier table.
*/
typedef struct ASCQ_Table
{
u8 ASC;
u8 ASCQ;
char *DevTypes;
char *Description;
} ASCQ_Table_t;
#if 0
/*
* SCSI Opcodes table.
*/
typedef struct SCSI_OPS_Table
{
u8 OpCode;
char *DevTypes;
char *ScsiCmndStr;
} SCSI_OPS_Table_t;
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Public entry point prototypes
*/
/* in scsiherr.c, needed by mptscsih.c */
extern int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif
......@@ -139,11 +139,6 @@ struct proc_dir_entry *mpt_proc_root_dir;
DmpServices_t *DmpService;
void *mpt_v_ASCQ_TablePtr;
const char **mpt_ScsiOpcodesPtr;
int mpt_ASCQ_TableSz;
#define WHOINIT_UNKNOWN 0xAA
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -165,7 +160,6 @@ static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]
static int FusionInitCalled = 0;
static int mpt_base_index = -1;
static int last_drv_idx = -1;
static int isense_idx = -1;
static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
......@@ -177,8 +171,8 @@ static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
static void mpt_detect_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
static void mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
static void mpt_adapter_disable(MPT_ADAPTER *ioc);
static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
......@@ -291,7 +285,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
int type;
int freeme;
ioc = bus_id;
ioc = (MPT_ADAPTER *)bus_id;
/*
* Drain the reply FIFO!
......@@ -333,8 +327,8 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
dprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p\n",
ioc->name, mr));
dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
ioc->name, mr, req_idx));
DBG_DUMP_REPLY_FRAME(mr)
/* NEW! 20010301 -sralston
......@@ -358,7 +352,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
/*
* Process turbo (context) reply...
*/
dirqprintk((MYIOC_s_INFO_FMT "Got TURBO reply(=%08x)\n", ioc->name, pa));
dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
cb_idx = mpt_stm_index;
......@@ -506,7 +500,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
if (results != evHandlers) {
/* CHECKME! Any special handling needed here? */
dprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
ioc->name, evHandlers, results));
}
......@@ -659,8 +653,6 @@ mpt_deregister(int cb_idx)
MptEvHandlers[cb_idx] = NULL;
last_drv_idx++;
if (isense_idx != -1 && isense_idx <= cb_idx)
isense_idx++;
}
}
......@@ -803,56 +795,60 @@ mpt_device_driver_deregister(int cb_idx)
* mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
* allocated per MPT adapter.
* @handle: Handle of registered MPT protocol driver
* @iocid: IOC unique identifier (integer)
* @ioc: Pointer to MPT adapter structure
*
* Returns pointer to a MPT request frame or %NULL if none are available
* or IOC is not active.
*/
MPT_FRAME_HDR*
mpt_get_msg_frame(int handle, MPT_ADAPTER *iocp)
mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
{
MPT_FRAME_HDR *mf;
unsigned long flags;
u16 req_idx; /* Request index */
/* validate handle and ioc identifier */
#ifdef MFCNT
if (!iocp->active)
if (!ioc->active)
printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
#endif
/* If interrupts are not attached, do not return a request frame */
if (!iocp->active)
if (!ioc->active)
return NULL;
spin_lock_irqsave(&iocp->FreeQlock, flags);
if (! Q_IS_EMPTY(&iocp->FreeQ)) {
spin_lock_irqsave(&ioc->FreeQlock, flags);
if (! Q_IS_EMPTY(&ioc->FreeQ)) {
int req_offset;
mf = iocp->FreeQ.head;
mf = ioc->FreeQ.head;
Q_DEL_ITEM(&mf->u.frame.linkage);
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
req_offset = (u8 *)mf - (u8 *)iocp->req_frames;
req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
/* u16! */
mf->u.frame.hwhdr.msgctxu.fld.req_idx =
cpu_to_le16(req_offset / iocp->req_sz);
req_idx = cpu_to_le16(req_offset / ioc->req_sz);
mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
#ifdef MFCNT
iocp->mfcnt++;
ioc->mfcnt++;
#endif
}
else
mf = NULL;
spin_unlock_irqrestore(&iocp->FreeQlock, flags);
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
#ifdef MFCNT
if (mf == NULL)
printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", iocp->mfcnt, iocp->req_depth);
printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
mfcounter++;
if (mfcounter == PRINT_MF_COUNT)
printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", iocp->mfcnt, iocp->req_depth);
printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
#endif
dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
iocp->name, handle, iocid, mf));
ioc->name, handle, ioc->id, mf));
return mf;
}
......@@ -861,23 +857,25 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *iocp)
* mpt_put_msg_frame - Send a protocol specific MPT request frame
* to a IOC.
* @handle: Handle of registered MPT protocol driver
* @iocid: IOC unique identifier (integer)
* @ioc: Pointer to MPT adapter structure
* @mf: Pointer to MPT request frame
*
* This routine posts a MPT request frame to the request post FIFO of a
* specific MPT adapter.
*/
void
mpt_put_msg_frame(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
u32 mf_dma_addr;
int req_offset;
u16 req_idx; /* Request index */
/* ensure values are reset properly! */
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
req_offset = (u8 *)mf - (u8 *)iocp->req_frames;
/* u16! */
mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_offset / iocp->req_sz);
req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
/* u16! */
req_idx = cpu_to_le16(req_offset / ioc->req_sz);
mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
#ifdef MPT_DEBUG_MSG_FRAME
......@@ -886,8 +884,8 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
int ii, n;
printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
iocp->name, m);
n = iocp->req_sz/4 - 1;
ioc->name, m);
n = ioc->req_sz/4 - 1;
while (m[n] == 0)
n--;
for (ii=0; ii<=n; ii++) {
......@@ -899,32 +897,33 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
}
#endif
mf_dma_addr = iocp->req_frames_low_dma + req_offset;
CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);
mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_free_msg_frame - Place MPT request frame back on FreeQ.
* @handle: Handle of registered MPT protocol driver
* @iocid: IOC unique identifier (integer)
* @ioc: Pointer to MPT adapter structure
* @mf: Pointer to MPT request frame
*
* This routine places a MPT request frame back on the MPT adapter's
* FreeQ.
*/
void
mpt_free_msg_frame(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
unsigned long flags;
/* Put Request back on FreeQ! */
spin_lock_irqsave(&iocp->FreeQlock, flags);
Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
spin_lock_irqsave(&ioc->FreeQlock, flags);
Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
#ifdef MFCNT
iocp->mfcnt--;
ioc->mfcnt--;
#endif
spin_unlock_irqrestore(&iocp->FreeQlock, flags);
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -996,7 +995,7 @@ mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
* mpt_send_handshake_request - Send MPT request via doorbell
* handshake method.
* @handle: Handle of registered MPT protocol driver
* @iocid: IOC unique identifier (integer)
* @ioc: Pointer to MPT adapter structure
* @reqBytes: Size of the request in bytes
* @req: Pointer to MPT request frame
* @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
......@@ -1010,7 +1009,7 @@ mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
* Returns 0 for success, non-zero for failure.
*/
int
mpt_send_handshake_request(int handle, MPT_ADAPTER *iocp, int reqBytes, u32 *req, int sleepFlag)
mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
{
int r = 0;
u8 *req_as_bytes;
......@@ -1026,37 +1025,38 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *iocp, int reqBytes, u32 *req
* setting cb_idx/req_idx. But ONLY if this request
* is in proper (pre-alloc'd) request buffer range...
*/
ii = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
if (reqBytes >= 12 && ii >= 0 && ii < iocp->req_depth) {
ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
}
/* Make sure there are no doorbells */
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
CHIPREG_WRITE32(&iocp->chip->Doorbell,
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
CHIPREG_WRITE32(&ioc->chip->Doorbell,
((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
/* Wait for IOC doorbell int */
ii = WaitForDoorbellInt(iocp, 5, sleepFlag);
if (ii < 0)
if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
return ii;
}
/* Read doorbell and check for active bit */
if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
return -5;
dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
iocp->name, ii));
ioc->name, ii));
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
r = WaitForDoorbellAck(iocp, 5, sleepFlag);
if (r < 0)
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
return -2;
}
/* Send request via doorbell handshake */
req_as_bytes = (u8 *) req;
for (ii = 0; ii < reqBytes/4; ii++) {
......@@ -1066,21 +1066,21 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *iocp, int reqBytes, u32 *req
(req_as_bytes[(ii*4) + 1] << 8) |
(req_as_bytes[(ii*4) + 2] << 16) |
(req_as_bytes[(ii*4) + 3] << 24));
CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
r = WaitForDoorbellAck(iocp, 5, sleepFlag);
if (r < 0) {
CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
r = -3;
break;
}
}
if (r >= 0 && WaitForDoorbellInt(iocp, 10, sleepFlag) >= 0)
if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
r = 0;
else
r = -4;
/* Make sure there are no doorbells */
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
return r;
}
......@@ -1141,11 +1141,15 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
u8 revision;
u8 pcixcmd;
static int mpt_ids = 0;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dent, *ent;
#endif
if (pci_enable_device(pdev))
return r;
dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
if (!pci_set_dma_mask(pdev, mask)) {
dprintk((KERN_INFO MYNAM
": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
......@@ -1170,9 +1174,8 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->alloc_total = sizeof(MPT_ADAPTER);
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
ioc->pcidev = pdev;
ioc->diagPending = 0;
spin_lock_init(&ioc->diagLock);
......@@ -1223,8 +1226,8 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -EINVAL;
}
dprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
dprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
mem = NULL;
/* Get logical ptr for PciMem0 space */
......@@ -1236,15 +1239,15 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -EINVAL;
}
ioc->memmap = mem;
dprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
dprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
&ioc->facts, &ioc->pfacts[0]));
ioc->mem_phys = mem_phys;
ioc->chip = (SYSIF_REGS*)mem;
/* Save Port IO values incase we need to do downloadboot */
/* Save Port IO values in case we need to do downloadboot */
{
u8 *pmem = (u8*)port;
ioc->pio_mem_phys = port;
......@@ -1314,7 +1317,6 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sprintf(ioc->name, "ioc%d", ioc->id);
Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
spin_lock_init(&ioc->FreeQlock);
/* Disable all! */
......@@ -1384,6 +1386,7 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
}
#ifdef CONFIG_PROC_FS
/*
* Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
*/
......@@ -1400,6 +1403,7 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ent->data = ioc;
}
}
#endif
return 0;
}
......@@ -1623,7 +1627,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
int hard_reset_done = 0;
int alt_ioc_ready = 0;
int hard;
int r;
int rc=0;
int ii;
int handlers;
int ret = 0;
......@@ -1673,39 +1677,37 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* and 1 if a hard reset was performed.
*/
if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
alt_ioc_ready = 1;
else
printk(KERN_WARNING MYNAM
": alt-%s: (%d) Not ready WARNING!\n",
ioc->alt_ioc->name, r);
": alt-%s: Not ready WARNING!\n",
ioc->alt_ioc->name);
}
for (ii=0; ii<5; ii++) {
/* Get IOC facts! Allow 1 retry */
if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0) {
dinitprintk((MYIOC_s_INFO_FMT
"ii=%d IocFacts failed r=%x\n", ioc->name, ii, r));
} else
/* Get IOC facts! Allow 5 retries */
if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
break;
}
if (r) {
dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed r=%x\n", ioc->name, r));
if (ii == 5) {
dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
ret = -2;
} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
MptDisplayIocCapabilities(ioc);
}
if (alt_ioc_ready) {
if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed r=%x\n", ioc->name, r));
if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
/* Retry - alt IOC was initialized once
*/
r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
}
if (r) {
dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed r=%x\n", ioc->name, r));
if (rc) {
dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
alt_ioc_ready = 0;
reset_alt_ioc_active = 0;
} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
......@@ -1718,29 +1720,29 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* init as upper addresses are needed for init.
* If fails, continue with alt-ioc processing
*/
if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0))
if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
ret = -3;
/* May need to check/upload firmware & data here!
* If fails, continue with alt-ioc processing
*/
if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0))
if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
ret = -4;
// NEW!
if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
ioc->alt_ioc->name, r);
ioc->alt_ioc->name, rc);
alt_ioc_ready = 0;
reset_alt_ioc_active = 0;
}
if (alt_ioc_ready) {
if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
alt_ioc_ready = 0;
reset_alt_ioc_active = 0;
printk(KERN_WARNING MYNAM
": alt-%s: (%d) init failure WARNING!\n",
ioc->alt_ioc->name, r);
ioc->alt_ioc->name, rc);
}
}
......@@ -1752,18 +1754,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/* Controller is not operational, cannot do upload
*/
if (ret == 0) {
r = mpt_do_upload(ioc, sleepFlag);
if (r != 0)
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
}
/* Handle the alt IOC too */
if ((alt_ioc_ready) && (ioc->alt_ioc->upload_fw)){
ddlprintk((MYIOC_s_INFO_FMT
"Alt-ioc firmware upload required!\n",
ioc->name));
r = mpt_do_upload(ioc->alt_ioc, sleepFlag);
if (r != 0)
rc = mpt_do_upload(ioc, sleepFlag);
if (rc != 0)
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
}
}
......@@ -1857,19 +1849,19 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* MptResetHandlers[] registered yet.
*/
if (hard_reset_done) {
r = handlers = 0;
rc = handlers = 0;
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
if ((ret == 0) && MptResetHandlers[ii]) {
dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
ioc->name, ii));
r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
handlers++;
}
if (alt_ioc_ready && MptResetHandlers[ii]) {
dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
ioc->name, ioc->alt_ioc->name, ii));
r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
handlers++;
}
}
......@@ -1930,84 +1922,90 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
/*
* mpt_adapter_disable - Disable misbehaving MPT adapter.
* @this: Pointer to MPT adapter structure
* @free: Free up alloc'd reply, request, etc.
*/
static void
mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
mpt_adapter_disable(MPT_ADAPTER *ioc)
{
if (this != NULL) {
int sz=0;
int ret;
if (this->cached_fw != NULL) {
ddlprintk((KERN_INFO MYNAM ": Pushing FW onto adapter\n"));
int sz;
int ret;
if ((ret = mpt_downloadboot(this, NO_SLEEP)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", ret);
}
if (ioc->cached_fw != NULL) {
ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", ret);
}
}
/* Disable adapter interrupts! */
CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
this->active = 0;
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&this->chip->IntStatus, 0);
if (freeup && this->fifo_pool != NULL) {
pci_free_consistent(this->pcidev,
this->fifo_pool_sz,
this->fifo_pool, this->fifo_pool_dma);
this->reply_frames = NULL;
this->reply_alloc = NULL;
this->req_frames = NULL;
this->req_alloc = NULL;
this->chain_alloc = NULL;
this->fifo_pool = NULL;
this->alloc_total -= this->fifo_pool_sz;
}
if (freeup && this->sense_buf_pool != NULL) {
sz = (this->req_depth * MPT_SENSE_BUFFER_ALLOC);
pci_free_consistent(this->pcidev, sz,
this->sense_buf_pool, this->sense_buf_pool_dma);
this->sense_buf_pool = NULL;
this->alloc_total -= sz;
}
/* Disable adapter interrupts! */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
if (freeup && this->events != NULL){
sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
kfree(this->events);
this->events = NULL;
this->alloc_total -= sz;
}
if (ioc->alloc != NULL) {
sz = ioc->alloc_sz;
dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
ioc->name, ioc->alloc, ioc->alloc_sz));
pci_free_consistent(ioc->pcidev, sz,
ioc->alloc, ioc->alloc_dma);
ioc->reply_frames = NULL;
ioc->req_frames = NULL;
ioc->alloc = NULL;
ioc->alloc_total -= sz;
}
if (freeup && this->cached_fw != NULL) {
if (ioc->sense_buf_pool != NULL) {
sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
pci_free_consistent(ioc->pcidev, sz,
ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
ioc->sense_buf_pool = NULL;
ioc->alloc_total -= sz;
}
sz = this->facts.FWImageSize;
pci_free_consistent(this->pcidev, sz,
this->cached_fw, this->cached_fw_dma);
this->cached_fw = NULL;
this->alloc_total -= sz;
}
if (ioc->events != NULL){
sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
kfree(ioc->events);
ioc->events = NULL;
ioc->alloc_total -= sz;
}
if (freeup && this->spi_data.nvram != NULL) {
kfree(this->spi_data.nvram);
this->spi_data.nvram = NULL;
}
if (ioc->cached_fw != NULL) {
sz = ioc->facts.FWImageSize;
pci_free_consistent(ioc->pcidev, sz,
ioc->cached_fw, ioc->cached_fw_dma);
ioc->cached_fw = NULL;
ioc->alloc_total -= sz;
}
if (freeup && this->spi_data.pIocPg3 != NULL) {
kfree(this->spi_data.pIocPg3);
this->spi_data.pIocPg3 = NULL;
}
if (ioc->spi_data.nvram != NULL) {
kfree(ioc->spi_data.nvram);
ioc->spi_data.nvram = NULL;
}
if (freeup && this->spi_data.pIocPg4 != NULL) {
sz = this->spi_data.IocPg4Sz;
pci_free_consistent(this->pcidev, sz,
this->spi_data.pIocPg4,
this->spi_data.IocPg4_dma);
this->spi_data.pIocPg4 = NULL;
this->alloc_total -= sz;
}
if (ioc->spi_data.pIocPg3 != NULL) {
kfree(ioc->spi_data.pIocPg3);
ioc->spi_data.pIocPg3 = NULL;
}
if (ioc->spi_data.pIocPg4 != NULL) {
sz = ioc->spi_data.IocPg4Sz;
pci_free_consistent(ioc->pcidev, sz,
ioc->spi_data.pIocPg4,
ioc->spi_data.IocPg4_dma);
ioc->spi_data.pIocPg4 = NULL;
ioc->alloc_total -= sz;
}
if (ioc->ReqToChain != NULL) {
kfree(ioc->ReqToChain);
kfree(ioc->RequestNB);
ioc->ReqToChain = NULL;
}
if (ioc->ChainToChain != NULL) {
kfree(ioc->ChainToChain);
ioc->ChainToChain = NULL;
}
}
......@@ -2015,43 +2013,43 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
/*
* mpt_adapter_dispose - Free all resources associated with a MPT
* adapter.
* @this: Pointer to MPT adapter structure
* @ioc: Pointer to MPT adapter structure
*
* This routine unregisters h/w resources and frees all alloc'd memory
* associated with a MPT adapter structure.
*/
static void
mpt_adapter_dispose(MPT_ADAPTER *this)
mpt_adapter_dispose(MPT_ADAPTER *ioc)
{
if (this != NULL) {
if (ioc != NULL) {
int sz_first, sz_last;
sz_first = this->alloc_total;
sz_first = ioc->alloc_total;
mpt_adapter_disable(this, 1);
mpt_adapter_disable(ioc);
if (this->pci_irq != -1) {
free_irq(this->pci_irq, this);
this->pci_irq = -1;
if (ioc->pci_irq != -1) {
free_irq(ioc->pci_irq, ioc);
ioc->pci_irq = -1;
}
if (this->memmap != NULL)
iounmap((u8 *) this->memmap);
if (ioc->memmap != NULL)
iounmap((u8 *) ioc->memmap);
#if defined(CONFIG_MTRR) && 0
if (this->mtrr_reg > 0) {
mtrr_del(this->mtrr_reg, 0, 0);
dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", this->name));
if (ioc->mtrr_reg > 0) {
mtrr_del(ioc->mtrr_reg, 0, 0);
dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
}
#endif
/* Zap the adapter lookup ptr! */
list_del(&this->list);
list_del(&ioc->list);
sz_last = this->alloc_total;
sz_last = ioc->alloc_total;
dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
this->name, sz_first-sz_last+(int)sizeof(*this), sz_first));
kfree(this);
ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
kfree(ioc);
}
}
......@@ -2226,13 +2224,13 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
ii++; cntdn--;
if (!cntdn) {
printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
ioc->name, (ii+5)/HZ);
ioc->name, (int)((ii+5)/HZ));
return -ETIME;
}
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(1 * HZ / 1000);
} else {
mdelay (1); /* 1 msec delay */
}
......@@ -2290,7 +2288,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
int r;
int req_sz;
int reply_sz;
u32 status;
int sz;
u32 status, vv;
u8 shiftFactor=1;
/* IOC *must* NOT be in RESET state! */
if (ioc->last_state == MPI_IOC_STATE_RESET) {
......@@ -2313,7 +2313,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
get_facts.Function = MPI_FUNCTION_IOC_FACTS;
/* Assert: All other get_facts fields are zero! */
dinitprintk((MYIOC_s_INFO_FMT "Sending get IocFacts request\n", ioc->name));
dinitprintk((MYIOC_s_INFO_FMT
"Sending get IocFacts request req_sz=%d reply_sz=%d\n",
ioc->name, req_sz, reply_sz));
/* No non-zero fields in the get_facts request are greater than
* 1 byte in size, so we can just fire it off as is.
......@@ -2386,6 +2388,13 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
}
sz = facts->FWImageSize;
if ( sz & 0x01 )
sz += 1;
if ( sz & 0x02 )
sz += 2;
facts->FWImageSize = sz;
if (!facts->RequestFrameSize) {
/* Something is wrong! */
printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
......@@ -2393,6 +2402,18 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
return -55;
}
r = sz = le32_to_cpu(facts->BlockSize);
vv = ((63 / (sz * 4)) + 1) & 0x03;
ioc->NB_for_64_byte_frame = vv;
while ( sz )
{
shiftFactor++;
sz = sz >> 1;
}
ioc->NBShiftFactor = shiftFactor;
dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
ioc->name, vv, shiftFactor, r));
if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
/*
* Set values for this IOC's request & reply frame sizes,
......@@ -2403,9 +2424,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
ioc->name, ioc->reply_sz, ioc->reply_depth));
dprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
ioc->name, ioc->req_sz, ioc->req_depth));
/* Get port facts! */
......@@ -2463,7 +2484,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
get_pfacts.PortNumber = portnum;
/* Assert: All other get_pfacts fields are zero! */
dprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
ioc->name, portnum));
/* No non-zero fields in the get_pfacts request are greater than
......@@ -2514,24 +2535,18 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
memset(&init_reply, 0, sizeof(init_reply));
ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
/* ioc_init.ChainOffset = 0; */
ioc_init.Function = MPI_FUNCTION_IOC_INIT;
/* ioc_init.Flags = 0; */
/* If we are in a recovery mode and we uploaded the FW image,
* then this pointer is not NULL. Skip the upload a second time.
* Set this flag if cached_fw set for either IOC.
*/
ioc->upload_fw = 0;
ioc_init.Flags = 0;
if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw))
ioc_init.Flags = MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE;
else
ioc->upload_fw = 1;
}
ddlprintk((MYIOC_s_INFO_FMT "flags %d, upload_fw %d \n",
ioc->name, ioc_init.Flags, ioc->upload_fw));
if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
ioc->upload_fw = 1;
else
ioc->upload_fw = 0;
ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
ioc->name, ioc->upload_fw, ioc->facts.Flags));
if ((int)ioc->chip_type <= (int)FC929) {
ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
......@@ -2540,17 +2555,13 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
}
ioc_init.MaxBuses = MPT_MAX_BUS;
/* ioc_init.MsgFlags = 0; */
/* ioc_init.MsgContext = cpu_to_le32(0x00000000); */
ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
ioc->facts.RequestFrameSize = ioc_init.ReplyFrameSize;
if (sizeof(dma_addr_t) == sizeof(u64)) {
/* Save the upper 32-bits of the request
* (reply) and sense buffers.
*/
ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
} else {
/* Force 32-bit addressing */
......@@ -2589,14 +2600,14 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(1 * HZ / 1000);
} else {
mdelay(1);
}
if (!cntdn) {
printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
ioc->name, (count+5)/HZ);
ioc->name, (int)((count+5)/HZ));
return -9;
}
......@@ -2642,7 +2653,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
/* port_enable.MsgFlags = 0; */
/* port_enable.MsgContext = 0; */
dprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
ioc->name, portnum, &port_enable));
/* RAID FW may take a long time to enable
......@@ -2666,20 +2677,22 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
}
/*
* Inputs: size - total FW bytes
* Outputs: frags - number of fragments needed
* Return NULL if failed.
* ioc: Pointer to MPT_ADAPTER structure
* size - total FW bytes
*/
void
mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
{
/* cached_fw
*/
if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
ioc->alloc_total += size;
if (ioc->cached_fw)
return; /* use already allocated memory */
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
} else {
if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
ioc->alloc_total += size;
}
}
/*
* If alt_img is NULL, delete from ioc structure.
* Else, delete a secondary image in same format.
......@@ -2690,6 +2703,8 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc)
int sz;
sz = ioc->facts.FWImageSize;
dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
pci_free_consistent(ioc->pcidev, sz,
ioc->cached_fw, ioc->cached_fw_dma);
ioc->cached_fw = NULL;
......@@ -2723,30 +2738,24 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
int sgeoffset;
u32 flagsLength;
int ii, sz, reply_sz;
int cmdStatus, freeMem = 0;
int cmdStatus;
/* If the image size is 0 or if the pointer is
* not NULL (error), we are done.
/* If the image size is 0, we are done.
*/
if (((sz = ioc->facts.FWImageSize) == 0) || ioc->cached_fw)
if ((sz = ioc->facts.FWImageSize) == 0)
return 0;
if ( sz & 0x01 )
sz += 1;
if ( sz & 0x02 )
sz += 2;
mpt_alloc_fw_memory(ioc, sz);
dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
if (ioc->cached_fw == NULL) {
/* Major Failure.
*/
return -ENOMEM;
}
dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
prequest = (FWUpload_t *)&request;
preply = (FWUploadReply_t *)&reply;
......@@ -2795,23 +2804,11 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
ioc->name, cmdStatus));
/* Check to see if we have a copy of this image in
* host memory already.
*/
if (cmdStatus == 0) {
ioc->upload_fw = 0;
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
freeMem = 1;
}
/* We already have a copy of this image or
* we had some type of an error - either the handshake
* failed (i != 0) or the command did not complete successfully.
*/
if (cmdStatus || freeMem) {
if (cmdStatus) {
ddlprintk((MYIOC_s_INFO_FMT ": do_upload freeing %s image \n",
ioc->name, cmdStatus ? "incomplete" : "duplicate"));
ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
ioc->name));
mpt_free_fw_memory(ioc);
}
......@@ -2839,28 +2836,26 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
MpiExtImageHeader_t *pExtImage;
u32 fwSize;
u32 diag0val;
#ifdef MPT_DEBUG
u32 diag1val = 0;
#endif
int count = 0;
int count;
u32 *ptrFw;
u32 diagRwData;
u32 nextImage;
u32 load_addr;
u32 ioc_state;
u32 ioc_state=0;
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
/* Get dma_addr and data transfer size.
*/
if ( ioc->facts.FWImageSize == 0 )
return -1;
/* Get the DMA from ioc or ioc->alt_ioc */
if (ioc->cached_fw == NULL)
return -2;
/* prevent a second downloadboot and memory free with alt_ioc */
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
ioc->alt_ioc->cached_fw = NULL;
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
......@@ -2868,18 +2863,17 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
diag0val |= (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
/* wait 100 msec */
/* wait 1 msec */
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(100 * HZ / 1000);
schedule_timeout(1 * HZ / 1000);
} else {
mdelay (100);
mdelay (1);
}
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
for (count = 0; count < 30; count ++) {
......@@ -2892,7 +2886,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
schedule_timeout(1000 * HZ / 1000);
} else {
mdelay (1000);
}
......@@ -2912,8 +2906,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
/* Set the DiagRwEn and Disable ARM bits */
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
CHIPREG_WRITE32(&ioc->chip->Diagnostic, (diag0val | MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
fwSize = (pFwHeader->ImageSize + 3)/4;
......@@ -2959,15 +2952,6 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
/* clear the PREVENT_IOC_BOOT bit */
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT\n",
ioc->name, diag0val));
diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
/* Clear the internal flash bad bit - autoincrementing register,
* so must do two writes.
*/
......@@ -2978,28 +2962,13 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off DISABLE_ARM, RW_ENABLE, RESET_HISTORY\n",
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
ioc->name, diag0val));
diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_RESET_HISTORY);
diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
/* wait 100 msec */
if (sleepFlag == CAN_SLEEP) {
ddlprintk((MYIOC_s_INFO_FMT "CAN_SLEEP 100 msec before reset the sequencer\n", ioc->name));
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(100 * HZ / 1000);
} else {
ddlprintk((MYIOC_s_INFO_FMT "mdelay 100 msec before reset the sequencer\n", ioc->name));
mdelay (100);
}
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
if ( diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_DISABLE_ARM) ) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed, diag0val=%x FLASH_BAD_SIG | DISABLE_ARM on\n ",
ioc->name, diag0val));
}
/* Write 0xFF to reset the sequencer */
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
......@@ -3007,26 +2976,18 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
ioc->name, count, ioc_state));
/* if ((r = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
if ((r = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed\n",
ioc->name));
return -EFAULT;
}
} */
/* wait 2 sec */
/* if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(5000 * HZ / 1000);
} else {
mdelay (5000);
} */
if ((SendIocInit(ioc, sleepFlag)) != 0) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
ioc->name));
return -EFAULT;
}
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
ioc->name));
return 0;
}
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(10 * HZ / 1000);
} else {
mdelay (10);
}
......@@ -3066,8 +3027,8 @@ static int
KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
{
int hard_reset_done = 0;
u32 ioc_state;
int cntdn, cnt = 0;
u32 ioc_state=0;
int cnt,cntdn;
dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
if ((int)ioc->chip_type > (int)FC929) {
......@@ -3078,7 +3039,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
schedule_timeout(1000 * HZ / 1000);
} else {
mdelay (1000);
}
......@@ -3088,26 +3049,27 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
if (hard_reset_done < 0)
return hard_reset_done;
dprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
ioc->name));
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 20; /* 20 seconds */
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
for (cnt=0; cnt<cntdn; cnt++) {
if ((ioc_state = mpt_GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
dprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
ioc->name, cnt));
ioc_state = mpt_GetIocState(ioc, 1);
if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
ioc->name, cnt));
return hard_reset_done;
}
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(10 * HZ / 1000);
} else {
mdelay (10);
}
}
printk(MYIOC_s_ERR_FMT "Failed to come READY after reset!\n",
ioc->name);
printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
ioc->name, ioc_state);
return -1;
}
......@@ -3197,12 +3159,6 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
/* Write the PreventIocBoot bit */
if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw)) {
diag0val |= MPI_DIAG_PREVENT_IOC_BOOT;
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
}
/*
* Disable the ARM (Bug fix)
*
......@@ -3244,20 +3200,13 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* FIXME? Examine results here? */
}
if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw)) {
if (ioc->cached_fw) {
/* If the DownloadBoot operation fails, the
* IOC will be left unusable. This is a fatal error
* case. _diag_reset will return < 0
*/
for (count = 0; count < 30; count ++) {
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
dprintk((MYIOC_s_INFO_FMT
"DbG2b: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
break;
}
......@@ -3265,7 +3214,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
schedule_timeout(1000 * HZ / 1000);
} else {
mdelay (1000);
}
......@@ -3293,7 +3242,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
schedule_timeout(1000 * HZ / 1000);
} else {
mdelay (1000);
}
......@@ -3417,13 +3366,13 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
count *= 10;
printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
ioc->name, (count+5)/HZ);
ioc->name, (int)((count+5)/HZ));
return -ETIME;
}
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(1 * HZ / 1000);
} else {
mdelay (1); /* 1 msec delay */
}
......@@ -3441,35 +3390,45 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* PrimeIocFifos - Initialize IOC request and reply FIFOs.
* @ioc: Pointer to MPT_ADAPTER structure
*
* This routine allocates memory for the MPT reply and request frame
* pools (if necessary), and primes the IOC reply FIFO with
* reply frames.
*
* Returns 0 for success, non-zero for failure.
* initChainBuffers - Allocate memory for and initialize
* chain buffers, chain buffer control arrays and spinlock.
* @hd: Pointer to MPT_SCSI_HOST structure
* @init: If set, initialize the spin lock.
*/
static int
PrimeIocFifos(MPT_ADAPTER *ioc)
int
initChainBuffers(MPT_ADAPTER *ioc)
{
MPT_FRAME_HDR *mf;
unsigned long b;
unsigned long flags;
dma_addr_t aligned_mem_dma;
u8 *aligned_mem;
int i, sz;
int chain_buffer_sz, reply_buffer_sz, request_buffer_sz;
int scale, num_sge, num_chain;
u8 *mem;
int sz, ii, num_chain;
int scale, num_sge, numSGE;
/* request buffer size, rounding UP to nearest 4-kB boundary */
request_buffer_sz = (ioc->req_sz * ioc->req_depth) + 128;
request_buffer_sz = ((request_buffer_sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
/* ReqToChain size must equal the req_depth
* index = req_idx
*/
if (ioc->ReqToChain == NULL) {
sz = ioc->req_depth * sizeof(int);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
return -1;
/* reply buffer size */
reply_buffer_sz = (ioc->reply_sz * ioc->reply_depth) + 128;
ioc->ReqToChain = (int *) mem;
dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
ioc->name, mem, sz));
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
return -1;
/* chain buffer size, copied from from mptscsih_initChainBuffers()
ioc->RequestNB = (int *) mem;
dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
ioc->name, mem, sz));
}
for (ii = 0; ii < ioc->req_depth; ii++) {
ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
}
/* ChainToChain size must equal the total number
* of chain buffers to be allocated.
* index = chain_idx
*
* Calculate the number of chain buffers needed(plus 1) per I/O
* then multiply the the maximum number of simultaneous cmds
......@@ -3477,79 +3436,134 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
* num_sge = num sge in request frame + last chain buffer
* scale = num sge per chain buffer if no chain element
*/
scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
if (sizeof(dma_addr_t) == sizeof(u64))
num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
else
num_sge = 1 + scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
if (sizeof(dma_addr_t) == sizeof(u64)) {
numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
(ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
} else {
numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
(ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
}
dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
ioc->name, num_sge, numSGE));
if ( numSGE > MPT_SCSI_SG_DEPTH )
numSGE = MPT_SCSI_SG_DEPTH;
num_chain = 1;
while (MPT_SCSI_SG_DEPTH - num_sge > 0) {
while (numSGE - num_sge > 0) {
num_chain++;
num_sge += (scale - 1);
}
num_chain++;
if ((int)ioc->chip_type > (int) FC929)
dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
ioc->name, numSGE, num_sge, num_chain));
if ((int) ioc->chip_type > (int) FC929)
num_chain *= MPT_SCSI_CAN_QUEUE;
else
num_chain *= MPT_FC_CAN_QUEUE;
chain_buffer_sz = num_chain * ioc->req_sz;
ioc->num_chain = num_chain;
if(ioc->fifo_pool == NULL) {
sz = num_chain * sizeof(int);
if (ioc->ChainToChain == NULL) {
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
return -1;
ioc->fifo_pool_sz = request_buffer_sz +
reply_buffer_sz + chain_buffer_sz;
ioc->ChainToChain = (int *) mem;
dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
ioc->name, mem, sz));
} else {
mem = (u8 *) ioc->ChainToChain;
}
memset(mem, 0xFF, sz);
return num_chain;
}
ioc->fifo_pool = pci_alloc_consistent(ioc->pcidev,
ioc->fifo_pool_sz, &ioc->fifo_pool_dma);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* PrimeIocFifos - Initialize IOC request and reply FIFOs.
* @ioc: Pointer to MPT_ADAPTER structure
*
* This routine allocates memory for the MPT reply and request frame
* pools (if necessary), and primes the IOC reply FIFO with
* reply frames.
*
* Returns 0 for success, non-zero for failure.
*/
static int
PrimeIocFifos(MPT_ADAPTER *ioc)
{
MPT_FRAME_HDR *mf;
unsigned long flags;
dma_addr_t alloc_dma;
u8 *mem;
int i, reply_sz, sz, total_size, num_chain;
/* Prime reply FIFO... */
if( ioc->fifo_pool == NULL)
if (ioc->reply_frames == NULL) {
if ( (num_chain = initChainBuffers(ioc)) < 0)
return -1;
total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
ioc->name, ioc->reply_sz, ioc->reply_depth));
dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
ioc->name, reply_sz, reply_sz));
sz = (ioc->req_sz * ioc->req_depth);
dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
ioc->name, ioc->req_sz, ioc->req_depth));
dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
ioc->name, sz, sz));
total_size += sz;
sz = num_chain * ioc->req_sz; /* chain buffer pool size */
dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
ioc->name, ioc->req_sz, num_chain));
dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
ioc->name, sz, sz, num_chain));
total_size += sz;
mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
if (mem == NULL) {
printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
ioc->name);
goto out_fail;
}
dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
memset(mem, 0, total_size);
ioc->alloc_total += total_size;
ioc->alloc = mem;
ioc->alloc_dma = alloc_dma;
ioc->alloc_sz = total_size;
ioc->reply_frames = (MPT_FRAME_HDR *) mem;
ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
alloc_dma += reply_sz;
mem += reply_sz;
ioc->alloc_total += ioc->fifo_pool_sz;
memset(ioc->fifo_pool, 0, ioc->fifo_pool_sz);
/* reply fifo pointers */
ioc->reply_alloc = ioc->fifo_pool;
ioc->reply_alloc_dma = ioc->fifo_pool_dma;
/* request fifo pointers */
ioc->req_alloc = ioc->reply_alloc+reply_buffer_sz;
ioc->req_alloc_dma = ioc->reply_alloc_dma+reply_buffer_sz;
/* chain buffer pointers */
ioc->chain_alloc = ioc->req_alloc+request_buffer_sz;
ioc->chain_alloc_dma = ioc->req_alloc_dma+request_buffer_sz;
ioc->chain_alloc_sz = chain_buffer_sz;
/* Prime reply FIFO... */
dprintk((KERN_INFO MYNAM ": %s.reply_alloc @ %p[%p], sz=%d bytes\n",
ioc->name, ioc->reply_alloc,
(void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
b = (unsigned long) ioc->reply_alloc;
b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
aligned_mem = (u8 *) b;
ioc->reply_frames = (MPT_FRAME_HDR *) aligned_mem;
ioc->reply_frames_dma =
(ioc->reply_alloc_dma + (aligned_mem - ioc->reply_alloc));
ioc->reply_frames_low_dma = (u32) (ioc->reply_frames_dma & 0xFFFFFFFF);
/* Request FIFO - WE manage this! */
dprintk((KERN_INFO MYNAM ": %s.req_alloc @ %p[%p], sz=%d bytes\n",
ioc->name, ioc->req_alloc,
(void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
b = (unsigned long) ioc->req_alloc;
b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
aligned_mem = (u8 *) b;
ioc->req_frames = (MPT_FRAME_HDR *) aligned_mem;
ioc->req_frames_dma =
(ioc->req_alloc_dma + (aligned_mem - ioc->req_alloc));
ioc->req_frames = (MPT_FRAME_HDR *) mem;
ioc->req_frames_dma = alloc_dma;
dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
ioc->name, mem, (void *)(ulong)alloc_dma));
ioc->req_frames_low_dma = (u32) (ioc->req_frames_dma & 0xFFFFFFFF);
ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
#if defined(CONFIG_MTRR) && 0
/*
......@@ -3557,79 +3571,93 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
* (at least as much as we can; "size and base must be
* multiples of 4 kiB"
*/
ioc->mtrr_reg = mtrr_add(ioc->fifo_pool,
ioc->fifo_pool_sz,
ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
sz,
MTRR_TYPE_WRCOMB, 1);
dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
ioc->name, ioc->fifo_pool, ioc->fifo_pool_sz));
ioc->name, ioc->req_frames_dma, sz));
#endif
} /* ioc->fifo_pool == NULL */
/* Post Reply frames to FIFO
*/
aligned_mem_dma = ioc->reply_frames_dma;
dprintk((KERN_INFO MYNAM ": %s.reply_frames @ %p[%p]\n",
ioc->name, ioc->reply_frames, (void *)(ulong)aligned_mem_dma));
for (i = 0; i < ioc->req_depth; i++) {
alloc_dma += ioc->req_sz;
mem += ioc->req_sz;
}
for (i = 0; i < ioc->reply_depth; i++) {
/* Write each address to the IOC! */
CHIPREG_WRITE32(&ioc->chip->ReplyFifo, aligned_mem_dma);
aligned_mem_dma += ioc->reply_sz;
}
ioc->ChainBuffer = mem;
ioc->ChainBufferDMA = alloc_dma;
dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
/* Initialize Request frames linked list
*/
aligned_mem_dma = ioc->req_frames_dma;
aligned_mem = (u8 *) ioc->req_frames;
dprintk((KERN_INFO MYNAM ": %s.req_frames @ %p[%p]\n",
ioc->name, aligned_mem, (void *)(ulong)aligned_mem_dma));
/* Initialize the free chain Q.
*/
spin_lock_irqsave(&ioc->FreeQlock, flags);
Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
for (i = 0; i < ioc->req_depth; i++) {
mf = (MPT_FRAME_HDR *) aligned_mem;
Q_INIT(&ioc->FreeChainQ, MPT_FRAME_HDR);
/* Queue REQUESTs *internally*! */
Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
aligned_mem += ioc->req_sz;
}
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
/* Post the chain buffers to the FreeChainQ.
*/
mem = (u8 *)ioc->ChainBuffer;
for (i=0; i < num_chain; i++) {
mf = (MPT_FRAME_HDR *) mem;
Q_ADD_TAIL(&ioc->FreeChainQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
mem += ioc->req_sz;
}
/* Initialize Request frames linked list
*/
alloc_dma = ioc->req_frames_dma;
mem = (u8 *) ioc->req_frames;
spin_lock_irqsave(&ioc->FreeQlock, flags);
Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
for (i = 0; i < ioc->req_depth; i++) {
mf = (MPT_FRAME_HDR *) mem;
/* Queue REQUESTs *internally*! */
Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
mem += ioc->req_sz;
}
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
if (ioc->sense_buf_pool == NULL) {
sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
ioc->sense_buf_pool =
pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
if (ioc->sense_buf_pool == NULL)
pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
if (ioc->sense_buf_pool == NULL) {
printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
ioc->name);
goto out_fail;
}
ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
ioc->alloc_total += sz;
dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
}
/* Post Reply frames to FIFO
*/
alloc_dma = ioc->alloc_dma;
dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
for (i = 0; i < ioc->reply_depth; i++) {
/* Write each address to the IOC! */
CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
alloc_dma += ioc->reply_sz;
}
return 0;
out_fail:
if (ioc->fifo_pool != NULL) {
if (ioc->alloc != NULL) {
sz = ioc->alloc_sz;
pci_free_consistent(ioc->pcidev,
ioc->fifo_pool_sz,
ioc->fifo_pool, ioc->fifo_pool_dma);
sz,
ioc->alloc, ioc->alloc_dma);
ioc->reply_frames = NULL;
ioc->reply_alloc = NULL;
ioc->req_frames = NULL;
ioc->req_alloc = NULL;
ioc->chain_alloc = NULL;
ioc->fifo_pool = NULL;
ioc->alloc_total -= ioc->fifo_pool_sz;
#if defined(CONFIG_MTRR) && 0
if (ioc->mtrr_reg > 0) {
mtrr_del(ioc->mtrr_reg, 0, 0);
dprintk((MYIOC_s_INFO_FMT "MTRR region de-registered\n",
ioc->name));
}
#endif
ioc->alloc_total -= sz;
}
if (ioc->sense_buf_pool != NULL) {
sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
......@@ -3691,8 +3719,8 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
dhsprintk((MYIOC_s_INFO_FMT "HandShake request start, WaitCnt=%d%s\n",
ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
/* Read doorbell and check for active bit */
if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
......@@ -3726,7 +3754,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
failcnt++;
}
dmfprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
DBG_DUMP_REQUEST_FRAME_HDR(req)
dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
......@@ -3781,7 +3809,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(1 * HZ / 1000);
count++;
}
} else {
......@@ -3831,7 +3859,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(1 * HZ / 1000);
count++;
}
} else {
......@@ -3933,7 +3961,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
}
#endif
dmfprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
DBG_DUMP_REPLY_FRAME(mptReply)
dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
......@@ -4280,9 +4308,11 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 )
if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
ioc->name, pPP0->Capabilities));
}
ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
if (data) {
......@@ -4905,8 +4935,8 @@ int
mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
{
ToolboxIstwiReadWriteRequest_t *pReq;
struct pci_dev *pdev;
MPT_FRAME_HDR *mf;
struct pci_dev *pdev;
unsigned long flags;
int rc;
u32 flagsLength;
......@@ -5224,12 +5254,6 @@ procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eo
if (drvname)
len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
/*
* Handle isense special case, because it
* doesn't do a formal mpt_register call.
*/
if (isense_idx == ii)
len += sprintf(buf+len, " Fusion MPT isense driver\n");
}
}
......@@ -5284,7 +5308,7 @@ procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eo
len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
(void *)ioc->req_alloc, (void *)(ulong)ioc->req_alloc_dma);
(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
/*
* Rounding UP to nearest 4-kB boundary here...
*/
......@@ -5296,8 +5320,8 @@ procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eo
4*ioc->facts.RequestFrameSize,
ioc->facts.GlobalCredits);
len += sprintf(buf+len, " ReplyFrames @ 0x%p (Dma @ 0x%p)\n",
(void *)ioc->reply_alloc, (void *)(ulong)ioc->reply_alloc_dma);
len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
sz = (ioc->reply_sz * ioc->reply_depth) + 128;
len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
......@@ -5590,7 +5614,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
}
evStr = EventDescriptionStr(event, evData0);
dprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
ioc->name,
evStr,
event));
......@@ -5662,7 +5686,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
*/
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
if (MptEvHandlers[ii]) {
dprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
ioc->name, ii));
r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
handlers++;
......@@ -5675,8 +5699,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
*/
if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
printk(MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
ioc->name, ii);
devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
ioc->name, ii));
}
}
......@@ -5700,9 +5724,8 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
"FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
};
u8 subcl = (log_info >> 24) & 0x7;
// u32 SubCl = log_info & 0x27000000;
printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}",
printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
ioc->name, log_info, subcl_str[subcl]);
}
......@@ -5905,50 +5928,6 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_register_ascqops_strings - Register SCSI ASC/ASCQ and SCSI
* OpCode strings from the (optional) isense module.
* @ascqTable: Pointer to ASCQ_Table_t structure
* @ascqtbl_sz: Number of entries in ASCQ_Table
* @opsTable: Pointer to array of SCSI OpCode strings (char pointers)
*
* Specialized driver registration routine for the isense driver.
*/
int
mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable)
{
int r = 0;
if (ascqTable && ascqtbl_sz && opsTable) {
mpt_v_ASCQ_TablePtr = ascqTable;
mpt_ASCQ_TableSz = ascqtbl_sz;
mpt_ScsiOpcodesPtr = opsTable;
printk(KERN_INFO MYNAM ": English readable SCSI-3 strings enabled:-)\n");
isense_idx = last_drv_idx;
r = 1;
}
return r;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_deregister_ascqops_strings - Deregister SCSI ASC/ASCQ and SCSI
* OpCode strings from the isense driver.
*
* Specialized driver deregistration routine for the isense driver.
*/
void
mpt_deregister_ascqops_strings(void)
{
mpt_v_ASCQ_TablePtr = NULL;
mpt_ASCQ_TableSz = 0;
mpt_ScsiOpcodesPtr = NULL;
printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n");
isense_idx = -1;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
EXPORT_SYMBOL(ioc_list);
EXPORT_SYMBOL(mpt_proc_root_dir);
EXPORT_SYMBOL(DmpService);
......@@ -5980,13 +5959,6 @@ EXPORT_SYMBOL(mpt_read_ioc_pg_3);
EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
EXPORT_SYMBOL(mpt_register_ascqops_strings);
EXPORT_SYMBOL(mpt_deregister_ascqops_strings);
EXPORT_SYMBOL(mpt_v_ASCQ_TablePtr);
EXPORT_SYMBOL(mpt_ASCQ_TableSz);
EXPORT_SYMBOL(mpt_ScsiOpcodesPtr);
static struct pci_driver mptbase_driver = {
.name = "mptbase",
.id_table = mptbase_pci_table,
......
......@@ -60,8 +60,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include "scsi3.h" /* SCSI defines */
#include "lsi/mpi_type.h"
#include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */
#include "lsi/mpi_ioc.h" /* Fusion MPT IOC(ontroller) defs */
......@@ -85,8 +83,8 @@
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.01.10"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.10"
#define MPT_LINUX_VERSION_COMMON "3.01.15"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.15"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
......@@ -403,6 +401,11 @@ typedef struct _ScsiCmndTracker {
void *tail;
} ScsiCmndTracker;
/* VirtDevice negoFlags field */
#define MPT_TARGET_NO_NEGO_WIDE 0x01
#define MPT_TARGET_NO_NEGO_SYNC 0x02
#define MPT_TARGET_NO_NEGO_QAS 0x04
#define MPT_TAPE_NEGO_IDP 0x08
/*
* VirtDevice - FC LUN device or SCSI target device
......@@ -420,8 +423,8 @@ typedef struct _VirtDevice {
u8 bus_id;
u8 minSyncFactor; /* 0xFF is async */
u8 maxOffset; /* 0 if async */
u8 maxWidth; /* 0 if narrow, 1 if wide*/
u8 negoFlags; /* bit field, 0 if WDTR/SDTR/QAS allowed */
u8 maxWidth; /* 0 if narrow, 1 if wide */
u8 negoFlags; /* bit field, see above */
u8 raidVolume; /* set, if RAID Volume */
u8 type; /* byte 0 of Inquiry data */
u8 cflags; /* controller flags */
......@@ -460,10 +463,6 @@ typedef struct _VirtDevice {
#define MPT_TARGET_FLAGS_VALID_56 0x10
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
#define MPT_TARGET_NO_NEGO_WIDE 0x01
#define MPT_TARGET_NO_NEGO_SYNC 0x02
#define MPT_TARGET_NO_NEGO_QAS 0x04
typedef struct _VirtDevTracker {
struct _VirtDevice *head;
struct _VirtDevice *tail;
......@@ -601,25 +600,30 @@ typedef struct _MPT_ADAPTER
int alloc_total;
u32 last_state;
int active;
u8 *fifo_pool; /* dma pool for fifo's */
dma_addr_t fifo_pool_dma;
int fifo_pool_sz; /* allocated size */
u8 *chain_alloc; /* chain buffer alloc ptr */
dma_addr_t chain_alloc_dma;
int chain_alloc_sz;
u8 *reply_alloc; /* Reply frames alloc ptr */
dma_addr_t reply_alloc_dma;
u8 *alloc; /* frames alloc ptr */
dma_addr_t alloc_dma;
u32 alloc_sz;
MPT_FRAME_HDR *reply_frames; /* Reply msg frames - rounded up! */
dma_addr_t reply_frames_dma;
u32 reply_frames_low_dma;
int reply_depth; /* Num Allocated reply frames */
int reply_sz; /* Reply frame size */
int num_chain; /* Number of chain buffers */
/* Pool of buffers for chaining. ReqToChain
* and ChainToChain track index of chain buffers.
* ChainBuffer (DMA) virt/phys addresses.
* FreeChainQ (lock) locking mechanisms.
*/
int *ReqToChain;
int *RequestNB;
int *ChainToChain;
u8 *ChainBuffer;
dma_addr_t ChainBufferDMA;
MPT_Q_TRACKER FreeChainQ;
spinlock_t FreeChainQlock;
CHIP_TYPE chip_type;
/* We (host driver) get to manage our own RequestQueue! */
u8 *req_alloc; /* Request frames alloc ptr */
dma_addr_t req_alloc_dma;
MPT_FRAME_HDR *req_frames; /* Request msg frames - rounded up! */
dma_addr_t req_frames_dma;
MPT_FRAME_HDR *req_frames; /* Request msg frames - rounded up! */
u32 req_frames_low_dma;
int req_depth; /* Number of request frames */
int req_sz; /* Request frame size (bytes) */
......@@ -662,6 +666,7 @@ typedef struct _MPT_ADAPTER
#else
u32 mfcnt;
#endif
u32 NB_for_64_byte_frame;
u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
IOCFactsReply_t facts;
......@@ -675,7 +680,8 @@ typedef struct _MPT_ADAPTER
u8 FirstWhoInit;
u8 upload_fw; /* If set, do a fw upload */
u8 reload_fw; /* Force a FW Reload on next reset */
u8 pad1[5];
u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
u8 pad1[4];
struct list_head list;
struct net_device *netdev;
} MPT_ADAPTER;
......@@ -759,10 +765,10 @@ typedef struct _mpt_sge {
#define dexitprintk(x)
#endif
#ifdef MPT_DEBUG_RESET
#define drsprintk(x) printk x
#if defined MPT_DEBUG_FAIL || defined (MPT_DEBUG_SG)
#define dfailprintk(x) printk x
#else
#define drsprintk(x)
#define dfailprintk(x)
#endif
#ifdef MPT_DEBUG_HANDSHAKE
......@@ -771,11 +777,34 @@ typedef struct _mpt_sge {
#define dhsprintk(x)
#endif
#ifdef MPT_DEBUG_EVENTS
#define devtprintk(x) printk x
#else
#define devtprintk(x)
#endif
#ifdef MPT_DEBUG_RESET
#define drsprintk(x) printk x
#else
#define drsprintk(x)
#endif
//#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
#if defined(MPT_DEBUG_MSG_FRAME)
#define dmfprintk(x) printk x
#define DBG_DUMP_REQUEST_FRAME(mfp) \
{ int i, n = 24; \
u32 *m = (u32 *)(mfp); \
for (i=0; i<n; i++) { \
if (i && ((i%8)==0)) \
printk("\n"); \
printk("%08x ", le32_to_cpu(m[i])); \
} \
printk("\n"); \
}
#else
#define dmfprintk(x)
#define DBG_DUMP_REQUEST_FRAME(mfp)
#endif
#ifdef MPT_DEBUG_IRQ
......@@ -796,13 +825,18 @@ typedef struct _mpt_sge {
#define ddlprintk(x)
#endif
#ifdef MPT_DEBUG_DV
#define ddvprintk(x) printk x
#else
#define ddvprintk(x)
#endif
#ifdef MPT_DEBUG_NEGO
#define dnegoprintk(x) printk x
#else
#define dnegoprintk(x)
#endif
#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
#define ddvtprintk(x) printk x
#else
......@@ -815,10 +849,40 @@ typedef struct _mpt_sge {
#define dctlprintk(x)
#endif
#ifdef MPT_DEBUG_RESET
#ifdef MPT_DEBUG_REPLY
#define dreplyprintk(x) printk x
#else
#define dreplyprintk(x)
#endif
#ifdef MPT_DEBUG_TM
#define dtmprintk(x) printk x
#define DBG_DUMP_TM_REQUEST_FRAME(mfp) \
{ u32 *m = (u32 *)(mfp); \
int i, n = 12; \
printk("TM_REQUEST:\n"); \
for (i=0; i<n; i++) { \
if (i && ((i%8)==0)) \
printk("\n"); \
printk("%08x ", le32_to_cpu(m[i])); \
} \
printk("\n"); \
}
#define DBG_DUMP_TM_REPLY_FRAME(mfp) \
{ u32 *m = (u32 *)(mfp); \
int i, n = (le32_to_cpu(m[0]) & 0x00FF0000) >> 16; \
printk("TM_REPLY MessageLength=%d:\n", n); \
for (i=0; i<n; i++) { \
if (i && ((i%8)==0)) \
printk("\n"); \
printk(" %08x", le32_to_cpu(m[i])); \
} \
printk("\n"); \
}
#else
#define dtmprintk(x)
#define DBG_DUMP_TM_REQUEST_FRAME(mfp)
#define DBG_DUMP_TM_REPLY_FRAME(mfp)
#endif
#ifdef MPT_DEBUG_NEH
......@@ -909,6 +973,10 @@ typedef struct _mpt_sge {
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define SCSI_STD_SENSE_BYTES 18
#define SCSI_STD_INQUIRY_BYTES 36
#define SCSI_MAX_INQUIRY_BYTES 96
/*
* MPT_SCSI_HOST defines - Used by the IOCTL and the SCSI drivers
* Private to the driver.
......@@ -952,17 +1020,6 @@ typedef struct _MPT_SCSI_HOST {
int port;
u32 pad0;
struct scsi_cmnd **ScsiLookup;
/* Pool of buffers for chaining. ReqToChain
* and ChainToChain track index of chain buffers.
* ChainBuffer (DMA) virt/phys addresses.
* FreeChainQ (lock) locking mechanisms.
*/
int *ReqToChain;
int *ChainToChain;
u8 *ChainBuffer;
dma_addr_t ChainBufferDMA;
MPT_Q_TRACKER FreeChainQ;
spinlock_t FreeChainQlock;
u32 qtag_tick;
VirtDevice **Targets;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
......@@ -978,16 +1035,13 @@ typedef struct _MPT_SCSI_HOST {
MPT_Q_TRACKER taskQ; /* TM request Q */
spinlock_t freedoneQlock;
int taskQcnt;
int num_chain; /* Number of chain buffers */
int max_sge; /* Max No of SGE*/
u8 numTMrequests;
u8 tmPending;
u8 resetPending;
u8 is_spi; /* Parallel SCSI i/f */
u8 negoNvram; /* DV disabled, nego NVRAM */
u8 is_multipath; /* Multi-path compatible */
u8 tmState;
u8 rsvd[1];
u8 rsvd[2];
MPT_FRAME_HDR *tmPtr; /* Ptr to TM request*/
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
struct scsi_cmnd *abortSCpnt;
......@@ -1057,10 +1111,8 @@ extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
extern void mpt_reset_deregister(int cb_idx);
extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx);
extern void mpt_device_driver_deregister(int cb_idx);
extern int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
extern void mpt_deregister_ascqops_strings(void);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc);
extern void mpt_free_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr);
extern void mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr);
......@@ -1088,10 +1140,6 @@ extern DmpServices_t *DmpService;
extern int mpt_lan_index; /* needed by mptlan.c */
extern int mpt_stm_index; /* needed by mptstm.c */
extern void *mpt_v_ASCQ_TablePtr;
extern const char **mpt_ScsiOpcodesPtr;
extern int mpt_ASCQ_TableSz;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */
......
......@@ -447,7 +447,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
mptctl_free_tm_flags(ioctl->ioc);
del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(mptctl_id, ioctl->ioc, mf);
mpt_free_msg_frame(ioctl->ioc, mf);
ioctl->tmPtr = NULL;
}
......@@ -522,7 +522,7 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(mptctl_id, ioc, ioctl->tmPtr);
mpt_free_msg_frame(ioc, ioctl->tmPtr);
}
} else {
......@@ -1808,7 +1808,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
struct buflist bufOut; /* data Out buffer */
dma_addr_t dma_addr_in;
dma_addr_t dma_addr_out;
int dir; /* PCI data direction */
int sgSize = 0; /* Num SG elements */
int iocnum, flagsLength;
int sz, rc = 0;
......@@ -2118,9 +2117,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
/* Set up the dataOut memory allocation */
if (karg.dataOutSize > 0) {
dir = PCI_DMA_TODEVICE;
if (karg.dataInSize > 0) {
flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_DIRECTION |
mpt_addr_size() )
<< MPI_SGE_FLAGS_SHIFT;
......@@ -2159,7 +2158,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
}
if (karg.dataInSize > 0) {
dir = PCI_DMA_FROMDEVICE;
flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
flagsLength |= karg.dataInSize;
......@@ -2207,7 +2205,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
del_timer(&ioc->ioctl->timer);
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
mpt_free_msg_frame(mptctl_id, ioc, mf);
mpt_free_msg_frame(ioc, mf);
}
} else {
mpt_put_msg_frame(mptctl_id, ioc, mf);
......@@ -2325,7 +2323,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
* otherwise, failure occured after mf acquired.
*/
if (mf)
mpt_free_msg_frame(mptctl_id, ioc, mf);
mpt_free_msg_frame(ioc, mf);
return rc;
}
......
......@@ -1332,7 +1332,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
if (pSimple == NULL) {
/**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n",
/**/ __FUNCTION__);
mpt_free_msg_frame(LanCtx, mpt_dev, mf);
mpt_free_msg_frame(mpt_dev, mf);
goto out;
}
......
......@@ -86,7 +86,6 @@
#include "mptbase.h"
#include "mptscsih.h"
#include "isense.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define my_NAME "Fusion MPT SCSI Host driver"
......@@ -100,6 +99,7 @@ MODULE_LICENSE("GPL");
/* Set string for command line args from insmod */
#ifdef MODULE
char *mptscsih = NULL;
MODULE_PARM(mptscsih, "s");
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -114,6 +114,7 @@ typedef struct _BIG_SENSE_BUF {
#define MPT_SCANDV_SOME_ERROR (0x00000004)
#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
#define MPT_SCANDV_ISSUE_SENSE (0x00000010)
#define MPT_SCANDV_FALLBACK (0x00000020)
#define MPT_SCANDV_MAX_RETRIES (10)
......@@ -161,10 +162,9 @@ static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *
static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
static int mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
SCSIIORequest_t *pReq, int req_idx);
static void mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx);
static int mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init);
static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
......@@ -323,44 +323,47 @@ mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_getFreeChainBuffes - Function to get a free chain
* mptscsih_getFreeChainBuffer - Function to get a free chain
* from the MPT_SCSI_HOST FreeChainQ.
* @hd: Pointer to the MPT_SCSI_HOST instance
* @ioc: Pointer to MPT_ADAPTER structure
* @req_idx: Index of the SCSI IO request frame. (output)
*
* return SUCCESS or FAILED
*/
static inline int
mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
{
MPT_FRAME_HDR *chainBuf;
unsigned long flags;
int rc;
int chain_idx;
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if (!Q_IS_EMPTY(&hd->FreeChainQ)) {
dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
ioc->name));
spin_lock_irqsave(&ioc->FreeQlock, flags);
if (!Q_IS_EMPTY(&ioc->FreeChainQ)) {
int offset;
chainBuf = hd->FreeChainQ.head;
chainBuf = ioc->FreeChainQ.head;
Q_DEL_ITEM(&chainBuf->u.frame.linkage);
offset = (u8 *)chainBuf - (u8 *)hd->ChainBuffer;
chain_idx = offset / hd->ioc->req_sz;
offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
chain_idx = offset / ioc->req_sz;
rc = SUCCESS;
dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
ioc->name, *retIndex, chainBuf));
}
else {
rc = FAILED;
chain_idx = MPT_HOST_NO_CHAIN;
dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
ioc->name));
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
*retIndex = chain_idx;
dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
hd->ioc->name, *retIndex, chainBuf));
return rc;
} /* mptscsih_getFreeChainBuffer() */
......@@ -368,14 +371,14 @@ mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
/*
* mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
* SCSIIORequest_t Message Frame.
* @hd: Pointer to MPT_SCSI_HOST structure
* @ioc: Pointer to MPT_ADAPTER structure
* @SCpnt: Pointer to scsi_cmnd structure
* @pReq: Pointer to SCSIIORequest_t structure
*
* Returns ...
*/
static int
mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
SCSIIORequest_t *pReq, int req_idx)
{
char *psge;
......@@ -391,6 +394,7 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
int newIndex;
int ii;
dma_addr_t v2;
u32 RequestNB;
sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
......@@ -400,25 +404,25 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
}
psge = (char *) &pReq->SGL;
frm_sz = hd->ioc->req_sz;
frm_sz = ioc->req_sz;
/* Map the data portion, if any.
* sges_left = 0 if no data transfer.
*/
if ( (sges_left = SCpnt->use_sg) ) {
sges_left = pci_map_sg(hd->ioc->pcidev,
sges_left = pci_map_sg(ioc->pcidev,
(struct scatterlist *) SCpnt->request_buffer,
SCpnt->use_sg,
SCpnt->sc_data_direction);
if (sges_left == 0)
return FAILED;
} else if (SCpnt->request_bufflen) {
SCpnt->SCp.dma_handle = pci_map_single(hd->ioc->pcidev,
SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
SCpnt->request_buffer,
SCpnt->request_bufflen,
SCpnt->sc_data_direction);
dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
hd->ioc->name, SCpnt, SCpnt->request_bufflen));
ioc->name, SCpnt, SCpnt->request_bufflen));
mptscsih_add_sge((char *) &pReq->SGL,
0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
SCpnt->SCp.dma_handle);
......@@ -493,12 +497,16 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
* Update the chain element
* Offset and Length fields.
*/
mptscsih_add_chain((char *)chainSge, 0, sgeOffset, hd->ChainBufferDMA + chain_dma_off);
mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
} else {
/* The current buffer is the original MF
* and there is no Chain buffer.
*/
pReq->ChainOffset = 0;
RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
dsgprintk((MYIOC_s_ERR_FMT
"Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
ioc->RequestNB[req_idx] = RequestNB;
}
} else {
/* At least one chain buffer is needed.
......@@ -513,7 +521,7 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
*/
dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
hd->ioc->name, sg_done));
ioc->name, sg_done));
/* Set LAST_ELEMENT flag for last non-chain element
* in the buffer. Since psge points at the NEXT
......@@ -537,13 +545,16 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
*/
u8 nextChain = (u8) (sgeOffset >> 2);
sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, hd->ChainBufferDMA + chain_dma_off);
mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
} else {
/* The original MF buffer requires a chain buffer -
* set the offset.
* Last element in this MF is a chain element.
*/
pReq->ChainOffset = (u8) (sgeOffset >> 2);
RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
ioc->RequestNB[req_idx] = RequestNB;
}
sges_left -= sg_done;
......@@ -552,19 +563,22 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
/* NOTE: psge points to the beginning of the chain element
* in current buffer. Get a chain buffer.
*/
if ((mptscsih_getFreeChainBuffer(hd, &newIndex)) == FAILED)
dsgprintk((MYIOC_s_INFO_FMT
"calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
ioc->name, pReq->CDB[0], SCpnt));
if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
return FAILED;
/* Update the tracking arrays.
* If chainSge == NULL, update ReqToChain, else ChainToChain
*/
if (chainSge) {
hd->ChainToChain[chain_idx] = newIndex;
ioc->ChainToChain[chain_idx] = newIndex;
} else {
hd->ReqToChain[req_idx] = newIndex;
ioc->ReqToChain[req_idx] = newIndex;
}
chain_idx = newIndex;
chain_dma_off = hd->ioc->req_sz * chain_idx;
chain_dma_off = ioc->req_sz * chain_idx;
/* Populate the chainSGE for the current buffer.
* - Set chain buffer pointer to psge and fill
......@@ -576,7 +590,7 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt,
/* Start the SGE for the next buffer
*/
psge = (char *) (hd->ChainBuffer + chain_dma_off);
psge = (char *) (ioc->ChainBuffer + chain_dma_off);
sgeOffset = 0;
sg_done = 0;
......@@ -631,7 +645,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
ioc->name);
mptscsih_freeChainBuffers(hd, req_idx);
mptscsih_freeChainBuffers(ioc, req_idx);
return 1;
}
......@@ -674,14 +688,15 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
scsi_state = pScsiReply->SCSIState;
scsi_status = pScsiReply->SCSIStatus;
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
dprintk((KERN_NOTICE " Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
dreplyprintk((KERN_NOTICE " Reply (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
mf, mr, sc));
dprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh"
", SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
status, scsi_state, pScsiReply->SCSIStatus,
le32_to_cpu(pScsiReply->IOCLogInfo)));
dreplyprintk((KERN_NOTICE "IOCStatus=%04xh SCSIState=%02xh"
" SCSIStatus=%02xh xfer_cnt=%08xh\n",
status, scsi_state, scsi_status, xfer_cnt));
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
copy_sense_data(sc, hd, mf, pScsiReply);
......@@ -701,7 +716,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
* But not: DID_BUS_BUSY lest one risk
* killing interrupt handler:-(
*/
sc->result = STS_BUSY;
sc->result = SAM_STAT_BUSY;
break;
case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
......@@ -731,13 +746,22 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
break;
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
sc->resid = sc->request_bufflen - xfer_cnt;
if ( xfer_cnt >= sc->underflow ) {
/* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status;
} else if ( xfer_cnt == 0 ) {
/* A CRC Error causes this condition; retry */
sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
(CHECK_CONDITION << 1);
sc->sense_buffer[0] = 0x70;
sc->sense_buffer[2] = NO_SENSE;
sc->sense_buffer[12] = 0;
sc->sense_buffer[13] = 0;
dprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
sc->sense_buffer[0] = 0x70;
sc->sense_buffer[2] = NO_SENSE;
sc->sense_buffer[12] = 0;
sc->sense_buffer[13] = 0;
} else {
sc->result = DID_SOFT_ERROR << 16;
}
dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
......@@ -745,9 +769,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
* Do upfront check for valid SenseData and give it
* precedence!
*/
scsi_status = pScsiReply->SCSIStatus;
sc->result = (DID_OK << 16) | scsi_status;
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
/* Have already saved the status and sense data
*/
......@@ -769,12 +791,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/* Give report and update residual count.
*/
dprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
sc->underflow));
dprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
sc->resid = sc->request_bufflen - xfer_cnt;
dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid));
dreplyprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid));
/* Report Queue Full
*/
......@@ -785,7 +807,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus;
scsi_status = pScsiReply->SCSIStatus;
sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state == 0) {
;
} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
......@@ -851,7 +874,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
} /* switch(status) */
dprintk((KERN_NOTICE " sc->result set to %08xh\n", sc->result));
dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
} /* end of address reply case */
/* Unmap the DMA buffers, if any. */
......@@ -868,7 +891,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->scsi_done(sc); /* Issue the command callback */
/* Free Chain buffers */
mptscsih_freeChainBuffers(hd, req_idx);
mptscsih_freeChainBuffers(ioc, req_idx);
return 1;
}
......@@ -964,11 +987,12 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, struct scsi_cmnd *SCpnt)
static void
mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
{
MPT_ADAPTER *ioc = hd->ioc;
struct scsi_cmnd *SCpnt;
MPT_FRAME_HDR *mf;
MPT_DONE_Q *buffer;
int ii;
int max = hd->ioc->req_depth;
int max = ioc->req_depth;
unsigned long flags;
dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
......@@ -987,7 +1011,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
*/
hd->ScsiLookup[ii] = NULL;
mf = MPT_INDEX_2_MFPTR(hd->ioc, ii);
mf = MPT_INDEX_2_MFPTR(ioc, ii);
dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
mf, SCpnt));
......@@ -997,12 +1021,12 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
*/
if (scsi_device_online(SCpnt->device)) {
if (SCpnt->use_sg) {
pci_unmap_sg(hd->ioc->pcidev,
pci_unmap_sg(ioc->pcidev,
(struct scatterlist *) SCpnt->request_buffer,
SCpnt->use_sg,
SCpnt->sc_data_direction);
} else if (SCpnt->request_bufflen) {
pci_unmap_single(hd->ioc->pcidev,
pci_unmap_single(ioc->pcidev,
SCpnt->SCp.dma_handle,
SCpnt->request_bufflen,
SCpnt->sc_data_direction);
......@@ -1012,10 +1036,10 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
SCpnt->host_scribble = NULL;
/* Free Chain buffers */
mptscsih_freeChainBuffers(hd, ii);
mptscsih_freeChainBuffers(ioc, ii);
/* Free Message frames */
mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
mpt_free_msg_frame(ioc, mf);
#if 1
/* Post to doneQ, do not reply until POST phase
......@@ -1087,119 +1111,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
/* Cleanup
*/
hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd, ii);
mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, (MPT_FRAME_HDR *)mf);
mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
}
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_initChainBuffers - Allocate memory for and initialize
* chain buffers, chain buffer control arrays and spinlock.
* @hd: Pointer to MPT_SCSI_HOST structure
* @init: If set, initialize the spin lock.
*/
static int
mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
{
MPT_FRAME_HDR *chain;
u8 *mem;
unsigned long flags;
int sz, ii, num_chain;
int scale, num_sge;
/* chain buffer allocation done from PrimeIocFifos */
if (hd->ioc->fifo_pool == NULL)
return -1;
hd->ChainBuffer = hd->ioc->chain_alloc;
hd->ChainBufferDMA = hd->ioc->chain_alloc_dma;
dprintk((KERN_INFO " ChainBuffer @ %p(%p), sz=%d\n",
hd->ChainBuffer, (void *)(ulong)hd->ChainBufferDMA, hd->ioc->chain_alloc_sz));
/* ReqToChain size must equal the req_depth
* index = req_idx
*/
if (hd->ReqToChain == NULL) {
sz = hd->ioc->req_depth * sizeof(int);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
return -1;
hd->ReqToChain = (int *) mem;
}
for (ii = 0; ii < hd->ioc->req_depth; ii++)
hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
/* ChainToChain size must equal the total number
* of chain buffers to be allocated.
* index = chain_idx
*
* Calculate the number of chain buffers needed(plus 1) per I/O
* then multiply the the maximum number of simultaneous cmds
*
* num_sge = num sge in request frame + last chain buffer
* scale = num sge per chain buffer if no chain element
*/
scale = hd->ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
if (sizeof(dma_addr_t) == sizeof(u64))
num_sge = scale + (hd->ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
else
num_sge = 1+ scale + (hd->ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
num_chain = 1;
while (hd->max_sge - num_sge > 0) {
num_chain++;
num_sge += (scale - 1);
}
num_chain++;
if ((int) hd->ioc->chip_type > (int) FC929)
num_chain *= MPT_SCSI_CAN_QUEUE;
else
num_chain *= MPT_FC_CAN_QUEUE;
hd->num_chain = num_chain;
sz = num_chain * sizeof(int);
if (hd->ChainToChain == NULL) {
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
return -1;
hd->ChainToChain = (int *) mem;
} else {
mem = (u8 *) hd->ChainToChain;
}
memset(mem, 0xFF, sz);
/* Initialize the free chain Q.
*/
if (init) {
spin_lock_init(&hd->FreeChainQlock);
}
spin_lock_irqsave (&hd->FreeChainQlock, flags);
Q_INIT(&hd->FreeChainQ, MPT_FRAME_HDR);
/* Post the chain buffers to the FreeChainQ.
*/
mem = (u8 *)hd->ChainBuffer;
for (ii=0; ii < num_chain; ii++) {
chain = (MPT_FRAME_HDR *) mem;
Q_ADD_TAIL(&hd->FreeChainQ.head, &chain->u.frame.linkage, MPT_FRAME_HDR);
mem += hd->ioc->req_sz;
}
spin_unlock_irqrestore(&hd->FreeChainQlock, flags);
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Hack! It might be nice to report if a device is returning QUEUE_FULL
......@@ -1386,7 +1305,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd = (MPT_SCSI_HOST *) sh->hostdata;
hd->ioc = ioc;
hd->max_sge = sh->sg_tablesize;
if ((int)ioc->chip_type > (int)FC929)
hd->is_spi = 1;
......@@ -1399,7 +1317,7 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!)
*/
sz = hd->ioc->req_depth * sizeof(void *);
sz = ioc->req_depth * sizeof(void *);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL) {
error = -ENOMEM;
......@@ -1412,11 +1330,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
ioc->name, hd->ScsiLookup, sz));
if (mptscsih_initChainBuffers(hd, 1) < 0) {
error = -EINVAL;
goto mptscsih_probe_failed;
}
/* Allocate memory for free and doneQ's
*/
sz = sh->can_queue * sizeof(MPT_DONE_Q);
......@@ -1474,8 +1387,7 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->resetPending = 0;
hd->abortSCpnt = NULL;
hd->tmPtr = NULL;
hd->numTMrequests = 0;
/* Clear the pointer used to store
* single-threaded commands, i.e., those
* issued during a bus scan, dv and
......@@ -1500,10 +1412,10 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* ioc->sh = sh; */
#ifdef MPTSCSIH_DBG_TIMEOUT
hd->ioc->timeout_hard = 0;
hd->ioc->timeout_delta = 30 * HZ;
hd->ioc->timeout_maxcnt = 0;
hd->ioc->timeout_cnt = 0;
ioc->timeout_hard = 0;
ioc->timeout_delta = 30 * HZ;
ioc->timeout_maxcnt = 0;
ioc->timeout_cnt = 0;
for (ii=0; ii < 8; ii++)
foo_to[ii] = NULL;
#endif
......@@ -1511,23 +1423,23 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Update with the driver setup
* values.
*/
if (hd->ioc->spi_data.maxBusWidth >
if (ioc->spi_data.maxBusWidth >
driver_setup.max_width) {
hd->ioc->spi_data.maxBusWidth =
ioc->spi_data.maxBusWidth =
driver_setup.max_width;
}
if (hd->ioc->spi_data.minSyncFactor <
if (ioc->spi_data.minSyncFactor <
driver_setup.min_sync_fac) {
hd->ioc->spi_data.minSyncFactor =
ioc->spi_data.minSyncFactor =
driver_setup.min_sync_fac;
}
if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) {
hd->ioc->spi_data.maxSyncOffset = 0;
if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
ioc->spi_data.maxSyncOffset = 0;
}
hd->ioc->spi_data.Saf_Te = driver_setup.saf_te;
ioc->spi_data.Saf_Te = driver_setup.saf_te;
hd->negoNvram = 0;
#ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
......@@ -1537,21 +1449,19 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
}
hd->ioc->spi_data.forceDv = 0;
ioc->spi_data.forceDv = 0;
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
hd->ioc->spi_data.dvStatus[ii] =
ioc->spi_data.dvStatus[ii] =
MPT_SCSICFG_NEGOTIATE;
}
if (hd->negoNvram == 0) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
hd->ioc->spi_data.dvStatus[ii] |=
MPT_SCSICFG_DV_NOT_DONE;
}
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
ioc->spi_data.dvStatus[ii] |=
MPT_SCSICFG_DV_NOT_DONE;
ddvprintk((MYIOC_s_INFO_FMT
"dv %x width %x factor %x saf_te %x\n",
hd->ioc->name, driver_setup.dv,
ioc->name, driver_setup.dv,
driver_setup.max_width,
driver_setup.min_sync_fac,
driver_setup.saf_te));
......@@ -1620,14 +1530,12 @@ mptscsih_remove(struct pci_dev *pdev)
hd = (MPT_SCSI_HOST *)host->hostdata;
if (hd != NULL) {
int sz1, sz2, sz3, sztarget=0;
int szr2chain = 0;
int szc2chain = 0;
int sz1, sz3, sztarget=0;
int szQ = 0;
mptscsih_shutdown(&pdev->dev);
sz1 = sz2 = sz3 = 0;
sz1 = sz3 = 0;
if (hd->ScsiLookup != NULL) {
sz1 = hd->ioc->req_depth * sizeof(void *);
......@@ -1635,18 +1543,6 @@ mptscsih_remove(struct pci_dev *pdev)
hd->ScsiLookup = NULL;
}
if (hd->ReqToChain != NULL) {
szr2chain = hd->ioc->req_depth * sizeof(int);
kfree(hd->ReqToChain);
hd->ReqToChain = NULL;
}
if (hd->ChainToChain != NULL) {
szc2chain = hd->num_chain * sizeof(int);
kfree(hd->ChainToChain);
hd->ChainToChain = NULL;
}
if (hd->memQ != NULL) {
szQ = host->can_queue * sizeof(MPT_DONE_Q);
kfree(hd->memQ);
......@@ -1680,9 +1576,9 @@ mptscsih_remove(struct pci_dev *pdev)
hd->Targets = NULL;
}
dprintk((MYIOC_s_INFO_FMT
"Free'd ScsiLookup (%d) Target (%d+%d) memory\n",
hd->ioc->name, sz1, sz3, sztarget));
dprintk((MYIOC_s_INFO_FMT
"Free'd ScsiLookup (%d) Target (%d+%d) memory\n",
hd->ioc->name, sz1, sz3, sztarget));
dprintk(("Free'd done and free Q (%d) memory\n", szQ));
/* NULL the Scsi_Host pointer
......@@ -1802,7 +1698,7 @@ mptscsih_init(void)
ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
dprintk((KERN_INFO MYNAM
devtprintk((KERN_INFO MYNAM
": Registered for IOC event notifications\n"));
}
......@@ -2249,7 +2145,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
(dma_addr_t) -1);
} else {
/* Add a 32 or 64 bit SGE */
rc = mptscsih_AddSGE(hd, SCpnt, pScsiReq, my_idx);
rc = mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx);
}
......@@ -2283,7 +2179,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
}
/* Trying to do DV to this target, extend timeout.
* Wait to issue intil flag is clear
* Wait to issue until flag is clear
*/
if (dvStatus & MPT_SCSICFG_DV_PENDING) {
mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
......@@ -2314,6 +2210,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
hd->ioc->name, SCpnt, mf, my_idx));
DBG_DUMP_REQUEST_FRAME(mf)
} else {
ddvtprintk((MYIOC_s_INFO_FMT "Pending cmd=%p idx %d\n",
hd->ioc->name, SCpnt, my_idx));
......@@ -2338,8 +2235,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
}
}
} else {
mptscsih_freeChainBuffers(hd, my_idx);
mpt_free_msg_frame(ScsiDoneCtx, hd->ioc, mf);
mptscsih_freeChainBuffers(hd->ioc, my_idx);
mpt_free_msg_frame(hd->ioc, mf);
did_errcode = 3;
goto did_error;
}
......@@ -2385,7 +2282,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
* No return.
*/
static void
mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
{
MPT_FRAME_HDR *chain;
unsigned long flags;
......@@ -2395,28 +2292,28 @@ mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
/* Get the first chain index and reset
* tracker state.
*/
chain_idx = hd->ReqToChain[req_idx];
hd->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
chain_idx = ioc->ReqToChain[req_idx];
ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
while (chain_idx != MPT_HOST_NO_CHAIN) {
/* Save the next chain buffer index */
next = hd->ChainToChain[chain_idx];
next = ioc->ChainToChain[chain_idx];
/* Free this chain buffer and reset
* tracker
*/
hd->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
chain = (MPT_FRAME_HDR *) (hd->ChainBuffer
+ (chain_idx * hd->ioc->req_sz));
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
Q_ADD_TAIL(&hd->FreeChainQ.head,
chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
+ (chain_idx * ioc->req_sz));
spin_lock_irqsave(&ioc->FreeQlock, flags);
Q_ADD_TAIL(&ioc->FreeChainQ.head,
&chain->u.frame.linkage, MPT_FRAME_HDR);
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
hd->ioc->name, chain_idx));
ioc->name, chain_idx));
/* handle next */
chain_idx = next;
......@@ -2480,12 +2377,6 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
}
spin_unlock_irqrestore(&ioc->diagLock, flags);
/* Do not do a Task Management if there are
* too many failed TMs on this adapter.
*/
if (hd->numTMrequests > MPT_HOST_TOO_MANY_TM)
doTask = 0;
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out and not bus reset, then we return a FAILED status to the caller.
* The call to mptscsih_tm_pending_wait() will set the pending flag if we are
......@@ -2593,7 +2484,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
/* Return Fail to calling function if no message frames available.
*/
if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
hd->ioc->name));
//return FAILED;
return -999;
......@@ -2624,27 +2515,28 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
pScsiTm->Reserved2[ii] = 0;
pScsiTm->TaskMsgContext = ctx2abort;
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt, ctx2abort (0x%08x), type (%d)\n",
hd->ioc->name, ctx2abort, type));
/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
mpt_put_msg_frame(hd->ioc->id, mf);
* Save the MF pointer in case the request times out.
*/
hd->tmPtr = mf;
hd->numTMrequests++;
hd->TMtimer.expires = jiffies + timeout;
add_timer(&hd->TMtimer);
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
hd->ioc->name, ctx2abort, type));
DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag))
!= 0) {
dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!"
dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, hd->ioc, mf));
hd->numTMrequests--;
hd->tmPtr = NULL;
del_timer(&hd->TMtimer);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc, mf);
mpt_free_msg_frame(hd->ioc, mf);
}
return retval;
......@@ -2673,7 +2565,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
SCpnt->result = DID_RESET << 16;
SCpnt->scsi_done(SCpnt);
dtmprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
"Can't locate host! (sc=%p)\n",
SCpnt));
return FAILED;
......@@ -2839,9 +2731,6 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
/* We are now ready to execute the task management request. */
spin_unlock_irq(host_lock);
// printk("testing start : mptscsih_schedule_reset\n");
// mptscsih_schedule_reset(hd);
// printk("testing end: mptscsih_schedule_reset\n");
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
< 0){
......@@ -2965,9 +2854,10 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
SCSITaskMgmt_t *pScsiTmReq;
MPT_SCSI_HOST *hd;
unsigned long flags;
u8 tmType = 0;
u16 iocstatus;
u8 tmType;
dtmprintk((MYIOC_s_INFO_FMT "SCSI TaskMgmt completed (mf=%p,r=%p)\n",
dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
ioc->name, mf, mr));
if (ioc->sh) {
/* Depending on the thread, a timer is activated for
......@@ -2978,7 +2868,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
if (hd->tmPtr) {
del_timer(&hd->TMtimer);
}
dtmprintk((MYIOC_s_INFO_FMT "taskQcnt (%d)\n",
dtmprintk((MYIOC_s_WARN_FMT "taskQcnt (%d)\n",
ioc->name, hd->taskQcnt));
} else {
dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
......@@ -2997,18 +2887,15 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
tmType = pScsiTmReq->TaskType;
dtmprintk((KERN_INFO " TaskType = %d, TerminationCount=%d\n",
tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
/* Error? (anything non-zero?) */
if (*(u32 *)&pScsiTmReply->Reserved2[0]) {
u16 iocstatus;
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
dtmprintk((KERN_INFO " SCSI TaskMgmt (%d) - Oops!\n", tmType));
dtmprintk((KERN_INFO " IOCStatus = %04xh\n", iocstatus));
dtmprintk((KERN_INFO " IOCLogInfo = %08xh\n",
le32_to_cpu(pScsiTmReply->IOCLogInfo)));
if (iocstatus) {
/* clear flags and continue.
*/
......@@ -3029,9 +2916,8 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
}
}
} else {
dtmprintk((KERN_INFO " SCSI TaskMgmt SUCCESS!\n"));
dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
hd->numTMrequests--;
hd->abortSCpnt = NULL;
flush_doneQ(hd);
......@@ -3121,12 +3007,21 @@ mptscsih_slave_alloc(struct scsi_device *device)
Q_INIT(&vdev->WaitQ, void);
Q_INIT(&vdev->SentQ, void);
Q_INIT(&vdev->DoneQ, void);
vdev->tflags = 0;
vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
vdev->ioc_id = hd->ioc->id;
vdev->target_id = device->id;
vdev->bus_id = hd->port;
vdev->bus_id = device->channel;
vdev->raidVolume = 0;
hd->Targets[device->id] = vdev;
if (hd->is_spi) {
if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
vdev->raidVolume = 1;
ddvtprintk((KERN_INFO
"RAID Volume @ id %d\n", device->id));
}
} else {
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
}
}
}
vdev->num_luns++;
......@@ -3167,15 +3062,15 @@ mptscsih_slave_destroy(struct scsi_device *device)
kfree(hd->Targets[device->id]);
hd->Targets[device->id] = NULL;
if (!hd->is_spi)
if (!hd->is_spi)
return;
if((hd->ioc->spi_data.isRaid) && (hd->ioc->spi_data.pIocPg3)) {
int i;
for(i=0;i<hd->ioc->spi_data.pIocPg3->NumPhysDisks &&
raid_volume==0;i++)
if(device->id ==
if(device->id ==
hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID) {
raid_volume=1;
hd->ioc->spi_data.forceDv |=
......@@ -3193,7 +3088,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
}
}
}
return;
}
......@@ -3231,8 +3126,16 @@ mptscsih_slave_configure(struct scsi_device *device)
pTarget = hd->Targets[device->id];
if (pTarget == NULL) {
/* error case - don't know about this device */
scsi_adjust_queue_depth(device, 0, 1);
/* Driver doesn't know about this device.
* Kernel may generate a "Dummy Lun 0" which
* may become a real Lun if a
* "scsi add-single-device" command is executed
* while the driver is active (hot-plug a
* device). LSI Raid controllers need
* queue_depth set to DEV_HIGH for this reason.
*/
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
MPT_SCSI_CMD_PER_DEV_HIGH);
goto slave_configure_exit;
}
......@@ -3293,8 +3196,6 @@ copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSI
SCSIIORequest_t *pReq;
u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
int index;
char devFoo[96];
IO_Info_t thisIo;
/* Get target structure
*/
......@@ -3333,35 +3234,10 @@ copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSI
ioc->eventContext++;
}
}
/* Print an error report for the user.
*/
thisIo.cdbPtr = sc->cmnd;
thisIo.sensePtr = sc->sense_buffer;
thisIo.SCSIStatus = pScsiReply->SCSIStatus;
thisIo.DoDisplay = 1;
if (hd->is_multipath)
sprintf(devFoo, "%d:%d:%d",
hd->ioc->id,
pReq->TargetID,
pReq->LUN[1]);
else
sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->device->id, sc->device->lun);
thisIo.DevIDStr = devFoo;
/* fubar */
thisIo.dataPtr = NULL;
thisIo.inqPtr = NULL;
if (sc->device) {
thisIo.inqPtr = sc->device->vendor-8; /* FIXME!!! */
}
(void) mpt_ScsiHost_ErrorReport(&thisIo);
} else {
dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
hd->ioc->name));
}
return;
}
static u32
......@@ -3511,14 +3387,10 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
/* 2. Flush running commands
* Clean drop test code - if compiled
* Clean ScsiLookup (and associated memory)
* AND clean mytaskQ
*/
/* 2a. Drop Test Command.
*/
/* 2b. Reply to OS all known outstanding I/O commands.
*/
mptscsih_flush_running_cmds(hd);
......@@ -3529,7 +3401,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
*/
if (hd->cmdPtr) {
del_timer(&hd->timer);
mpt_free_msg_frame(ScsiScanDvCtx, ioc, hd->cmdPtr);
mpt_free_msg_frame(ioc, hd->cmdPtr);
}
/* 2d. If a task management has not completed,
......@@ -3537,7 +3409,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
*/
if (hd->tmPtr) {
del_timer(&hd->TMtimer);
mpt_free_msg_frame(ScsiTaskCtx, ioc, hd->tmPtr);
mpt_free_msg_frame(ioc, hd->tmPtr);
}
#ifdef MPTSCSIH_DBG_TIMEOUT
......@@ -3564,7 +3436,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* 2. Chain Buffer initialization
*/
mptscsih_initChainBuffers(hd, 0);
/* 3. tmPtr clear
*/
......@@ -3574,8 +3445,10 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* 4. Renegotiate to all devices, if SCSI
*/
if (hd->is_spi)
if (hd->is_spi) {
dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
}
/* 5. Enable new commands to be posted
*/
......@@ -3583,7 +3456,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
hd->resetPending = 0;
hd->numTMrequests = 0;
hd->tmState = TM_STATE_NONE;
/* 6. If there was an internal command,
......@@ -3625,7 +3497,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
MPT_SCSI_HOST *hd;
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
dprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event));
switch (event) {
......@@ -3757,394 +3629,6 @@ static struct scsi_host_template driver_template = {
.use_clustering = ENABLE_CLUSTERING,
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* 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;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_initTarget - Target, LUN alloc/free functionality.
......@@ -4167,48 +3651,33 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
{
int indexed_lun, lun_index;
VirtDevice *vdev;
ScsiCfgData *pSpi;
char data_56;
dprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
hd->ioc->name, bus_id, target_id, lun, hd));
/* Is LUN supported? If so, upper 3 bits will be 0
/* Is LUN supported? If so, upper 2 bits will be 0
* in first byte of inquiry data.
*/
if (data[0] & 0xe0)
return;
vdev = hd->Targets[target_id];
if ((vdev = hd->Targets[target_id]) == NULL) {
return;
}
lun_index = (lun >> 5); /* 32 luns per lun_index */
indexed_lun = (lun % 32);
vdev->luns[lun_index] |= (1 << indexed_lun);
vdev->raidVolume = 0;
if (hd->is_spi) {
if (hd->ioc->spi_data.isRaid & (1 << target_id)) {
vdev->raidVolume = 1;
ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
}
}
if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
if ( dlen > 8 ) {
memcpy (vdev->inq_data, data, 8);
} else {
memcpy (vdev->inq_data, data, dlen);
}
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
/* If LUN 0, tape and have not done DV, set the DV flag.
*/
if (hd->is_spi && (lun == 0) && (data[0] == SCSI_TYPE_TAPE)) {
ScsiCfgData *pSpi = &hd->ioc->spi_data;
if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
}
if ( (data[0] == SCSI_TYPE_PROC) &&
if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
/* Treat all Processors as SAF-TE if
* command line option is set */
vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
mptscsih_writeIOCPage4(hd, target_id, bus_id);
}else if ((data[0] == TYPE_PROCESSOR) &&
!(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
if ( dlen > 49 ) {
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
......@@ -4221,30 +3690,51 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
mptscsih_writeIOCPage4(hd, target_id, bus_id);
}
} else {
/* Treat all Processors as SAF-TE if
* command line option is set */
if ( hd->ioc->spi_data.Saf_Te ) {
vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
mptscsih_writeIOCPage4(hd, target_id, bus_id);
}
}
}
if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
if ( dlen > 8 ) {
memcpy (vdev->inq_data, data, 8);
} else {
memcpy (vdev->inq_data, data, dlen);
}
data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
if (dlen > 56) {
if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
/* Update the target capabilities
/* If have not done DV, set the DV flag.
*/
data_56 = data[56];
vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
pSpi = &hd->ioc->spi_data;
if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
}
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
if (dlen > 56) {
if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
/* Update the target capabilities
*/
data_56 = data[56];
vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
}
}
mptscsih_setTargetNegoParms(hd, vdev, data_56);
} else {
/* Initial Inquiry may not request enough data bytes to
* obtain byte 57. DV will; if target doesn't return
* at least 57 bytes, data[56] will be zero. */
if (dlen > 56) {
if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
/* Update the target capabilities
*/
data_56 = data[56];
vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
mptscsih_setTargetNegoParms(hd, vdev, data_56);
}
}
}
mptscsih_setTargetNegoParms(hd, vdev, data_56);
}
dprintk((KERN_INFO " target = %p\n", vdev));
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -4258,7 +3748,6 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
ScsiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id;
int nvram;
char canQ = 0;
VirtDevice *vdev;
int ii;
u8 width = MPT_NARROW;
......@@ -4267,14 +3756,6 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
u8 version, nfactor;
u8 noQas = 1;
if (!hd->is_spi) {
if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
if (target->inq_data[7] & 0x02)
target->tflags |= MPT_TARGET_FLAGS_Q_YES;
}
return;
}
target->negoFlags = pspi_data->noQas;
/* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
......@@ -4284,137 +3765,152 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
/* Set flags based on Inquiry data
*/
if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
version = target->inq_data[2] & 0x07;
if (version < 2) {
width = 0;
factor = MPT_ULTRA2;
offset = pspi_data->maxSyncOffset;
} else {
if (target->inq_data[7] & 0x20) {
width = 1;
}
version = target->inq_data[2] & 0x07;
if (version < 2) {
width = 0;
factor = MPT_ULTRA2;
offset = pspi_data->maxSyncOffset;
target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
} else {
if (target->inq_data[7] & 0x20) {
width = 1;
}
if (target->inq_data[7] & 0x10) {
/* bits 2 & 3 show Clocking support
*/
if (target->inq_data[7] & 0x10) {
factor = pspi_data->minSyncFactor;
if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
/* bits 2 & 3 show Clocking support */
if ((byte56 & 0x0C) == 0)
factor = MPT_ULTRA2;
else {
if ((byte56 & 0x03) == 0)
factor = MPT_ULTRA160;
else
else {
factor = MPT_ULTRA320;
}
offset = pspi_data->maxSyncOffset;
/* If RAID, never disable QAS
* else if non RAID, do not disable
* QAS if bit 1 is set
* bit 1 QAS support, non-raid only
* bit 0 IU support
*/
if ((target->raidVolume == 1) || (byte56 & 0x02)) {
noQas = 0;
if (byte56 & 0x02)
{
ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
noQas = 0;
}
if (target->inq_data[0] == TYPE_TAPE) {
if (byte56 & 0x01)
target->negoFlags |= MPT_TAPE_NEGO_IDP;
}
}
}
} else {
factor = MPT_ASYNC;
offset = 0;
ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
noQas = 0;
}
}
offset = pspi_data->maxSyncOffset;
if (target->inq_data[7] & 0x02) {
canQ = 1;
/* If RAID, never disable QAS
* else if non RAID, do not disable
* QAS if bit 1 is set
* bit 1 QAS support, non-raid only
* bit 0 IU support
*/
if (target->raidVolume == 1) {
noQas = 0;
}
} else {
factor = MPT_ASYNC;
offset = 0;
}
}
/* Update tflags based on NVRAM settings. (SCSI only)
*/
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
nvram = pspi_data->nvram[id];
nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
if ( (target->inq_data[7] & 0x02) == 0) {
target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
}
if (width)
width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
/* Update tflags based on NVRAM settings. (SCSI only)
*/
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
nvram = pspi_data->nvram[id];
nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
if (offset > 0) {
/* Ensure factor is set to the
* maximum of: adapter, nvram, inquiry
*/
if (nfactor) {
if (nfactor < pspi_data->minSyncFactor )
nfactor = pspi_data->minSyncFactor;
if (width)
width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
factor = max(factor, nfactor);
if (factor == MPT_ASYNC)
offset = 0;
} else {
if (offset > 0) {
/* Ensure factor is set to the
* maximum of: adapter, nvram, inquiry
*/
if (nfactor) {
if (nfactor < pspi_data->minSyncFactor )
nfactor = pspi_data->minSyncFactor;
factor = max(factor, nfactor);
if (factor == MPT_ASYNC)
offset = 0;
factor = MPT_ASYNC;
}
} else {
offset = 0;
factor = MPT_ASYNC;
}
}
/* Make sure data is consistent
*/
if ((!width) && (factor < MPT_ULTRA2)) {
factor = MPT_ULTRA2;
} else {
factor = MPT_ASYNC;
}
}
/* Save the data to the target structure.
*/
target->minSyncFactor = factor;
target->maxOffset = offset;
target->maxWidth = width;
if (canQ) {
target->tflags |= MPT_TARGET_FLAGS_Q_YES;
}
/* Make sure data is consistent
*/
if ((!width) && (factor < MPT_ULTRA2)) {
factor = MPT_ULTRA2;
}
target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
/* Save the data to the target structure.
*/
target->minSyncFactor = factor;
target->maxOffset = offset;
target->maxWidth = width;
/* Disable unused features.
*/
if (!width)
target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
if (!offset)
target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
/* Disable unused features.
*/
if (!width)
target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
/* GEM, processor WORKAROUND
*/
if (((target->inq_data[0] & 0x1F) == 0x03)
|| ((target->inq_data[0] & 0x1F) > 0x08)) {
target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
} else {
if (noQas && (pspi_data->noQas == 0)) {
pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
if (!offset)
target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
/* Disable QAS in a mixed configuration case
*/
if ( factor > MPT_ULTRA320 )
noQas = 0;
ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
for (ii = 0; ii < id; ii++) {
if ( (vdev = hd->Targets[ii]) ) {
vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
}
}
/* GEM, processor WORKAROUND
*/
if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
} else {
if (noQas && (pspi_data->noQas == 0)) {
pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
/* Disable QAS in a mixed configuration case
*/
ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
for (ii = 0; ii < id; ii++) {
if ( (vdev = hd->Targets[ii]) ) {
vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
}
}
}
/* Write SDP1 on this I/O to this target */
if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
} else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
}
}
return;
/* Write SDP1 on this I/O to this target */
if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
} else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -4428,14 +3924,18 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
{
u8 cmd;
ScsiCfgData *pSpi;
ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
return;
cmd = pReq->CDB[0];
if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
ScsiCfgData *pSpi = &hd->ioc->spi_data;
pSpi = &hd->ioc->spi_data;
if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
/* Set NEED_DV for all hidden disks
*/
......@@ -4501,6 +4001,8 @@ mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr,
*requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
*requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
if (flags & MPT_TAPE_NEGO_IDP)
*requestedPtr |= 0x08000000;
} else if (factor < MPT_ULTRA2) {
*requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
}
......@@ -4615,6 +4117,16 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
//negoFlags = MPT_TARGET_NO_NEGO_SYNC;
}
/* If id is not a raid volume, get the updated
* transmission settings from the target structure.
*/
if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
width = pTarget->maxWidth;
factor = pTarget->minSyncFactor;
offset = pTarget->maxOffset;
negoFlags = pTarget->negoFlags;
}
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* Force to async and narrow if DV has not been executed
* for this ID
......@@ -4626,21 +4138,13 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
}
#endif
/* If id is not a raid volume, get the updated
* transmission settings from the target structure.
*/
if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
width = pTarget->maxWidth;
factor = pTarget->minSyncFactor;
offset = pTarget->maxOffset;
negoFlags = pTarget->negoFlags;
}
if (flags & MPT_SCSICFG_BLK_NEGO)
negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
mptscsih_setDevicePage1Flags(width, factor, offset,
&requested, &configuration, negoFlags);
dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
target_id, width, factor, offset, negoFlags, requested, configuration));
/* Get a MF for this command.
*/
......@@ -4745,9 +4249,6 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
return -EAGAIN;
}
ddvprintk((MYIOC_s_INFO_FMT "writeIOCPage4 (mf=%p, id=%d)\n",
ioc->name, mf, target_id));
/* Set the request and the data pointers.
* Place data at end of MF.
*/
......@@ -4784,9 +4285,9 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
dsprintk((MYIOC_s_INFO_FMT
"writeIOCPage4: pgaddr 0x%x\n",
ioc->name, (target_id | (bus<<8))));
dinitprintk((MYIOC_s_INFO_FMT
"writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
......@@ -4913,13 +4414,15 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
} else {
SCSIIOReply_t *pReply;
u16 status;
u8 scsi_status;
pReply = (SCSIIOReply_t *) mr;
status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
scsi_status = pReply->SCSIStatus;
ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
status, pReply->SCSIState, pReply->SCSIStatus,
status, pReply->SCSIState, scsi_status,
le32_to_cpu(pReply->IOCLogInfo)));
switch(status) {
......@@ -4964,7 +4467,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/* save sense data in global structure
*/
completionCode = MPT_SCANDV_SENSE;
hd->pLocal->scsiStatus = pReply->SCSIStatus;
hd->pLocal->scsiStatus = scsi_status;
sense_data = ((u8 *)hd->ioc->sense_buf_pool +
(req_idx * MPT_SENSE_BUFFER_ALLOC));
......@@ -4975,7 +4478,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
sense_data));
} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
if (pReq->CDB[0] == CMD_Inquiry)
if (pReq->CDB[0] == INQUIRY)
completionCode = MPT_SCANDV_ISSUE_SENSE;
else
completionCode = MPT_SCANDV_DID_RESET;
......@@ -4985,11 +4488,8 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
completionCode = MPT_SCANDV_DID_RESET;
else {
/* If no error, this will be equivalent
* to MPT_SCANDV_GOOD
*/
completionCode = MPT_SCANDV_GOOD;
hd->pLocal->scsiStatus = pReply->SCSIStatus;
hd->pLocal->scsiStatus = scsi_status;
}
break;
......@@ -5016,7 +4516,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
*/
wakeup:
/* Free Chain buffers (will never chain) in scan or dv */
//mptscsih_freeChainBuffers(hd, req_idx);
//mptscsih_freeChainBuffers(ioc, req_idx);
/*
* Wake up the original calling thread
......@@ -5188,7 +4688,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
/* Set command specific information
*/
switch (cmd) {
case CMD_Inquiry:
case INQUIRY:
cmdLen = 6;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
......@@ -5196,13 +4696,13 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
cmdTimeout = 10;
break;
case CMD_TestUnitReady:
case TEST_UNIT_READY:
cmdLen = 6;
dir = MPI_SCSIIO_CONTROL_READ;
cmdTimeout = 10;
break;
case CMD_StartStopUnit:
case START_STOP:
cmdLen = 6;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
......@@ -5210,7 +4710,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
cmdTimeout = 15;
break;
case CMD_RequestSense:
case REQUEST_SENSE:
cmdLen = 6;
CDB[0] = cmd;
CDB[4] = io->size;
......@@ -5218,7 +4718,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
cmdTimeout = 10;
break;
case CMD_ReadBuffer:
case READ_BUFFER:
cmdLen = 10;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
......@@ -5237,7 +4737,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
cmdTimeout = 10;
break;
case CMD_WriteBuffer:
case WRITE_BUFFER:
cmdLen = 10;
dir = MPI_SCSIIO_CONTROL_WRITE;
CDB[0] = cmd;
......@@ -5252,21 +4752,21 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
cmdTimeout = 10;
break;
case CMD_Reserve6:
case RESERVE:
cmdLen = 6;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
cmdTimeout = 10;
break;
case CMD_Release6:
case RELEASE:
cmdLen = 6;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
cmdTimeout = 10;
break;
case CMD_SynchronizeCache:
case SYNCHRONIZE_CACHE:
cmdLen = 10;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
......@@ -5322,7 +4822,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
else
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
if (cmd == CMD_RequestSense) {
if (cmd == REQUEST_SENSE) {
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
hd->ioc->name, cmd));
......@@ -5430,7 +4930,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
/* Following parameters will not change
* in this routine.
*/
iocmd.cmd = CMD_SynchronizeCache;
iocmd.cmd = SYNCHRONIZE_CACHE;
iocmd.flags = 0;
iocmd.physDiskNum = -1;
iocmd.data = NULL;
......@@ -5500,6 +5000,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
/* Force to async, narrow */
mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
&configuration, flags);
dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
"offset=0 negoFlags=%x request=%x config=%x\n",
id, flags, requested, configuration));
pcfg1Data->RequestedParameters = le32_to_cpu(requested);
pcfg1Data->Reserved = 0;
pcfg1Data->Configuration = le32_to_cpu(configuration);
......@@ -5732,11 +5235,14 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
if ((pTarget != NULL) && (!pTarget->raidVolume)) {
if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
pTarget->negoFlags |= hd->ioc->spi_data.noQas;
dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
mptscsih_writeSDP1(hd, 0, ii, 0);
}
} else {
if (mptscsih_is_phys_disk(hd->ioc, ii) == 1)
if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
}
}
}
return;
......@@ -5815,7 +5321,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
lun = 0;
bus = (u8) bus_number;
ddvtprintk((MYIOC_s_NOTE_FMT
"DV started: bus=%d, id %d dv @ %p\n",
"DV started: bus=%d, id=%d dv @ %p\n",
ioc->name, bus, id, &dv));
/* Prep DV structure
......@@ -5829,8 +5335,6 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
*/
dv.cmd = MPT_GET_NVRAM_VALS;
mptscsih_dv_parms(hd, &dv, NULL);
if ((!dv.max.width) && (!dv.max.offset))
return 0;
/* Prep SCSI IO structure
*/
......@@ -5842,15 +5346,6 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
iocmd.rsvd = iocmd.rsvd2 = 0;
pTarget = hd->Targets[id];
if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
/* Another GEM workaround. Check peripheral device type,
* if PROCESSOR, quit DV.
*/
if (((pTarget->inq_data[0] & 0x1F) == 0x03) || ((pTarget->inq_data[0] & 0x1F) > 0x08)) {
pTarget->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
return 0;
}
}
/* Use tagged commands if possible.
*/
......@@ -5950,7 +5445,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Finish iocmd inititialization - hidden or visible disk? */
if (ioc->spi_data.pIocPg3) {
/* Searc IOC page 3 for matching id
/* Search IOC page 3 for matching id
*/
Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
......@@ -5992,7 +5487,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
*/
hd->pLocal = NULL;
readPage0 = 0;
sz = SCSI_STD_INQUIRY_BYTES;
sz = SCSI_MAX_INQUIRY_BYTES;
rc = MPT_SCANDV_GOOD;
while (1) {
ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
......@@ -6017,7 +5512,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
(hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
iocmd.cmd = CMD_RequestSense;
iocmd.cmd = REQUEST_SENSE;
iocmd.data_dma = buf1_dma;
iocmd.data = pbuf1;
iocmd.size = 0x12;
......@@ -6037,10 +5532,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
goto target_done;
}
iocmd.cmd = CMD_Inquiry;
iocmd.cmd = INQUIRY;
iocmd.data_dma = buf1_dma;
iocmd.data = pbuf1;
iocmd.size = sz;
memset(pbuf1, 0x00, sz);
if (mptscsih_do_cmd(hd, &iocmd) < 0)
goto target_done;
else {
......@@ -6048,7 +5544,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
goto target_done;
rc = hd->pLocal->completion;
if (rc == MPT_SCANDV_GOOD) {
if (hd->pLocal->scsiStatus == STS_BUSY) {
if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
retcode = 1;
else
......@@ -6078,7 +5574,17 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Another GEM workaround. Check peripheral device type,
* if PROCESSOR, quit DV.
*/
if (((pbuf1[0] & 0x1F) == 0x03) || ((pbuf1[0] & 0x1F) > 0x08))
if (inq0 == TYPE_PROCESSOR) {
mptscsih_initTarget(hd,
bus,
id,
lun,
pbuf1,
sz);
goto target_done;
}
if (inq0 > 0x08)
goto target_done;
if (mptscsih_do_cmd(hd, &iocmd) < 0)
......@@ -6102,6 +5608,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if ((pbuf1[56] & 0x02) == 0) {
pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
ddvprintk((MYIOC_s_NOTE_FMT
"DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
ioc->name, id, pbuf1[56]));
}
}
}
......@@ -6118,10 +5627,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if ((!dv.now.width) && (!dv.now.offset))
goto target_done;
iocmd.cmd = CMD_Inquiry;
iocmd.cmd = INQUIRY;
iocmd.data_dma = buf2_dma;
iocmd.data = pbuf2;
iocmd.size = sz;
memset(pbuf2, 0x00, sz);
if (mptscsih_do_cmd(hd, &iocmd) < 0)
goto target_done;
else if (hd->pLocal == NULL)
......@@ -6174,14 +5684,26 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if (memcmp(pbuf1, pbuf2, sz) != 0) {
if (!firstPass)
doFallback = 1;
} else
} else {
ddvprintk((MYIOC_s_NOTE_FMT
"DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
mptscsih_initTarget(hd,
bus,
id,
lun,
pbuf1,
sz);
break; /* test complete */
}
}
} else if (rc == MPT_SCANDV_ISSUE_SENSE)
doFallback = 1; /* set fallback flag */
else if ((rc == MPT_SCANDV_DID_RESET) || (rc == MPT_SCANDV_SENSE))
else if ((rc == MPT_SCANDV_DID_RESET) ||
(rc == MPT_SCANDV_SENSE) ||
(rc == MPT_SCANDV_FALLBACK))
doFallback = 1; /* set fallback flag */
else
goto target_done;
......@@ -6213,7 +5735,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
iocmd.cmd = CMD_TestUnitReady;
iocmd.cmd = TEST_UNIT_READY;
iocmd.data_dma = -1;
iocmd.data = NULL;
iocmd.size = 0;
......@@ -6236,14 +5758,14 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
ioc->name, skey, asc, ascq));
if (skey == SK_UNIT_ATTENTION)
if (skey == UNIT_ATTENTION)
notDone++; /* repeat */
else if ((skey == SK_NOT_READY) &&
else if ((skey == NOT_READY) &&
(asc == 0x04)&&(ascq == 0x01)) {
/* wait then repeat */
mdelay (2000);
notDone++;
} else if ((skey == SK_NOT_READY) && (asc == 0x3A)) {
} else if ((skey == NOT_READY) && (asc == 0x3A)) {
/* no medium, try read test anyway */
notDone = 0;
} else {
......@@ -6257,7 +5779,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
goto target_done;
}
iocmd.cmd = CMD_ReadBuffer;
iocmd.cmd = READ_BUFFER;
iocmd.data_dma = buf1_dma;
iocmd.data = pbuf1;
iocmd.size = 4;
......@@ -6305,11 +5827,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
ddvprintk((MYIOC_s_INFO_FMT
"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
ioc->name, skey, asc, ascq));
if (skey == SK_ILLEGAL_REQUEST) {
if (skey == ILLEGAL_REQUEST) {
notDone = 0;
} else if (skey == SK_UNIT_ATTENTION) {
} else if (skey == UNIT_ATTENTION) {
notDone++; /* repeat */
} else if ((skey == SK_NOT_READY) &&
} else if ((skey == NOT_READY) &&
(asc == 0x04)&&(ascq == 0x01)) {
/* wait then repeat */
mdelay (2000);
......@@ -6364,14 +5886,14 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
for (patt = 0; patt < 4; patt++) {
ddvprintk(("Pattern %d\n", patt));
if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
iocmd.cmd = CMD_TestUnitReady;
iocmd.cmd = TEST_UNIT_READY;
iocmd.data_dma = -1;
iocmd.data = NULL;
iocmd.size = 0;
if (mptscsih_do_cmd(hd, &iocmd) < 0)
goto target_done;
iocmd.cmd = CMD_Release6;
iocmd.cmd = RELEASE;
iocmd.data_dma = -1;
iocmd.data = NULL;
iocmd.size = 0;
......@@ -6393,7 +5915,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
repeat = 5;
while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
iocmd.cmd = CMD_Reserve6;
iocmd.cmd = RESERVE;
iocmd.data_dma = -1;
iocmd.data = NULL;
iocmd.size = 0;
......@@ -6416,7 +5938,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
skey, asc, ascq));
if ((skey == SK_NOT_READY) && (asc == 0x04)&&
if ((skey == NOT_READY) && (asc == 0x04)&&
(ascq == 0x01)) {
/* wait then repeat */
mdelay (2000);
......@@ -6435,7 +5957,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
mptscsih_fillbuf(pbuf1, sz, patt, 1);
iocmd.cmd = CMD_WriteBuffer;
iocmd.cmd = WRITE_BUFFER;
iocmd.data_dma = buf1_dma;
iocmd.data = pbuf1;
iocmd.size = sz;
......@@ -6476,10 +5998,10 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
ddvprintk((MYIOC_s_INFO_FMT
"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
hd->pLocal->sense[12], hd->pLocal->sense[13]));
if (skey == SK_UNIT_ATTENTION) {
if (skey == UNIT_ATTENTION) {
patt = -1;
continue;
} else if (skey == SK_ILLEGAL_REQUEST) {
} else if (skey == ILLEGAL_REQUEST) {
if (iocmd.flags & MPT_ICFLAG_ECHO) {
if (dataBufSize >= bufsize) {
iocmd.flags &= ~MPT_ICFLAG_ECHO;
......@@ -6497,7 +6019,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
}
iocmd.cmd = CMD_ReadBuffer;
iocmd.cmd = READ_BUFFER;
iocmd.data_dma = buf2_dma;
iocmd.data = pbuf2;
iocmd.size = sz;
......@@ -6572,7 +6094,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
ddvprintk((MYIOC_s_INFO_FMT
"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
hd->pLocal->sense[12], hd->pLocal->sense[13]));
if (skey == SK_UNIT_ATTENTION) {
if (skey == UNIT_ATTENTION) {
patt = -1;
continue;
}
......@@ -6588,7 +6110,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
target_done:
if (iocmd.flags & MPT_ICFLAG_RESERVED) {
iocmd.cmd = CMD_Release6;
iocmd.cmd = RELEASE;
iocmd.data_dma = -1;
iocmd.data = NULL;
iocmd.size = 0;
......@@ -6610,8 +6132,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if ((cfg.hdr != NULL) && (retcode == 0)){
/* If disk, not U320, disable QAS
*/
if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320))
if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
ddvprintk((MYIOC_s_NOTE_FMT
"noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
}
dv.cmd = MPT_SAVE;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
......@@ -6640,8 +6165,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if (pDvBuf)
pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
ddvtprintk((MYIOC_s_INFO_FMT "DV Done.\n",
ioc->name));
ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
ioc->name, id));
return retcode;
}
......@@ -6721,8 +6246,8 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
dv->max.offset = offset;
dv->max.factor = factor;
dv->max.flags = negoFlags;
ddvprintk((" width %d, factor %x, offset %x flags %x\n",
width, factor, offset, negoFlags));
ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
id, width, factor, offset, negoFlags));
break;
case MPT_UPDATE_MAX:
......@@ -6740,8 +6265,8 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
dv->now.width = dv->max.width;
dv->now.offset = dv->max.offset;
dv->now.factor = dv->max.factor;
ddvprintk(("width %d, factor %x, offset %x, flags %x\n",
dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
break;
case MPT_SET_MAX:
......@@ -6757,14 +6282,15 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
if (pPage1) {
mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
dv->now.offset, &val, &configuration, dv->now.flags);
dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
pPage1->RequestedParameters = le32_to_cpu(val);
pPage1->Reserved = 0;
pPage1->Configuration = le32_to_cpu(configuration);
}
ddvprintk(("width %d, factor %x, offset %x request %x, config %x\n",
dv->now.width, dv->now.factor, dv->now.offset, val, configuration));
ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
break;
case MPT_SET_MIN:
......@@ -6781,12 +6307,14 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
if (pPage1) {
mptscsih_setDevicePage1Flags (width, factor,
offset, &val, &configuration, negoFlags);
dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
id, width, factor, offset, negoFlags, val, configuration));
pPage1->RequestedParameters = le32_to_cpu(val);
pPage1->Reserved = 0;
pPage1->Configuration = le32_to_cpu(configuration);
}
ddvprintk(("width %d, factor %x, offset %x request %x config %x\n",
width, factor, offset, val, configuration));
ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
id, width, factor, offset, val, configuration, negoFlags));
break;
case MPT_FALLBACK:
......@@ -6846,6 +6374,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
factor = MPT_ASYNC;
}
dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
dv->now.width = width;
dv->now.offset = offset;
......@@ -6856,21 +6385,23 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
if (pPage1) {
mptscsih_setDevicePage1Flags (width, factor, offset, &val,
&configuration, dv->now.flags);
dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
id, width, offset, factor, dv->now.flags, val, configuration));
pPage1->RequestedParameters = le32_to_cpu(val);
pPage1->Reserved = 0;
pPage1->Configuration = le32_to_cpu(configuration);
}
ddvprintk(("Finish: offset %d, factor %x, width %d, request %x config %x\n",
dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
break;
case MPT_SAVE:
ddvprintk((MYIOC_s_NOTE_FMT
"Saving to Target structure: ", hd->ioc->name));
ddvprintk(("offset %d, factor %x, width %d \n",
dv->now.offset, dv->now.factor, dv->now.width));
ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
/* Save these values to target structures
* or overwrite nvram (phys disks only).
......
/*
* linux/drivers/message/fusion/scsi3.h
* SCSI-3 definitions and macros.
* (Ultimately) SCSI-3 definitions; for now, inheriting
* SCSI-2 definitions.
*
* Copyright (c) 1996-2004 Steven J. Ralston
* Written By: Steven J. Ralston (19960517)
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
*
* $Id: scsi3.h,v 1.9 2002/02/27 18:45:02 sralston Exp $
*/
#ifndef SCSI3_H_INCLUDED
#define SCSI3_H_INCLUDED
/***************************************************************************/
/****************************************************************************
*
* Includes
*/
#ifdef __KERNEL__
#include <linux/types.h>
#else
#ifndef U_STUFF_DEFINED
#define U_STUFF_DEFINED
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#endif
#endif
/****************************************************************************
*
* Defines
*/
/*
* SCSI Commands
*/
#define CMD_TestUnitReady 0x00
#define CMD_RezeroUnit 0x01 /* direct-access devices */
#define CMD_Rewind 0x01 /* sequential-access devices */
#define CMD_RequestSense 0x03
#define CMD_FormatUnit 0x04
#define CMD_ReassignBlock 0x07
#define CMD_Read6 0x08
#define CMD_Write6 0x0A
#define CMD_WriteFilemark 0x10
#define CMD_Space 0x11
#define CMD_Inquiry 0x12
#define CMD_ModeSelect6 0x15
#define CMD_ModeSense6 0x1A
#define CMD_Reserve6 0x16
#define CMD_Release6 0x17
#define CMD_Erase 0x19
#define CMD_StartStopUnit 0x1b /* direct-access devices */
#define CMD_LoadUnload 0x1b /* sequential-access devices */
#define CMD_ReceiveDiagnostic 0x1C
#define CMD_SendDiagnostic 0x1D
#define CMD_ReadCapacity 0x25
#define CMD_Read10 0x28
#define CMD_Write10 0x2A
#define CMD_WriteVerify 0x2E
#define CMD_Verify 0x2F
#define CMD_SynchronizeCache 0x35
#define CMD_ReadDefectData 0x37
#define CMD_WriteBuffer 0x3B
#define CMD_ReadBuffer 0x3C
#define CMD_ReadLong 0x3E
#define CMD_LogSelect 0x4C
#define CMD_LogSense 0x4D
#define CMD_ModeSelect10 0x55
#define CMD_Reserve10 0x56
#define CMD_Release10 0x57
#define CMD_ModeSense10 0x5A
#define CMD_PersistReserveIn 0x5E
#define CMD_PersistReserveOut 0x5F
#define CMD_ReportLuns 0xA0
/*
* Control byte field
*/
#define CONTROL_BYTE_NACA_BIT 0x04
#define CONTROL_BYTE_Flag_BIT 0x02
#define CONTROL_BYTE_Link_BIT 0x01
/*
* SCSI Messages
*/
#define MSG_COMPLETE 0x00
#define MSG_EXTENDED 0x01
#define MSG_SAVE_POINTERS 0x02
#define MSG_RESTORE_POINTERS 0x03
#define MSG_DISCONNECT 0x04
#define MSG_IDERROR 0x05
#define MSG_ABORT 0x06
#define MSG_REJECT 0x07
#define MSG_NOP 0x08
#define MSG_PARITY_ERROR 0x09
#define MSG_LINKED_CMD_COMPLETE 0x0a
#define MSG_LCMD_COMPLETE_W_FLG 0x0b
#define MSG_BUS_DEVICE_RESET 0x0c
#define MSG_ABORT_TAG 0x0d
#define MSG_CLEAR_QUEUE 0x0e
#define MSG_INITIATE_RECOVERY 0x0f
#define MSG_RELEASE_RECOVRY 0x10
#define MSG_TERMINATE_IO 0x11
#define MSG_SIMPLE_QUEUE 0x20
#define MSG_HEAD_OF_QUEUE 0x21
#define MSG_ORDERED_QUEUE 0x22
#define MSG_IGNORE_WIDE_RESIDUE 0x23
#define MSG_IDENTIFY 0x80
#define MSG_IDENTIFY_W_DISC 0xc0
/*
* SCSI Phases
*/
#define PHS_DATA_OUT 0x00
#define PHS_DATA_IN 0x01
#define PHS_COMMAND 0x02
#define PHS_STATUS 0x03
#define PHS_MSG_OUT 0x06
#define PHS_MSG_IN 0x07
/*
* Statuses
*/
#define STS_GOOD 0x00
#define STS_CHECK_CONDITION 0x02
#define STS_CONDITION_MET 0x04
#define STS_BUSY 0x08
#define STS_INTERMEDIATE 0x10
#define STS_INTERMEDIATE_CONDITION_MET 0x14
#define STS_RESERVATION_CONFLICT 0x18
#define STS_COMMAND_TERMINATED 0x22
#define STS_TASK_SET_FULL 0x28
#define STS_QUEUE_FULL 0x28
#define STS_ACA_ACTIVE 0x30
#define STS_VALID_MASK 0x3e
#define SCSI_STATUS(x) ((x) & STS_VALID_MASK)
/*
* SCSI QTag Types
*/
#define QTAG_SIMPLE 0x20
#define QTAG_HEAD_OF_Q 0x21
#define QTAG_ORDERED 0x22
/*
* SCSI Sense Key Definitons
*/
#define SK_NO_SENSE 0x00
#define SK_RECOVERED_ERROR 0x01
#define SK_NOT_READY 0x02
#define SK_MEDIUM_ERROR 0x03
#define SK_HARDWARE_ERROR 0x04
#define SK_ILLEGAL_REQUEST 0x05
#define SK_UNIT_ATTENTION 0x06
#define SK_DATA_PROTECT 0x07
#define SK_BLANK_CHECK 0x08
#define SK_VENDOR_SPECIFIC 0x09
#define SK_COPY_ABORTED 0x0a
#define SK_ABORTED_COMMAND 0x0b
#define SK_EQUAL 0x0c
#define SK_VOLUME_OVERFLOW 0x0d
#define SK_MISCOMPARE 0x0e
#define SK_RESERVED 0x0f
#define SCSI_MAX_INQUIRY_BYTES 96
#define SCSI_STD_INQUIRY_BYTES 36
#undef USE_SCSI_COMPLETE_INQDATA
/*
* Structure definition for SCSI Inquiry Data
*
* NOTE: The following structure is 96 bytes in size
* iff USE_SCSI_COMPLETE_INQDATA IS defined above (i.e. w/ "#define").
* If USE_SCSI_COMPLETE_INQDATA is NOT defined above (i.e. w/ "#undef")
* then the following structure is only 36 bytes in size.
* THE CHOICE IS YOURS!
*/
typedef struct SCSI_Inquiry_Data
{
#ifdef USE_SCSI_COMPLETE_INQDATA
u8 InqByte[SCSI_MAX_INQUIRY_BYTES];
#else
u8 InqByte[SCSI_STD_INQUIRY_BYTES];
#endif
/*
* the following structure works only for little-endian (Intel,
* LSB first (1234) byte order) systems with 4-byte ints.
*
u32 Periph_Device_Type : 5,
Periph_Qualifier : 3,
Device_Type_Modifier : 7,
Removable_Media : 1,
ANSI_Version : 3,
ECMA_Version : 3,
ISO_Version : 2,
Response_Data_Format : 4,
reserved_0 : 3,
AERC : 1 ;
u32 Additional_Length : 8,
reserved_1 :16,
SftReset : 1,
CmdQue : 1,
reserved_2 : 1,
Linked : 1,
Sync : 1,
WBus16 : 1,
WBus32 : 1,
RelAdr : 1 ;
u8 Vendor_ID[8];
u8 Product_ID[16];
u8 Revision_Level [4];
#ifdef USE_SCSI_COMPLETE_INQDATA
u8 Vendor_Specific[20];
u8 reserved_3[40];
#endif
*
*/
} SCSI_Inquiry_Data_t;
#define INQ_PERIPHINFO_BYTE 0
#define INQ_Periph_Qualifier_MASK 0xe0
#define INQ_Periph_Device_Type_MASK 0x1f
#define INQ_Peripheral_Qualifier(inqp) \
(int)((*((u8*)(inqp)+INQ_PERIPHINFO_BYTE) & INQ_Periph_Qualifier_MASK) >> 5)
#define INQ_Peripheral_Device_Type(inqp) \
(int)(*((u8*)(inqp)+INQ_PERIPHINFO_BYTE) & INQ_Periph_Device_Type_MASK)
#define INQ_DEVTYPEMOD_BYTE 1
#define INQ_RMB_BIT 0x80
#define INQ_Device_Type_Modifier_MASK 0x7f
#define INQ_Removable_Medium(inqp) \
(int)(*((u8*)(inqp)+INQ_DEVTYPEMOD_BYTE) & INQ_RMB_BIT)
#define INQ_Device_Type_Modifier(inqp) \
(int)(*((u8*)(inqp)+INQ_DEVTYPEMOD_BYTE) & INQ_Device_Type_Modifier_MASK)
#define INQ_VERSIONINFO_BYTE 2
#define INQ_ISO_Version_MASK 0xc0
#define INQ_ECMA_Version_MASK 0x38
#define INQ_ANSI_Version_MASK 0x07
#define INQ_ISO_Version(inqp) \
(int)(*((u8*)(inqp)+INQ_VERSIONINFO_BYTE) & INQ_ISO_Version_MASK)
#define INQ_ECMA_Version(inqp) \
(int)(*((u8*)(inqp)+INQ_VERSIONINFO_BYTE) & INQ_ECMA_Version_MASK)
#define INQ_ANSI_Version(inqp) \
(int)(*((u8*)(inqp)+INQ_VERSIONINFO_BYTE) & INQ_ANSI_Version_MASK)
#define INQ_BYTE3 3
#define INQ_AERC_BIT 0x80
#define INQ_TrmTsk_BIT 0x40
#define INQ_NormACA_BIT 0x20
#define INQ_RDF_MASK 0x0F
#define INQ_AER_Capable(inqp) \
(int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_AERC_BIT)
#define INQ_TrmTsk(inqp) \
(int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_TrmTsk_BIT)
#define INQ_NormACA(inqp) \
(int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_NormACA_BIT)
#define INQ_Response_Data_Format(inqp) \
(int)(*((u8*)(inqp)+INQ_BYTE3) & INQ_RDF_MASK)
#define INQ_CAPABILITY_BYTE 7
#define INQ_RelAdr_BIT 0x80
#define INQ_WBus32_BIT 0x40
#define INQ_WBus16_BIT 0x20
#define INQ_Sync_BIT 0x10
#define INQ_Linked_BIT 0x08
/* INQ_Reserved BIT 0x40 */
#define INQ_CmdQue_BIT 0x02
#define INQ_SftRe_BIT 0x01
#define IS_RelAdr_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_RelAdr_BIT)
#define IS_WBus32_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_WBus32_BIT)
#define IS_WBus16_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_WBus16_BIT)
#define IS_Sync_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_Sync_BIT)
#define IS_Linked_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_Linked_BIT)
#define IS_CmdQue_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_CmdQue_BIT)
#define IS_SftRe_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_SftRe_BIT)
#define INQ_Width_BITS \
(INQ_WBus32_BIT | INQ_WBus16_BIT)
#define IS_Wide_DEV(inqp) \
(int)(*((u8*)(inqp)+INQ_CAPABILITY_BYTE) & INQ_Width_BITS)
/*
* SCSI peripheral device types
*/
#define SCSI_TYPE_DAD 0x00 /* Direct Access Device */
#define SCSI_TYPE_SAD 0x01 /* Sequential Access Device */
#define SCSI_TYPE_TAPE SCSI_TYPE_SAD
#define SCSI_TYPE_PRT 0x02 /* Printer */
#define SCSI_TYPE_PROC 0x03 /* Processor */
#define SCSI_TYPE_WORM 0x04
#define SCSI_TYPE_CDROM 0x05
#define SCSI_TYPE_SCAN 0x06 /* Scanner */
#define SCSI_TYPE_OPTICAL 0x07 /* Magneto/Optical */
#define SCSI_TYPE_CHANGER 0x08
#define SCSI_TYPE_COMM 0x09 /* Communications device */
#define SCSI_TYPE_UNKNOWN 0x1f
#define SCSI_TYPE_UNCONFIGURED_LUN 0x7f
#define SCSI_TYPE_MAX_KNOWN SCSI_TYPE_COMM
/*
* Peripheral Qualifiers
*/
#define DEVICE_PRESENT 0x00
#define LUN_NOT_PRESENT 0x01
#define LUN_NOT_SUPPORTED 0x03
/*
* ANSI Versions
*/
#ifndef SCSI_1
#define SCSI_1 0x01
#endif
#ifndef SCSI_2
#define SCSI_2 0x02
#endif
#ifndef SCSI_3
#define SCSI_3 0x03
#endif
#define SCSI_MAX_SENSE_BYTES 255
#define SCSI_STD_SENSE_BYTES 18
#define SCSI_PAD_SENSE_BYTES (SCSI_MAX_SENSE_BYTES - SCSI_STD_SENSE_BYTES)
#undef USE_SCSI_COMPLETE_SENSE
/*
* Structure definition for SCSI Sense Data
*
* NOTE: The following structure is 255 bytes in size
* iiff USE_SCSI_COMPLETE_SENSE IS defined above (i.e. w/ "#define").
* If USE_SCSI_COMPLETE_SENSE is NOT defined above (i.e. w/ "#undef")
* then the following structure is only 19 bytes in size.
* THE CHOICE IS YOURS!
*
*/
typedef struct SCSI_Sense_Data
{
#ifdef USE_SCSI_COMPLETE_SENSE
u8 SenseByte[SCSI_MAX_SENSE_BYTES];
#else
u8 SenseByte[SCSI_STD_SENSE_BYTES];
#endif
/*
* the following structure works only for little-endian (Intel,
* LSB first (1234) byte order) systems with 4-byte ints.
*
u8 Error_Code :4, // 0x00
Error_Class :3,
Valid :1
;
u8 Segment_Number // 0x01
;
u8 Sense_Key :4, // 0x02
Reserved :1,
Incorrect_Length_Indicator:1,
End_Of_Media :1,
Filemark :1
;
u8 Information_MSB; // 0x03
u8 Information_Byte2; // 0x04
u8 Information_Byte1; // 0x05
u8 Information_LSB; // 0x06
u8 Additional_Length; // 0x07
u32 Command_Specific_Information; // 0x08 - 0x0b
u8 Additional_Sense_Code; // 0x0c
u8 Additional_Sense_Code_Qualifier; // 0x0d
u8 Field_Replaceable_Unit_Code; // 0x0e
u8 Illegal_Req_Bit_Pointer :3, // 0x0f
Illegal_Req_Bit_Valid :1,
Illegal_Req_Reserved :2,
Illegal_Req_Cmd_Data :1,
Sense_Key_Specific_Valid :1
;
u16 Sense_Key_Specific_Data; // 0x10 - 0x11
#ifdef USE_SCSI_COMPLETE_SENSE
u8 Additional_Sense_Data[SCSI_PAD_SENSE_BYTES];
#else
u8 Additional_Sense_Data[1];
#endif
*
*/
} SCSI_Sense_Data_t;
#define SD_ERRCODE_BYTE 0
#define SD_Valid_BIT 0x80
#define SD_Error_Code_MASK 0x7f
#define SD_Valid(sdp) \
(int)(*((u8*)(sdp)+SD_ERRCODE_BYTE) & SD_Valid_BIT)
#define SD_Error_Code(sdp) \
(int)(*((u8*)(sdp)+SD_ERRCODE_BYTE) & SD_Error_Code_MASK)
#define SD_SEGNUM_BYTE 1
#define SD_Segment_Number(sdp) (int)(*((u8*)(sdp)+SD_SEGNUM_BYTE))
#define SD_SENSEKEY_BYTE 2
#define SD_Filemark_BIT 0x80
#define SD_EOM_BIT 0x40
#define SD_ILI_BIT 0x20
#define SD_Sense_Key_MASK 0x0f
#define SD_Filemark(sdp) \
(int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_Filemark_BIT)
#define SD_EOM(sdp) \
(int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_EOM_BIT)
#define SD_ILI(sdp) \
(int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_ILI_BIT)
#define SD_Sense_Key(sdp) \
(int)(*((u8*)(sdp)+SD_SENSEKEY_BYTE) & SD_Sense_Key_MASK)
#define SD_INFO3_BYTE 3
#define SD_INFO2_BYTE 4
#define SD_INFO1_BYTE 5
#define SD_INFO0_BYTE 6
#define SD_Information3(sdp) (int)(*((u8*)(sdp)+SD_INFO3_BYTE))
#define SD_Information2(sdp) (int)(*((u8*)(sdp)+SD_INFO2_BYTE))
#define SD_Information1(sdp) (int)(*((u8*)(sdp)+SD_INFO1_BYTE))
#define SD_Information0(sdp) (int)(*((u8*)(sdp)+SD_INFO0_BYTE))
#define SD_ADDL_LEN_BYTE 7
#define SD_Additional_Sense_Length(sdp) \
(int)(*((u8*)(sdp)+SD_ADDL_LEN_BYTE))
#define SD_Addl_Sense_Len SD_Additional_Sense_Length
#define SD_CMD_SPECIFIC3_BYTE 8
#define SD_CMD_SPECIFIC2_BYTE 9
#define SD_CMD_SPECIFIC1_BYTE 10
#define SD_CMD_SPECIFIC0_BYTE 11
#define SD_Cmd_Specific_Info3(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC3_BYTE))
#define SD_Cmd_Specific_Info2(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC2_BYTE))
#define SD_Cmd_Specific_Info1(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC1_BYTE))
#define SD_Cmd_Specific_Info0(sdp) (int)(*((u8*)(sdp)+SD_CMD_SPECIFIC0_BYTE))
#define SD_ADDL_SENSE_CODE_BYTE 12
#define SD_Additional_Sense_Code(sdp) \
(int)(*((u8*)(sdp)+SD_ADDL_SENSE_CODE_BYTE))
#define SD_Addl_Sense_Code SD_Additional_Sense_Code
#define SD_ASC SD_Additional_Sense_Code
#define SD_ADDL_SENSE_CODE_QUAL_BYTE 13
#define SD_Additional_Sense_Code_Qualifier(sdp) \
(int)(*((u8*)(sdp)+SD_ADDL_SENSE_CODE_QUAL_BYTE))
#define SD_Addl_Sense_Code_Qual SD_Additional_Sense_Code_Qualifier
#define SD_ASCQ SD_Additional_Sense_Code_Qualifier
#define SD_FIELD_REPL_UNIT_CODE_BYTE 14
#define SD_Field_Replaceable_Unit_Code(sdp) \
(int)(*((u8*)(sdp)+SD_FIELD_REPL_UNIT_CODE_BYTE))
#define SD_Field_Repl_Unit_Code SD_Field_Replaceable_Unit_Code
#define SD_FRUC SD_Field_Replaceable_Unit_Code
#define SD_FRU SD_Field_Replaceable_Unit_Code
/*
* Sense-Key Specific offsets and macros.
*/
#define SD_SKS2_BYTE 15
#define SD_SKS_Valid_BIT 0x80
#define SD_SKS_Cmd_Data_BIT 0x40
#define SD_SKS_Bit_Ptr_Valid_BIT 0x08
#define SD_SKS_Bit_Ptr_MASK 0x07
#define SD_SKS1_BYTE 16
#define SD_SKS0_BYTE 17
#define SD_Sense_Key_Specific_Valid(sdp) \
(int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Valid_BIT)
#define SD_SKS_Valid SD_Sense_Key_Specific_Valid
#define SD_SKS_CDB_Error(sdp) \
(int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Cmd_Data_BIT)
#define SD_Was_Illegal_Request SD_SKS_CDB_Error
#define SD_SKS_Bit_Pointer_Valid(sdp) \
(int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Bit_Ptr_Valid_BIT)
#define SD_SKS_Bit_Pointer(sdp) \
(int)(*((u8*)(sdp)+SD_SKS2_BYTE) & SD_SKS_Bit_Ptr_MASK)
#define SD_Field_Pointer(sdp) \
(int)( ((u16)(*((u8*)(sdp)+SD_SKS1_BYTE)) << 8) \
+ *((u8*)(sdp)+SD_SKS0_BYTE) )
#define SD_Bad_Byte SD_Field_Pointer
#define SD_Actual_Retry_Count SD_Field_Pointer
#define SD_Progress_Indication SD_Field_Pointer
/*
* Mode Sense Write Protect Mask
*/
#define WRITE_PROTECT_MASK 0X80
/*
* Medium Type Codes
*/
#define OPTICAL_DEFAULT 0x00
#define OPTICAL_READ_ONLY_MEDIUM 0x01
#define OPTICAL_WRITE_ONCE_MEDIUM 0x02
#define OPTICAL_READ_WRITABLE_MEDIUM 0x03
#define OPTICAL_RO_OR_WO_MEDIUM 0x04
#define OPTICAL_RO_OR_RW_MEDIUM 0x05
#define OPTICAL_WO_OR_RW_MEDIUM 0x06
/*
* Structure definition for READ6, WRITE6 (6-byte CDB)
*/
typedef struct SCSI_RW6_CDB
{
u32 OpCode :8,
LBA_HI :5, /* 5 MSBit's of the LBA */
Lun :3,
LBA_MID :8, /* NOTE: total of 21 bits in LBA */
LBA_LO :8 ; /* Max LBA = 0x001fffff */
u8 BlockCount;
u8 Control;
} SCSI_RW6_t;
#define MAX_RW6_LBA ((u32)0x001fffff)
/*
* Structure definition for READ10, WRITE10 (10-byte CDB)
*
* NOTE: ParityCheck bit is applicable only for VERIFY and WRITE VERIFY for
* the ADP-92 DAC only. In the SCSI2 spec. this same bit is defined as a
* FUA (forced unit access) bit for READs and WRITEs. Since this driver
* does not use the FUA, this bit is defined as it is used by the ADP-92.
* Also, for READ CAPACITY, only the OpCode field is used.
*/
typedef struct SCSI_RW10_CDB
{
u8 OpCode;
u8 Reserved1;
u32 LBA;
u8 Reserved2;
u16 BlockCount;
u8 Control;
} SCSI_RW10_t;
#define PARITY_CHECK 0x08 /* parity check bit - byte[1], bit 3 */
/*
* Structure definition for data returned by READ CAPACITY cmd;
* READ CAPACITY data
*/
typedef struct READ_CAP_DATA
{
u32 MaxLBA;
u32 BlockBytes;
} SCSI_READ_CAP_DATA_t, *pSCSI_READ_CAP_DATA_t;
/*
* Structure definition for FORMAT UNIT CDB (6-byte CDB)
*/
typedef struct _SCSI_FORMAT_UNIT
{
u8 OpCode;
u8 Reserved1;
u8 VendorSpecific;
u16 Interleave;
u8 Control;
} SCSI_FORMAT_UNIT_t;
/*
* Structure definition for REQUEST SENSE (6-byte CDB)
*/
typedef struct _SCSI_REQUEST_SENSE
{
u8 OpCode;
u8 Reserved1;
u8 Reserved2;
u8 Reserved3;
u8 AllocLength;
u8 Control;
} SCSI_REQ_SENSE_t;
/*
* Structure definition for REPORT LUNS (12-byte CDB)
*/
typedef struct _SCSI_REPORT_LUNS
{
u8 OpCode;
u8 Reserved1[5];
u32 AllocationLength;
u8 Reserved2;
u8 Control;
} SCSI_REPORT_LUNS_t, *pSCSI_REPORT_LUNS_t;
/*
* (per-level) LUN information bytes
*/
/*
* Following doesn't work on ARMCC compiler
* [apparently] because it pads every struct
* to be multiple of 4 bytes!
* So SCSI_LUN_LEVELS_t winds up being 16
* bytes instead of 8!
*
typedef struct LUN_INFO
{
u8 AddrMethod_plus_LunOrBusNumber;
u8 LunOrTarget;
} SCSI_LUN_INFO_t, *pSCSI_LUN_INFO_t;
typedef struct LUN_LEVELS
{
SCSI_LUN_INFO_t LUN_0;
SCSI_LUN_INFO_t LUN_1;
SCSI_LUN_INFO_t LUN_2;
SCSI_LUN_INFO_t LUN_3;
} SCSI_LUN_LEVELS_t, *pSCSI_LUN_LEVELS_t;
*/
/*
* All 4 levels (8 bytes) of LUN information
*/
typedef struct LUN_LEVELS
{
u8 LVL1_AddrMethod_plus_LunOrBusNumber;
u8 LVL1_LunOrTarget;
u8 LVL2_AddrMethod_plus_LunOrBusNumber;
u8 LVL2_LunOrTarget;
u8 LVL3_AddrMethod_plus_LunOrBusNumber;
u8 LVL3_LunOrTarget;
u8 LVL4_AddrMethod_plus_LunOrBusNumber;
u8 LVL4_LunOrTarget;
} SCSI_LUN_LEVELS_t, *pSCSI_LUN_LEVELS_t;
/*
* Structure definition for data returned by REPORT LUNS cmd;
* LUN reporting parameter list format
*/
typedef struct LUN_REPORT
{
u32 LunListLength;
u32 Reserved;
SCSI_LUN_LEVELS_t LunInfo[1];
} SCSI_LUN_REPORT_t, *pSCSI_LUN_REPORT_t;
/****************************************************************************
*
* Externals
*/
/****************************************************************************
*
* Public Typedefs & Related Defines
*/
/****************************************************************************
*
* Macros (embedded, above)
*/
/****************************************************************************
*
* Public Variables
*/
/****************************************************************************
*
* Public Prototypes (module entry points)
*/
/***************************************************************************/
#endif
static const char *ScsiOpcodeString[256] = {
"TEST UNIT READY\0\01", /* 00h */
"REWIND\0\002"
"\001REZERO UNIT", /* 01h */
"\0\0", /* 02h */
"REQUEST SENSE\0\01", /* 03h */
"FORMAT UNIT\0\03"
"\001FORMAT MEDIUM\0"
"\002FORMAT", /* 04h */
"READ BLOCK LIMITS\0\1", /* 05h */
"\0\0", /* 06h */
"REASSIGN BLOCKS\0\02"
"\010INITIALIZE ELEMENT STATUS", /* 07h */
"READ(06)\0\04"
"\001READ\0"
"\003RECEIVE\0"
"\011GET MESSAGE(06)", /* 08h */
"\0\0", /* 09h */
"WRITE(06)\0\05"
"\001WRITE\0"
"\002PRINT\0"
"\003SEND(6)\0"
"\011SEND MESSAGE(06)", /* 0Ah */
"SEEK(06)\0\02"
"\003SLEW AND PRINT", /* 0Bh */
"\0\0", /* 0Ch */
"\0\0", /* 0Dh */
"\0\0", /* 0Eh */
"READ REVERSE\0\01", /* 0Fh */
"WRITE FILEMARKS\0\02"
"\003SYNCRONIZE BUFFER", /* 10h */
"SPACE(6)\0\01", /* 11h */
"INQUIRY\0\01", /* 12h */
"VERIFY\0\01", /* 13h */
"RECOVER BUFFERED DATA\0\01", /* 14h */
"MODE SELECT(06)\0\01", /* 15h */
"RESERVE(06)\0\02"
"\010RESERVE ELEMENT(06)", /* 16h */
"RELEASE(06)\0\02"
"\010RELEASE ELEMENT(06)", /* 17h */
"COPY\0\01", /* 18h */
"ERASE\0\01", /* 19h */
"MODE SENSE(06)\0\01", /* 1Ah */
"STOP START UNIT\0\04"
"\001LOAD UNLOAD\0"
"\002STOP PRINT\0"
"\006SCAN\0\002", /* 1Bh */
"RECEIVE DIAGNOSTIC RESULTS\0\01", /* 1Ch */
"SEND DIAGNOSTIC\0\01", /* 1Dh */
"PREVENT ALLOW MEDIUM REMOVAL\0\01", /* 1Eh */
"\0\0", /* 1Fh */
"\0\0", /* 20h */
"\0\0", /* 21h */
"\0\0", /* 22h */
"READ FORMAT CAPACITIES\0\01", /* 23h */
"SET WINDOW\0\01", /* 24h */
"READ CAPACITY\0\03"
"\006GET WINDOW\0"
"\037FREAD CARD CAPACITY", /* 25h */
"\0\0", /* 26h */
"\0\0", /* 27h */
"READ(10)\0\02"
"\011GET MESSAGE(10)", /* 28h */
"READ GENERATION\0\01", /* 29h */
"WRITE(10)\0\03"
"\011SEND(10)\0"
"\011SEND MESSAGE(10)", /* 2Ah */
"SEEK(10)\0\03"
"LOCATE(10)\0"
"POSITION TO ELEMENT", /* 2Bh */
"ERASE(10)\0\01", /* 2Ch */
"READ UPDATED BLOCK\0\01", /* 2Dh */
"WRITE AND VERIFY(10)\0\01", /* 2Eh */
"VERIFY(10)\0\01", /* 2Fh */
"SEARCH DATA HIGH(10)\0\01", /* 30h */
"SEARCH DATA EQUAL(10)\0\02"
"OBJECT POSITION", /* 31h */
"SEARCH DATA LOW(10)\0\01", /* 32h */
"SET LIMITS(10)\0\01", /* 33h */
"PRE-FETCH(10)\0\03"
"READ POSITION\0"
"GET DATA BUFFER STATUS", /* 34h */
"SYNCHRONIZE CACHE(10)\0\01", /* 35h */
"LOCK UNLOCK CACHE(10)\0\01", /* 36h */
"READ DEFECT DATA(10)\0\01", /* 37h */
"MEDIUM SCAN\0\01", /* 38h */
"COMPARE\0\01", /* 39h */
"COPY AND VERIFY\0\01", /* 3Ah */
"WRITE BUFFER\0\01", /* 3Bh */
"READ BUFFER\0\01", /* 3Ch */
"UPDATE BLOCK\0\01", /* 3Dh */
"READ LONG\0\01", /* 3Eh */
"WRITE LONG\0\01", /* 3Fh */
"CHANGE DEFINITION\0\01", /* 40h */
"WRITE SAME(10)\0\01", /* 41h */
"READ SUB-CHANNEL\0\01", /* 42h */
"READ TOC/PMA/ATIP\0\01", /* 43h */
"REPORT DENSITY SUPPORT\0\01", /* 44h */
"READ HEADER\0\01", /* 44h */
"PLAY AUDIO(10)\0\01", /* 45h */
"GET CONFIGURATION\0\01", /* 46h */
"PLAY AUDIO MSF\0\01", /* 47h */
"PLAY AUDIO TRACK INDEX\0\01", /* 48h */
"PLAY TRACK RELATIVE(10)\0\01", /* 49h */
"GET EVENT STATUS NOTIFICATION\0\01", /* 4Ah */
"PAUSE/RESUME\0\01", /* 4Bh */
"LOG SELECT\0\01", /* 4Ch */
"LOG SENSE\0\01", /* 4Dh */
"STOP PLAY/SCAN\0\01", /* 4Eh */
"\0\0", /* 4Fh */
"XDWRITE(10)\0\01", /* 50h */
"XPWRITE(10)\0\02"
"READ DISC INFORMATION", /* 51h */
"XDREAD(10)\0\01"
"READ TRACK INFORMATION", /* 52h */
"RESERVE TRACK\0\01", /* 53h */
"SEND OPC INFORMATION\0\01", /* 54h */
"MODE SELECT(10)\0\01", /* 55h */
"RESERVE(10)\0\02"
"RESERVE ELEMENT(10)", /* 56h */
"RELEASE(10)\0\02"
"RELEASE ELEMENT(10)", /* 57h */
"REPAIR TRACK\0\01", /* 58h */
"READ MASTER CUE\0\01", /* 59h */
"MODE SENSE(10)\0\01", /* 5Ah */
"CLOSE TRACK/SESSION\0\01", /* 5Bh */
"READ BUFFER CAPACITY\0\01", /* 5Ch */
"SEND CUE SHEET\0\01", /* 5Dh */
"PERSISTENT RESERVE IN\0\01", /* 5Eh */
"PERSISTENT RESERVE OUT\0\01", /* 5Fh */
"\0\0", /* 60h */
"\0\0", /* 61h */
"\0\0", /* 62h */
"\0\0", /* 63h */
"\0\0", /* 64h */
"\0\0", /* 65h */
"\0\0", /* 66h */
"\0\0", /* 67h */
"\0\0", /* 68h */
"\0\0", /* 69h */
"\0\0", /* 6Ah */
"\0\0", /* 6Bh */
"\0\0", /* 6Ch */
"\0\0", /* 6Dh */
"\0\0", /* 6Eh */
"\0\0", /* 6Fh */
"\0\0", /* 70h */
"\0\0", /* 71h */
"\0\0", /* 72h */
"\0\0", /* 73h */
"\0\0", /* 74h */
"\0\0", /* 75h */
"\0\0", /* 76h */
"\0\0", /* 77h */
"\0\0", /* 78h */
"\0\0", /* 79h */
"\0\0", /* 7Ah */
"\0\0", /* 7Bh */
"\0\0", /* 7Ch */
"\0\0", /* 7Eh */
"\0\0", /* 7Eh */
"\0\0", /* 7Fh */
"XDWRITE EXTENDED(16)\0\01", /* 80h */
"REBUILD(16)\0\01", /* 81h */
"REGENERATE(16)\0\01", /* 82h */
"EXTENDED COPY\0\01", /* 83h */
"RECEIVE COPY RESULTS\0\01", /* 84h */
"ACCESS CONTROL IN [proposed]\0\01", /* 86h */
"ACCESS CONTROL OUT [proposed]\0\01", /* 87h */
"READ(16)\0\01", /* 88h */
"DEVICE LOCKS [proposed]\0\01", /* 89h */
"WRITE(16)\0\01", /* 8Ah */
"\0\0", /* 8Bh */
"READ ATTRIBUTES [proposed]\0\01", /* 8Ch */
"WRITE ATTRIBUTES [proposed]\0\01", /* 8Dh */
"WRITE AND VERIFY(16)\0\01", /* 8Eh */
"VERIFY(16)\0\01", /* 8Fh */
"PRE-FETCH(16)\0\01", /* 90h */
"SYNCHRONIZE CACHE(16)\0\02"
"SPACE(16) [1]", /* 91h */
"LOCK UNLOCK CACHE(16)\0\02"
"LOCATE(16) [1]", /* 92h */
"WRITE SAME(16)\0\01", /* 93h */
"[usage proposed by SCSI Socket Services project]\0\01", /* 94h */
"[usage proposed by SCSI Socket Services project]\0\01", /* 95h */
"[usage proposed by SCSI Socket Services project]\0\01", /* 96h */
"[usage proposed by SCSI Socket Services project]\0\01", /* 97h */
"MARGIN CONTROL [proposed]\0\01", /* 98h */
"\0\0", /* 99h */
"\0\0", /* 9Ah */
"\0\0", /* 9Bh */
"\0\0", /* 9Ch */
"\0\0", /* 9Dh */
"SERVICE ACTION IN [proposed]\0\01", /* 9Eh */
"SERVICE ACTION OUT [proposed]\0\01", /* 9Fh */
"REPORT LUNS\0\01", /* A0h */
"BLANK\0\01", /* A1h */
"SEND EVENT\0\01", /* A2h */
"MAINTENANCE (IN)\0\02"
"SEND KEY", /* A3h */
"MAINTENANCE (OUT)\0\02"
"REPORT KEY", /* A4h */
"MOVE MEDIUM\0\02"
"PLAY AUDIO(12)", /* A5h */
"EXCHANGE MEDIUM\0\02"
"LOAD/UNLOAD C/DVD", /* A6h */
"MOVE MEDIUM ATTACHED\0\02"
"SET READ AHEAD\0\01", /* A7h */
"READ(12)\0\02"
"GET MESSAGE(12)", /* A8h */
"PLAY TRACK RELATIVE(12)\0\01", /* A9h */
"WRITE(12)\0\02"
"SEND MESSAGE(12)", /* AAh */
"\0\0", /* ABh */
"ERASE(12)\0\02"
"GET PERFORMANCE", /* ACh */
"READ DVD STRUCTURE\0\01", /* ADh */
"WRITE AND VERIFY(12)\0\01", /* AEh */
"VERIFY(12)\0\01", /* AFh */
"SEARCH DATA HIGH(12)\0\01", /* B0h */
"SEARCH DATA EQUAL(12)\0\01", /* B1h */
"SEARCH DATA LOW(12)\0\01", /* B2h */
"SET LIMITS(12)\0\01", /* B3h */
"READ ELEMENT STATUS ATTACHED\0\01", /* B4h */
"REQUEST VOLUME ELEMENT ADDRESS\0\01", /* B5h */
"SEND VOLUME TAG\0\02"
"SET STREAMING", /* B6h */
"READ DEFECT DATA(12)\0\01", /* B7h */
"READ ELEMENT STATUS\0\01", /* B8h */
"READ CD MSF\0\01", /* B9h */
"REDUNDANCY GROUP (IN)\0\02"
"SCAN", /* BAh */
"REDUNDANCY GROUP (OUT)\0\02"
"SET CD-ROM SPEED", /* BBh */
"SPARE (IN)\0\02"
"PLAY CD", /* BCh */
"SPARE (OUT)\0\02"
"MECHANISM STATUS", /* BDh */
"VOLUME SET (IN)\0\02"
"READ CD", /* BEh */
"VOLUME SET (OUT)\0\0\02"
"SEND DVD STRUCTURE", /* BFh */
"\0\0", /* C0h */
"\0\0", /* C1h */
"\0\0", /* C2h */
"\0\0", /* C3h */
"\0\0", /* C4h */
"\0\0", /* C5h */
"\0\0", /* C6h */
"\0\0", /* C7h */
"\0\0", /* C8h */
"\0\0", /* C9h */
"\0\0", /* CAh */
"\0\0", /* CBh */
"\0\0", /* CCh */
"\0\0", /* CDh */
"\0\0", /* CEh */
"\0\0", /* CFh */
"\0\0", /* D0h */
"\0\0", /* D1h */
"\0\0", /* D2h */
"\0\0", /* D3h */
"\0\0", /* D4h */
"\0\0", /* D5h */
"\0\0", /* D6h */
"\0\0", /* D7h */
"\0\0", /* D8h */
"\0\0", /* D9h */
"\0\0", /* DAh */
"\0\0", /* DBh */
"\0\0", /* DCh */
"\0\0", /* DEh */
"\0\0", /* DEh */
"\0\0", /* DFh */
"\0\0", /* E0h */
"\0\0", /* E1h */
"\0\0", /* E2h */
"\0\0", /* E3h */
"\0\0", /* E4h */
"\0\0", /* E5h */
"\0\0", /* E6h */
"\0\0", /* E7h */
"\0\0", /* E8h */
"\0\0", /* E9h */
"\0\0", /* EAh */
"\0\0", /* EBh */
"\0\0", /* ECh */
"\0\0", /* EDh */
"\0\0", /* EEh */
"\0\0", /* EFh */
"\0\0", /* F0h */
"\0\0", /* F1h */
"\0\0", /* F2h */
"\0\0", /* F3h */
"\0\0", /* F4h */
"\0\0", /* F5h */
"\0\0", /* F6h */
"\0\0", /* F7h */
"\0\0", /* F8h */
"\0\0", /* F9h */
"\0\0", /* FAh */
"\0\0", /* FBh */
"\0\0", /* FEh */
"\0\0", /* FEh */
"\0\0", /* FEh */
"\0\0" /* FFh */
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment