home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- *
- * SOURCE FILE NAME = ATAPIGEN.C
- *
- * DESCRIPTION : General functions for ATAPI driver
- *
- *
- * 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.
- * 04/03/94 @V117508 117508 Remove unneeded ctxhook procedure and data
- * 04/05/96 @V151168 Merged warm dock/swap code.
- * 05/24/96 @V155162 Thinkpad docking/swapping IDE update.
- ***************************************************************************/
-
- #define INCL_NOBASEAPI
- #define INCL_NOPMAPI
- #include "os2.h"
- #include "dos.h"
- #include "devcmd.h"
- #include "dskinit.h"
-
- #include "iorb.h"
- #include "addcalls.h"
- #include "dhcalls.h"
-
- // for APM /*@V151168*/
- #include "apmcalls.h" /*@V151168*/
- #include "doccalls.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"
-
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ IODelay ║
- ║ ║
- ║ Wait for 1 µsec ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID FAR IODelay()
- {
- ULONG IODelayCtr = IODelayCount;
-
- while( IODelayCtr--)
- ;
- }
-
- /*
- ╔════════════════════════════════════╗
- ║ ║
- ║ setmem ║
- ║ ║
- ║ Sets memory starting at location ║
- ║ p, to the value c, for len bytes ║
- ║ ║
- ╚════════════════════════════════════╝
- */
- VOID NEAR setmem( PBYTE d, USHORT c, USHORT len )
- {
- USHORT i;
-
- for ( i = 0; i < len ; i++ )
- d[i] = (UCHAR) c;
-
- return;
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ memcopy ║
- ║ ║
- ║ Copies the contents of memory ║
- ║ at the source (s) to the ║
- ║ destination (d), for len bytes ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR memcopy( PBYTE d, PBYTE s, USHORT len )
- {
- USHORT i;
- USHORT j;
-
- j = len >> 1;
-
- for ( i = 0; i < j ; i++ )
- ((PUSHORT) d)[i] = ((PUSHORT) s)[i];
-
- if ( j & 1 ) d[len-1] = s[len-1];
-
-
- return;
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ strncpy ║
- ║ ║
- ║ Copies the contents of string ║
- ║ (s) to that of string (d) for ║
- ║ (n) characters. (d) is then ║
- ║ null terminated. ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR strncpy( PSZ d, PSZ s, USHORT n )
- {
- while( *s && n-- ) *d++ = *s++;
- *d = 0;
-
- return;
- }
-
- /*
- ╔═══════════════════════════════════╗
- ║ ║
- ║ strncmp ║
- ║ ║
- ║ Compares the contents of string ║
- ║ (s) to that of string (d) for ║
- ║ (n) characters. ║
- ║ ║
- ╚═══════════════════════════════════╝
- */
- BOOL NEAR strncmp( PSZ d, PSZ s, USHORT n )
- {
- BOOL rc = TRUE;
-
- while( n-- )
- if ( *d++ != *s++)
- {
- rc = FALSE;
- break;
- }
-
- return( rc );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ BSYWAIT ║
- ║ ║
- ║ Poll for BSY until success or ║
- ║ until exceed max poll time ║
- ║ ║
- ║ Returns True if BSY clear ║
- ║ False if exceeded max poll time ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR BSYWAIT ( NPACB npACB )
- {
-
- ULONG cMS = WaitBSYCount; /*V@93531*/
- USHORT Status;
-
- /*
- ┌──────────────────────────────────────┐
- │ Poll for BSY up to WaitBSYCount times│
- └──────────────────────────────────────┘
- */
-
- do
- {
- Status = GetRegister ( npACB, FI_PSTATUS );
- IODelay();
- } while (((Status & FX_BUSY) || Calibrate) && --cMS);
-
- return (cMS);
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ DRQ_SET_WAIT ║
- ║ ║
- ║ Poll for DRQ until asserted or ║
- ║ until exceed max poll time ║
- ║ ║
- ║ Returns True if DRQ set ║
- ║ False if exceeded max poll time ║
- ║ ║
- ╚══════════════════════════════════╝
- */ /*V@93531*/
- USHORT FAR BSY_CLR_DRQ_SET_WAIT( NPACB npACB ) /*V@93531*/
- { /*V@93531*/
- /*V@93531*/
- ULONG cMS = WaitDRQCount; /*V@93531*/
- USHORT Status; /*V@93531*/
- /*V@93531*/
- /* V@93531*/
- /*┌──────────────────────────────────────┐ V@93531*/
- /*│ Poll for DRQ up to WaitDRQCount times│ V@93531*/
- /*└──────────────────────────────────────┘ V@93531*/
- /*V@93531*/
- do /*V@93531*/
- { /*V@93531*/
- Status = GetRegister ( npACB, FI_PSTATUS ); /*V@93531*/
- IODelay(); /*V@93531*/
- } while (( !(Status & FX_DRQ) ||
- Status & FX_BUSY ||
- Calibrate) &&
- --cMS); /*V@93531*/
- /*V@93531*/
- return (cMS); /*V@93531*/
- } /*V@93531*/
- /*V@93531*/
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ DRQ_AND_BSY_CLEAR_WAIT ║
- ║ ║
- ║ Poll for DRQ and BSY until both ║
- ║ are clear or until exceed max ║
- ║ poll time ║
- ║ ║
- ║ Returns True if DRQ AND BSY are ║
- ║ both clear, ║
- ║ False if exceeded max poll time ║
- ║ ║
- ╚══════════════════════════════════╝
- */ /*V@93531*/
- USHORT NEAR DRQ_AND_BSY_CLEAR_WAIT ( NPACB npACB ) /*V@93531*/
- { /*V@93531*/
- /*V@93531*/
- USHORT cMS = WaitDRQCount; /*V@93531*/
- USHORT Status; /*V@93531*/
- /*V@93531*/
- /* ┌──────────────────────────────────────────────┐ V@93531*/
- /* │ Poll for DRQ and BSY up to WaitDRQCount times│ V@93531*/
- /* └──────────────────────────────────────────────┘ V@93531*/
- /*V@93531*/
- do /*V@93531*/
- { /*V@93531*/
- Status = GetRegister ( npACB, FI_PSTATUS ); /*V@93531*/
- IODelay(); /*V@93531*/
- } while (( (Status & FX_BUSY) ||
- (Status & FX_DRQ ) ||
- Calibrate) &&
- --cMS); /*V@93531*/
- /* enddo */ /*V@93531*/
- /*V@93531*/
- return( (Status & (FX_BUSY | FX_DRQ)) ? FALSE : TRUE ); /*V@93531*//*@V155162*/
- } /*V@93531*/
-
-
- /*
- ╔══════════════════════════════════════════════════════════════════╗
- ║ ║
- ║ VirtToPhys - Convert a virtual to physical address ║
- ║ ║
- ║ Convert a virtual to a physical address. This routine does ║
- ║ not use DevHlp_VirtToPhys since that devhlp is not callable ║
- ║ at interrupt time. ║
- ║ ║
- ║ ULONG VirtToPhys (PBYTE VirtAddr) ║
- ║ ║
- ║ ENTRY: VirtAddr - 16:16 virutal address ║
- ║ ║
- ║ RETURN: ULONG - 32 bit phys address ║
- ║ ║
- ╚══════════════════════════════════════════════════════════════════╝
- */
-
- ULONG VirtToPhys (PBYTE VirtAddr)
- {
-
- USHORT rc;
- SCATGATENTRY ScatGatEntry;
- ULONG VirtLinAddr;
- ULONG ScatLinAddr;
- ULONG PageListCount;
-
- rc = DevHelp_VirtToLin((USHORT) (SELECTOROF(VirtAddr)),
- (ULONG) (OFFSETOF(VirtAddr)),
- (PLIN) &VirtLinAddr);
-
- rc = DevHelp_VirtToLin((USHORT) ( ((ULONG)((PVOID) &ScatGatEntry)) >> 16),
- (ULONG) ( (USHORT)((PVOID) &ScatGatEntry)),
- (PLIN) &ScatLinAddr);
-
- rc = DevHelp_LinToPageList(VirtLinAddr, 1, ScatLinAddr,
- (PULONG) &PageListCount);
-
- return(ScatGatEntry.ppXferBuf);
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR SelectUnit( NPACB npACB, USHORT UnitId )
- {
- USHORT Port;
- USHORT Data;
-
- Port = npACB->IOPorts[FI_PDRVSLCT];
- npACB->IORegs[FI_PDRVSLCT] =
- DEFAULT_ATAPI_DRV_SLCT_REG | ((UnitId == 0) ? UNIT0 : UNIT1 );
- Data = npACB->IORegs[FI_PDRVSLCT];
-
- outp( Port, Data );
- IODelay();
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR SuspendOtherAdd( NPACB npACB )
- {
- PIORB_DEVICE_CONTROL pIORB;
- NPUSHORT npUS;
-
- DISABLE
- if ( npACB->iorbinuse )
- {
- _asm int 3
- }
- npACB->iorbinuse = 1;
- ENABLE
-
- pIORB = (PIORB_DEVICE_CONTROL) &npACB->IORB;
- 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.RequestControl = IORB_ASYNC_POST;
- pIORB->iorbh.NotifyAddress = NotifySuspendResumeDone;
- pIORB->IRQHandlerAddress = npACB->IRQHandler; /*@V93531*/
-
- pIORB->Flags = DC_SUSPEND_DEFERRED | DC_SUSPEND_IRQADDR_VALID; /*@V93531*/
-
- npUS = (NPUSHORT) pIORB->iorbh.DMWorkSpace;
-
- *npUS = (USHORT) npACB;
-
- (*npACB->SharedDriverEP) ((PVOID)(pIORB));
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- USHORT NEAR ResumeOtherAdd( NPACB npACB )
- {
- PIORB_DEVICE_CONTROL pIORB;
- NPUSHORT npUS;
-
- DISABLE
- if ( npACB->iorbinuse )
- {
- _asm int 3
- }
- npACB->iorbinuse = 1;
- ENABLE
-
- pIORB = (PIORB_DEVICE_CONTROL) &npACB->IORB;
- 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.RequestControl = IORB_ASYNC_POST;
- pIORB->iorbh.NotifyAddress = NotifySuspendResumeDone;
-
- npUS = (NPUSHORT) pIORB->iorbh.DMWorkSpace;
-
- *npUS = (USHORT) npACB;
-
- (*npACB->SharedDriverEP) ((PVOID)(pIORB));
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- ULONG NEAR QueryOtherAdd( NPACB npACB )
- {
- PIORB_DEVICE_CONTROL pIORB;
-
- DISABLE
- if ( npACB->iorbinuse )
- {
- _asm int 3
- }
- npACB->iorbinuse = 1;
- ENABLE
-
- pIORB = (PIORB_DEVICE_CONTROL) &npACB->IORB;
- 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_GET_QUEUE_STATUS;
- pIORB->iorbh.RequestControl = 0;
- pIORB->iorbh.NotifyAddress = 0;
-
- (*npACB->SharedDriverEP) ((PVOID)(pIORB));
- while ( !(pIORB->iorbh.Status & IORB_DONE) ) /* Wait till done */
- ;
-
- npACB->iorbinuse = 0;
- return( pIORB->QueueStatus );
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID FAR _loadds NotifySuspendResumeDone( PIORB pIORB )
- {
- NPACB npACB;
-
-
- npACB = ((NPACB *) pIORB->DMWorkSpace)[0];
-
- npACB->iorbinuse = 0;
-
- #ifdef DEBUG
- if( !(pIORB->Status & IORB_DONE) || (pIORB->Status & IORB_ERROR) )
- {
- _asm int 3
- }
- #endif
-
- StartOSM( npACB );
-
- }
-
- /*
- ╔══════════════════════════════════╗
- ║ ║
- ║ IDECDStr ║
- ║ ║
- ║ Stategy Routine for IBMIDECD ║
- ║ ║
- ║ Accepts only the Init Base ║
- ║ device drivers command (0x1B). ║
- ║ Returns unknown command for ║
- ║ all others. ║
- ║ ║
- ╚══════════════════════════════════╝
- */
- VOID NEAR IDECDStr()
- {
- PRPH pRPH;
- USHORT Cmd;
-
- _asm {
- mov word ptr pRPH[0], bx /* pRPH is initialized to */
- mov word ptr pRPH[2], es /* ES:BX passed from the kernel */
- }
-
- pRPH->Status = STATUS_DONE;
- Cmd = pRPH->Cmd;
-
- if( Cmd == CMDInitBase )
- {
- DriverInit( (PRPINITIN) pRPH );
- }
- else if( Cmd == CMDInitComplete ) /*@V155162*/
- { /*@V155162*/
- if ( APMAttach() == 0 ) /*@V151168*//* moved for @V155162*/
- { /*@V151168*//* moved for @V155162*/
- APMRegister( APMEventHandler, /*@V151168*//* moved for @V155162*/
- APM_NOTIFYSETPWR | APM_NOTIFYNORMRESUME | /*@V151168*//* moved for @V155162*/
- APM_NOTIFYCRITRESUME,(USHORT) 0); /*@V151168*//* moved for @V155162*/
- } /*@V151168*//* moved for @V155162*/
- } /*@V155162*/
- else if( Cmd == CMDInit )
- {
- _asm int 3
- Device_Help = ((PRPINITIN)pRPH)->DevHlpEP;
- TTYWrite ( UninstallMsg );
- TTYWrite ( DevEqualsMsg );
- pRPH->Status = STATUS_DONE;
- }
- else
- {
- _asm int 3
- pRPH->Status = STATUS_DONE | STATUS_ERR_UNKCMD;
- }
- _asm { /*@V151168*/
- leave
- retf
- }
- } /* IDECDStr */
-
-
- /* @V151168
- ** Register for APM messages at the end of Initialization. @V151168
- */ /*@V151168*/
- VOID NEAR ATAPICompleteInit( NPACB npACB ) /*@V151168*/
- { /*@V151168*/
- npACB->OSMState = ACBOS_COMPLETE_IORB;
- }
-
-
- /*------------------------------------*/ /*@V151168*/
- /* APM Suspend/Resume Support */ /*@V151168*/
- /* Reinitializes adapters and units */ /*@V151168*/
- /* following a resume event. */ /*@V151168*/
- /*------------------------------------*/ /*@V151168*/
- /*@V151168*/
- USHORT FAR APMEventHandler(PAPMEVENT Event) /*@V151168*/
- { /*@V151168*/
- USHORT Message = (USHORT)Event->ulParm1; /*@V151168*/
- USHORT PwrState; /*@V151168*/
- /*@V151168*/
- if ( Message == APM_SETPWRSTATE ) /*@V151168*/
- { /*@V151168*/
- PwrState = (USHORT)(Event->ulParm2 >> 16); /*@V151168*/
- if (PwrState != APM_PWRSTATEREADY) /*@V151168*/
- { /*@V151168*/
- return ( APMSuspend() ); /*@V151168*/
- } /*@V151168*/
- } /*@V151168*/
- else if ( Message == APM_NORMRESUMEEVENT || /*@V151168*/
- Message == APM_CRITRESUMEEVENT ) /*@V151168*/
- { /*@V151168*/
- return(APMResume()); /*@V151168*/
- } /*@V151168*/
- return 0; /*@V151168*/
- } /*@V151168*/
- /*@V151168*/
- /* @V151168
- * APMSuspend is currently a no-op @V151168
- */ /*@V151168*/
- USHORT NEAR APMSuspend() /*@V151168*/
- { /*@V151168*/
- return 0; /*@V151168*/
- } /*@V151168*/
- /*@V151168*/
- USHORT NEAR APMResume() /*@V151168*/
- { /*@V151168*/
- NPATBL npAT = AdapterTable; /*@V151168*/
- NPACB npACB; /*@V151168*/
- NPUCB npUCB; /*@V151168*/
- USHORT i; /*@V151168*/
- USHORT j, rc; /*@V151168*/
- USHORT Flags; /*@V155162*/
- /*@V151168*/
- for (i=0; i< cAdapters; i++, npAT++ ) /*@V151168*/
- { /*@V151168*/
- if ( !(npAT->Flags & ATBF_DISABLED) ) /*@V151168*/
- { /*@V151168*/
- if ( npACB = npAT->npACB ) /*@V151168*/
- { /*@V151168*/
- for (j = 0; j < MAX_UNITS; j++ ) /*@V151168*/
- { /*@V151168*/
- npUCB = &npACB->UnitCB[j]; /*@V151168*/
- /*@V151168*/
- if( npUCB->Flags & UCBF_FORCE ) /*@V155162*/
- { /*@V155162*/
- Flags = npUCB->Flags & UCBF_NOTPRESENT; /*@V155162*/
- // Try to claim the unit, which does an identify /*@V155162*/
- // command. If this works, assume the drive is /*@V155162*/
- // back. /*@V155162*/
- npUCB->Flags &= ~UCBF_NOTPRESENT; /*@V155162*/
- rc = ClaimUnit( npAT, TRUE, 0, NULL, NULL ); /*@V155162*/
- if( Flags != (npUCB->Flags & UCBF_NOTPRESENT) ) /*@V155162*/
- { /*@V155162*/
- npUCB->Flags |= UCBF_MEDIACHANGED; /*@V155162*/
- } /*@V155162*/
- } /*@V155162*/
- } /*@V151168*/
- } /*@V151168*/
- } /*@V151168*/
- } /*@V151168*/
- return 0; /*@V151168*/
- } /*@V151168*/
-
-