home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
rmfiles.zip
/
mitsrc.zip
/
CDINIT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-06
|
37KB
|
918 lines
#define INCL_DOSINFOSEG
#define INCL_NO_SCB
#define INCL_INITRP_ONLY
#include "os2.h" // \DRV6\H
#include "dos.h" // \DRV6\H
#include "sas.h" // \DRV6\H
#include "devcmd.h" // \DRV6\H
#include "iorb.h" // \DRV6\SRC\DEV\DASD\DISKH
#include "reqpkt.h" // \DRV6\SRC\DEV\DASD\DISKH
#include "addcalls.h" // \DRV6\SRC\DEV\DASD\DISKH
#include "dskinit.h"
#include "devclass.h"
#include <scsi.h>
#include <cdbscsi.h>
#include "cmd.h"
#include "devhelp.h" // \DRV6\SRC\DEV\DASD\DISKH
#include "cdb.h"
#include "proto.h"
#include "rmbase.h"
#include "rmcalls.h"
#include <string.h>
#include <memory.h>
#define BAD_PARMS 0x8113
#define STATUS_QUIET_FAIL 0x8015 | STATUS_DONE
static BOOL Allocated=FALSE;
BYTE Adapter[16]="MITSUMI$";
USHORT DeviceHandle=0;
extern USHORT near AdapterBase, near StatusRegister,near DataStatusRegister, near IrqNum, near IrqMode;
extern PUCHAR near YieldFlag;
extern PGINFOSEG near PGinfo;
extern void ScaleClock(UCHAR CpuType);
extern UCHAR near traceflag;
extern BOOL near ReadStatusLate;
extern UCHAR near wDrvVer[4];
extern BOOL near Lu002;
static char devstring[]="CDROM_0 ";
static UCHAR ProductIDMsg[] = \
"\n\r" \
"IBM OS/2 MITFX001.ADD 1.10\n\r" \
"?ITSUMI CD-ROM ? ? Port: 0?00 IRQ: 000? ";
//"012345678901234567890123456789012345678901234567890"
// 15 23 35 48
MSGTABLE ProductIDMsgParm = { MSG_REPLACEMENT_STRING,
1,
ProductIDMsg,
};
static USHORT ValidPorts[] = {
//static USHORT ValidPorts[16*4];// = {
0x300,
0x320, // Micron ships at 320 default (used to be 300)
// 0x360,
// 0x390,
0x340,
};
#define PortChoices sizeof(ValidPorts)/sizeof(USHORT)
static UCHAR charstring[]="0123456789ABCDEF";
int Active_Counter = 0 ;
static PIORB Head=0L, Tail=0L ; // Pointers to request packets queue management
//ULONG DevHlp=0;
ULONG Device_Help=0;
PFN RM_Help0 = 0L; /*VPNP*/
PFN RM_Help3 = 0L; /*VPNP*/
DRIVERSTRUCT DriverStruct =
{
"MITFX001.ADD", /* DrvrName */
"Mitsumi CDROM Driver", /* DrvrDescript */
"IBM OS/2", /* VendorName */
CMVERSION_MAJOR, /* MajorVer */
CMVERSION_MINOR, /* MinorVer */
1994,9,1, /* Date */
0, /* DrvrFlags */
DRT_ADDDM, /* DrvrType */
DRS_ADD, /* DrvrSubType */
NULL /* DrvrCallback */
};
/*----------------------------------------------*/
/* Adapter Description */ /*VPNP*/
/*----------------------------------------------*/
ADAPTERSTRUCT AdapterStruct =
{
"Proprietary CD Controller", /* AdaptDescriptName; */
0, /* AdaptFlags; */
AS_BASE_MSD, /* BaseType; */
AS_SUB_OTHER, /* SubType; */
AS_INTF_GENERIC, /* InterfaceType; */
AS_HOSTBUS_ISA, /* HostBusType; */
AS_BUSWIDTH_16BIT, /* HostBusWidth; */
NULL, /* pAdjunctList; */
NULL /* reserved */
};
/*----------------------------------------------*/
/* Device Description */ /*VPNP*/
/*----------------------------------------------*/
DEVICESTRUCT DevStruct =
{
"CDROM Drive", /* DevDescriptName; */
DS_REMOVEABLE_MEDIA, /* DevFlags; */
DS_TYPE_CDROM /* DevFlags; */
};
HDRIVER hDriver = 0L; /*VPNP*/
HADAPTER hAdapter=0;
HDEVICE hDevice=0;
USHORT RMFlags = 0; /*VPNP*/
UCHAR ResourceBuf[sizeof(AHRESOURCE)+sizeof(HRESOURCE)*2]; /*VPNP*/
PAHRESOURCE pResourceList = (PAHRESOURCE) &ResourceBuf; /*VPNP*/
extern void EnableASIC(USHORT Port, USHORT IRQ,USHORT type,USHORT CardPort);
extern BOOL near PortValid(void);
/************************ START OF SPECIFICATIONS *****************************
* *
* SUBROUTINE NAME: CDStrat1 *
* *
* DESCRIPTIVE NAME: Strategy 1 entry point *
* *
* FUNCTION: This routine processes request "Device Driver Request Packets". *
* Only, Initialize Base Request is accepted. All other requests *
* are rejected. *
* *
* NOTES: This routine runs in protect mode only as a single thread *
* at level 3 with IOPL. *
* *
* INPUT: ES:BX contain pointer to request packet. *
* *
************************* END OF SPECIFICATIONS ******************************/
VOID FAR CDStrat1()
{
PRPH pRPH; // Pointer to RPH (Request Packet Header)
USHORT Cmd; // Local variable
_asm { mov word ptr pRPH[0], bx // pRPH is initialize to
mov word ptr pRPH[2], es }; // ES:BX passed from the kernel
Cmd = pRPH->Cmd;
if (Cmd == CMDInitBase)
DriveInit( (PRPINITIN) pRPH );
else
pRPH->Status = STATUS_ERR_UNKCMD;
}
/************************ START OF SPECIFICATIONS *****************************
* *
* SUBROUTINE NAME: ProcessReq *
* *
* DESCRIPTIVE NAME: Process IORB Requests *
* *
* FUNCTION: This routine receives the I/O Request Blocks to process *
* from the Queing entrypoint *
* *
************************* END OF SPECIFICATIONS ******************************/
VOID ProcessReq( PIORBH pIORB )
{
PSCSI_STATUS_BLOCK pStatus;
BOOL Status = TRUE;
USHORT CmdCode;
USHORT SubCmd;
CmdCode=pIORB->CommandCode;
SubCmd =pIORB->CommandModifier;
switch(CmdCode)
{
case IOCC_CONFIGURATION :
switch(SubCmd)
{
case IOCM_GET_DEVICE_TABLE:
Build_Device_Table((PIORB_CONFIGURATION) pIORB);
break;
case IOCM_COMPLETE_INIT:
break;
default:
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
} /* end switch */
break;
case IOCC_UNIT_CONTROL :
switch(SubCmd)
{
case IOCM_ALLOCATE_UNIT :
if(!Allocated)
{
Allocated=TRUE;
} /* end if */
else
{
IORB_CmdErr(IOERR_UNIT_ALLOCATED, pIORB,0,0);
} /* end else */
break;
case IOCM_DEALLOCATE_UNIT:
if(Allocated)
{
Allocated=FALSE;
} /* end if */
else
{
IORB_CmdErr(IOERR_UNIT_NOT_ALLOCATED, pIORB,0,0);
} /* end else */
break;
case IOCM_CHANGE_UNITINFO:
// not used
if(!Allocated)
{
IORB_CmdErr(IOERR_UNIT_NOT_ALLOCATED, pIORB,0,0);
} /* end if */
break;
default:
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
} /* end switch */
break;
case IOCC_GEOMETRY :
switch(SubCmd)
{
case IOCM_GET_MEDIA_GEOMETRY :
case IOCM_GET_DEVICE_GEOMETRY:
if(Allocated)
{
if(!GetGeometry(SubCmd,(PIORB_GEOMETRY)pIORB))
IORB_CmdErr(IOERR_UNIT_NOT_READY, pIORB,SCSI_SK_NOTRDY,0);
} /* end if */
else
{
IORB_CmdErr(IOERR_UNIT_NOT_ALLOCATED, pIORB,0,0);
} /* end else */
break;
case IOCM_SET_MEDIA_GEOMETRY :
case IOCM_SET_LOGICAL_GEOMETRY:
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
default:
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
} /* end switch */
break;
case IOCC_EXECUTE_IO :
switch(SubCmd)
{
case IOCM_READ :
// currently not used
case IOCM_READ_VERIFY :
// currently not used
case IOCM_READ_PREFETCH :
// currently not used
case IOCM_WRITE :
case IOCM_WRITE_VERIFY :
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
default:
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
} /* end switch */
break;
case IOCC_FORMAT :
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
case IOCC_UNIT_STATUS :
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
case IOCC_DEVICE_CONTROL :
if(SubCmd!=IOCM_ABORT)
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
} /* end else */
// error
break;
case IOCC_ADAPTER_PASSTHRU :
switch(SubCmd)
{
case IOCM_EXECUTE_SCB :
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
case IOCM_EXECUTE_CDB:
if(Allocated)
{
pIORB->Status &= (~IORB_STATUSBLOCK_AVAIL);
if(pIORB->RequestControl & IORB_REQ_STATUSBLOCK)
{
pStatus=(PSCSI_STATUS_BLOCK)MAKEP(SELECTOROF(pIORB),pIORB->pStatusBlock);
pStatus->Flags &= ~STATUS_SENSEDATA_VALID;
pStatus->SenseData->ErrCode_Valid = 0; // ?????
pStatus->SenseData->SenseKey = 0;
pStatus->SenseData->AddSenseCode=0;
} /* end if */
ProcessCDB(pIORB);
}
else
{
IORB_CmdErr(IOERR_UNIT_NOT_ALLOCATED, pIORB,0,0);
} /* end else */
break;
default:
// error
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
break;
} /* end switch */
break;
default:
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, pIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_COMMAND_OPCODE);
// error
break;
} /* end switch */
// set the IORB as Done processing
pIORB->Status |= IORB_DONE;
// if there is an Asyn post routine, call it now
if (pIORB->RequestControl & IORB_ASYNC_POST)
pIORB->NotifyAddress(pIORB);
}
/************************ START OF SPECIFICATIONS *****************************
* *
* SUBROUTINE NAME: IORB_CmdErr *
* *
* DESCRIPTIVE NAME: IORB error completion *
* *
* FUNCTION: This routine sets the error code into the IORB header, then *
* calls ThisIORB_Complete with error completion status. *
* *
************************* END OF SPECIFICATIONS ******************************/
VOID IORB_CmdErr (USHORT ErrCode, PIORBH pIORB, USHORT Sense_key, USHORT AdditionalSense)
{
PSCSI_STATUS_BLOCK pStatus;
if(pIORB)
{
pIORB->ErrorCode = ErrCode;
pIORB->Status |= IORB_ERROR;
if(pIORB->RequestControl & IORB_REQ_STATUSBLOCK)
{
pIORB->Status |= IORB_STATUSBLOCK_AVAIL;
pStatus=(PSCSI_STATUS_BLOCK)MAKEP(SELECTOROF(pIORB),pIORB->pStatusBlock);
pStatus->Flags |= STATUS_SENSEDATA_VALID;
pStatus->SenseData->ErrCode_Valid = 0x70; // ?????
pStatus->SenseData->SenseKey = Sense_key;
pStatus->SenseData->AddSenseCode=AdditionalSense;
} /* end if */
} /* end if */
return;
}
/************************ START OF SPECIFICATIONS *****************************
* *
* SUBROUTINE NAME: Build_Device_Table *
* *
* DESCRIPTIVE NAME: Build Adapter information table *
* *
* FUNCTION: This routine fills the DEVICETABLE, ADAPTERINFO and UNITINFO *
* tables pointed to by the IORB. All current data is compiled *
* data tables. *
* *
************************* END OF SPECIFICATIONS ******************************/
VOID Build_Device_Table(PIORB_CONFIGURATION pIORB)
{
DEVICETABLE far *pDEVT = pIORB->pDeviceTable;
PADAPTERINFO pADAPT;
PUNITINFO pUNIT;
INT A;
USHORT FlagMask = (UF_NOSCSI_SUPT + UF_CHANGELINE + UF_REMOVABLE | UF_NODASD_SUPT );
pIORB->DeviceTableLen = (sizeof (UNITINFO) );
pIORB->DeviceTableLen += sizeof (ADAPTERINFO) + sizeof (DEVICETABLE);
pDEVT->ADDLevelMajor = ADD_LEVEL_MAJOR;
pDEVT->ADDLevelMinor = ADD_LEVEL_MINOR;
pDEVT->ADDHandle = DeviceHandle;
pDEVT->TotalAdapters = 1;
pDEVT->pAdapter[0] = (NPADAPTERINFO) (OFFSETOF (pIORB->pDeviceTable) +
sizeof (DEVICETABLE));
pADAPT = MAKEP (SELECTOROF (pIORB->pDeviceTable), pDEVT->pAdapter[0]);
pUNIT = &(pADAPT->UnitInfo[0]);
for (A = 0; A < 15; A++)
{
pADAPT->AdapterName[A] = Adapter[A];
} ;
pADAPT->AdapterUnits = 1;
pADAPT->AdapterDevBus = AI_DEVBUS_NONSCSI_CDROM;
pADAPT->AdapterIOAccess = AI_IOACCESS_PIO;
pADAPT->AdapterHostBus = AI_HOSTBUS_ISA | AI_BUSWIDTH_8BIT;
pADAPT->AdapterSCSITargetID = 0;
pADAPT->AdapterSCSILUN = 0;
pADAPT->AdapterFlags = 0;
pADAPT->MaxHWSGList = 0;
pADAPT->MaxCDBTransferLength = 0;
pUNIT->AdapterIndex = 0;
pUNIT->UnitIndex = 0;
pUNIT->UnitFlags = FlagMask;
pUNIT->UnitHandle = 0;
pUNIT->UnitType = UIB_TYPE_CDROM;
pUNIT->QueuingCount = 1;
pUNIT->FilterADDHandle = 0;
return;
}
/************************ START OF SPECIFICATIONS *****************************
* *
* SUBROUTINE NAME: GetGeometry *
* *
* DESCRIPTIVE NAME: Return Geometry to IORB sender *
* *
* FUNCTION: This routine stores the geometry for either the physical *
* device or the current media as requested. *
* *
************************* END OF SPECIFICATIONS ******************************/
BOOL GetGeometry(USHORT SubCmd, PIORB_GEOMETRY pIORB)
{
CDROMSTAT Data;
BOOL rc=FALSE;
USHORT Status;
pIORB->pGeometry->TotalSectors = DefaultDiscSize; // set default
pIORB->pGeometry->BytesPerSector = 2048; // set default
DevHelp_RAS( 175 ,0 , 0, NULL);
if(!ReadyHardware((PIORB)pIORB,SCSI_READ_CAPACITY))
{
Status=DriveCommand(ReadToc,NULL,NULL,&Data,sizeof(Data.TOC));
if( (!DOOROPEN(Status)) && (!COMMANDCHECK(Status)) )
{
pIORB->pGeometry->TotalSectors = (((BCD2Bin(Data.TOC.LeadoutMin)*60)+BCD2Bin(Data.TOC.LeadoutSec))*75)+BCD2Bin(Data.TOC.LeadoutFrame);
// MAKEULONG(MAKEUSHORT(BCD2Bin(Data.TOC.LeadoutFrame),MAKEUSHORT(BCD2Bin(Data.TOC.LeadoutSec),BCD2Bin(Data.TOC.LeadoutMin)));
pIORB->pGeometry->BytesPerSector = 2048;
pIORB->pGeometry->NumHeads = 1;
pIORB->pGeometry->SectorsPerTrack = 0x1ff;
pIORB->pGeometry->TotalCylinders = 0;
pIORB->GeometryLen = sizeof (GEOMETRY);
DevHelp_RAS( 176 ,0 , 0, NULL);
rc=TRUE;
} /* end if */
} /* end if */
DevHelp_RAS( 177 ,0 , 0, NULL);
return rc;
}
/************************ START OF SPECIFICATIONS *****************************
* *
* SUBROUTINE NAME: DriveInit *
* *
* DESCRIPTIVE NAME: Soundblaster Pro Driver Init *
* *
* FUNCTION: This procedure initializes the device driver. *
* *
* Installation will fail if there are no SBPro detected *
* *
* This routine runs in protect mode only as a single thread *
* at CPL = 0. *
* *
************************* END OF SPECIFICATIONS ******************************/
VOID DriveInit(PRPINITIN pRPH )
{
PRPINITOUT pRPO;
extern UCHAR near last_data_byte;
extern VOID last_code_byte();
USHORT i,l,temp,state,PortScan,Attachment=0,AttachmentPort;
PDDD_PARM_LIST Parmlist=(PDDD_PARM_LIST)pRPH->InitArgs;
PSZ Parms=MAKEP(SELECTOROF(Parmlist),Parmlist->cmd_line_args);
PMACHINE_CONFIG_INFO pMch=MAKEP(SELECTOROF(Parmlist),Parmlist->machine_config_table);
BOOL Verbose=FALSE;
PUCHAR p;
UCHAR a1,a2,a3;
struct DevClassTableStruc far *pdevs;
RESOURCESTRUCT Resource;
ADJUNCT AdjunctData;
PortScan=0; // start at first array entry
// DevHlp = (ULONG)pRPH->DevHlpEP;
Device_Help = (ULONG)pRPH->DevHlpEP;
pRPO = (PRPINITOUT) pRPH;
// for(i=0,l=0x300; i<PortChoices;i++,l+=4 ) // lets scan all the ports
// {
// ValidPorts[i]=l;
// } /* end for */
i=strlen(Parms);
for(l=0; l<i; l++) // lower case the entire string
{
Parms[l]|=0x20;
} /* end for */
for(;Parms && *Parms ; ) // loop thru parms
{
if(*Parms=='/') // did we find a slash?
{
if(!memcmp(Parms,"/e",2)) // read status early?
{
Parms+=2; // skip over
ReadStatusLate=FALSE; // set flag for pre-read status
} /* end if */
else if(!memcmp(Parms,"/v",2)) // verbose message request?
{
Parms+=2; // skip over
Verbose=TRUE; // set flag verbose mode
} /* end if */
#if defined(TRACE) | defined(TRACE1)
else if(!memcmp(Parms,"/t",2)) // enable tracing?
{
Parms+=2; // skip over
traceflag=TRUE; // enable tracing
} /* end if */
#endif
else if(!memcmp(Parms,"/i:",3)) // is it the one we want?
{
if((i=strlen(Parms))>=4) // still enough chars to process?
{
Parms+=3; // skip over /I:
if(Parms[1]>='0' && Parms[1]<='9') // two byte irq number?
{
temp= ((Parms[0] - '0') *10 ) + // get the irq specified
(Parms[1] - '0') ;
Parms+=2; // skip over xx irqnum
} /* end if */
else // single byte irq number
{
temp= (Parms[0] - '0'); // get the irq specified
Parms+=1; // skip over x irqnum
} /* end else */
switch(temp) // make sure its one of our choices
{
case 2:
IrqMode=Irq9; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
case 3:
IrqMode=Irq3; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
case 5:
IrqMode=Irq5; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
case 9:
IrqMode=Irq9; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
case 10:
IrqMode=Irq10; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
case 11:
IrqMode=Irq11; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
case 12:
IrqMode=Irq12; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
case 15:
IrqMode=Irq15; // set adapter pattern
IrqNum=temp; // valid IRQnumber
break;
default: // bad irq number
IrqMode=0;
IrqNum=0;
break;
} /* end switch */
}
}
else if(!memcmp(Parms,"/p:",3)) // is it the one we want?
{
if(strlen(Parms)>=6) // still enough chars to process?
{
Parms+=3; // skip over /p:
a1=Parms[0]-(((Parms[0] & 0x70) == 0x30)?48:87);
a2=Parms[1]-(((Parms[1] & 0x70) == 0x30)?48:87);
a3=Parms[2]-(((Parms[2] & 0x70) == 0x30)?48:87);
temp= (a1*256 ) + (a2*16) + (a3) ;
Parms+=3; // skip over address
// Remove address range verification to allow the sound blaster with p:230
//
// if(temp>=0x300 && temp<=0x3fc && ((temp & 3) ==0))
// {
ValidPorts[PortScan=(PortChoices-1)]=temp; // use only last entry
// } /* end if */
// else
// {
// PortScan=PortChoices; // past maximum
// } /* end else */
} /* end if */
else // /P: specified, but not enough bytes left
{
PortScan=PortChoices; // past maximum
}
} /* end if */
else if(!memcmp(Parms,"/at:",4)) // is it the one we want?
{
if(strlen(Parms)>=6) // still enough chars to process?
{
Parms+=4; // skip over /p:
Attachment+=(Parms[0] -0x30)*10;
Attachment+=(Parms[1] -0x30);
Parms+=2;
switch(Attachment)
{
case 5:
break;
case 6:
if(Parms[0]==',')
{
Parms++;
a1=Parms[0]-(((Parms[0] & 0x70) == 0x30)?48:87);
a2=Parms[1]-(((Parms[1] & 0x70) == 0x30)?48:87);
a3=Parms[2]-(((Parms[2] & 0x70) == 0x30)?48:87);
AttachmentPort=(a1*256 ) + (a2*16) + (a3) ;
Parms+=3; // skip over address
}
else
{
AttachmentPort=0x220;
}
break;
default:
Attachment=0;
break;
}
} /* end if */
else // /P: specified, but not enough bytes left
{
PortScan=PortChoices; // past maximum
}
} /* end if */
else
Parms++;
} /* end if */
else
Parms++;
} /* end for */
if(!(pMch->BusInfo & BUSINFO_MCA)) // only if not MCA
{
RMCreateDriver(&DriverStruct,
&hDriver);
PGinfo = (PGINFOSEG)DevHelp_GetDosVar(1); // pointer to global info segment
ScaleClock((UCHAR)(PGinfo->uchMinorVersion?pMch->CpuInfo:I386)); // say 386 if not 2.1 or above
DevHelp_RAS( 170 ,0 , sizeof(PGinfo->msecs),&PGinfo->msecs);
#if 0 // resource manager is supposed to handle this
if(PortScan==0) // nothing selected, scan all
{
if(pdevs = (struct DevClassTableStruc far *)DevHelp_GetDosVar(DHGETDOSV_DEVICECLASSTABLE))
{
// pointer to add device table
// make sure we don't collide
// with Adaptec 152x adapter
for(i=0;i<pdevs->DCCount ;i++ ) // spin thru all adapters
{
if(!memcmp(pdevs->DCTableEntries[i].DCName,"AHA1520.ADD",11))
{
ValidPorts[PortChoices-1]=ValidPorts[0];
break;
} /* end if */
} /* end for */
} /* end if */
} /* end if */
#endif
for(; PortScan<PortChoices; PortScan++) // loop thru array of addresses
{
Resource.ResourceType = RS_TYPE_IO;
Resource.IOResource.BaseIOPort = ValidPorts[PortScan];
Resource.IOResource.NumIOPorts = 3; // what is this???
Resource.IOResource.IOFlags = RS_IO_EXCLUSIVE;
Resource.IOResource.IOAddressLines = 10;
pResourceList->NumResource = 1;
pResourceList->hResource[0] = 0L; /*VPNP*/
pResourceList->hResource[1] = 0L; /*VPNP*/
if(!RMAllocResource( hDriver, &pResourceList->hResource[0], &Resource ))
{
if(Attachment)
EnableASIC(ValidPorts[PortScan],IrqNum,Attachment,AttachmentPort); // enable Orchid or Cardinal ASIC
AdapterBase=ValidPorts[PortScan]; // get base address
StatusRegister=AdapterBase+1, // status register address
DataStatusRegister=AdapterBase+2; // data status register address
if(PortValid() && ChkBaseAddx()) // check for adapter presence
{ // found adapter
DevHelp_RAS( 170 ,AdapterBase , sizeof(PGinfo->msecs),&PGinfo->msecs);
break;
}
else // no adapter found at this address
{
RMDeallocResource( hDriver, pResourceList->hResource[0]);
DevHelp_RAS( 171 ,AdapterBase , sizeof(PGinfo->msecs),&PGinfo->msecs);
}
}
} /* end for */
} /* end if */
else
{
PortScan=PortChoices; // force no loading on MCA machines
} /* end else */
if(PortScan==PortChoices) // if over max entries to search thru
{ // adapter wasn't found
pRPO->CodeEnd = 0;
pRPO->DataEnd = 0;
pRPO->rph.Status = STATUS_QUIET_FAIL;
DevHelp_RAS( 174 ,0, 0, NULL);
RMDestroyDriver(hDriver); // remove Resource manager definition
for(i=0; i<sizeof(ProductIDMsg);i++ )
{
if(ProductIDMsg[i]=='?')
{
strcpy(&ProductIDMsg[i],"No units detected.");
break;
} /* end if */
} /* end for */
if(Verbose)
{
DevHelp_DisplayMsg(&ProductIDMsgParm);
} /* end if */
}
else
{
if(ChkDrive())
{
DevHelp_RAS( 172 ,0 , 0, NULL);
}
else
DevHelp_RAS( 173 ,0, 0,NULL);
RMCreateAdapter( hDriver, &hAdapter, &AdapterStruct, (HDEVICE)NULL, (PAHRESOURCE)pResourceList );
pRPO->CodeEnd = (USHORT)last_code_byte; // set our code end
pRPO->DataEnd = (USHORT)&last_data_byte; // and data
YieldFlag=DevHelp_GetDosVar(7); // get address of yield flag
// register our ADD
DeviceHandle=DevHelp_RegisterDeviceClass(Adapter, (PVOID)IORBEntry, 0, 1);
pRPO->rph.Status = 0x100;
for(i=0,state=0; i<sizeof(ProductIDMsg);i++ )
{
if(ProductIDMsg[i]=='?')
{
switch(state)
{
case 0:
ProductIDMsg[i]='M';
DevStruct.DevDescriptName=&ProductIDMsg[i];
state=1;
break;
case 1:
switch(wDrvVer[0])
{
case 'M':
if(Lu002)
{
p="LU002S";
} /* end if */
else
{
p="LU005S";
} /* end else */
break;
case 'F':
p="FX001";
break;
case 'D':
p="FX001D";
break;
default:
p="unkown";
break;
} /* end switch */
memcpy(&ProductIDMsg[i],p,strlen(p));
state=2;
break;
case 2:
memcpy(&ProductIDMsg[i],wDrvVer,strlen(wDrvVer));
p=&ProductIDMsg[i]+strlen(wDrvVer);
state=3;
break;
case 3:
ProductIDMsg[i++]=charstring[(AdapterBase / 256)];
ProductIDMsg[i++]=charstring[((AdapterBase & 250)/16)];
ProductIDMsg[i]=charstring[(AdapterBase & 15)];
state=4;
break;
case 4:
if(IrqNum)
{
ProductIDMsg[i]=charstring[IrqNum];
} /* end if */
else
{
strcpy(&ProductIDMsg[i-3],"Polled");
} /* end else */
break;
default:
break;
} /* end switch */
} /* end if */
} /* end for */
if(Verbose)
{
DevHelp_DisplayMsg(&ProductIDMsgParm);
} /* end if */
*p='\0';
memset(&AdjunctData,0,sizeof(AdjunctData));
AdjunctData.AdjType=ADJ_ADD_UNIT;
AdjunctData.AdjLength=sizeof(AdjunctData);
AdjunctData.Add_Unit.ADDHandle=DeviceHandle;
AdjunctData.Add_Unit.UnitHandle=0;
DevStruct.pAdjunctList=&AdjunctData;
// nasty code here. the text we were already using for the device string
// is a static variable, modified with parms we found during install
// so to save space, we are going to backup and PVERLAY a portion of the
// existing message..
// backup length of new text
DevStruct.DevDescriptName-=strlen(devstring);
// copy in this new stupid prefix...
memcpy(DevStruct.DevDescriptName,devstring,strlen(devstring));
// now create the device with this new modified title..
RMCreateDevice( hDriver, &hDevice, &DevStruct, hAdapter, NULL);
}
return;
}
// =========================================== //
// //
// This routine will queue the request packet //
// //
// input : rp - request packet pointer to be //
// queued //
// //
// ------------------------------------------- //
void QIORB( PIORBH pIORB )
{
pIORB->pNxtIORB = 0L ; // Clear forward link pointer
if( Head==Tail && Head==0L ) // if nothing queued
Head = Tail = pIORB ; // make this one both head and tail
else
{
Tail->pNxtIORB = pIORB ; // else link this one to last
Tail = pIORB ; // and make this one last in list
}
}
// ================================================= //
// //
// This routine will dequeue the last request packet //
// //
// input : none //
// //
// output : last request packet in list //
// //
// ------------------------------------------------- //
PIORBH DeQIORB( void )
{
PIORBH pIORB ;
if( pIORB=Head ) // if there is an entry on queue
{
Head = pIORB->pNxtIORB ; // unlink it
if( Head == 0L ) // if only entry
Tail = 0L ; // clear tail pointer too
}
return pIORB ; // return pointer to dequeued packet
}
/************************ START OF SPECIFICATIONS *****************************
* *
* SUBROUTINE NAME: IORBEntry *
* *
* DESCRIPTIVE NAME: IORB Entry point *
* *
* FUNCTION: This routine receives the I/O Request Blocks from the device *
* and filter managers. *
* *
************************* END OF SPECIFICATIONS ******************************/
VOID _loadds FAR IORBEntry( PIORBH pIORB )
{
++Active_Counter;
QIORB(pIORB);
if( Active_Counter==1 )
{
while(Head)
{
ProcessReq(DeQIORB());
} /* end while */
}
--Active_Counter;
}