home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- *
- * SOURCE FILE NAME = NEIORB1.C
- *
- * DESCRIPTIVE NAME = IORB processor for CD-ROM NEC filter drivers
- *
- * 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 = V2.0
- *
- * DATE
- *
- * DESCRIPTION
- *
- *
- * FUNCTIONS Filters SCSI-2 Command Descriptor Blocks and routes
- * them to the vendor unique filter routines.
- *
- * ENTRY POINTS:
- *
- * DEPENDENCIES:
- *
- * NOTES
- *
- *
- * STRUCTURES
- *
- * EXTERNAL REFERENCES
- *
- * EXTERNAL FUNCTIONS
- *
- * CHANGE ACTIVITY =
- * DATE FLAG APAR CHANGE DESCRIPTION
- * -------- ---------- ----- --------------------------------------
- * mm/dd/yy @Vr.mpppxx xxxxx xxxxxxx
- ****************************************************************************/
-
- #include "flthdr.h"
-
- USHORT FilterRequest (PIORB);
- USHORT Filter_ReadCapacity (PIORB_CDB);
- USHORT Filter_TestUnitReady (PIORB_CDB);
- VOID ProcessNextState (PIORB_CDB, USHORT);
- VOID _loadds FAR Filter_NotifyDoneIORB (PIORB_CDB);
- VOID NEC_Sense_Fix (PIORB_CDB);
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_IORB
- *
- * DESCRIPTION = Filters IORB Requests from OS2CROM.DMD
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT = NONE
- *
- * RETURN-NORMAL = NONE
- * RETURN-ERROR = NONE
- *
- ****************************************************************************/
-
- VOID _loadds FAR Filter_IORB (pIORB)
-
- PIORB pIORB;
- {
- USHORT action_code;
- NPUNITCB pUnitCB;
- USHORT (NEAR *pRoutine)(PIORB_CDB);
- PIORB_FLTWORK pFilter_workspace;
-
- /*
- ** Handle the Get Device Table call. Since we are just filtering
- ** requests, return a table with no unit info.
- */
- if (pIORB->CommandCode == IOCC_CONFIGURATION)
- {
- if (pIORB->CommandModifier == IOCM_GET_DEVICE_TABLE)
- {
- ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->ADDLevelMajor = 1;
- ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->ADDLevelMinor = 0;
- ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->ADDHandle = FilterADDHandle;
- ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->TotalAdapters = 0;
- }
-
- pIORB->Status = IORB_DONE;
- pIORB->ErrorCode = 0;
- if (pIORB->RequestControl & IORB_ASYNC_POST)
- (pIORB->NotifyAddress) ( (PIORB) pIORB);
- return;
- }
-
-
- if (pIORB->UnitHandle >= NumCDROMDrives)
- {
- pIORB->Status = IORB_DONE + IORB_ERROR;
- pIORB->ErrorCode = IOERR_UNIT_NOT_ALLOCATED;
- if (pIORB->RequestControl & IORB_ASYNC_POST)
- (pIORB->NotifyAddress) ( (PIORB) pIORB);
- return;
- }
-
-
- /* Replace unit handle for filter with unit handle for the ADD */
-
- pUnitCB = &UnitCBTable[pIORB->UnitHandle];
- pIORB->UnitHandle = pUnitCB->ADDUnitHandle;
-
- if ( ( (USHORT) pRoutine = FilterRequest (pIORB)) != 0)
- {
- pFilter_workspace = (PIORB_FLTWORK) ((PIORB_CDB)pIORB)->filter_workspace;
-
- pFilter_workspace->CDM_NotifyAddress = pIORB->NotifyAddress;
- pFilter_workspace->pUnitCB = pUnitCB;
-
- action_code = (pRoutine) ( (PIORB_CDB) pIORB);
- if ( ( pUnitCB->product_id[6] == '2' ) ||
- ( pUnitCB->product_id[12] == ' ' ) )
- {
- NEC_Sense_Fix ( (PIORB_CDB) pIORB);
- }
- ProcessNextState ( (PIORB_CDB) pIORB, action_code);
- return;
- }
- else /* Call the ADD for any requests which aren't filtered. */
- {
- (pUnitCB->AdapterDriverEP) (pIORB);
- return;
- }
- }
-
- /****************************************************************************
- *
- * FUNCTION NAME = FilterRequest
- *
- * DESCRIPTION = See if this request should be filtered
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT FilterRequest (pIORB)
-
- PIORB pIORB;
- {
- USHORT (NEAR *SCSI_Group0_Table[])() =
- {
- { Filter_TestUnitReady }, /* 0x00 - Test Unit Ready */
- { 0 }, /* 0x01 - Rezero Unit */
- { 0 }, /* 0x02 - */
- { 0 }, /* 0x03 - Request Sense */
- { 0 }, /* 0x04 - */
- { 0 }, /* 0x05 - */
- { 0 }, /* 0x06 - */
- { 0 }, /* 0x07 - */
- { 0 }, /* 0x08 - Read (6) */
- { 0 }, /* 0x09 - */
- { 0 }, /* 0x0A - Write (6) */
- { Filter_Seek_6 }, /* 0x0B - Seek (6) */
- { 0 }, /* 0x0C - */
- { 0 }, /* 0x0D - */
- { 0 }, /* 0x0E - */
- { 0 }, /* 0x0F - */
- { 0 }, /* 0x10 - */
- { 0 }, /* 0x11 - */
- { 0 }, /* 0x12 - Inquiry */
- { 0 }, /* 0x13 - */
- { 0 }, /* 0x14 - */
- { Filter_ModeSelect }, /* 0x15 - Mode Select (6) */
- { 0 }, /* 0x16 - Reserve */
- { 0 }, /* 0x17 - Release */
- { 0 }, /* 0x18 - */
- { 0 }, /* 0x19 - */
- { 0 }, /* 0x1A - Mode Sense */
- { Filter_StartStopUnit }, /* 0x1B - Start/Stop Unit */
- { 0 }, /* 0x1C - Receive Diagnostic */
- { 0 }, /* 0x1D - Send Diagnostic */
- { Filter_PreventAllowRemoval }, /* 0x1E - Prevent/Allow Removal */
- { 0 }, /* 0x1F - */
- };
-
- USHORT (NEAR *SCSI_Group1_Table[])() =
- {
- { 0 }, /* 0x20 - */
- { 0 }, /* 0x21 - */
- { 0 }, /* 0x22 - */
- { 0 }, /* 0x23 - */
- { 0 }, /* 0x24 - */
- { Filter_ReadCapacity }, /* 0x25 - Read Capacity */
- { 0 }, /* 0x26 - */
- { 0 }, /* 0x27 - */
- { 0 }, /* 0x28 - Read (10) */
- { 0 }, /* 0x29 - */
- { 0 }, /* 0x2A - Write (10) */
- { Filter_Seek_10 }, /* 0x2B - Seek (10) */
- { 0 }, /* 0x2C - */
- { 0 }, /* 0x2D - */
- { 0 }, /* 0x2E - Write & Verify (10) */
- { 0 }, /* 0x2F - Verify (10) */
- };
-
-
- USHORT (NEAR *SCSI_Group2_Table[])() =
- {
- { 0 }, /* 0x40 - */
- { 0 }, /* 0x41 - */
- { Filter_ReadSubChannel }, /* 0x42 - Read sub-channel */
- { Filter_ReadTOC }, /* 0x43 - Read TOC */
- { Filter_ReadHeader }, /* 0x44 - Read Header */
- { 0 }, /* 0x45 - Play Audio (10) */
- { 0 }, /* 0x46 - */
- { Filter_PlayAudio_MSF }, /* 0x47 - Play Audio MSF */
- { 0 }, /* 0x48 - Play Audio Track/Index*/
- { 0 }, /* 0x49 - Play Audio Track Rel. */
- { 0 }, /* 0x4A - */
- { Filter_Pause_Resume }, /* 0x4B - Pause/Resume */
- { 0 }, /* 0x4C - */
- { 0 }, /* 0x4D - */
- { 0 }, /* 0x4E - */
- { 0 }, /* 0x4F - */
- };
-
-
- /* USHORT (NEAR *SCSI_Group5_Table[])() = */
- /* { */
- /* { Filter_PlayAudio_12 }, 0xA5 - Play Audio (12) */
- /* { Filter_CmdError }, 0xA6 - */
- /* { Filter_CmdError }, 0xA7 - */
- /* { Filter_Read_12 }, 0xA8 - Read (12) */
- /* { Filter_PlayAudio_Track_12 }, 0xA9 - Play Audio Track (12) */
- /* }; */
-
-
- UCHAR command;
- USHORT (NEAR *pRoutine)();
- struct SCSI_command FAR * pCDB;
-
- pRoutine = 0;
-
- if (pIORB->CommandCode == IOCC_ADAPTER_PASSTHRU &&
- pIORB->CommandModifier == IOCM_EXECUTE_CDB)
- {
- pCDB = (struct SCSI_command FAR *)
- ((PIORB_ADAPTER_PASSTHRU)pIORB)->pControllerCmd;
-
- command = pCDB->byte_0;
-
- if (command >= 0 && command <= 0x1F)
- pRoutine = SCSI_Group0_Table[command];
- else if (command >= 0x20 && command <= 0x2F)
- pRoutine = SCSI_Group1_Table[command-0x20];
- else if (command >= 0x40 && command <= 0x4F)
- pRoutine = SCSI_Group2_Table[command-0x40];
- /* else if
- ** (command >= 0xA5 && command <= 0xA9)
- ** pRoutine = SCSI_Group5_Table[command-0xA5];
- */
- else
- pRoutine = 0;
-
- }
- return((USHORT)pRoutine);
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_NotifyDoneIORB
- *
- * DESCRIPTION = Filter notification routine
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT = NONE
- *
- * RETURN-NORMAL = NONE
- *
- * RETURN-ERROR = NONE
- *
- ****************************************************************************/
-
- VOID _loadds FAR Filter_NotifyDoneIORB (pIORB)
-
- PIORB_CDB pIORB;
-
- {
- USHORT action_code;
- PIORB_FLTWORK pFilter_workspace;
- NPUNITCB pUnitCB;
-
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
- pUnitCB = pFilter_workspace->pUnitCB;
-
- if ( ( pUnitCB->product_id[6] == '2' ) ||
- ( pUnitCB->product_id[12] == ' ' ) )
- {
- NEC_Sense_Fix (pIORB);
- }
-
- if ( (pIORB->apt.iorbh.Status & IORB_ERROR) &&
- ( !(pIORB->apt.iorbh.Status & IORB_RECOV_ERROR) ) &&
- ( !(pFilter_workspace->flags & FWF_SKIP_ERROR_CHECK) ) )
- {
- pFilter_workspace->flags = 0;
- action_code = NOTIFY_CDM;
- }
- else
- {
- pFilter_workspace->flags = 0;
- action_code = (pFilter_workspace->completion_address) (pIORB);
- }
- ProcessNextState (pIORB, action_code);
- return;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = ProcessNextState
- *
- * DESCRIPTION = Process next state of the request
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT = NONE
- *
- * RETURN-NORMAL = NONE
- *
- * RETURN-ERROR = NONE
- *
- ****************************************************************************/
-
- VOID ProcessNextState (pIORB, action_code)
-
- PIORB_CDB pIORB;
- USHORT action_code;
- {
-
- NPUNITCB pUnitCB;
- PIORB_FLTWORK pFilter_workspace;
-
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
-
- pUnitCB = pFilter_workspace->pUnitCB;
-
- switch (action_code)
- {
- case CALL_ADD_AND_RET:
- pIORB->apt.iorbh.Status = 0;
- pIORB->apt.iorbh.ErrorCode = 0;
- (pUnitCB->AdapterDriverEP) ((PIORB)pIORB);
- break;
-
- case CALL_ADD_AND_NOTIFY_FILTER:
- (PVOID) pIORB->apt.iorbh.NotifyAddress=(PVOID) Filter_NotifyDoneIORB;
- pIORB->apt.iorbh.Status = 0;
- pIORB->apt.iorbh.ErrorCode = 0;
- (pUnitCB->AdapterDriverEP) ((PIORB)pIORB);
- break;
-
- case CALL_ADD_AND_NOTIFY_CDM:
- pIORB->apt.iorbh.NotifyAddress = pFilter_workspace->CDM_NotifyAddress;
- pIORB->apt.iorbh.Status = 0;
- pIORB->apt.iorbh.ErrorCode = 0;
- (pUnitCB->AdapterDriverEP) ((PIORB)pIORB);
- break;
-
- case NOTIFY_CDM:
- pIORB->apt.iorbh.NotifyAddress = pFilter_workspace->CDM_NotifyAddress;
- pIORB->apt.iorbh.Status |= IORB_DONE;
- (pIORB->apt.iorbh.NotifyAddress) ( (PIORB) pIORB);
- break;
-
- case NOTIFY_CDM_WITH_ERROR:
- pIORB->apt.iorbh.Status = IORB_DONE + IORB_ERROR;
- pIORB->apt.iorbh.ErrorCode = IOERR_CMD_NOT_SUPPORTED;
- pIORB->apt.iorbh.NotifyAddress = pFilter_workspace->CDM_NotifyAddress;
- (pIORB->apt.iorbh.NotifyAddress) ( (PIORB) pIORB);
- break;
- }
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = NEC_Sense_Fix
- *
- * DESCRIPTION = The older family of NEC drives place the Sense Code at byte 9
- * instead of byte 12. This routine will move the Sense Code to
- * byte 12 and also set the IORB Error Code to the correct value
- * to reflect the valid sense code.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT = NONE
- *
- * RETURN-NORMAL = NONE
- *
- * RETURN-ERROR = NONE
- *
- ****************************************************************************/
-
- VOID NEC_Sense_Fix (PIORB_CDB pIORB)
- {
- UCHAR sense_key, sense_code;
-
- PIORB_FLTWORK pFilter_workspace;
- NPUNITCB pUnitCB;
-
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
- pUnitCB = pFilter_workspace->pUnitCB;
-
- if ( pIORB->apt.iorbh.Status & IORB_STATUSBLOCK_AVAIL )
- {
- sense_key = pIORB->sense_data.sense_key;
- sense_code = pIORB->sense_data.command_specific_info[1];
-
- pIORB->sense_data.additional_sense_code = sense_code;
-
- if ( sense_key )
- {
- switch ( sense_key )
- {
- case SK_NO_SENSE:
- pIORB->apt.iorbh.ErrorCode = IOERR_ADAPTER_REFER_TO_STATUS;
- break;
-
- case SK_UNIT_ATTENTION:
- pIORB->apt.iorbh.ErrorCode = IOERR_MEDIA_CHANGED;
- break;
-
- case SK_NOT_READY:
- pIORB->apt.iorbh.ErrorCode = IOERR_UNIT_NOT_READY;
- break;
-
- case SK_MEDIUM_ERROR:
- pIORB->apt.iorbh.ErrorCode = IOERR_RBA_CRC_ERROR;
- break;
-
- case SK_HARDWARE_ERROR:
- if ( sense_code == ASC_LBA_NOT_FOUND )
- pIORB->apt.iorbh.ErrorCode = IOERR_RBA_LIMIT;
- else
- pIORB->apt.iorbh.ErrorCode = IOERR_DEVICE_REQ_NOT_SUPPORTED;
- break;
-
- case SK_DATA_PROTECT:
- pIORB->apt.iorbh.ErrorCode = IOERR_MEDIA_WRITE_PROTECT;
- break;
-
- case SK_VOLUME_OVERFLOW:
- pIORB->apt.iorbh.ErrorCode = IOERR_RBA_LIMIT;
- break;
-
- default:
- pIORB->apt.iorbh.ErrorCode = IOERR_DEVICE_NONSPECIFIC;
- break;
- }
- pIORB->apt.iorbh.Status = IORB_DONE | IORB_ERROR |
- IORB_STATUSBLOCK_AVAIL;
- }
- else
- {
- pIORB->apt.iorbh.ErrorCode = 0;
- pIORB->apt.iorbh.Status = IORB_DONE;
- }
- }
-
- }
-
-
-