home *** CD-ROM | disk | FTP | other *** search
- /* SCCSID = %W% %E% */
- /**************************************************************************
- *
- * SOURCE FILE NAME = ATAPINIT.C
- *
- * DESCRIPTION : ATAPI driver initialization
- *
- *
- * Copyright : COPYRIGHT IBM CORPORATION, 1991, 1992
- * LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
- * REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
- * RESTRICTED MATERIALS OF IBM
- * IBM CONFIDENTIAL
- *
- * VERSION = 1.0
- *
- * DATE
- *
- * DESCRIPTION :
- *
- * Purpose:
- *
- *
- * CHANGE ACTIVITY =
- * DATE FLAG DEFECT CHANGE DESCRIPTION
- * -------- ---------- ------ --------------------------------------
- * 08/22/94 V@93531 93531 1) Suspend/Resume logic passes IRQ handler
- * address. 2) DRQ polling is not valid while
- * BSY bit set.
- * 09/08/94 @V98451 Add Resource Manger
- * 03/07/94 @V117508 117508 Remove unneeded ctxhook procedure and data
- * 04/03/95 @V117508 117508 Add #defines to include MCA version of driver
- * 05/10/95 @V121891 121891 Fix problem in 2 min time delay fix - most
- * of which was resolved in 117508.
- * 11/30/95 @V132280 PJ19658 Fix so as not to claim non-CDROM units -
- * GetATAPIUnits().
- * Added HWRESOURCE to fix Suspend/Resume.
- * 02/02/96 @V127556 BT update. Got rid of extra Resume which
- * was being sent to IBM1S506.ADD at init.
- * 04/05/96 @V151168 Merged warm dock/swap code.
- * 05/09/96 @V153151 Moved some code and data from init to
- * run-time residency.
- * 05/24/96 @V155162 Thinkpad docking/swapping IDE update.
- * 06/18/96 @V156660 Synched search keys in RM between IBMIDECD
- * and IBM1S506.
- * 08/26/96 @V162970 Fixed the DIAMOND 8X CDROM problem.
- * 04/26/98 @V195083 Added Panasonic PD support.
- ***************************************************************************/
-
- #define INCL_NOBASEAPI
- #define INCL_NOPMAPI
- #define INCL_DOSERRORS
- #include "os2.h"
- #include "dos.h"
- #include "bseerr.h"
- #include "devclass.h"
- #include "dskinit.h"
-
- #include "iorb.h"
- #include "addcalls.h"
- #include "dhcalls.h"
- #include "apmcalls.h" /*@V151168*/
-
- #define INCL_INITRP_ONLY
- #include "reqpkt.h"
-
- #include "scsi.h"
- #include "cdbscsi.h"
-
- #include "atapicon.h"
- #include "atapireg.h"
- #include "atapityp.h"
- #include "atapiext.h"
- #include "atapipro.h"
- #include "rmcalls.h"
-
- static strnswap( PSZ d, PSZ s, USHORT n );
- VOID NEAR set_data_in_sg( PBYTE, PIORB_ADAPTER_PASSTHRU, USHORT ); /*@V151168*/
-
- // If the CDROM is not present, use this code to Fake the /*@V151168*/
- // operations so that OS2CDROM.DMD believes that a CD-ROM /*@V151168*/
- // is really there but empty /*@V151168*/
- int FakeATA(NPACB npACB) /*@V151168*/
- { /*@V151168*/
- PBYTE pSGVirtBuf; //virtual address of SG xfer buffer /*@V151168*/
- PSCATGATENTRY pSGLIST; /*@V151168*/
- USHORT Flag; /*@V151168*/
- /*@V151168*/
- npACB->pIORB->Status = IORB_DONE; /*@V151168*/
- npACB->pIORB->ErrorCode = 0; // to be sure this succeeds /*@V151168*/
- /*@V151168*/
- if (npACB->npUCB->ReqFlags & UCBR_IDENTIFY) /*@V151168*/
- { /*@V151168*/
- // Copy Fake ATA Identify Buffer and set request done /*@V151168*/
- /*@V151168*/
- pSGLIST = ( (PIORB_ADAPTER_PASSTHRU)(npACB->pIORB))->pSGList; /*@V151168*/
- /*@V151168*/
- // SGlist has phys buffer pointer, convert to Virt to use /*@V151168*/
- if ( DevHelp_PhysToVirt( pSGLIST->ppXferBuf, /*@V151168*/
- (USHORT)pSGLIST->XferBufLen, /*@V151168*/
- (PVOID) &pSGVirtBuf, /*@V151168*/
- &Flag ) ) /*@V151168*/
- { // we should never get here.... /*@V151168*/
- _asm int 3 /*@V151168*/
- } /*@V151168*/
- memcopy( (PBYTE)pSGVirtBuf, /*@V151168*/
- (PBYTE)&atapi_identify_data, /*@V151168*/
- (USHORT)pSGLIST->XferBufLen); /*@V151168*/
- return(0); /*@V151168*/
- } /*@V151168*/
- /*@V151168*/
- if (npACB->npUCB->ReqFlags & UCBR_RESET) /*@V151168*/
- { /*@V151168*/
- //Make believe a reset hapened /*@V151168*/
- return(0); /*@V151168*/
- /*@V151168*/
- } /*@V151168*/
- npACB->pIORB->Status = IORB_DONE | IORB_ERROR; /*@V151168*/
- npACB->pIORB->ErrorCode = IOERR_CMD_SYNTAX; // Failure code /*@V151168*/
- return(1); //error, unknown command /*@V151168*/
- } /*@V151168*/
- /*@V151168*/
- // /*@V151168*/
- // Fake ATAPI requests /*@V151168*/
- // /*@V151168*/
- int FakeATAPI(NPACB npACB) /*@V151168*/
- { /*@V151168*/
- UCHAR Opcode; /* ATAPI Packet Commands Opcode */ /*@V151168*/
- PIORB_ADAPTER_PASSTHRU pIORB_pass = /*@V151168*/
- (PIORB_ADAPTER_PASSTHRU)npACB->pIORB; /*@V151168*/
- PSCSI_REQSENSE_DATA pSenseData; /* for setting return status */ /*@V151168*/
- struct CDB_ModeSense_10 FAR *pCDB; /*@V151168*/
- UCHAR ASC; /* additional sense code */ /*@V151168*/
- /* pointer to the SCSI status block */ /*@V151168*/
- PSCSI_STATUS_BLOCK pSCSISB; /*@V151168*/
- /*@V151168*/
- /* ATAPI Commands for CD-ROM Drives */ /*@V151168*/
- /*@V151168*/
- /*@V151168*/
- Opcode = pIORB_pass->pControllerCmd[0]; /*@V151168*/
- /*@V151168*/
- switch ( Opcode ) { /*@V151168*/
- /*@V151168*/
- case SCSI_INQUIRY : /*@V151168*/
- /* set INQUIRY data in s/g list. */ /*@V151168*/
- set_data_in_sg( (PBYTE) &inquiry_data, pIORB_pass, /*@V151168*/
- sizeof( SCSI_INQDATA ) ); /*@V151168*/
- pSenseData = &no_audio_status; /* set OK status */ /*@V151168*/
- break; /*@V151168*/
- /*@V151168*/
- case SCSI_MODE_SELECT_10 : /*@V151168*/
- /* set Invalid field in Command Packet */ /*@V151168*/
- pSenseData = &invalid_field_in_cmd_pkt; /*@V151168*/
- break; /*@V151168*/
- /*@V151168*/
- case SCSI_MODE_SENSE_10 : /*@V151168*/
- pCDB = (struct CDB_ModeSense_10 FAR *) /*@V151168*/
- pIORB_pass->pControllerCmd; /*@V151168*/
- /*@V151168*/
- if ( pCDB->page_code == PAGE_CAPABILITIES && /*@V151168*/
- ( pCDB->PC == PC_DEFAULT || pCDB->PC == PC_CURRENT ) ) {/*@V151168*/
- /*@V151168*/
- /* set mode sense data in s/g list. */ /*@V151168*/
- set_data_in_sg( (PBYTE) mode_sense_10_page_cap, pIORB_pass,/*@V151168*/
- LEN_MODE_SENSE_10 ); /*@V151168*/
- pSenseData = &no_audio_status; /* set OK status */ /*@V151168*/
- /*@V151168*/
- } /*@V151168*/
- else /*@V151168*/
- { /*@V151168*/
- /* set NOT-READY status */ /*@V151168*/
- pSenseData = &medium_not_present; /*@V151168*/
- } /*@V151168*/
- break; /*@V151168*/
- /*@V151168*/
- case SCSI_REQUEST_SENSE : /*@V151168*/
- /* sense data is read in s/g list.* */ /*@V151168*/
- set_data_in_sg( (PBYTE) &medium_not_present, pIORB_pass, /*@V151168*/
- sizeof( SCSI_REQSENSE_DATA ) ); /*@V151168*/
- pSenseData = &no_audio_status; /* set OK status */ /*@V151168*/
- break; /*@V151168*/
- /*@V151168*/
- case SCSI_TEST_UNIT_READY : /*@V151168*/
- default : /*@V151168*/
- /* set NOT-READY status */ /*@V151168*/
- pSenseData = &medium_not_present; /*@V151168*/
- break; /*@V151168*/
- /*@V151168*/
- } /* endswitch */ /*@V151168*/
- /*@V151168*/
- /*@V151168*/
- /* set ErrorCode from additional Sense Code. */ /*@V151168*/
- /* pSenseData must be set appropriately. */ /*@V151168*/
- /*@V151168*/
- ASC = pSenseData->AddSenseCode; /*@V151168*/
- /*@V151168*/
- if ( ASC > MaxAddSenseDataEntry ) { /*@V151168*/
- npACB->pIORB->ErrorCode = IOERR_ADAPTER_REFER_TO_STATUS; /*@V151168*/
- } else { /*@V151168*/
- npACB->pIORB->ErrorCode = AddSenseDataMap[ASC]; /*@V151168*/
- } /*@V151168*/
- npACB->IORBError = npACB->pIORB->ErrorCode; /* make sure */ /*@V151168*/
- /*@V151168*/
- if ( npACB->pIORB->ErrorCode ) { /*@V151168*/
- /*@V151168*/
- npACB->pIORB->Status |= IORB_ERROR | IORB_DONE; /*@V151168*/
- /*@V151168*/
- /* return sense data if requested */ /*@V151168*/
- /*@V151168*/
- if ( npACB->pIORB->RequestControl & IORB_REQ_STATUSBLOCK ) { /*@V151168*/
- pSCSISB = MAKEP( SELECTOROF(npACB->pIORB), /*@V151168*/
- (NPBYTE) npACB->pIORB->pStatusBlock); /*@V151168*/
- memcopy( (PBYTE) pSCSISB->SenseData, /*@V151168*/
- (PBYTE) pSenseData, /*@V151168*/
- ( pSCSISB->ReqSenseLen > SENSE_DATA_BYTES ) ? /*@V151168*/
- /* min(a, b) */ /*@V151168*/
- SENSE_DATA_BYTES : pSCSISB->ReqSenseLen ); /*@V151168*/
- /*@V151168*/
- /* sense data is vaild */ /*@V151168*/
- pSCSISB->Flags |= STATUS_SENSEDATA_VALID; /*@V151168*/
- /* status info returned */ /*@V151168*/
- npACB->pIORB->Status |= IORB_STATUSBLOCK_AVAIL; /*@V151168*/
- } /*@V151168*/
- } else { /*@V151168*/
- npACB->pIORB->Status |= IORB_DONE; /*@V151168*/
- } /*@V151168*/
- /*@V151168*/
- return( FALSE ); /*@V151168*/
- } /*@V151168*/
- /*@V151168*/
- /*----------------------------------------------------------------*//*@V151168*/
- /* Function: Copy data from buffer to S/G list. *//*@V151168*/
- /* Input: pbuf, pIORB, buf_len *//*@V151168*/
- /* Output: none *//*@V151168*/
- /*----------------------------------------------------------------*//*@V151168*/
- VOID NEAR set_data_in_sg( PBYTE pbuf, PIORB_ADAPTER_PASSTHRU pIORB, /*@V151168*/
- USHORT buf_len ) /*@V151168*/
- { /*@V151168*/
- UCHAR i; /*@V151168*/
- PSCATGATENTRY pTempSGList; /*@V151168*/
- ULONG ppSrcDst; /* physical address */ /*@V151168*/
- PBYTE pSrcDst; /* virtual address by PhysToVirt *//*@V151168*/
- USHORT XferCur; /* segment length */ /*@V151168*/
- USHORT ModeFlag; /* for PhysToVirt */ /*@V151168*/
- USHORT copy_bytes; /*@V151168*/
- USHORT total_bytes; /* total_bytes + nokori_bytes == buf_len *//*@V151168*/
- USHORT nokori_bytes; /*@V151168*/
- /*@V151168*/
- pTempSGList = pIORB->pSGList; /*@V151168*/
- total_bytes = 0; /*@V151168*/
- nokori_bytes = buf_len; /*@V151168*/
- /*@V151168*/
- for (i=0; i<pIORB->cSGList && total_bytes<buf_len ; i++, /*@V151168*/
- pTempSGList++) { /*@V151168*/
- /*@V151168*/
- ppSrcDst = pTempSGList->ppXferBuf; /*@V151168*/
- XferCur = pTempSGList->XferBufLen; /*@V151168*/
- /*@V151168*/
- if ( DevHelp_PhysToVirt( ppSrcDst, XferCur, /*@V151168*/
- (PVOID) &pSrcDst, &ModeFlag ) ) { /*@V151168*/
- #ifdef DEBUG /*@V151168*/
- INT3; /*@V151168*/
- #endif /*@V151168*/
- } /*@V151168*/
- /*@V151168*/
- copy_bytes = ( XferCur < nokori_bytes ) ? XferCur : /*@V151168*/
- nokori_bytes; /*@V151168*/
- memcopy( pSrcDst, pbuf, copy_bytes); /*@V151168*/
- /*@V151168*/
- total_bytes += copy_bytes; /* update # of copied bytes */ /*@V151168*/
- pbuf += copy_bytes; /* increment pointer */ /*@V151168*/
- nokori_bytes -= copy_bytes;/* update # of byte to be copied *//*@V151168*/
- } /* endfor */ /*@V151168*/
- } /*@V151168*/
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID FAR _loadds NotifyIORBDone( PIORB pIORB ) /*@V153151*/
- {
- USHORT AwakeCount;
- PUCHAR pWSFlags; /* work space flags */
-
- pWSFlags = pIORB->DMWorkSpace;
-
- DISABLE
- if ( ( pIORB->Status & IORB_DONE ) && ( *pWSFlags & WSF_PROC_BLOCK ) )
- {
- *pWSFlags &= ~WSF_PROC_BLOCK;
- DevHelp_ProcRun( (ULONG) pIORB, &AwakeCount );
- }
- ENABLE
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT GetIdentifyData( NPACB npACB, USHORT UnitId, PBYTE pID )
- {
- NPIORB_ADAPTER_PASSTHRU npIORB = &InitIORB;
- NPUCB npUCB = &npACB->UnitCB[UnitId];
- USHORT ErrorCode = 0;
- PUCHAR pWSFlags; /* work space flags */
- NPIDENTIFYDATA npID; /*@V151168*/
-
- npUCB->ReqFlags |= UCBR_IDENTIFY;
-
- if ( DevHelp_VirtToPhys( (PVOID) pID,
- (PULONG) &IdentifySGList.ppXferBuf ) )
- {
- _asm { int 3 }
- }
-
- pWSFlags = (PUCHAR) npIORB->iorbh.DMWorkSpace;
- setmem( (PBYTE) npIORB, 0, sizeof(IORB_ADAPTER_PASSTHRU) );
-
- npIORB->iorbh.Length = sizeof(IORB_ADAPTER_PASSTHRU);
- npIORB->iorbh.UnitHandle = (USHORT) &npACB->UnitCB[UnitId];
- npIORB->iorbh.CommandCode = IOCC_ADAPTER_PASSTHRU;
- npIORB->iorbh.CommandModifier = IOCM_EXECUTE_ATA;
- npIORB->iorbh.Status = 0; /*@V132280*/
- npIORB->iorbh.RequestControl = IORB_ASYNC_POST;
- npIORB->iorbh.NotifyAddress = NotifyIORBDone; /*@V153151*/
- npIORB->cSGList = 1;
- npIORB->pSGList = &IdentifySGList;
-
- ATAPIADDEntry( (PIORB) npIORB );
-
- DISABLE
- *pWSFlags |= WSF_PROC_BLOCK;
-
- while( !(npIORB->iorbh.Status & IORB_DONE) )
- {
- DevHelp_ProcBlock( (ULONG)(PIORB) npIORB, -1, WAIT_IS_NOT_INTERRUPTABLE );
- DISABLE
- }
-
- npUCB->ReqFlags &= ~UCBR_IDENTIFY;
-
- ENABLE
-
- npID = (NPIDENTIFYDATA)pID; /*@V151168*/
- /*@V151168*/
- if ( (npIORB->iorbh.Status & IORB_ERROR) || /*@V151168*/
- (npID->ModelNum[0] == 0) ) /*@V151168*/
- { // if failure, check if forced unit, if so set flag if /*@V151168*/
- // not present /*@V151168*/
- if( npUCB->Flags & UCBF_FORCE ) /*@V155162*/
- { /*@V151168*/
- npUCB->Flags |= UCBF_NOTPRESENT; //set fake flag /*@V151168*/
- npIORB->iorbh.Status |= IORB_ERROR; /*@V155162*/
- npIORB->iorbh.ErrorCode = IOERR_UNIT_NOT_READY; /*@V155162*/
- } /*@V151168*/
- } /*@V151168*/
-
- return( (npIORB->iorbh.Status & IORB_ERROR) ? npIORB->iorbh.ErrorCode : 0 );
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- static strnswap( PSZ d, PSZ s, USHORT n )
- {
- USHORT j = 1;
-
- while( s[j] && n-- ) { *d++ = s[j]; j^=1; s+=(j*2); }
- *d = 0;
-
- return ( 0 );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR ATAPIIdentify( NPATBL npAT )
- {
- NPIDENTIFYDATA npID;
- NPUTBL npUT;
- NPACB npACB = npAT->npACB;
- NPUCB npUCB;
- USHORT rc;
- USHORT UnitType = 0xff;
- USHORT Model;
- USHORT UnitId;
-
- npID = (NPIDENTIFYDATA) ScratchBuf;
- UnitId = npACB->npUCB->UnitId;
- npUT = &npAT->Unit[UnitId];
- npUCB = npACB->npUCB;
-
- npUCB->Capabilities = 0; /*@V93531*/
-
- if ( !(rc=GetIdentifyData( npACB, UnitId, (PBYTE) npID )))
- {
- #define DONTCARE 0
- #define NEC_CDR_260 1
- #define NEC_CDR_250 2
- #define MATSHITA_CR_571 3
-
- if( strncmp( MatshitaID, /*@V155162*/
- npID->ModelNum,sizeof(npID->ModelNum)))
- Model = MATSHITA_CR_571;
- else if( strncmp( Nec01ID, /*@V155162*/
- npID->ModelNum,sizeof(npID->ModelNum)))
- {
- Model = NEC_CDR_260;
- strncpy( npUT->Firmware, npID->Firmware, sizeof(npID->Firmware));
- if( strncmp( Nec01FWID, /*@V155162*/
- npID->Firmware, sizeof(npID->Firmware)))
- {
- npUCB->Capabilities |= UCBC_SPEC_REV_17B;
- npUCB->Capabilities |= UCBC_IRQ_ON_ATA_COMPLETE;
- npACB->IRQTimeOut *= 4;
- }
- }
- else if( strncmp( Nec02ID, /*@V155162*/
- npID->ModelNum,sizeof(npID->ModelNum)))
- {
- Model = NEC_CDR_250;
- }
- else
- Model = DONTCARE;
-
- /*
- ┌────────────────────────────────────────┐
- │ Save Model/Serial/Firmware Information │
- └────────────────────────────────────────┘
- */
- if ( (Model == NEC_CDR_260 ) &&
- ( npUCB->Capabilities & UCBC_SPEC_REV_17B) )
- {
- strncpy( npUT->ModelNum, npID->ModelNum, sizeof(npID->ModelNum));
- strncpy( npUT->Serial, npID->Serial, sizeof(npID->Serial));
- }
- else
- {
- strnswap( npUT->ModelNum, npID->ModelNum, sizeof(npID->ModelNum)-2);
- strnswap( npUT->Serial, npID->Serial, sizeof(npID->Serial)-2);
- strnswap( npUT->Firmware, npID->Firmware, sizeof(npID->Firmware)-2);
- }
-
- if( strncmp( npUT->Serial, BlankSerial, /*@V155162*/
- sizeof(npID->Serial) ) )
- npUT->Serial[0] = 0;
-
- switch (npID->GenConfig.CmdPktSize)
- {
- case 0 : npUCB->CmdPacketLength = 12;
- break;
-
- case 1 : npUCB->CmdPacketLength = 16;
- break;
-
- default: npUCB->CmdPacketLength = 00;
- rc = 1;
- }
-
- switch (npID->GenConfig.CmdDRQType)
- {
- case 0 : npUCB->Capabilities |= UCBC_MICROPROCESSOR_DRQ;
- break;
-
- case 1 : npUCB->Capabilities |= UCBC_INTERRUPT_DRQ;
- break;
-
- case 2 : npUCB->Capabilities |= UCBC_ACCELERATED_DRQ;
- break;
-
- default: npUCB->Capabilities |= UCBC_MICROPROCESSOR_DRQ;
- rc = 1;
- }
-
- switch (npID->GenConfig.ProtocolType)
- {
- case 0 :
- case 1 : npUCB->Capabilities |= UCBC_ATA;
- break;
-
- case 2 :
- case 3 : npUCB->Capabilities |= UCBC_ATAPI;
- break;
-
- default: npUCB->Capabilities |= UCBC_ATA;
- rc = 1;
- }
-
- switch ( UnitType = npID->GenConfig.DeviceType )
- {
- case UIB_TYPE_DISK :
- npUCB->Capabilities |= UCBC_DIRECT_ACCESS_DEVICE;
- break;
-
- case UIB_TYPE_CDROM :
- npUCB->Capabilities |= UCBC_CDROM_DEVICE;
- break;
-
- case UIB_TYPE_OPTICAL_MEMORY :
- npUCB->Capabilities |= UCBC_OPTICAL_MEMORY_DEVICE;
- break;
-
- default: npUCB->Capabilities &= ~(UCBC_DIRECT_ACCESS_DEVICE |
- UCBC_CDROM_DEVICE |
- UCBC_OPTICAL_MEMORY_DEVICE);
- rc = 1;
- }
-
- if ( npID->Capabilities & IDD_DMASupported )
- npUCB->Capabilities |= UCBC_DMA;
- else
- npUCB->Capabilities &= ~UCBC_DMA;
-
- if ( npID->Capabilities & IDD_LBASupported )
- npUCB->Capabilities |= UCBC_LBA;
- else
- npUCB->Capabilities &= ~UCBC_LBA;
-
- if ( npID->Capabilities & IDD_IORDYSupported )
- npUCB->Capabilities |= UCBC_IORDY;
- else
- npUCB->Capabilities &= ~UCBC_IORDY;
-
- if ( npID->Capabilities & IDD_IORDYDisablable )
- npUCB->Capabilities |= UCBC_IORDY_DISABLE;
- else
- npUCB->Capabilities &= ~UCBC_IORDY_DISABLE;
-
- switch ( Model )
- {
- case NEC_CDR_260 :
- case NEC_CDR_250 :
- UnitType = 5;
- npUCB->CmdPacketLength = 12;
- npUCB->Capabilities |= UCBC_MICROPROCESSOR_DRQ |
- UCBC_ATAPI |
- UCBC_CDROM_DEVICE;
- rc = 0;
- break;
-
- case MATSHITA_CR_571 :
- npUCB->Capabilities &= ~UCBC_SPEC_REV_17B;
- npUCB->Capabilities |= UCBC_IRQ_ON_ATA_COMPLETE;
- break;
-
- default:
- npUCB->Capabilities &= ~UCBC_SPEC_REV_17B;
- npUCB->Capabilities &= ~UCBC_IRQ_ON_ATA_COMPLETE;
- }
- }
-
- if ( rc )
- {
- return( -1 );
- }
-
- return( UnitType );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR InitSuspendOtherAdd( NPACB npACB )
- {
- PIORB_DEVICE_CONTROL pIORB;
- PUCHAR pWSFlags; /* work space flags */
-
- DISABLE
- if ( npACB->iorbinuse )
- {
- _asm int 3
- }
- npACB->iorbinuse = 1;
- ENABLE
-
- pIORB = (PIORB_DEVICE_CONTROL) &npACB->IORB;
- pWSFlags = pIORB->iorbh.DMWorkSpace;
- setmem( (PVOID) pIORB, 0, sizeof(npACB->IORB));
-
- pIORB->iorbh.Length = sizeof(IORB_DEVICE_CONTROL);
- pIORB->iorbh.UnitHandle = npACB->SharedDriverUnitHandle;
- pIORB->iorbh.CommandCode = IOCC_DEVICE_CONTROL;
- pIORB->iorbh.CommandModifier = IOCM_SUSPEND;
- pIORB->iorbh.Status = 0; /*@V132280*/
- pIORB->iorbh.RequestControl = IORB_ASYNC_POST;
- pIORB->iorbh.NotifyAddress = NotifyIORBDone; /*@V153151*/
- pIORB->IRQHandlerAddress = npACB->IRQHandler; /*@V93531*/
- pIORB->Flags = DC_SUSPEND_IMMEDIATE /*@V93531*/
- | DC_SUSPEND_IRQADDR_VALID; /*@V93531*/
-
- (*npACB->SharedDriverEP) ((PVOID)(pIORB));
-
- DISABLE
- *pWSFlags |= WSF_PROC_BLOCK;
-
- while( !(pIORB->iorbh.Status & IORB_DONE) )
- {
- DevHelp_ProcBlock( (ULONG) pIORB, -1, WAIT_IS_NOT_INTERRUPTABLE );
- DISABLE
- }
-
- npACB->iorbinuse = 0;
- ENABLE
-
- return( pIORB->iorbh.ErrorCode );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR InitResumeOtherAdd( NPACB npACB )
- {
- PIORB_DEVICE_CONTROL pIORB;
- PUCHAR pWSFlags; /* work space flags */
-
- DISABLE
- if ( npACB->iorbinuse )
- {
- _asm int 3
- }
- npACB->iorbinuse = 1;
- ENABLE
-
- pIORB = (PIORB_DEVICE_CONTROL) &npACB->IORB;
- pWSFlags = pIORB->iorbh.DMWorkSpace;
- setmem( (PVOID) pIORB, 0, sizeof(npACB->IORB));
-
- pIORB->iorbh.Length = sizeof(IORB_DEVICE_CONTROL);
- pIORB->iorbh.UnitHandle = npACB->SharedDriverUnitHandle;
- pIORB->iorbh.CommandCode = IOCC_DEVICE_CONTROL;
- pIORB->iorbh.CommandModifier = IOCM_RESUME;
- pIORB->iorbh.Status = 0; /*@V132280*/
- pIORB->iorbh.RequestControl = IORB_ASYNC_POST;
- pIORB->iorbh.NotifyAddress = NotifyIORBDone; /*@V153151*/
-
- pIORB->Flags |= DC_SUSPEND_IMMEDIATE;
-
- (*npACB->SharedDriverEP) ((PVOID)(pIORB));
-
- DISABLE
- *pWSFlags |= WSF_PROC_BLOCK;
-
- while( !(pIORB->iorbh.Status & IORB_DONE) )
- {
- DevHelp_ProcBlock( (ULONG) pIORB, -1, WAIT_IS_NOT_INTERRUPTABLE );
- DISABLE
- }
-
- npACB->iorbinuse = 0;
- ENABLE
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT FAR CheckReady( NPACB npACB )
- {
- ULONG WaitCount;
- USHORT Status;
-
- npACB->TimerFlags &= ~ACBT_BUSY;
-
- WaitCount = CheckReadyCount;
-
- while( WaitCount-- )
- {
- Status = GetRegister( npACB, FI_PSTATUS );
-
- if ( !(Status & FX_BUSY) && (Status & FX_READY) )
- {
- if ( !Calibrate )
- break;
- }
- }
-
- if ( Status & FX_BUSY )
- {
- npACB->TimerFlags |= ACBT_BUSY;
- }
-
- npACB->IORegs[FI_PSTATUS] = Status;
-
- return( ((npACB->TimerFlags & ACBT_BUSY) || !(Status & FX_READY)) ? 1 : 0);
- }
-
-
- /*------------------------------------------------------------------------*/
- /* */
- /* Calibration Routines */
- /* */
- /* These routines adjust the loop counts in various I/O */
- /* workers to achieve the correct real-time delays and */
- /* timeout values. */
- /* */
- /*------------------------------------------------------------------------*/
-
- /*------------------------------------*/
- /* CalibrateTimers */
- /* */
- /* This routine does calibration of */
- /* the IODelay and other timed */
- /* functions */
- /* */
- /*------------------------------------*/
-
- VOID FAR CalibrateTimers( NPACB npACB )
- {
- /*----------------------------------------*/
- /* Set a known loop count for each worker */
- /*----------------------------------------*/
-
- CheckReadyCount = CALIBRATE_LOOP_COUNT;
- IODelayCount = CALIBRATE_LOOP_COUNT;
- WaitDRQCount = CALIBRATE_LOOP_COUNT;
- WaitBSYCount = CALIBRATE_LOOP_COUNT;
-
- /*----------------------------------------------------*/
- /* CalibrateWorker returns the loop count for the */
- /* worker routine to achieve a delay of 1ms. */
- /* */
- /* This loop count is scaled up (or down) to achieve */
- /* the requested realtime delay. */
- /* */
- /* Note: all timed functions are dependent on the */
- /* IODelay worker! Therefore IODelay must be */
- /* calibrated first. */
- /*----------------------------------------------------*/
-
- IODelayCount = CalibrateWorker( npACB, (PCV) &IODelay ) / uSPerMS;
- if ( !IODelayCount )
- IODelayCount = 1;
-
- CheckReadyCount = CalibrateWorker( npACB, (PCV) &CheckReady ) * MAX_WAIT_READY;
- if ( !CheckReadyCount )
- CheckReadyCount = 100;
-
- WaitBSYCount = CalibrateWorker( npACB, (PCV) &CheckReady ) * MAX_WAIT_BSY;
- if ( !WaitBSYCount )
- WaitBSYCount = 1000;
-
- WaitDRQCount = CalibrateWorker( npACB, (PCV) &BSY_CLR_DRQ_SET_WAIT ) * MAX_WAIT_DRQ;
- if ( !WaitDRQCount )
- WaitDRQCount = 1000;
-
- }
-
- /*-----------------------------------------------*/
- /* CalibrateWorker */
- /* */
- /* We call the worker routine with a known loop */
- /* count for a known realtime interval. */
- /* */
- /*-----------------------------------------------*/
- ULONG FAR CalibrateWorker( NPACB npACB, PCV pWorker )
- {
- ULONG CallCount = 0;
-
- Calibrate = 1;
- CallWorker = 1;
- CallWorkerSync = 1;
-
- if ( ADD_StartTimerMS((PULONG) &CalibrateTimerHandle,
- (ULONG) CALIBRATE_TIMER_INTERVAL,
- (PFN) CalibrateTimer,
- (ULONG) 0,
- (ULONG) 0 ) )
- {
- _asm { int 3 }
- }
-
- /*--------------------------------------*/
- /* Synchronize with the begining of the */
- /* next timer interval */
- /*--------------------------------------*/
- while ( CallWorkerSync )
- ;
-
- /*--------------------------------------*/
- /* Call the worker until the interval */
- /* expires. */
- /*--------------------------------------*/
- while ( CallWorker )
- {
- (*pWorker)( npACB );
-
- CallCount++;
- }
-
- ADD_CancelTimer( CalibrateTimerHandle );
-
- Calibrate = 0;
-
- /*-----------------------------------------------*/
- /* The number of calls to the worker times the */
- /* known worker loop count divided by the */
- /* realtime interval in miliseconds gives us */
- /* the proper loop count for 1ms of delay. */
- /* */
- /* Note: The timer package adds 1 tick to the */
- /* calculated interval to compensate */
- /* for it not being aligned. We factor */
- /* this out by using this alternate */
- /* define for the interval. */
- /*-----------------------------------------------*/
-
- CallCount *= CALIBRATE_LOOP_COUNT;
-
- return ( CallCount / CALIBRATE_INTERVAL_ACTUAL );
- }
-
- /*---------------------------------------*/
- /* CalibrateTimer */
- /* */
- /* This routine is called by the */
- /* timer handler each time a calibration */
- /* interval expires */
- /* */
- /* Normally two calibration intervals */
- /* elapse. One so that we can sync up */
- /* with the timer and one to do the */
- /* calibration. */
- /* */
- /*---------------------------------------*/
- VOID FAR CalibrateTimer( ULONG hCalibrateTimer, ULONG Unused1, ULONG Unused2 )
- {
- if ( CallWorkerSync )
- {
- CallWorkerSync = 0;
- }
- else
- {
- CallWorker = 0;
- }
- }
-
-
- /*
- ** Called from: DriverInit() Resume = FALSE
- ** APMResume() Resume = TRUE
- **
- ** With Resume = FALSE, issue IOCM_ALLOCATE_UNIT command to the device
- ** driver that identified the ATAPI unit. The unit can be real or
- ** FORCEd but must be identified as an ATAPI device at power-on boot
- ** initialization. The IOCM_ALLOCATE_UNIT command is done only once at
- ** initialization time. At APMResume(), Resume = TRUE, try to recognize
- ** and activate the drive that MAY now be present. If UCBF_NOTPRESENT
- ** is set then unit is definitely not currently present.
- ** UCBF_NOTRPRESENT is always reset when this routine is called from
- ** APMResume().
- **
- ** Normaly the device's registers are defined for FORCEd adapters but
- ** in the case of PCMCIA attached adapters, it is possible the registers
- ** may not yet be defined in AdapterTable. In this case short circuit
- ** ATAPIIdentify() and set the UCBF_NOTPRESENT and return.
- */
- USHORT NEAR ClaimUnit( NPATBL npAT, BOOL Resume, USHORT UnitHandle, /*@V155162*/
- PUNITINFO pOldUnitInfo, VOID (FAR *DriverEP)() )
- {
- PUNITINFO pUI;
- NPACB npACB;
-
- USHORT rc = 0;
- USHORT UnitType;
-
- USHORT FeatureReg; /*@V98451*/
- ULONG OldIRQTimeOut; /*@V117508*/
- NPUCB npUCB; /*@V155162*///vbr
- USHORT l, num_retry; /*@V162970*/
-
- npACB = npAT->npACB; /*@V155162*/
- npUCB = npACB->npUCB; /*@V155162*///vbr
-
- /* @V155162
- ** PCMCIA adapters may not have registers defined yet. @V155162
- ** If not then the FORCEd unit is definitely not present. @V155162
- ** The registers will be defined during PCMCIA card insertion @V155162
- ** event procssing for this driver. @V155162
- */ /*@V155162*/
- if( !npAT->BasePort ) /*@V155162*/
- { /*@V155162*/
- npUCB->Flags |= UCBF_NOTPRESENT; /*@V155162*/
- } /*@V155162*/
- else if( npUCB->Flags & UCBF_NOTPRESENT ) /*@V155162*/
- { /*@V155162*/
- UnitType = UIB_TYPE_CDROM; /*@V155162*/
- } /*@V155162*/
- else /*@V155162*/
- { /*@V155162*/
- /* @V127556
- ** Suspend ATA driver so we can calibrate this driver to the HW. @V127556
- */ /*@V127556*/
- if( !(rc = InitSuspendOtherAdd( npACB )) ) /*@V127556*/
- { /*@V127556*/
- npACB->suspended = 0; /*@V127556*/
- npACB->ResourceFlags |= ACBRF_CURR_OWNER; /*@V127556*/
- } /*@V127556*/
- else /*@V127556*/
- { /*@V127556*/
- goto ClaimUnitExit; /*@V127556*/
- } /*@V127556*/
-
- if ( !TimersCalibrated )
- {
- CalibrateTimers( npAT->npACB );
- TimersCalibrated = 1;
- }
-
- /* SONY CDs come up in DMA mode sometimes. Therefore, we must force them */
- /* into non-DMA mode. */
-
- FeatureReg = npAT->BasePort + 1; /*@V98451*/
- outp( FeatureReg, 0 ); /*@V98451*/
-
- /* @V127556
- ** We are done with the HW, so resume ATA driver. @V127556
- */ /*@V127556*/
- if( !(rc = InitResumeOtherAdd( npACB )) ) /*@V127556*/
- { /*@V127556*/
- npACB->suspended = 1; /*@V127556*/
- npACB->ResourceFlags &= ~ACBRF_CURR_OWNER; /*@V127556*/
- } /*@V127556*/
- else /*@V127556*/
- { /*@V127556*/
- goto ClaimUnitExit; /*@V127556*/
- } /*@V127556*/
-
- OldIRQTimeOut = npACB->IRQTimeOut; /*@V121891*/
- npACB->IRQTimeOut = INIT_TIMEOUT_SHORT; /*@V117508*/
-
- UnitType = ATAPIIdentify( npAT );
- /*@V155162*/
- /*VVVVVVVV*/
- if ( (UnitType == 0xffff) && (!(npUCB->Flags & UCBF_FORCE)) ) /*@V162970*/
- {
- /*
- * If the ATAPIIdentify fail, we send the ATAPI Reset to recover it and
- * retry again. For Diamond 8x cdrom, sometimes it needs to retry many times
- * until there is no error.
- */
- for ( num_retry = 0; num_retry < ATAPI_NUM_RETRIES; num_retry++)
- {
- ATAPIReset( npAT );
-
- /* Wait 15 seconds */
-
- for ( l = 0; l < ATAPI_RESET_DELAY; l++ ) /*@V159438*/
- {
- IODelay();
- }
-
- UnitType = ATAPIIdentify( npAT );
- if (UnitType != 0xffff)
- break;
- } /* end of for num_retry */
- } /*@V162970*/
- /*AAAAAAAA*/
- npACB->IRQTimeOut = OldIRQTimeOut; /*@V117508*/
-
- // The above has determined the default timeout in ms. /*@V195083*/
- // Henceforth, TimeOut, is the default timeout value. /*@V195083*/
- // IRQTimeOut can be changed with each request to an IORB /*@V195083*/
- // requested value. /*@V195083*/
- npACB->TimeOut = npACB->IRQTimeOut; /*@V195083*/
-
- } /*@V155162*/
-
- if( !Resume && (UnitType == UIB_TYPE_CDROM) ) /*@V155162*/
- { /*@V155162*/
- pUI = (PUNITINFO) InitAllocate ( sizeof(UNITINFO) );
- setmem( ScratchBuf, 0, sizeof(ScratchBuf) );
- memcopy( (PVOID) pUI, (PVOID) pOldUnitInfo, sizeof(UNITINFO));
-
- pUI->FilterADDHandle = ADDHandle;
- pUI->UnitType = UIB_TYPE_CDROM;
- pUI->UnitHandle = (USHORT)npACB->npUCB;
- pUI->UnitFlags = UF_REMOVABLE | UF_CHANGELINE |
- UF_NODASD_SUPT | UF_NOSCSI_SUPT;
-
- if ( !( rc = Issue_AllocateUnit( UnitHandle, DriverEP )) )
- {
- rc = Issue_ChangeUnitInfo( pUI, UnitHandle, DriverEP );
- if ( Issue_DeallocateUnit( UnitHandle, DriverEP ))
- {
- npAT->Flags |= ATBF_DISABLED;
- }
- else /*@V155162*/
- { /*@V155162*/
- npACB->cUnits++;
- } /*@V155162*/
- }
-
- if ( rc )
- {
- npAT->Flags |= ATBF_DISABLED;
- }
- }
- else /*@V117508*/
- { /*@V117508*/
- rc = 1; /*@V117508*/
- } /*@V117508*/
-
- ClaimUnitExit:
-
- return( rc );
- }
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID FAR DriverInit( PRPINITIN pRPH )
- {
- PRPINITIN pRPI = (PRPINITIN) pRPH;
- PRPINITOUT pRPO = (PRPINITOUT) pRPH;
- NPATBL npAT = AdapterTable;
- NPACB npACB;
- PDDD_PARM_LIST pDDD_Parm_List;
- PMACHINE_CONFIG_INFO pMCHI;
- USHORT iAdpt;
- USHORT iUnit;
- USHORT rc = 0;
- PBYTE pTimerPool;
- struct DevClassTableStruc far *pDriverTable;
-
- /*┌──────────────────────────────────────────────────────┐
- │Setup DevHelp service entry point for DHCALLS library │
- └──────────────────────────────────────────────────────┘ */
- Device_Help = pRPH->DevHlpEP;
-
- //┌────────────────────────────────────────┐
- //│Put name from Config.sys in DrvrName of │
- //│the DriverStruct structure. │
- //└────────────────────────────────────────┘
-
- RMGetDriverName (pRPI, DriverStruct.DrvrName, DrvrNameSize);
-
- /*┌────────────────────────────────────┐
- │Point to intialization vector table │
- │see h\dskinit.h for details │
- └────────────────────────────────────┘ */
- pDDD_Parm_List = (PDDD_PARM_LIST) pRPI->InitArgs;
-
- /*┌──────────────────────────────────────────────┐
- │Transfer information from Machine Info Packet │
- └──────────────────────────────────────────────┘ */
- pMCHI = MAKEP( SELECTOROF(pDDD_Parm_List),
- (USHORT) pDDD_Parm_List->machine_config_table );
-
-
- MachineID = (pMCHI->Model << 8) | pMCHI->SubModel;
-
- /*┌───────────────────────────────────────────────┐ */ /*@V117508*/
- /*│If this is a uChannel machine, share interrupt │ */ /*@V117508*/
- /*└───────────────────────────────────────────────┘ */ /*@V117508*/
- if ( pMCHI->BusInfo & BUSINFO_MCA ) /*@V117508*/
- { /*@V117508*/
- LevelInterrupt= 1; /*@V117508*/
- } /*@V117508*/
-
- /*┌───────────────────────────────────────────┐
- │Check the paramters on the config.sys line │
- └───────────────────────────────────────────┘ */
- if ( ParseCmdLine( pDDD_Parm_List ) )
- {
- TTYWrite( ParmErrMsg );
- }
-
- if (!(DevHelp_AttachDD("CMD640X$",(NPBYTE)&DDTable)))
- {
- if (Verbose)
- {
- TTYWrite ("CMD640X.ADD driver found. IBM ATAPI filter not loaded.");
- }
-
- pRPO->CodeEnd = 0;
- pRPO->DataEnd = 0;
- pRPO->rph.Status = STDON + STERR + ERROR_I24_QUIET_INIT_FAIL;
-
- return;
- }
-
- pTimerPool = (PBYTE) InitAllocate( TIMER_POOL_SIZE );
-
- ADD_InitTimer( pTimerPool, TIMER_POOL_SIZE );
-
- SetupADDVars();
-
- /* ┌────────────────────────────────────────────┐
- │ Find ATAPI Units that have been identified │
- │ and claim them. │
- └────────────────────────────────────────────┘ */
-
- GetATAPIUnits();
-
- if ( Installed )
- {
- if ( Verbose )
- {
- PrintInfo( AdapterTable );
- }
- pRPO->CodeEnd = (USHORT) &DriverInit;
- pRPO->DataEnd = (USHORT) &BeginInitData;
- pRPO->rph.Status = STDON;
-
- }
- else
- {
-
- ADD_DeInstallTimer();
-
- npAT = AdapterTable;
-
- if ( Verbose )
- {
- TTYWrite( UninstallMsg );
- }
-
-
- pRPO->CodeEnd = 0;
- pRPO->DataEnd = 0;
- pRPO->rph.Status = STDON + STERR + ERROR_I24_QUIET_INIT_FAIL;
-
- }
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR SetupADDVars()
- {
- SELDESCINFO SwapCodeDesc;
-
-
- /*┌───────────────────────────────┐
- │Linear Address of data segment │
- └───────────────────────────────┘ */
- (PBYTE) plDataSeg = (PBYTE) &plDataSeg;
- if ( DevHelp_VirtToLin( (SEL) SELECTOROF(plDataSeg),
- (ULONG) 0,
- (PLIN) &plDataSeg ) )
- {
- _asm { int 3 }
- }
-
- plADDLockHandle = plDataSeg + (USHORT) &ADDLockHandle[0];
-
- /*┌───────────────────────────────────────┐
- │Linear Address of swap code and length │
- └───────────────────────────────────────┘ */
- (PBYTE) plSwapCode = (PBYTE) &StartOSM;
- if ( DevHelp_GetDescInfo( (SEL) SELECTOROF (plSwapCode),
- (PBYTE) &SwapCodeDesc ) )
- {
- _asm { int 3 }
- }
-
- plSwapCode = SwapCodeDesc.BaseAddr;
- SwapCodeLen = SwapCodeDesc.Limit + 1;
-
- /*┌──────────────────────────────────────────┐
- │Point to KERNEL Interrupt level indicator │
- └──────────────────────────────────────────┘ */
- if ( DevHelp_GetDOSVar( (USHORT) DHGETDOSV_INTERRUPTLEV,
- (USHORT) 0,
- (PPVOID) &pNestedIntCount ) )
- {
- _asm { int 3 }
- }
- DevHelp_VirtToPhys( (PVOID) SenseDataBuf, (PULONG) &ppSenseDataBuf );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- NPBYTE FAR InitAllocate( USHORT Size )
- {
- NPBYTE p = (NPBYTE) -1;
-
- if ( Size < ACBPoolAvail )
- {
- p = (NPBYTE) npACBPool;
-
- setmem((PBYTE) npACBPool, 0, Size );
-
- npACBPool += Size;
- ACBPoolAvail -= Size;
- }
- return( p );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID FAR InitDeAllocate( USHORT Size )
- {
- npACBPool -= Size;
- ACBPoolAvail += Size;
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR PrintInfo( NPATBL npAT )
- {
- NPACB npACB;
- NPUCB npUCB;
- NPUTBL npUT;
- USHORT i, j, k, l;
-
- TTYWrite( VersionMsg );
- for ( j = 0; j < MAX_ADAPTERS ; j++, npAT++ )
- {
- if ( !(npAT->Flags & ATBF_DISABLED) )
- {
- sprintf( (PUCHAR) StringBuffer,
- (PUCHAR) "Controller: %1d Base Port: %4x "
- "IRQ: %2x; Status = %s",
- (USHORT) j,
- (USHORT) npAT->BasePort,
- (USHORT) npAT->IRQLevel,
- (PSZ) AdptMsgs[npAT->Status] );
-
- TTYWrite ( StringBuffer );
-
- if ( npACB = npAT->npACB )
- {
- for (i = 0; i < MAX_UNITS; i++ )
- {
- npUT = &npAT->Unit[i];
- npUCB = &npACB->UnitCB[i];
-
- if ( npUT->Status==UTS_OK )
- {
- sprintf( (PUCHAR) StringBuffer,
- (PUCHAR) "Unit %1d - Status = %s%s", /* [001] */
- (USHORT) i,
- (PSZ) UnitMsgs[npUT->Status], /* [001] */
- (PSZ) ((npUCB->Flags&UCBF_BM_DMA) ? " - BM DMA ON" : "")); /* [001] */
-
- TTYWrite ( StringBuffer );
-
- sprintf( (PUCHAR) StringBuffer,
- (PUCHAR) "Model Number : %s",
- (PSZ) npUT->ModelNum);
- TTYWrite ( StringBuffer );
-
- sprintf( (PUCHAR) StringBuffer,
- (PUCHAR) "Firmware Revision: %s",
- (PSZ) npUT->Firmware);
- TTYWrite ( StringBuffer );
-
- sprintf( (PUCHAR) StringBuffer,
- (PUCHAR) "Serial Number : %s",
- (PSZ) ((npUT->Serial[0]) ? npUT->Serial : "<None>" ));
- TTYWrite ( StringBuffer );
-
- sprintf( StringBuffer, " " );
- TTYWrite( StringBuffer );
- // sprintf( (PUCHAR) StringBuffer,
- // (PUCHAR) "BMICOM = %4.4X, BMISTA = %4.4X, BMIDTP = %4.4X\n",
- // npACB->BMICOM,
- // npACB->BMISTA,
- // npACB->BMIDTP );
- // TTYWrite( StringBuffer );
- //
- // sprintf( (PUCHAR) StringBuffer,
- // (PUCHAR) "PRD Address = %8.8lX, PRD Count = %d\n",
- // npACB->BMDMA_SGList, npACB->BMDMA_SGListCount );
- // TTYWrite( StringBuffer );
- }
- }
- }
- }
- }
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR TTYWrite( PSZ Buf )
- {
- InitMsg.MsgStrings[0] = Buf;
-
- DevHelp_Save_Message( (NPBYTE) &InitMsg );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR GetATAPIUnits()
- {
- NPATBL npAT = AdapterTable;
- NPUTBL npUT;
- NPIORB_CONFIGURATION pIORB;
- DEVICETABLE *pDeviceTable;
- NPADAPTERINFO pAdapterInfo;
- UNITINFO OldUnitInfo;
- NPACB npACB = 0;
- NPUCB npUCB;
- PRESOURCE_ENTRY pRE;
-
- struct DevClassTableStruc far *pDriverTable;
-
- USHORT rc, i, j, k;
- USHORT n = 0;
-
- USHORT UnitFlags;
- USHORT UnitType;
- USHORT UnitHandle;
- USHORT DriveCount = 0;
-
- HANDLELIST HandleList;
- PSZ SearchKey = SearchKeytxt;
- HADAPTER hAdapter;
- HDRIVER hDevice;
-
- ULONG PhysAddr; /* [001] */
- USHORT Port, Data; /* [001] */
-
- VOID (FAR * DriverEP) ();
-
- if ( rc = DevHelp_GetDOSVar((USHORT) DHGETDOSV_DEVICECLASSTABLE, 1,
- (PPVOID) &pDriverTable) )
- {
- _asm { int 3 }
- }
-
- pDeviceTable = (DEVICETABLE *) ScratchBuf1;
-
- for (i = 0; i < pDriverTable->DCCount; i++)
- {
- pIORB = (NPIORB_CONFIGURATION) &InitIORB;
- pIORB->iorbh.Length = sizeof(IORB_CONFIGURATION);
- pIORB->iorbh.CommandCode = IOCC_CONFIGURATION;
- pIORB->iorbh.CommandModifier = IOCM_GET_DEVICE_TABLE;
- pIORB->iorbh.Status = 0;
- pIORB->iorbh.RequestControl = 0;
- pIORB->iorbh.NotifyAddress = 0;
- pIORB->pDeviceTable = (PVOID) ScratchBuf1;
- pIORB->DeviceTableLen = sizeof(ScratchBuf1);
-
- OFFSETOF(DriverEP) = pDriverTable->DCTableEntries[i].DCOffset;
- SELECTOROF(DriverEP) = pDriverTable->DCTableEntries[i].DCSelector;
-
- setmem( ScratchBuf1, 0, sizeof(ScratchBuf1) ); /*@V132280*/
-
- (*DriverEP) ((PVOID)(pIORB));
-
- while ( !(pIORB->iorbh.Status & IORB_DONE) ) /* Wait till done */
- ;
-
- if (pIORB->iorbh.Status & IORB_ERROR )
- continue; /* Skip to next device */
-
- for (j = 0; j < pDeviceTable->TotalAdapters; j++ )
- {
- pAdapterInfo = pDeviceTable->pAdapter[j];
-
- for (k = 0; k < pAdapterInfo->AdapterUnits; k++)
- {
- UnitType = pAdapterInfo->UnitInfo[k].UnitType;
- UnitHandle = pAdapterInfo->UnitInfo[k].UnitHandle;
- UnitFlags = pAdapterInfo->UnitInfo[k].UnitFlags; /*@V155162*/
- if ( UnitType == UIB_TYPE_ATAPI )
- {
- if ( !Installed )
- {
- Installed = TRUE;
-
- if ( DevHelp_RegisterDeviceClass( (NPSZ) AdapterName,
- (PFN) &ATAPIADDEntry,
- (USHORT) 0,
- (USHORT) 1,
- (PUSHORT) &ADDHandle ) )
- {
- _asm int 3
- }
-
- //┌────────────────────────┐
- //│ Allocate Driver Handle │
- //└────────────────────────┘
- if(RMCreateDriver(&DriverStruct,
- &hDriver))
- {
- _asm int 3
- }
- }
- if ( !npACB )
- {
- npAT->Flags &= ~ATBF_DISABLED;
- npACB = npAT->npACB = (NPACB) InitAllocate( sizeof(ACB) );
- setmem((PBYTE) npACB, 0, sizeof(ACB) );
- ACBPtrs[cAdapters].npACB = npACB;
- npACB->IRQHandler = npAT->IRQHandler;
- npACB->ReqFlags |= ACBR_CONFIGURE_ACB;
-
- npACB->ResourceFlags |= ACBRF_SHARED;
-
- pRE = (PRESOURCE_ENTRY) ScratchBuf;
- setmem( ScratchBuf, 0, sizeof(ScratchBuf) );
-
- if ( rc = Issue_ReportResources ( pRE, UnitHandle, DriverEP ) )
- {
- npAT->Flags |= ATBF_DISABLED;
- continue; /* go to next adapter */
- }
-
- /* Is there an IRQ entry? */
- /* Is there a port entry? */
-
- if ( ( pRE->Max_Resource_Entry < RE_PORT ) ||
- ( !pRE->cIRQ_Entries ) ||
- ( !pRE->cPort_Entries ))
- {
- rc = 1;
- npAT->Flags |= ATBF_DISABLED;
- continue; /* go to next adapter */
- }
-
- npAT->BasePort = pRE->npPort_Entry->StartPort;
- npAT->IRQLevel = pRE->npIRQ_Entry->IRQ_Value;
- npAT->cUnits++;
- npAT->Flags |= ATBF_ATAPI_PRESENT;
- npAT->Status = ATS_OK;
-
- /* Begin [001] Get base address for Bus Master DMA */
-
- if ( pRE->cPort_Entries > 2 )
- {
- npACB->BMICOM = (pRE->npPort_Entry)[2].StartPort;
- npACB->BMISTA = npACB->BMICOM+2;
- npACB->BMIDTP = npACB->BMISTA+2;
-
- npACB->Flags |= ACBF_BM_DMA;
- /* Allocate space for scatter/gather table. Disable Bus Master DMA if */
- /* allocation fails */
-
- if ( !DevHelp_AllocPhys( MR_4K_LIMIT, 0, &PhysAddr ) )
- {
- /* Calculate useable size of scatter/gather table. Restrictions are:
- *
- * 1) Cannot span a 4KB boundary
- * 2) must be ULONG aligned
- *
- * store resulting physical address, size in bytes of useable area,
- * and number of descriptors permitted.
- */
-
- if ( (npACB->BMDMA_SGListSize = (PhysAddr & (MR_4K_LIMIT-1))) <=
- (MR_4K_LIMIT/2) )
- {
- /* Larger half is before 4KB boundary */
-
- npACB->BMDMA_SGList = (PhysAddr & ~3L); /* ULONG align it */
- if ( PhysAddr & 3 )
- {
- npACB->BMDMA_SGList += 4; /* keep in boundaries */
- }
- npACB->BMDMA_SGListSize = MR_4K_LIMIT - npACB->BMDMA_SGListSize;
- npACB->BMDMA_SGListSize &= ~3L; /* adjust size for ULONGs */
- if ( PhysAddr & 3 )
- {
- npACB->BMDMA_SGListSize -= 4; /* keep in boundaries */
- }
- }
- else
- {
- /* larger half is after 4KB boundary */
-
- npACB->BMDMA_SGList = (PhysAddr - npACB->BMDMA_SGListSize) + MR_4K_LIMIT;
- npACB->BMDMA_SGListSize &= ~3L; /* adjust size for ULONGs */
- }
- npACB->BMDMA_SGListCount = npACB->BMDMA_SGListSize / 8;
- }
- else
- {
- npACB->Flags &= ~ACBF_BM_DMA;
- }
- }
-
- /* End [001] */
-
- if ( npACB->ReqFlags & ACBR_CONFIGURE_ACB )
- {
- ConfigureACB( npAT );
- }
-
- npACB->SharedDriverEP = DriverEP;
- npACB->SharedDriverUnitHandle = UnitHandle;
- }
- else
- {
- npAT->cUnits++;
- }
- npUT = &npAT->Unit[k];
- npUCB = npACB->npUCB = &npACB->UnitCB[k];
-
- if( UnitFlags & UF_FORCE ) /*@V155162*/
- { /*@V155162*/
- npUCB->Flags |= UCBF_FORCE; /*@V155162*/
- if( UnitFlags & UF_NOTPRESENT ) /*@V155162*/
- { /*@V155162*/
- npUCB->Flags |= UCBF_NOTPRESENT; /*@V155162*/
- } /*@V155162*/
- } /*@V155162*/
-
- npUCB->npACB = npACB;
- npUCB->UnitId = npACB->UnitId = k;
-
- memcopy ( (PVOID) &OldUnitInfo,
- (PVOID) &pAdapterInfo->UnitInfo[k],
- sizeof(UNITINFO) );
- if (ClaimUnit( npAT, FALSE, UnitHandle, /*@V155162*/
- (PUNITINFO)&OldUnitInfo, DriverEP ))
- {
- npUT->Status = UTS_NOT_PRESENT;
- npAT->cUnits--; /* @V132280 */
- }
- else
- {
- npUT->Status = UTS_OK;
-
- HandleList.cMaxHandles = 1;
-
- SearchKey[4] = '0' + j; /*@V156660 - modified */
-
- //┌───────────────────────────────────────────┐
- //│ Find the IDE adapter in the resource tree │
- //│ and attach a device │
- //└───────────────────────────────────────────┘
-
- if ( !(RMKeyToHandleList ( HANDLE_PHYS_TREE,
- SearchKey,
- (PHANDLELIST) &HandleList )) )
- {
- if ( HandleList.cHandles )
- {
- if ( RMCreateDevice( hDriver,
- &hDevice,
- &DevStruct,
- HandleList.Handles[0],
- NULL ))
- {
- _asm int 3
- }
- }
- }
- DevStruct.DevDescriptName[6] = '0' + n; //sam
- n++;
- }
- }
-
- /* Begin [001] */
-
- if ( npACB && npACB->Flags & ACBF_BM_DMA )
- {
- Port = npACB->BMISTA;
- inp( Port, Data );
- if ( Data & ACBX_BMISTA_D0DMA )
- npACB->UnitCB[0].Flags |= UCBF_BM_DMA;
- if ( Data & ACBX_BMISTA_D1DMA )
- npACB->UnitCB[1].Flags |= UCBF_BM_DMA;
- }
-
- /* End [001] */
-
- }
- if ( npACB )
- {
- npAT->Flags |= ATBF_ATAPI_PRESENT;
- cAdapters++;
- npAT++;
- npACB = 0;
- }
- }
- }
- }
-
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR Issue_ReportResources( PRESOURCE_ENTRY pRE,
- USHORT UnitHandle, VOID (FAR *DriverEP)() )
- {
- NPIORB_RESOURCE npIORB;
-
- npIORB = (NPIORB_RESOURCE) &InitIORB;
- setmem ( (PVOID) npIORB, 0, sizeof(InitIORB) );
-
- npIORB->iorbh.Length = sizeof(IORB_RESOURCE);
- npIORB->iorbh.UnitHandle = UnitHandle;
- npIORB->iorbh.CommandCode = IOCC_RESOURCE;
- npIORB->iorbh.CommandModifier = IOCM_REPORT_RESOURCES;
- npIORB->iorbh.Status = 0;
- npIORB->iorbh.RequestControl = 0;
- npIORB->iorbh.NotifyAddress = 0;
- npIORB->ResourceEntryLen = sizeof(ScratchBuf);
- npIORB->pResourceEntry = pRE;
-
- (*DriverEP) ((PVOID)(npIORB));
- while ( !(npIORB->iorbh.Status & IORB_DONE) ) /* Wait till done */
- ;
-
- return( npIORB->iorbh.ErrorCode );
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR Issue_AllocateUnit( USHORT UnitHandle, VOID (FAR *DriverEP)() )
- {
- NPIORB_UNIT_CONTROL npIORB;
- PUCHAR pWSFlags; /* work space flags */
-
- npIORB = (NPIORB_UNIT_CONTROL) &InitIORB;
- pWSFlags = (PUCHAR) npIORB->iorbh.DMWorkSpace;
- setmem ( (PVOID) npIORB, 0, sizeof(InitIORB) );
-
- npIORB->iorbh.Length = sizeof(IORB_UNIT_CONTROL);
- npIORB->iorbh.UnitHandle = UnitHandle;
- npIORB->iorbh.CommandCode = IOCC_UNIT_CONTROL;
- npIORB->iorbh.CommandModifier = IOCM_ALLOCATE_UNIT;
- npIORB->iorbh.Status = 0;
- npIORB->iorbh.RequestControl = IORB_ASYNC_POST;
- npIORB->iorbh.NotifyAddress = NotifyIORBDone; /*@V153151*/
-
- (*DriverEP) ((PVOID)(npIORB));
-
- DISABLE
- *pWSFlags |= WSF_PROC_BLOCK;
-
- while( !(npIORB->iorbh.Status & IORB_DONE) )
- {
- DevHelp_ProcBlock( (ULONG) npIORB, 100, WAIT_IS_INTERRUPTABLE );
- DISABLE
- }
-
- ENABLE
-
- return( npIORB->iorbh.ErrorCode );
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR Issue_DeallocateUnit( USHORT UnitHandle, VOID (FAR *DriverEP)() )
- {
- NPIORB_UNIT_CONTROL npIORB;
-
- npIORB = (NPIORB_UNIT_CONTROL) &InitIORB;
- setmem ( (PVOID) npIORB, 0, sizeof(InitIORB) );
-
- npIORB->iorbh.Length = sizeof(IORB_UNIT_CONTROL);
- npIORB->iorbh.UnitHandle = UnitHandle;
- npIORB->iorbh.CommandCode = IOCC_UNIT_CONTROL;
- npIORB->iorbh.CommandModifier = IOCM_DEALLOCATE_UNIT;
- npIORB->iorbh.Status = 0;
- npIORB->iorbh.RequestControl = 0;
- npIORB->iorbh.NotifyAddress = 0;
-
- (*DriverEP) ((PVOID)(npIORB));
- while ( !(npIORB->iorbh.Status & IORB_DONE) ) /* Wait till done */
- ;
-
- return( npIORB->iorbh.ErrorCode );
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR Issue_ChangeUnitInfo( PUNITINFO pUI, USHORT UnitHandle,
- VOID (FAR *DriverEP)() )
- {
- NPIORB_UNIT_CONTROL npIORB;
-
- npIORB = (NPIORB_UNIT_CONTROL) &InitIORB;
- setmem ( (PVOID) npIORB, 0, sizeof(InitIORB) );
-
- npIORB->iorbh.Length = sizeof(IORB_UNIT_CONTROL);
- npIORB->iorbh.UnitHandle = UnitHandle;
- npIORB->iorbh.CommandCode = IOCC_UNIT_CONTROL;
- npIORB->iorbh.CommandModifier = IOCM_CHANGE_UNITINFO;
- npIORB->iorbh.Status = 0;
- npIORB->iorbh.RequestControl = 0;
- npIORB->iorbh.NotifyAddress = 0;
- npIORB->UnitInfoLen = sizeof(ScratchBuf);
- npIORB->pUnitInfo = pUI;
-
- (*DriverEP) ((PVOID)(npIORB));
- while ( !(npIORB->iorbh.Status & IORB_DONE) ) /* Wait unil done */
- ;
-
- return( npIORB->iorbh.ErrorCode );
- }
-
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR ConfigureACB( NPATBL npAT )
- {
- NPACB npACB;
- UCHAR i;
-
- npACB = npAT->npACB;
-
- for (i = FI_PDATA; i < FI_PDEVCON; i++ )
- {
- npACB->IOPorts[i] = npAT->BasePort + i;
- npACB->IORegs[i] = 0;
- }
- /*┌───────────────────────────────────────────────────────────┐
- │ Error Register and Feature Register have the same address │
- └───────────────────────────────────────────────────────────┘*/
- npACB->IOPorts[FI_PERROR] = npACB->IOPorts[FI_PFEATURE];
-
- /*┌────────────────────────────────────────────────────────────┐
- │ Status Register and Command Register have the same address │
- └────────────────────────────────────────────────────────────┘*/
- npACB->IOPorts[FI_PSTATUS] = npACB->IOPorts[FI_PCMD];
-
- npACB->IOPorts[FI_PDEVCON] = npACB->IOPorts[FI_PDRVSLCT] | 0x300;
-
- npACB->IORegs[FI_PDEVCON] = DEFAULT_ATAPI_DEVCON_REG;
-
- npACB->IRQLevel = npAT->IRQLevel;
- npACB->IRQHandler = npAT->IRQHandler;
-
- npACB->TimeOut = IRQ_TIMEOUT_LENGTH; /*@V117508*/
- npACB->IRQTimeOut = INIT_TIMEOUT_LONG;
- npACB->DelayedResetInterval = DELAYED_RESET_INTERVAL;
-
- npACB->InternalCmd.IOSGPtrs.iPortAddress =npACB->IOPorts[FI_PDATA];
- npACB->ExternalCmd.IOSGPtrs.iPortAddress =npACB->IOPorts[FI_PDATA];
- npACB->npCmdIO = &npACB->ExternalCmd;
-
- npACB->ReqFlags &= ~ACBR_CONFIGURE_ACB;
-
- if ( npAT->Flags & ATBF_SHARED_ADAPTER )
- {
- npACB->ResourceFlags |= ACBRF_SHARED;
- npACB->suspended = 1;
- }
- else
- {
- npACB->suspended = 0;
- }
- }
-
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR ParseCmdLine( PDDD_PARM_LIST pADDParms )
- {
- PSZ pCmdLine;
- PSZ pCurrChar;
- USHORT LtoUval = 'a' - 'A';
- USHORT rc = 0;
-
- pCmdLine = MAKEP( SELECTOROF(pADDParms),
- (USHORT) pADDParms->cmd_line_args );
-
-
- for ( pCurrChar = pCmdLine; *pCurrChar; pCurrChar++ )
- {
- /* Convert from lower case to upper case */
- if ( *pCurrChar >= 'a' && *pCurrChar <= 'z' )
- *pCurrChar = *pCurrChar - LtoUval;
-
- if ( *pCurrChar == '/')
- {
- pCurrChar++;
- if ( (*pCurrChar == 'V') || (*pCurrChar == 'v') )
- {
- Verbose = TRUE;
- }
- else
- {
- if ( *pCurrChar == 'F') /*@V151168*/
- { /*@V151168*/
- Force = 1; /*@V151168*/
- AdaptersForced = 1; /*@V151168*/
- } /*@V151168*/
- else /*@V151168*/
- { /*@V151168*/
- rc = 1;
- break;
- } /*@V151168*/
- }
- }
- }
- return( rc );
- }
- /*------------------------------------*/ /*@V162970*/
- /* */ /*@VVVVVVV*/
- /* */
- /* */
- /*------------------------------------*/
- USHORT NEAR ATAPIReset( NPATBL npAT )
- {
- NPACB npACB = npAT->npACB;
- USHORT rc = 0;
- USHORT Data;
- USHORT Port;
- USHORT i;
- USHORT UnitId;
-
- UnitId = npACB->npUCB->UnitId;
-
- SelectUnit( npACB, UnitId );
-
- Data = FX_SOFTRESET;
- Port = npACB->IOPorts[FI_PCMD];
- outp( Port, Data );
-
- for ( i=0; i<8; i++ )
- {
- rc = CheckReady( npACB );
- if ( !rc )
- {
- break;
- }
- }
-
- return( rc ); /*@AAAAAAA*/
- } /*@V162979*/
-
-
-