?? aspi_hlio.cpp
字號:
/**************************************************************/intaspi_scan_scsi_bus (scsi_devices_list_t **list){ int result = RET_OK; SRB_HAInquiry inq; *list = aspi_dlist_alloc (); if (*list == NULL) return (RET_NO_MEM); memset (&inq, 0, sizeof (SRB_HAInquiry)); inq.SRB_Cmd = SC_HA_INQUIRY; inq.SRB_HaId = 0; aspi_send_cmd ((LPSRB) &inq); if (inq.SRB_Status == SS_COMP) { /* enumerate host adapters and get all devices attached */ int host_adapter, host_adapters_cnt = inq.HA_Count; for (host_adapter=0; result == RET_OK && host_adapter<host_adapters_cnt; ++host_adapter) { /* aspi_rescan_host (host_adapter); */ memset (&inq, 0, sizeof (SRB_HAInquiry)); inq.SRB_Cmd = SC_HA_INQUIRY; inq.SRB_HaId = host_adapter; aspi_send_cmd ((LPSRB) &inq); if (inq.SRB_Status == SS_COMP) { int scsi_id, scsi_ids_cnt = inq.HA_Unique [3] == 0 ? 8 : inq.HA_Unique [3]; u_int32_t alignment_mask = (inq.HA_Unique [1] << 8) | inq.HA_Unique [0]; switch (alignment_mask) { case 0x0000: alignment_mask = 1; break; /* byte alignment */ case 0x0001: alignment_mask = 2; break; /* word alignment */ case 0x0002: alignment_mask = 4; break; /* double-word alignment */ case 0x0007: alignment_mask = 8; break; /* 8-bytes alignment */ default: ++alignment_mask; } for (scsi_id=0; result == RET_OK && scsi_id<scsi_ids_cnt; ++scsi_id) { int lun, lun_cnt = 8; for (lun=0; result == RET_OK && lun<lun_cnt; ++lun) { SRB_GDEVBlock dtype; memset (&dtype, 0, sizeof (SRB_GDEVBlock)); dtype.SRB_Cmd = SC_GET_DEV_TYPE; dtype.SRB_HaId = host_adapter; dtype.SRB_Target = scsi_id; dtype.SRB_Lun = lun; aspi_send_cmd ((LPSRB) &dtype); if (dtype.SRB_Status == SS_COMP) { /* device found */ char device_name [28 + 1]; u_int32_t sector_size, size_in_sectors; /* prepare for an error */ strcpy (device_name, "???"); sector_size = size_in_sectors = -1;#if 1 /* return codes are intentionately ignored */ aspi_inquiry (host_adapter, scsi_id, lun, device_name); aspi_stat (host_adapter, scsi_id, lun, §or_size, &size_in_sectors);#endif result = aspi_dlist_add (*list, host_adapter, scsi_id, lun, dtype.SRB_DeviceType, alignment_mask, device_name, sector_size, size_in_sectors);#if 0 /* left to see how it is done */ const char *type; char device_name [42]; switch (dtype.SRB_DeviceType) { case DTYPE_DASD: type = "Direct access storage device"; break; case DTYPE_SEQD: type = "Sequential access storage device"; break; case DTYPE_PRNT: type = "Printer device"; break; case DTYPE_PROC: type = "Processor device"; break; case DTYPE_WORM: type = "WORM device"; break; case DTYPE_CDROM: type = "CD-ROM device"; break; case DTYPE_SCAN: type = "Scanner device"; break; case DTYPE_OPTI: type = "Optical memory device"; break; case DTYPE_JUKE: type = "Medium changer device"; break; case DTYPE_COMM: type = "Communication device"; break; default: type = "Unknown type"; } printf ("%d:%d:%d ", host_adapter, scsi_id, lun); if (aspi_inquiry (host_adapter, scsi_id, lun, device_name) == RET_OK) printf ("\t%s: %s\n", device_name, type); else printf ("\t???: %s\n", type);#endif } } /* LUN loop */ } /* SCSI ID loop */ } } /* host adapters loop */ } return (result);}/**************************************************************/intaspi_stat (int host, int scsi_id, int lun, u_int32_t *sector_size, u_int32_t *size_in_sectors){ SRB_ExecSCSICmd exec; unsigned char capacity [8]; int result; memset (&exec, 0, sizeof (SRB_ExecSCSICmd)); exec.SRB_Cmd = SC_EXEC_SCSI_CMD; exec.SRB_HaId = host; exec.SRB_Flags = SRB_DIR_IN; exec.SRB_Target = scsi_id; exec.SRB_Lun = lun; exec.SRB_BufLen = sizeof (capacity); exec.SRB_BufPointer = capacity; exec.SRB_SenseLen = SENSE_LEN; exec.SRB_CDBLen = 10; /* MMC2R11A.PDF, 6.1.17 READ CAPACITY; mandatory */ exec.CDBByte [0] = SCSI_RD_CAPAC; result = aspi_exec_to (&exec, ASPI_TIMEOUT_IN_SEC * 1000); if (result == RET_OK) { *size_in_sectors = (capacity [0] << 24 | capacity [1] << 16 | capacity [2] << 8 | capacity [3] << 0) + 1; *sector_size = (capacity [4] << 24 | capacity [5] << 16 | capacity [6] << 8 | capacity [7] << 0); } return (result);}/**************************************************************/intaspi_mmc_read_cd (int host, int scsi_id, int lun, u_int32_t start_sector, u_int32_t num_sectors, u_int32_t sector_size, void *output){ SRB_ExecSCSICmd exec; /* only those sector sizes are supported */ if (sector_size != 2048 && sector_size != 2352) return (RET_ERR); memset (&exec, 0, sizeof (SRB_ExecSCSICmd)); exec.SRB_Cmd = SC_EXEC_SCSI_CMD; exec.SRB_HaId = host; exec.SRB_Flags = SRB_DIR_IN; exec.SRB_Target = scsi_id; exec.SRB_Lun = lun; exec.SRB_BufLen = num_sectors * sector_size; exec.SRB_BufPointer = (unsigned char*) output; exec.SRB_SenseLen = SENSE_LEN; /* MMC-R10A.PDF, 5.1.8 READ CD command; mandatory for CD-devices; suitable for CD-medias; some devices support it for DVD-medias */ exec.SRB_CDBLen = 12; exec.CDBByte [ 0] = 0xBE; exec.CDBByte [ 1] = 0x00; exec.CDBByte [ 2] = (BYTE) ((start_sector >> 24) & 0xff); exec.CDBByte [ 3] = (BYTE) ((start_sector >> 16) & 0xff); exec.CDBByte [ 4] = (BYTE) ((start_sector >> 8) & 0xff); exec.CDBByte [ 5] = (BYTE) ((start_sector >> 0) & 0xff); exec.CDBByte [ 6] = (BYTE) ((num_sectors >> 16) & 0xff); exec.CDBByte [ 7] = (BYTE) ((num_sectors >> 8) & 0xff); exec.CDBByte [ 8] = (BYTE) ((num_sectors >> 0) & 0xff); exec.CDBByte [ 9] = sector_size == 2352 ? 0xF8 : 0x10; exec.CDBByte [10] = 0x00; exec.CDBByte [11] = 0x00; return (aspi_exec_to (&exec, ASPI_TIMEOUT_IN_SEC * 1000));}/**************************************************************/intaspi_read_10 (int host, int scsi_id, int lun, u_int32_t start_sector, u_int32_t num_sectors, void *output){ SRB_ExecSCSICmd exec; memset (&exec, 0, sizeof (SRB_ExecSCSICmd)); exec.SRB_Cmd = SC_EXEC_SCSI_CMD; exec.SRB_HaId = host; exec.SRB_Flags = SRB_DIR_IN; exec.SRB_Target = scsi_id; exec.SRB_Lun = lun; exec.SRB_BufLen = num_sectors * 2048; /* sector size is assumed to be 2048-bytes */ exec.SRB_BufPointer = (unsigned char*) output; exec.SRB_SenseLen = SENSE_LEN; /* SBC-R08C.PDF, 6.1.5 READ(10) command; mandatory for CD- and DVD-devices; suitable for CD- and DVD-medias */ exec.SRB_CDBLen = 12; exec.CDBByte [ 0] = 0x28; exec.CDBByte [ 1] = 0x00; exec.CDBByte [ 2] = (BYTE) ((start_sector >> 24) & 0xff); exec.CDBByte [ 3] = (BYTE) ((start_sector >> 16) & 0xff); exec.CDBByte [ 4] = (BYTE) ((start_sector >> 8) & 0xff); exec.CDBByte [ 5] = (BYTE) ((start_sector >> 0) & 0xff); exec.CDBByte [ 6] = 0x00; exec.CDBByte [ 7] = (BYTE) ((num_sectors >> 8) & 0xff); exec.CDBByte [ 8] = (BYTE) ((num_sectors >> 0) & 0xff); exec.CDBByte [ 9] = 0x00; exec.CDBByte [10] = 0x00; exec.CDBByte [11] = 0x00; return (aspi_exec_to (&exec, ASPI_TIMEOUT_IN_SEC * 1000));}/**************************************************************/static const char*aspi_srb_status_meaning (int status){ switch (status) { /* from wnaspi32.h: */ case SS_PENDING: return ("SRB being processed"); case SS_COMP: return ("SRB completed without error"); case SS_ABORTED: return ("SRB aborted"); case SS_ABORT_FAIL: return ("Unable to abort SRB"); case SS_ERR: return ("SRB completed with error"); case SS_INVALID_CMD: return ("Invalid ASPI command"); case SS_INVALID_HA: return ("Invalid host adapter number"); case SS_NO_DEVICE: return ("SCSI device not installed"); case SS_INVALID_SRB: return ("Invalid parameter set in SRB"); case SS_BUFFER_ALIGN: return ("Buffer not aligned"); case SS_ILLEGAL_MODE: return ("Unsupported Windows mode"); case SS_NO_ASPI: return ("No ASPI managers resident"); case SS_FAILED_INIT: return ("ASPI for windows failed init"); case SS_ASPI_IS_BUSY: return ("No resources available to execute cmd"); case SS_BUFFER_TO_BIG: return ("Buffer size to big to handle"); case SS_MISMATCHED_COMPONENTS: return ("The DLLs/EXEs of ASPI don't version check"); case SS_NO_ADAPTERS: return ("No host adapters to manage"); case SS_INSUFFICIENT_RESOURCES: return ("Couldn't allocate resources needed to init"); case SS_ASPI_IS_SHUTDOWN: return ("Call came to ASPI after PROCESS_DETACH"); case SS_BAD_INSTALL: return ("DLL or other components are installed wrong"); default: return ("Unknown"); }}/**************************************************************/static const char*aspi_sense_key_meaning (int sense){ switch (sense) { /* from SPC-R11A.PDF: */ case 0x00: return ("No sense"); case 0x01: return ("Recovered error"); case 0x02: return ("Not ready"); case 0x03: return ("Medium error"); case 0x04: return ("Hadrware error"); case 0x05: return ("Illegal request"); case 0x06: return ("Unit attention"); case 0x07: return ("Data protect"); case 0x08: return ("Blank check"); case 0x09: return ("Vendor specific"); case 0x0a: return ("Copy aborted"); case 0x0b: return ("Aborted command"); case 0x0c: return ("Obsolete"); case 0x0d: return ("Volume overflow"); case 0x0e: return ("Miscompare"); case 0x0f: return ("Reserved"); default: return ("Unknown"); }}/**************************************************************/static const char*aspi_sense_asc_ascq_meaning (int asc, int ascq){ /* NOTICE: using a static buffer is not a thread-safe */ static char message [100]; /* from SPC-R11A.PDF: */ /**/ if (asc == 0x00 && ascq == 0x00) return ("No additional sense information"); else if (asc == 0x00 && ascq == 0x06) return ("I/O process terminated"); else if (asc == 0x00 && ascq == 0x11) return ("Audio play operation in progress"); else if (asc == 0x00 && ascq == 0x12) return ("Audio play operation paused"); else if (asc == 0x00 && ascq == 0x13) return ("Audio play operation successfully completed"); else if (asc == 0x00 && ascq == 0x14) return ("Audio play operation stopped due to error"); else if (asc == 0x00 && ascq == 0x16) return ("Operation in progress"); else if (asc == 0x00 && ascq == 0x17) return ("Cleaning requested"); else if (asc == 0x04 && ascq == 0x00) return ("Logical unit not ready, cause not reportable"); else if (asc == 0x04 && ascq == 0x01) return ("Logical unit is in process of becoming ready"); else if (asc == 0x04 && ascq == 0x02) return ("Logical unit not ready, initializing cmd. reqd"); else if (asc == 0x04 && ascq == 0x03) return ("Logical unit not ready, manual intervention reqd"); else if (asc == 0x04 && ascq == 0x07) return ("Logical unit not ready, operation in progress"); else if (asc == 0x04 && ascq == 0x08) return ("Logical unit not ready, long write in progress"); else if (asc == 0x05 && ascq == 0x00) return ("Logical unit does not respond to selection"); else if (asc == 0x08 && ascq == 0x00) return ("Logical unit communication failure"); else if (asc == 0x08 && ascq == 0x01) return ("Logical unit communication time-out"); else if (asc == 0x08 && ascq == 0x02) return ("Logical unit communication parity error"); else if (asc == 0x08 && ascq == 0x03) return ("Logical unit communication CRC error"); else if (asc == 0x09 && ascq == 0x00) return ("Track following error"); else if (asc == 0x09 && ascq == 0x01) return ("Track servo failure"); else if (asc == 0x10 && ascq == 0x00) return ("ID CRC or ECC error"); else if (asc == 0x11 && ascq == 0x00) return ("Unrecovered read error"); else if (asc == 0x11 && ascq == 0x06) return ("CIRC unrecovered error"); else if (asc == 0x11 && ascq == 0x11) return ("Read error - loss of streaming"); else if (asc == 0x15 && ascq == 0x00) return ("Random positioning error"); else if (asc == 0x16 && ascq == 0x00) return ("Data synchronization mark error"); else if (asc == 0x16 && ascq == 0x01) return ("Data sync error - data rewritten"); else if (asc == 0x16 && ascq == 0x02) return ("Data sync error - reccomend rewrite"); else if (asc == 0x16 && ascq == 0x03) return ("Data sync error - data auto-reallocated"); else if (asc == 0x16 && ascq == 0x04) return ("Data sync error - reccomend reassignment"); else if (asc == 0x1a && ascq == 0x00) return ("Parameter list length error"); else if (asc == 0x1b && ascq == 0x00) return ("Synchronious data transfer error"); else if (asc == 0x20 && ascq == 0x00) return ("Invalid command operation code"); else if (asc == 0x21 && ascq == 0x00) return ("LBA (logical block address) out of range"); else if (asc == 0x21 && ascq == 0x01) return ("Invalid element address"); else if (asc == 0x24 && ascq == 0x00) return ("Invalid field in CDB"); else if (asc == 0x26 && ascq == 0x00) return ("Invalid field in parameter list"); else if (asc == 0x26 && ascq == 0x01) return ("Parameter not supported"); else if (asc == 0x26 && ascq == 0x02) return ("Parameter value invalid"); else if (asc == 0x29 && ascq == 0x04) return ("Device internal reset"); else if (asc == 0x2b && ascq == 0x00) return ("Copy cannot execute since host cannot disconnect"); else if (asc == 0x2c && ascq == 0x00) return ("Command sequence error"); else if (asc == 0x2f && ascq == 0x00) return ("Commands cleared by another initiator"); else if (asc == 0x30 && ascq == 0x00) return ("Incompatible medium installed"); else if (asc == 0x30 && ascq == 0x01) return ("Cannot read medium - unknown format"); else if (asc == 0x30 && ascq == 0x02) return ("Cannot read medium - incompatible format"); else if (asc == 0x30 && ascq == 0x07) return ("Cleaning failure"); else if (asc == 0x3a && ascq == 0x00) return ("Medium not present"); else if (asc == 0x3a && ascq == 0x01) return ("Medium not present - tray closed"); else if (asc == 0x3a && ascq == 0x02) return ("Medium not present - tray open"); else if (asc == 0x3b && ascq == 0x04) return ("End of medium reached"); else if (asc == 0x3d && ascq == 0x00) return ("Invalid bits in identify message"); else if (asc == 0x3f && ascq == 0x02) return ("Changed operating definition"); else if (asc == 0x3f && ascq == 0x03) return ("Inquiry data has changed"); else if (asc == 0x40) { sprintf (message, "Diagnostic failure on component %02x", ascq); return (message); } else if (asc == 0x44 && ascq == 0x00) return ("Internal target failure"); else if (asc == 0x47 && ascq == 0x00) return ("SCSI parity error"); else if (asc == 0x49 && ascq == 0x00) return ("Invalid message error"); else if (asc == 0x4a && ascq == 0x00) return ("Command phase error"); else if (asc == 0x4b && ascq == 0x00) return ("Data phase error"); else if (asc == 0x63 && ascq == 0x00) return ("End of user data encountered on this track"); else if (asc == 0x64 && ascq == 0x00) return ("Illegal mode for this track"); else if (asc == 0x64 && ascq == 0x01) return ("Invalid packet size"); else if (asc == 0x73 && ascq == 0x00) return ("CD control error"); else { sprintf (message, "ASC %02x, ASCQ %02x", asc, ascq); return (message); }}/**************************************************************/unsigned longaspi_get_last_error_code (void){ /* NOTICE: that is not thread safe */ return ((err_srb_status << 24) | (err_sense << 16) | (err_asc << 8) | (err_ascq));}/**************************************************************/const char*aspi_get_last_error_msg (void){ return (aspi_get_error_msg (aspi_get_last_error_code ()));}/**************************************************************/const char*aspi_get_error_msg (unsigned long aspi_error_code){ int srb_status = (aspi_error_code >> 24) & 0xff; int sense_key = (aspi_error_code >> 16) & 0xff; int asc = (aspi_error_code >> 8) & 0xff; int ascq = aspi_error_code & 0xff; /**/ if (asc != 0x00 && ascq != 0x00) return (aspi_sense_asc_ascq_meaning (asc, ascq)); else if (srb_status != SS_COMP) return (aspi_srb_status_meaning (srb_status)); else return (aspi_sense_key_meaning (sense_key));}/**************************************************************/voidaspi_dispose_error_msg (char *msg){ /* do nothing */ msg = NULL;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -