/* This is part of ODS2 written by Paul Nankervis, * email address: Paulnank@au1.ibm.com * * ODS2 is distributed freely for all members of the * VMS community to use. However all derived works * must maintain comments in their source to acknowledge * the contributions of the original author and * subsequent contributors. This is free software; no * warranty is offered, and while we believe it to be useful, * you use it at your own risk. */ #include #include "scsidefs.h" #include "ssdef.h" #include "stsdef.h" #include "wnaspi32.h" static unsigned ASPI_adapters = 0; /* Count of ASPI adapters */ static unsigned ASPI_devices = 0; /* Count of ASPI devices accessed */ static unsigned ASPI_status = 0; /* Temporary status indicator */ static unsigned ASPI_HaStat = 0; /* Temporary status indicator */ static unsigned ASPI_TargStat = 0; /* Temporary status indicator */ static HANDLE ASPI_event; /* Windows event for ASPI wait */ static SRB_ExecSCSICmd ASPI_srb; /* SRB buffer for ASPI commands */ static unsigned aspi_execute( short bus, short id, BYTE Flags, DWORD BufLen, BYTE *BufPointer, BYTE CDBLen, BYTE CDBByte ); static unsigned aspi_identify( short bus, short id, unsigned *sectors, unsigned *bytespersector ); static unsigned aspi_enumerate(); /************************************************************* aspi_execute() */ static unsigned aspi_execute( short bus, short id, BYTE Flags, DWORD BufLen, BYTE *BufPointer, BYTE CDBLen, BYTE CDBByte ) { ASPI_srb.SRB_Cmd = SC_EXEC_SCSI_CMD; ASPI_srb.SRB_Status = SS_PENDING; ASPI_srb.SRB_HaId = bus; ASPI_srb.SRB_Flags = Flags | SRB_EVENT_NOTIFY; ASPI_srb.SRB_Hdr_Rsvd = 0; ASPI_srb.SRB_Target = id; ASPI_srb.SRB_Lun = 0; ASPI_srb.SRB_Rsvd1 = 0; ASPI_srb.SRB_BufLen = BufLen; ASPI_srb.SRB_BufPointer = BufPointer; ASPI_srb.SRB_SenseLen = SENSE_LEN; ASPI_srb.SRB_CDBLen = CDBLen; ASPI_srb.SRB_HaStat = 0; ASPI_srb.SRB_TargStat = 0; ASPI_srb.SRB_PostProc = ASPI_event; ASPI_srb.SRB_Rsvd2 = NULL; memset( ASPI_srb.SRB_Rsvd3, 0 ,sizeof( ASPI_srb.SRB_Rsvd3 ) ); ASPI_srb.CDBByte[0] = CDBByte; SendASPI32Command( &ASPI_srb ); /* Perform the command... */ while ( ASPI_srb.SRB_Status == SS_PENDING ) { WaitForSingleObject( ASPI_event, INFINITE ); } ResetEvent( ASPI_event ); ASPI_status = ASPI_srb.SRB_Status; ASPI_HaStat = ASPI_srb.SRB_HaStat; ASPI_TargStat = ASPI_srb.SRB_TargStat; if ( ASPI_srb.SRB_Status != SS_COMP ) { return SS$_PARITY; } return SS$_NORMAL; } /************************************************************ aspi_identify() */ /* Routine to identify a device found by ASPI */ static unsigned aspi_identify( short bus, short id, unsigned *sectors, unsigned *bytespersector ) { vmscond_t sts; struct SCSI_Inquiry { unsigned char device; unsigned char dev_qual2; unsigned char version; unsigned char response_format; unsigned char additional_length; unsigned char unused[2]; unsigned char flags; char vendor[8]; char product[16]; char revision[4]; unsigned char extra[60]; } InquiryBuffer; ASPI_srb.CDBByte[1] = 0; /* SCSI Inquiry packet */ ASPI_srb.CDBByte[2] = 0; ASPI_srb.CDBByte[3] = 0; ASPI_srb.CDBByte[4] = sizeof( InquiryBuffer ); ASPI_srb.CDBByte[5] = 0; sts = aspi_execute( bus, id, SRB_DIR_IN, sizeof( InquiryBuffer ), (BYTE *) &InquiryBuffer, 6, SCSI_INQUIRY ); if ( sts & STS$M_SUCCESS ) { ASPI_srb.CDBByte[1] = 0;/* SCSI TEST if ready packet */ ASPI_srb.CDBByte[2] = 0; ASPI_srb.CDBByte[3] = 0; ASPI_srb.CDBByte[4] = 0; ASPI_srb.CDBByte[5] = 0; sts = aspi_execute( bus, id, 0, 0, NULL, 6, SCSI_TST_U_RDY ); if ( !( sts & STS$M_SUCCESS ) ) { ASPI_srb.CDBByte[1] = 0; /* SCSI START STOP packet */ ASPI_srb.CDBByte[2] = 0; ASPI_srb.CDBByte[3] = 0; ASPI_srb.CDBByte[4] = 1; /* Start unit */ ASPI_srb.CDBByte[5] = 0; sts = aspi_execute( bus, id, 0, 0, NULL, 6 ,SCSI_START_STP ); } if ( sts & STS$M_SUCCESS ) { struct { unsigned char blocks[4]; unsigned char sectsz[4]; } CapBuffer; memset( ASPI_srb.CDBByte, 0, sizeof( ASPI_srb.CDBByte ) ); sts = aspi_execute( bus, id, SRB_DIR_IN, sizeof( CapBuffer ), (BYTE *) &CapBuffer, 10, SCSI_RD_CAPAC ); if ( sts & STS$M_SUCCESS ) { *sectors = ( CapBuffer.blocks[0] << 24 ) | ( CapBuffer.blocks[1] << 16 ) | ( CapBuffer.blocks[2] << 8 ) | CapBuffer.blocks[3] ; *bytespersector = ( CapBuffer.sectsz[0] << 24 ) | ( CapBuffer.sectsz[1] << 16 ) | ( CapBuffer.sectsz[2] << 8 ) | CapBuffer.sectsz[3] ; } } printf( "ASPI (Bus %d,ID %d) %8.8s %16.16s %4.4s %s %d\n", bus, id, InquiryBuffer.vendor,InquiryBuffer.product, InquiryBuffer.revision, ( InquiryBuffer.dev_qual2 & 0x80 ) ? "Removable" : "Fixed", *bytespersector ); if ( !( sts & STS$M_SUCCESS ) ) { printf( "Drive not ready.\n" ); sts = SS$_DEVOFFLINE; } } else { printf( "SCSI Inquiry failed.\n" ); sts = SS$_DEVCMDERR; } if ( !( sts & STS$M_SUCCESS ) ) { int i; printf( "ASPI (Bus %d,ID %d) Error sense %x %x %x - ", bus, id, ASPI_status, ASPI_HaStat, ASPI_TargStat ); for ( i = 0; i < SENSE_LEN; i++ ) { printf( " %x", ASPI_srb.SenseArea[i] ); } printf( "\n" ); } return sts; } /*********************************************************** aspi_enumerate() */ /* Initialize ASPI and enumerate the ASPI drives */ static unsigned aspi_enumerate() { short aspi_bus, aspi_id; unsigned sectors, bytespersector; DWORD ASPIStatus; SRB_GDEVBlock Ssrb; if ( ASPI_adapters == 0 ) { ASPIStatus = GetASPI32SupportInfo(); ASPI_status = ASPIStatus; if ( HIBYTE( LOWORD( ASPIStatus ) ) != SS_COMP ) { printf( "Could not initialize ASPI (%x).\n", ASPIStatus ); printf( "Please check that ASPI is installed and started " "properly.\n" ); return 8; } else { ASPI_adapters = LOWORD( LOBYTE( ASPIStatus ) ); ASPI_event = CreateEvent( NULL, FALSE, FALSE, NULL ); if ( ASPI_event == NULL ) { return 8; } } } Ssrb.SRB_Cmd = SC_GET_DEV_TYPE; Ssrb.SRB_HaId = 0; Ssrb.SRB_Flags = SRB_EVENT_NOTIFY; Ssrb.SRB_Hdr_Rsvd = 0; Ssrb.SRB_Lun = 0; ASPI_devices = 0; for ( aspi_bus = 0; aspi_bus < ASPI_adapters; aspi_bus++ ) { for ( aspi_id = 0; aspi_id <= 15; aspi_id++ ) { Ssrb.SRB_HaId = aspi_bus; Ssrb.SRB_Target = aspi_id; ASPIStatus = SendASPI32Command( &Ssrb ); ASPI_status = ASPIStatus; if ( ASPIStatus == SS_COMP ) { ASPI_devices++; sectors = 0; bytespersector = 0; aspi_identify( aspi_bus, aspi_id, §ors, &bytespersector ); printf( "Device Type: 0x%x%s, Sectors: %lu, Bytes Per Sector: %lu\n", Ssrb.SRB_DeviceType, ( ( Ssrb.SRB_DeviceType == DTYPE_CROM ) ? " (CD-ROM)" : ( ( Ssrb.SRB_DeviceType == DTYPE_OPTI ) ? " (Optical)" : "" ) ), sectors, bytespersector ); } } } if ( ASPI_devices == 0 ) { printf( "Could not find a suitable ASPI device.\n" ); return 8; } return SS$_NORMAL; } /********************************************************************* main() */ int main( ) { aspi_enumerate(); return EXIT_SUCCESS; }