diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/aic7xxx/aiclib.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/scsi/aic7xxx/aiclib.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aiclib.c | 1412 |
1 files changed, 1412 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c new file mode 100644 index 00000000000..79bfd9efd8e --- /dev/null +++ b/drivers/scsi/aic7xxx/aiclib.c @@ -0,0 +1,1412 @@ +/* + * Implementation of Utility functions for all SCSI device types. + * + * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. + * Copyright (c) 1997, 1998 Kenneth D. Merry. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $ + * $Id$ + */ + +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/version.h> + +/* Core SCSI definitions */ +#include "scsi.h" +#include <scsi/scsi_host.h> +#include "aiclib.h" +#include "cam.h" + +#ifndef FALSE +#define FALSE 0 +#endif /* FALSE */ +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef ERESTART +#define ERESTART -1 /* restart syscall */ +#endif +#ifndef EJUSTRETURN +#define EJUSTRETURN -2 /* don't modify regs, just return */ +#endif + +static int ascentrycomp(const void *key, const void *member); +static int senseentrycomp(const void *key, const void *member); +static void fetchtableentries(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *, + const struct sense_key_table_entry **, + const struct asc_table_entry **); +static void * scsibsearch(const void *key, const void *base, size_t nmemb, + size_t size, + int (*compar)(const void *, const void *)); +typedef int (cam_quirkmatch_t)(caddr_t, caddr_t); +static int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, + int str_len); +static caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, + int num_entries, int entry_size, + cam_quirkmatch_t *comp_func); + +#define SCSI_NO_SENSE_STRINGS 1 +#if !defined(SCSI_NO_SENSE_STRINGS) +#define SST(asc, ascq, action, desc) \ + asc, ascq, action, desc +#else +static const char empty_string[] = ""; + +#define SST(asc, ascq, action, desc) \ + asc, ascq, action, empty_string +#endif + +static const struct sense_key_table_entry sense_key_table[] = +{ + { SSD_KEY_NO_SENSE, SS_NOP, "NO SENSE" }, + { SSD_KEY_RECOVERED_ERROR, SS_NOP|SSQ_PRINT_SENSE, "RECOVERED ERROR" }, + { + SSD_KEY_NOT_READY, SS_TUR|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, + "NOT READY" + }, + { SSD_KEY_MEDIUM_ERROR, SS_RDEF, "MEDIUM ERROR" }, + { SSD_KEY_HARDWARE_ERROR, SS_RDEF, "HARDWARE FAILURE" }, + { SSD_KEY_ILLEGAL_REQUEST, SS_FATAL|EINVAL, "ILLEGAL REQUEST" }, + { SSD_KEY_UNIT_ATTENTION, SS_FATAL|ENXIO, "UNIT ATTENTION" }, + { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" }, + { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" }, + { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" }, + { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" }, + { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" }, + { SSD_KEY_EQUAL, SS_NOP, "EQUAL" }, + { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" }, + { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" }, + { SSD_KEY_RESERVED, SS_FATAL|EIO, "RESERVED" } +}; + +static const int sense_key_table_size = + sizeof(sense_key_table)/sizeof(sense_key_table[0]); + +static struct asc_table_entry quantum_fireball_entries[] = { + {SST(0x04, 0x0b, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, initializing cmd. required")} +}; + +static struct asc_table_entry sony_mo_entries[] = { + {SST(0x04, 0x00, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, cause not reportable")} +}; + +static struct scsi_sense_quirk_entry sense_quirk_table[] = { + { + /* + * The Quantum Fireball ST and SE like to return 0x04 0x0b when + * they really should return 0x04 0x02. 0x04,0x0b isn't + * defined in any SCSI spec, and it isn't mentioned in the + * hardware manual for these drives. + */ + {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"}, + /*num_sense_keys*/0, + sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry), + /*sense key entries*/NULL, + quantum_fireball_entries + }, + { + /* + * This Sony MO drive likes to return 0x04, 0x00 when it + * isn't spun up. + */ + {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"}, + /*num_sense_keys*/0, + sizeof(sony_mo_entries)/sizeof(struct asc_table_entry), + /*sense key entries*/NULL, + sony_mo_entries + } +}; + +static const int sense_quirk_table_size = + sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]); + +static struct asc_table_entry asc_table[] = { +/* + * From File: ASC-NUM.TXT + * SCSI ASC/ASCQ Assignments + * Numeric Sorted Listing + * as of 5/12/97 + * + * D - DIRECT ACCESS DEVICE (SBC) 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) + * . . R - CD DEVICE (MMC) + * . . S - SCANNER DEVICE (SGC) + * . . .O - OPTICAL MEMORY DEVICE (SBC) + * . . . M - MEDIA CHANGER DEVICE (SMC) + * . . . C - COMMUNICATION DEVICE (SSC) + * . . . .A - STORAGE ARRAY DEVICE (SCC) + * . . . . E - ENCLOSURE SERVICES DEVICE (SES) + * DTLPWRSOMCAE ASC ASCQ Action Description + * ------------ ---- ---- ------ -----------------------------------*/ +/* DTLPWRSOMCAE */{SST(0x00, 0x00, SS_NOP, + "No additional sense information") }, +/* T S */{SST(0x00, 0x01, SS_RDEF, + "Filemark detected") }, +/* T S */{SST(0x00, 0x02, SS_RDEF, + "End-of-partition/medium detected") }, +/* T */{SST(0x00, 0x03, SS_RDEF, + "Setmark detected") }, +/* T S */{SST(0x00, 0x04, SS_RDEF, + "Beginning-of-partition/medium detected") }, +/* T S */{SST(0x00, 0x05, SS_RDEF, + "End-of-data detected") }, +/* DTLPWRSOMCAE */{SST(0x00, 0x06, SS_RDEF, + "I/O process terminated") }, +/* R */{SST(0x00, 0x11, SS_FATAL|EBUSY, + "Audio play operation in progress") }, +/* R */{SST(0x00, 0x12, SS_NOP, + "Audio play operation paused") }, +/* R */{SST(0x00, 0x13, SS_NOP, + "Audio play operation successfully completed") }, +/* R */{SST(0x00, 0x14, SS_RDEF, + "Audio play operation stopped due to error") }, +/* R */{SST(0x00, 0x15, SS_NOP, + "No current audio status to return") }, +/* DTLPWRSOMCAE */{SST(0x00, 0x16, SS_FATAL|EBUSY, + "Operation in progress") }, +/* DTL WRSOM AE */{SST(0x00, 0x17, SS_RDEF, + "Cleaning requested") }, +/* D W O */{SST(0x01, 0x00, SS_RDEF, + "No index/sector signal") }, +/* D WR OM */{SST(0x02, 0x00, SS_RDEF, + "No seek complete") }, +/* DTL W SO */{SST(0x03, 0x00, SS_RDEF, + "Peripheral device write fault") }, +/* T */{SST(0x03, 0x01, SS_RDEF, + "No write current") }, +/* T */{SST(0x03, 0x02, SS_RDEF, + "Excessive write errors") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x00, + SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EIO, + "Logical unit not ready, cause not reportable") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x01, + SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY, + "Logical unit is in process of becoming ready") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x02, SS_START|SSQ_DECREMENT_COUNT|ENXIO, + "Logical unit not ready, initializing cmd. required") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x03, SS_FATAL|ENXIO, + "Logical unit not ready, manual intervention required")}, +/* DTL O */{SST(0x04, 0x04, SS_FATAL|EBUSY, + "Logical unit not ready, format in progress") }, +/* DT W OMCA */{SST(0x04, 0x05, SS_FATAL|EBUSY, + "Logical unit not ready, rebuild in progress") }, +/* DT W OMCA */{SST(0x04, 0x06, SS_FATAL|EBUSY, + "Logical unit not ready, recalculation in progress") }, +/* DTLPWRSOMCAE */{SST(0x04, 0x07, SS_FATAL|EBUSY, + "Logical unit not ready, operation in progress") }, +/* R */{SST(0x04, 0x08, SS_FATAL|EBUSY, + "Logical unit not ready, long write in progress") }, +/* DTL WRSOMCAE */{SST(0x05, 0x00, SS_RDEF, + "Logical unit does not respond to selection") }, +/* D WR OM */{SST(0x06, 0x00, SS_RDEF, + "No reference position found") }, +/* DTL WRSOM */{SST(0x07, 0x00, SS_RDEF, + "Multiple peripheral devices selected") }, +/* DTL WRSOMCAE */{SST(0x08, 0x00, SS_RDEF, + "Logical unit communication failure") }, +/* DTL WRSOMCAE */{SST(0x08, 0x01, SS_RDEF, + "Logical unit communication time-out") }, +/* DTL WRSOMCAE */{SST(0x08, 0x02, SS_RDEF, + "Logical unit communication parity error") }, +/* DT R OM */{SST(0x08, 0x03, SS_RDEF, + "Logical unit communication crc error (ultra-dma/32)")}, +/* DT WR O */{SST(0x09, 0x00, SS_RDEF, + "Track following error") }, +/* WR O */{SST(0x09, 0x01, SS_RDEF, + "Tracking servo failure") }, +/* WR O */{SST(0x09, 0x02, SS_RDEF, + "Focus servo failure") }, +/* WR O */{SST(0x09, 0x03, SS_RDEF, + "Spindle servo failure") }, +/* DT WR O */{SST(0x09, 0x04, SS_RDEF, + "Head select fault") }, +/* DTLPWRSOMCAE */{SST(0x0A, 0x00, SS_FATAL|ENOSPC, + "Error log overflow") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x00, SS_RDEF, + "Warning") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x01, SS_RDEF, + "Specified temperature exceeded") }, +/* DTLPWRSOMCAE */{SST(0x0B, 0x02, SS_RDEF, + "Enclosure degraded") }, +/* T RS */{SST(0x0C, 0x00, SS_RDEF, + "Write error") }, +/* D W O */{SST(0x0C, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Write error - recovered with auto reallocation") }, +/* D W O */{SST(0x0C, 0x02, SS_RDEF, + "Write error - auto reallocation failed") }, +/* D W O */{SST(0x0C, 0x03, SS_RDEF, + "Write error - recommend reassignment") }, +/* DT W O */{SST(0x0C, 0x04, SS_RDEF, + "Compression check miscompare error") }, +/* DT W O */{SST(0x0C, 0x05, SS_RDEF, + "Data expansion occurred during compression") }, +/* DT W O */{SST(0x0C, 0x06, SS_RDEF, + "Block not compressible") }, +/* R */{SST(0x0C, 0x07, SS_RDEF, + "Write error - recovery needed") }, +/* R */{SST(0x0C, 0x08, SS_RDEF, + "Write error - recovery failed") }, +/* R */{SST(0x0C, 0x09, SS_RDEF, + "Write error - loss of streaming") }, +/* R */{SST(0x0C, 0x0A, SS_RDEF, + "Write error - padding blocks added") }, +/* D W O */{SST(0x10, 0x00, SS_RDEF, + "ID CRC or ECC error") }, +/* DT WRSO */{SST(0x11, 0x00, SS_RDEF, + "Unrecovered read error") }, +/* DT W SO */{SST(0x11, 0x01, SS_RDEF, + "Read retries exhausted") }, +/* DT W SO */{SST(0x11, 0x02, SS_RDEF, + "Error too long to correct") }, +/* DT W SO */{SST(0x11, 0x03, SS_RDEF, + "Multiple read errors") }, +/* D W O */{SST(0x11, 0x04, SS_RDEF, + "Unrecovered read error - auto reallocate failed") }, +/* WR O */{SST(0x11, 0x05, SS_RDEF, + "L-EC uncorrectable error") }, +/* WR O */{SST(0x11, 0x06, SS_RDEF, + "CIRC unrecovered error") }, +/* W O */{SST(0x11, 0x07, SS_RDEF, + "Data re-synchronization error") }, +/* T */{SST(0x11, 0x08, SS_RDEF, + "Incomplete block read") }, +/* T */{SST(0x11, 0x09, SS_RDEF, + "No gap found") }, +/* DT O */{SST(0x11, 0x0A, SS_RDEF, + "Miscorrected error") }, +/* D W O */{SST(0x11, 0x0B, SS_RDEF, + "Unrecovered read error - recommend reassignment") }, +/* D W O */{SST(0x11, 0x0C, SS_RDEF, + "Unrecovered read error - recommend rewrite the data")}, +/* DT WR O */{SST(0x11, 0x0D, SS_RDEF, + "De-compression CRC error") }, +/* DT WR O */{SST(0x11, 0x0E, SS_RDEF, + "Cannot decompress using declared algorithm") }, +/* R */{SST(0x11, 0x0F, SS_RDEF, + "Error reading UPC/EAN number") }, +/* R */{SST(0x11, 0x10, SS_RDEF, + "Error reading ISRC number") }, +/* R */{SST(0x11, 0x11, SS_RDEF, + "Read error - loss of streaming") }, +/* D W O */{SST(0x12, 0x00, SS_RDEF, + "Address mark not found for id field") }, +/* D W O */{SST(0x13, 0x00, SS_RDEF, + "Address mark not found for data field") }, +/* DTL WRSO */{SST(0x14, 0x00, SS_RDEF, + "Recorded entity not found") }, +/* DT WR O */{SST(0x14, 0x01, SS_RDEF, + "Record not found") }, +/* T */{SST(0x14, 0x02, SS_RDEF, + "Filemark or setmark not found") }, +/* T */{SST(0x14, 0x03, SS_RDEF, + "End-of-data not found") }, +/* T */{SST(0x14, 0x04, SS_RDEF, + "Block sequence error") }, +/* DT W O */{SST(0x14, 0x05, SS_RDEF, + "Record not found - recommend reassignment") }, +/* DT W O */{SST(0x14, 0x06, SS_RDEF, + "Record not found - data auto-reallocated") }, +/* DTL WRSOM */{SST(0x15, 0x00, SS_RDEF, + "Random positioning error") }, +/* DTL WRSOM */{SST(0x15, 0x01, SS_RDEF, + "Mechanical positioning error") }, +/* DT WR O */{SST(0x15, 0x02, SS_RDEF, + "Positioning error detected by read of medium") }, +/* D W O */{SST(0x16, 0x00, SS_RDEF, + "Data synchronization mark error") }, +/* D W O */{SST(0x16, 0x01, SS_RDEF, + "Data sync error - data rewritten") }, +/* D W O */{SST(0x16, 0x02, SS_RDEF, + "Data sync error - recommend rewrite") }, +/* D W O */{SST(0x16, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Data sync error - data auto-reallocated") }, +/* D W O */{SST(0x16, 0x04, SS_RDEF, + "Data sync error - recommend reassignment") }, +/* DT WRSO */{SST(0x17, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with no error correction applied") }, +/* DT WRSO */{SST(0x17, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with retries") }, +/* DT WR O */{SST(0x17, 0x02, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with positive head offset") }, +/* DT WR O */{SST(0x17, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with negative head offset") }, +/* WR O */{SST(0x17, 0x04, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with retries and/or CIRC applied") }, +/* D WR O */{SST(0x17, 0x05, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data using previous sector id") }, +/* D W O */{SST(0x17, 0x06, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - data auto-reallocated") }, +/* D W O */{SST(0x17, 0x07, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - recommend reassignment")}, +/* D W O */{SST(0x17, 0x08, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - recommend rewrite") }, +/* D W O */{SST(0x17, 0x09, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data without ECC - data rewritten") }, +/* D W O */{SST(0x18, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with error correction applied") }, +/* D WR O */{SST(0x18, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with error corr. & retries applied") }, +/* D WR O */{SST(0x18, 0x02, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - data auto-reallocated") }, +/* R */{SST(0x18, 0x03, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with CIRC") }, +/* R */{SST(0x18, 0x04, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with L-EC") }, +/* D WR O */{SST(0x18, 0x05, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - recommend reassignment") }, +/* D WR O */{SST(0x18, 0x06, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data - recommend rewrite") }, +/* D W O */{SST(0x18, 0x07, SS_NOP|SSQ_PRINT_SENSE, + "Recovered data with ECC - data rewritten") }, +/* D O */{SST(0x19, 0x00, SS_RDEF, + "Defect list error") }, +/* D O */{SST(0x19, 0x01, SS_RDEF, + "Defect list not available") }, +/* D O */{SST(0x19, 0x02, SS_RDEF, + "Defect list error in primary list") }, +/* D O */{SST(0x19, 0x03, SS_RDEF, + "Defect list error in grown list") }, +/* DTLPWRSOMCAE */{SST(0x1A, 0x00, SS_RDEF, + "Parameter list length error") }, +/* DTLPWRSOMCAE */{SST(0x1B, 0x00, SS_RDEF, + "Synchronous data transfer error") }, +/* D O */{SST(0x1C, 0x00, SS_RDEF, + "Defect list not found") }, +/* D O */{SST(0x1C, 0x01, SS_RDEF, + "Primary defect list not found") }, +/* D O */{SST(0x1C, 0x02, SS_RDEF, + "Grown defect list not found") }, +/* D W O */{SST(0x1D, 0x00, SS_FATAL, + "Miscompare during verify operation" )}, +/* D W O */{SST(0x1E, 0x00, SS_NOP|SSQ_PRINT_SENSE, + "Recovered id with ecc correction") }, +/* D O */{SST(0x1F, 0x00, SS_RDEF, + "Partial defect list transfer") }, +/* DTLPWRSOMCAE */{SST(0x20, 0x00, SS_FATAL|EINVAL, + "Invalid command operation code") }, +/* DT WR OM */{SST(0x21, 0x00, SS_FATAL|EINVAL, + "Logical block address out of range" )}, +/* DT WR OM */{SST(0x21, 0x01, SS_FATAL|EINVAL, + "Invalid element address") }, +/* D */{SST(0x22, 0x00, SS_FATAL|EINVAL, + "Illegal function") }, /* Deprecated. Use 20 00, 24 00, or 26 00 instead */ +/* DTLPWRSOMCAE */{SST(0x24, 0x00, SS_FATAL|EINVAL, + "Invalid field in CDB") }, +/* DTLPWRSOMCAE */{SST(0x25, 0x00, SS_FATAL|ENXIO, + "Logical unit not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x00, SS_FATAL|EINVAL, + "Invalid field in parameter list") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x01, SS_FATAL|EINVAL, + "Parameter not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x02, SS_FATAL|EINVAL, + "Parameter value invalid") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x03, SS_FATAL|EINVAL, + "Threshold parameters not supported") }, +/* DTLPWRSOMCAE */{SST(0x26, 0x04, SS_FATAL|EINVAL, + "Invalid release of active persistent reservation") }, +/* DT W O */{SST(0x27, 0x00, SS_FATAL|EACCES, + "Write protected") }, +/* DT W O */{SST(0x27, 0x01, SS_FATAL|EACCES, + "Hardware write protected") }, +/* DT W O */{SST(0x27, 0x02, SS_FATAL|EACCES, + "Logical unit software write protected") }, +/* T */{SST(0x27, 0x03, SS_FATAL|EACCES, + "Associated write protect") }, +/* T */{SST(0x27, 0x04, SS_FATAL|EACCES, + "Persistent write protect") }, +/* T */{SST(0x27, 0x05, SS_FATAL|EACCES, + "Permanent write protect") }, +/* DTLPWRSOMCAE */{SST(0x28, 0x00, SS_RDEF, + "Not ready to ready change, medium may have changed") }, +/* DTLPWRSOMCAE */{SST(0x28, 0x01, SS_FATAL|ENXIO, + "Import or export element accessed") }, +/* + * XXX JGibbs - All of these should use the same errno, but I don't think + * ENXIO is the correct choice. Should we borrow from the networking + * errnos? ECONNRESET anyone? + */ +/* DTLPWRSOMCAE */{SST(0x29, 0x00, SS_RDEF, + "Power on, reset, or bus device reset occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x01, SS_RDEF, + "Power on occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x02, SS_RDEF, + "Scsi bus reset occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x03, SS_RDEF, + "Bus device reset function occurred") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x04, SS_RDEF, + "Device internal reset") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x05, SS_RDEF, + "Transceiver mode changed to single-ended") }, +/* DTLPWRSOMCAE */{SST(0x29, 0x06, SS_RDEF, + "Transceiver mode changed to LVD") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x00, SS_RDEF, + "Parameters changed") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x01, SS_RDEF, + "Mode parameters changed") }, +/* DTL WRSOMCAE */{SST(0x2A, 0x02, SS_RDEF, + "Log parameters changed") }, +/* DTLPWRSOMCAE */{SST(0x2A, 0x03, SS_RDEF, + "Reservations preempted") }, +/* DTLPWRSO C */{SST(0x2B, 0x00, SS_RDEF, + "Copy cannot execute since host cannot disconnect") }, +/* DTLPWRSOMCAE */{SST(0x2C, 0x00, SS_RDEF, + "Command sequence error") }, +/* S */{SST(0x2C, 0x01, SS_RDEF, + "Too many windows specified") }, +/* S */{SST(0x2C, 0x02, SS_RDEF, + "Invalid combination of windows specified") }, +/* R */{SST(0x2C, 0x03, SS_RDEF, + "Current program area is not empty") }, +/* R */{SST(0x2C, 0x04, SS_RDEF, + "Current program area is empty") }, +/* T */{SST(0x2D, 0x00, SS_RDEF, + "Overwrite error on update in place") }, +/* DTLPWRSOMCAE */{SST(0x2F, 0x00, SS_RDEF, + "Commands cleared by another initiator") }, +/* DT WR OM */{SST(0x30, 0x00, SS_RDEF, + "Incompatible medium installed") }, +/* DT WR O */{SST(0x30, 0x01, SS_RDEF, + "Cannot read medium - unknown format") }, +/* DT WR O */{SST(0x30, 0x02, SS_RDEF, + "Cannot read medium - incompatible format") }, +/* DT */{SST(0x30, 0x03, SS_RDEF, + "Cleaning cartridge installed") }, +/* DT WR O */{SST(0x30, 0x04, SS_RDEF, + "Cannot write medium - unknown format") }, +/* DT WR O */{SST(0x30, 0x05, SS_RDEF, + "Cannot write medium - incompatible format") }, +/* DT W O */{SST(0x30, 0x06, SS_RDEF, + "Cannot format medium - incompatible medium") }, +/* DTL WRSOM AE */{SST(0x30, 0x07, SS_RDEF, + "Cleaning failure") }, +/* R */{SST(0x30, 0x08, SS_RDEF, + "Cannot write - application code mismatch") }, +/* R */{SST(0x30, 0x09, SS_RDEF, + "Current session not fixated for append") }, +/* DT WR O */{SST(0x31, 0x00, SS_RDEF, + "Medium format corrupted") }, +/* D L R O */{SST(0x31, 0x01, SS_RDEF, + "Format command failed") }, +/* D W O */{SST(0x32, 0x00, SS_RDEF, + "No defect spare location available") }, +/* D W O */{SST(0x32, 0x01, SS_RDEF, + "Defect list update failure") }, +/* T */{SST(0x33, 0x00, SS_RDEF, + "Tape length error") }, +/* DTLPWRSOMCAE */{SST(0x34, 0x00, SS_RDEF, + "Enclosure failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x00, SS_RDEF, + "Enclosure services failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x01, SS_RDEF, + "Unsupported enclosure function") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x02, SS_RDEF, + "Enclosure services unavailable") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x03, SS_RDEF, + "Enclosure services transfer failure") }, +/* DTLPWRSOMCAE */{SST(0x35, 0x04, SS_RDEF, + "Enclosure services transfer refused") }, +/* L */{SST(0x36, 0x00, SS_RDEF, + "Ribbon, ink, or toner failure") }, +/* DTL WRSOMCAE */{SST(0x37, 0x00, SS_RDEF, + "Rounded parameter") }, +/* DTL WRSOMCAE */{SST(0x39, 0x00, SS_RDEF, + "Saving parameters not supported") }, +/* DTL WRSOM */{SST(0x3A, 0x00, SS_NOP, + "Medium not present") }, +/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, + "Medium not present - tray closed") }, +/* DT WR OM */{SST(0x3A, 0x01, SS_NOP, + "Medium not present - tray open") }, +/* DT WR OM */{SST(0x3A, 0x03, SS_NOP, + "Medium not present - Loadable") }, +/* DT WR OM */{SST(0x3A, 0x04, SS_NOP, + "Medium not present - medium auxiliary " + "memory accessible") }, +/* DT WR OM */{SST(0x3A, 0xFF, SS_NOP, NULL) },/* Range 0x05->0xFF */ +/* TL */{SST(0x3B, 0x00, SS_RDEF, + "Sequential positioning error") }, +/* T */{SST(0x3B, 0x01, SS_RDEF, + "Tape position error at beginning-of-medium") }, +/* T */{SST(0x3B, 0x02, SS_RDEF, + "Tape position error at end-of-medium") }, +/* L */{SST(0x3B, 0x03, SS_RDEF, + "Tape or electronic vertical forms unit not ready") }, +/* L */{SST(0x3B, 0x04, SS_RDEF, + "Slew failure") }, +/* L */{SST(0x3B, 0x05, SS_RDEF, + "Paper jam") }, +/* L */{SST(0x3B, 0x06, SS_RDEF, + "Failed to sense top-of-form") }, +/* L */{SST(0x3B, 0x07, SS_RDEF, + "Failed to sense bottom-of-form") }, +/* T */{SST(0x3B, 0x08, SS_RDEF, + "Reposition error") }, +/* S */{SST(0x3B, 0x09, SS_RDEF, + "Read past end of medium") }, +/* S */{SST(0x3B, 0x0A, SS_RDEF, + "Read past beginning of medium") }, +/* S */{SST(0x3B, 0x0B, SS_RDEF, + "Position past end of medium") }, +/* T S */{SST(0x3B, 0x0C, SS_RDEF, + "Position past beginning of medium") }, +/* DT WR OM */{SST(0x3B, 0x0D, SS_FATAL|ENOSPC, + "Medium destination element full") }, +/* DT WR OM */{SST(0x3B, 0x0E, SS_RDEF, + "Medium source element empty") }, +/* R */{SST(0x3B, 0x0F, SS_RDEF, + "End of medium reached") }, +/* DT WR OM */{SST(0x3B, 0x11, SS_RDEF, + "Medium magazine not accessible") }, +/* DT WR OM */{SST(0x3B, 0x12, SS_RDEF, + "Medium magazine removed") }, +/* DT WR OM */{SST(0x3B, 0x13, SS_RDEF, + "Medium magazine inserted") }, +/* DT WR OM */{SST(0x3B, 0x14, SS_RDEF, + "Medium magazine locked") }, +/* DT WR OM */{SST(0x3B, 0x15, SS_RDEF, + "Medium magazine unlocked") }, +/* DTLPWRSOMCAE */{SST(0x3D, 0x00, SS_RDEF, + "Invalid bits in identify message") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x00, SS_RDEF, + "Logical unit has not self-configured yet") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x01, SS_RDEF, + "Logical unit failure") }, +/* DTLPWRSOMCAE */{SST(0x3E, 0x02, SS_RDEF, + "Timeout on logical unit") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x00, SS_RDEF, + "Target operating conditions have changed") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x01, SS_RDEF, + "Microcode has been changed") }, +/* DTLPWRSOMC */{SST(0x3F, 0x02, SS_RDEF, + "Changed operating definition") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x03, SS_INQ_REFRESH|SSQ_DECREMENT_COUNT, + "Inquiry data has changed") }, +/* DT WR OMCAE */{SST(0x3F, 0x04, SS_RDEF, + "Component device attached") }, +/* DT WR OMCAE */{SST(0x3F, 0x05, SS_RDEF, + "Device identifier changed") }, +/* DT WR OMCAE */{SST(0x3F, 0x06, SS_RDEF, + "Redundancy group created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x07, SS_RDEF, + "Redundancy group deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x08, SS_RDEF, + "Spare created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x09, SS_RDEF, + "Spare deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x0A, SS_RDEF, + "Volume set created or modified") }, +/* DT WR OMCAE */{SST(0x3F, 0x0B, SS_RDEF, + "Volume set deleted") }, +/* DT WR OMCAE */{SST(0x3F, 0x0C, SS_RDEF, + "Volume set deassigned") }, +/* DT WR OMCAE */{SST(0x3F, 0x0D, SS_RDEF, + "Volume set reassigned") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x0E, SS_RDEF, + "Reported luns data has changed") }, +/* DTLPWRSOMCAE */{SST(0x3F, 0x0F, SS_RETRY|SSQ_DECREMENT_COUNT + | SSQ_DELAY_RANDOM|EBUSY, + "Echo buffer overwritten") }, +/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, "Medium Loadable") }, +/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, + "Medium auxiliary memory accessible") }, +/* D */{SST(0x40, 0x00, SS_RDEF, + "Ram failure") }, /* deprecated - use 40 NN instead */ +/* DTLPWRSOMCAE */{SST(0x40, 0x80, SS_RDEF, + "Diagnostic failure: ASCQ = Component ID") }, +/* DTLPWRSOMCAE */{SST(0x40, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) },/* Range 0x80->0xFF */ +/* D */{SST(0x41, 0x00, SS_RDEF, + "Data path failure") }, /* deprecated - use 40 NN instead */ +/* D */{SST(0x42, 0x00, SS_RDEF, + "Power-on or self-test failure") }, /* deprecated - use 40 NN instead */ +/* DTLPWRSOMCAE */{SST(0x43, 0x00, SS_RDEF, + "Message error") }, +/* DTLPWRSOMCAE */{SST(0x44, 0x00, SS_RDEF, + "Internal target failure") }, +/* DTLPWRSOMCAE */{SST(0x45, 0x00, SS_RDEF, + "Select or reselect failure") }, +/* DTLPWRSOMC */{SST(0x46, 0x00, SS_RDEF, + "Unsuccessful soft reset") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x00, SS_RDEF|SSQ_FALLBACK, + "SCSI parity error") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x01, SS_RDEF|SSQ_FALLBACK, + "Data Phase CRC error detected") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x02, SS_RDEF|SSQ_FALLBACK, + "SCSI parity error detected during ST data phase") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x03, SS_RDEF|SSQ_FALLBACK, + "Information Unit iuCRC error") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x04, SS_RDEF|SSQ_FALLBACK, + "Asynchronous information protection error detected") }, +/* DTLPWRSOMCAE */{SST(0x47, 0x05, SS_RDEF|SSQ_FALLBACK, + "Protocol server CRC error") }, +/* DTLPWRSOMCAE */{SST(0x48, 0x00, SS_RDEF|SSQ_FALLBACK, + "Initiator detected error message received") }, +/* DTLPWRSOMCAE */{SST(0x49, 0x00, SS_RDEF, + "Invalid message error") }, +/* DTLPWRSOMCAE */{SST(0x4A, 0x00, SS_RDEF, + "Command phase error") }, +/* DTLPWRSOMCAE */{SST(0x4B, 0x00, SS_RDEF, + "Data phase error") }, +/* DTLPWRSOMCAE */{SST(0x4C, 0x00, SS_RDEF, + "Logical unit failed self-configuration") }, +/* DTLPWRSOMCAE */{SST(0x4D, 0x00, SS_RDEF, + "Tagged overlapped commands: ASCQ = Queue tag ID") }, +/* DTLPWRSOMCAE */{SST(0x4D, 0xFF, SS_RDEF|SSQ_RANGE, + NULL)}, /* Range 0x00->0xFF */ +/* DTLPWRSOMCAE */{SST(0x4E, 0x00, SS_RDEF, + "Overlapped commands attempted") }, +/* T */{SST(0x50, 0x00, SS_RDEF, + "Write append error") }, +/* T */{SST(0x50, 0x01, SS_RDEF, + "Write append position error") }, +/* T */{SST(0x50, 0x02, SS_RDEF, + "Position error related to timing") }, +/* T O */{SST(0x51, 0x00, SS_RDEF, + "Erase failure") }, +/* T */{SST(0x52, 0x00, SS_RDEF, + "Cartridge fault") }, +/* DTL WRSOM */{SST(0x53, 0x00, SS_RDEF, + "Media load or eject failed") }, +/* T */{SST(0x53, 0x01, SS_RDEF, + "Unload tape failure") }, +/* DT WR OM */{SST(0x53, 0x02, SS_RDEF, + "Medium removal prevented") }, +/* P */{SST(0x54, 0x00, SS_RDEF, + "Scsi to host system interface failure") }, +/* P */{SST(0x55, 0x00, SS_RDEF, + "System resource failure") }, +/* D O */{SST(0x55, 0x01, SS_FATAL|ENOSPC, + "System buffer full") }, +/* R */{SST(0x57, 0x00, SS_RDEF, + "Unable to recover table-of-contents") }, +/* O */{SST(0x58, 0x00, SS_RDEF, + "Generation does not exist") }, +/* O */{SST(0x59, 0x00, SS_RDEF, + "Updated block read") }, +/* DTLPWRSOM */{SST(0x5A, 0x00, SS_RDEF, + "Operator request or state change input") }, +/* DT WR OM */{SST(0x5A, 0x01, SS_RDEF, + "Operator medium removal request") }, +/* DT W O */{SST(0x5A, 0x02, SS_RDEF, + "Operator selected write protect") }, +/* DT W O */{SST(0x5A, 0x03, SS_RDEF, + "Operator selected write permit") }, +/* DTLPWRSOM */{SST(0x5B, 0x00, SS_RDEF, + "Log exception") }, +/* DTLPWRSOM */{SST(0x5B, 0x01, SS_RDEF, + "Threshold condition met") }, +/* DTLPWRSOM */{SST(0x5B, 0x02, SS_RDEF, + "Log counter at maximum") }, +/* DTLPWRSOM */{SST(0x5B, 0x03, SS_RDEF, + "Log list codes exhausted") }, +/* D O */{SST(0x5C, 0x00, SS_RDEF, + "RPL status change") }, +/* D O */{SST(0x5C, 0x01, SS_NOP|SSQ_PRINT_SENSE, + "Spindles synchronized") }, +/* D O */{SST(0x5C, 0x02, SS_RDEF, + "Spindles not synchronized") }, +/* DTLPWRSOMCAE */{SST(0x5D, 0x00, SS_RDEF, + "Failure prediction threshold exceeded") }, +/* DTLPWRSOMCAE */{SST(0x5D, 0xFF, SS_RDEF, + "Failure prediction threshold exceeded (false)") }, +/* DTLPWRSO CA */{SST(0x5E, 0x00, SS_RDEF, + "Low power condition on") }, +/* DTLPWRSO CA */{SST(0x5E, 0x01, SS_RDEF, + "Idle condition activated by timer") }, +/* DTLPWRSO CA */{SST(0x5E, 0x02, SS_RDEF, + "Standby condition activated by timer") }, +/* DTLPWRSO CA */{SST(0x5E, 0x03, SS_RDEF, + "Idle condition activated by command") }, +/* DTLPWRSO CA */{SST(0x5E, 0x04, SS_RDEF, + "Standby condition activated by command") }, +/* S */{SST(0x60, 0x00, SS_RDEF, + "Lamp failure") }, +/* S */{SST(0x61, 0x00, SS_RDEF, + "Video acquisition error") }, +/* S */{SST(0x61, 0x01, SS_RDEF, + "Unable to acquire video") }, +/* S */{SST(0x61, 0x02, SS_RDEF, + "Out of focus") }, +/* S */{SST(0x62, 0x00, SS_RDEF, + "Scan head positioning error") }, +/* R */{SST(0x63, 0x00, SS_RDEF, + "End of user area encountered on this track") }, +/* R */{SST(0x63, 0x01, SS_FATAL|ENOSPC, + "Packet does not fit in available space") }, +/* R */{SST(0x64, 0x00, SS_RDEF, + "Illegal mode for this track") }, +/* R */{SST(0x64, 0x01, SS_RDEF, + "Invalid packet size") }, +/* DTLPWRSOMCAE */{SST(0x65, 0x00, SS_RDEF, + "Voltage fault") }, +/* S */{SST(0x66, 0x00, SS_RDEF, + "Automatic document feeder cover up") }, +/* S */{SST(0x66, 0x01, SS_RDEF, + "Automatic document feeder lift up") }, +/* S */{SST(0x66, 0x02, SS_RDEF, + "Document jam in automatic document feeder") }, +/* S */{SST(0x66, 0x03, SS_RDEF, + "Document miss feed automatic in document feeder") }, +/* A */{SST(0x67, 0x00, SS_RDEF, + "Configuration failure") }, +/* A */{SST(0x67, 0x01, SS_RDEF, + "Configuration of incapable logical units failed") }, +/* A */{SST(0x67, 0x02, SS_RDEF, + "Add logical unit failed") }, +/* A */{SST(0x67, 0x03, SS_RDEF, + "Modification of logical unit failed") }, +/* A */{SST(0x67, 0x04, SS_RDEF, + "Exchange of logical unit failed") }, +/* A */{SST(0x67, 0x05, SS_RDEF, + "Remove of logical unit failed") }, +/* A */{SST(0x67, 0x06, SS_RDEF, + "Attachment of logical unit failed") }, +/* A */{SST(0x67, 0x07, SS_RDEF, + "Creation of logical unit failed") }, +/* A */{SST(0x68, 0x00, SS_RDEF, + "Logical unit not configured") }, +/* A */{SST(0x69, 0x00, SS_RDEF, + "Data loss on logical unit") }, +/* A */{SST(0x69, 0x01, SS_RDEF, + "Multiple logical unit failures") }, +/* A */{SST(0x69, 0x02, SS_RDEF, + "Parity/data mismatch") }, +/* A */{SST(0x6A, 0x00, SS_RDEF, + "Informational, refer to log") }, +/* A */{SST(0x6B, 0x00, SS_RDEF, + "State change has occurred") }, +/* A */{SST(0x6B, 0x01, SS_RDEF, + "Redundancy level got better") }, +/* A */{SST(0x6B, 0x02, SS_RDEF, + "Redundancy level got worse") }, +/* A */{SST(0x6C, 0x00, SS_RDEF, + "Rebuild failure occurred") }, +/* A */{SST(0x6D, 0x00, SS_RDEF, + "Recalculate failure occurred") }, +/* A */{SST(0x6E, 0x00, SS_RDEF, + "Command to logical unit failed") }, +/* T */{SST(0x70, 0x00, SS_RDEF, + "Decompression exception short: ASCQ = Algorithm ID") }, +/* T */{SST(0x70, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) }, /* Range 0x00 -> 0xFF */ +/* T */{SST(0x71, 0x00, SS_RDEF, + "Decompression exception long: ASCQ = Algorithm ID") }, +/* T */{SST(0x71, 0xFF, SS_RDEF|SSQ_RANGE, + NULL) }, /* Range 0x00 -> 0xFF */ +/* R */{SST(0x72, 0x00, SS_RDEF, + "Session fixation error") }, +/* R */{SST(0x72, 0x01, SS_RDEF, + "Session fixation error writing lead-in") }, +/* R */{SST(0x72, 0x02, SS_RDEF, + "Session fixation error writing lead-out") }, +/* R */{SST(0x72, 0x03, SS_RDEF, + "Session fixation error - incomplete track in session") }, +/* R */{SST(0x72, 0x04, SS_RDEF, + "Empty or partially written reserved track") }, +/* R */{SST(0x73, 0x00, SS_RDEF, + "CD control error") }, +/* R */{SST(0x73, 0x01, SS_RDEF, + "Power calibration area almost full") }, +/* R */{SST(0x73, 0x02, SS_FATAL|ENOSPC, + "Power calibration area is full") }, +/* R */{SST(0x73, 0x03, SS_RDEF, + "Power calibration area error") }, +/* R */{SST(0x73, 0x04, SS_RDEF, + "Program memory area update failure") }, +/* R */{SST(0x73, 0x05, SS_RDEF, + "program memory area is full") } +}; + +static const int asc_table_size = sizeof(asc_table)/sizeof(asc_table[0]); + +struct asc_key +{ + int asc; + int ascq; +}; + +static int +ascentrycomp(const void *key, const void *member) +{ + int asc; + int ascq; + const struct asc_table_entry *table_entry; + + asc = ((const struct asc_key *)key)->asc; + ascq = ((const struct asc_key *)key)->ascq; + table_entry = (const struct asc_table_entry *)member; + + if (asc >= table_entry->asc) { + + if (asc > table_entry->asc) + return (1); + + if (ascq <= table_entry->ascq) { + /* Check for ranges */ + if (ascq == table_entry->ascq + || ((table_entry->action & SSQ_RANGE) != 0 + && ascq >= (table_entry - 1)->ascq)) + return (0); + return (-1); + } + return (1); + } + return (-1); +} + +static int +senseentrycomp(const void *key, const void *member) +{ + int sense_key; + const struct sense_key_table_entry *table_entry; + + sense_key = *((const int *)key); + table_entry = (const struct sense_key_table_entry *)member; + + if (sense_key >= table_entry->sense_key) { + if (sense_key == table_entry->sense_key) + return (0); + return (1); + } + return (-1); +} + +static void +fetchtableentries(int sense_key, int asc, int ascq, + struct scsi_inquiry_data *inq_data, + const struct sense_key_table_entry **sense_entry, + const struct asc_table_entry **asc_entry) +{ + void *match; + const struct asc_table_entry *asc_tables[2]; + const struct sense_key_table_entry *sense_tables[2]; + struct asc_key asc_ascq; + size_t asc_tables_size[2]; + size_t sense_tables_size[2]; + int num_asc_tables; |