home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cdrom.zip
/
DDK
/
BASE
/
SRC
/
DEV
/
DASD
/
CDROM
/
OS2CDROM
/
cdqueue.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-18
|
29KB
|
997 lines
/**************************************************************************
*
* SOURCE FILE NAME = CDQUEUE.C
*
* DESCRIPTIVE NAME = Request queuing routines for OS/2 CD-ROM Manager
*
* 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 Maintains queues of IORB requests that are awaiting
* processing. Also provides routing of IORBs to
* Adapter Device Drivers.
*
* ENTRY POINTS:
*
* DEPENDENCIES:
*
* NOTES
*
*
* STRUCTURES
*
* EXTERNAL REFERENCES
*
* EXTERNAL FUNCTIONS
*
* CHANGE ACTIVITY =
* DATE FLAG APAR CHANGE DESCRIPTION
* -------- ---------- ----- --------------------------------------
* 09/08/95 @V135221 Sam Detweiler - CD-ROM changer support
*
****************************************************************************/
#include "cdh.h"
VOID CallADD (NPUNITCB, NPIORB);
USHORT ProcessError (NPUNITCB, NPIORB);
UCHAR NEAR MapIORBError(USHORT);
USHORT NEAR MapSenseData(NPIORB);
VOID NEAR TraceError(NPIORB_CDB);
VOID NEAR PurgeWaitingQueue (NPUNITCB);
USHORT NEAR RemoveWaitingQueue (NPUNITCB, NPIORB);
VOID NEAR BuildCDB_ChangerLoad(NPUNITCB, NPIORB_CDB FAR *,USHORT); //SD@135221
/****************************************************************************
*
* FUNCTION NAME = QueueIORB
*
* DESCRIPTION = Put a request on a waiting queue.
*
* Put a request on the waiting queue in the unit control block
* for the specified unit.
*
* VOID PutWaitingQueue (NPUNITCB pUnitCB, NPIORB pIORB)
*
* INPUT = pUnitCB - Pointer to UnitCB
* pIORB - Pointer to IORB
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID QueueIORB (pUnitCB, pIORB)
NPUNITCB pUnitCB;
NPIORB pIORB;
{
NPIORB_DMWORK pDMWork;
NPIORB pPrevIORB;
PUSHFLAGS;
DISABLE;
pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
pDMWork->WaitingQueueLink = 0;
pDMWork->pUnitCB = pUnitCB;
if (pUnitCB->WaitingQueue.Head == 0)
{
pUnitCB->WaitingQueue.Head = pIORB;
pUnitCB->WaitingQueue.Tail = pIORB;
}
else
{
pPrevIORB = pUnitCB->WaitingQueue.Tail;
pDMWork = (NPIORB_DMWORK) &(pPrevIORB->DMWorkSpace);
pDMWork->WaitingQueueLink = pIORB;
pUnitCB->WaitingQueue.Tail = pIORB;
}
pUnitCB->NumReqsWaiting++;
CD_NumReqsWaiting++;
POPFLAGS;
}
/****************************************************************************
*
* FUNCTION NAME = PullWaitingQueue
*
* DESCRIPTION = Pull a request from a waiting queue.
*
* USHORT PullWaitingQueue (NPUNITCB pUnitCB, NPIORB *pIORB)
*
* INPUT = pUnitCB - Pointer to UnitCB
* pIORB - returned pointer to IORB
*
* OUTPUT = USHORT - = 0, Request pulled
* <> 0, No request pulled, queues empty
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT PullWaitingQueue (pUnitCB, pIORB)
NPUNITCB pUnitCB;
NPIORB FAR *pIORB;
{
USHORT rc;
NPIORB pReq;
NPIORB_DMWORK pDMWork;
PUSHFLAGS;
DISABLE;
/*
** Make sure there's a request waiting to be processed before
** searching the queues.
*/
if (pUnitCB->NumReqsWaiting == 0)
{
rc = ERROR;
goto PullRet;
}
pReq = pUnitCB->WaitingQueue.Head;
pDMWork = (NPIORB_DMWORK) &(pReq->DMWorkSpace);
pUnitCB->WaitingQueue.Head = pDMWork->WaitingQueueLink;
pDMWork->WaitingQueueLink = 0;
if (pUnitCB->WaitingQueue.Head == 0)
pUnitCB->WaitingQueue.Tail = 0;
*pIORB = pReq;
pUnitCB->NumReqsWaiting--;
CD_NumReqsWaiting--;
rc = NO_ERROR;
PullRet:
POPFLAGS;
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = PurgeWaitingQueue
*
* DESCRIPTION = Purge the waiting queue on a media changed errror.
*
* USHORT PurgeWaitingQueue (NPUNITCB pUnitCB)
*
* INPUT = pUnitCB - Pointer to UnitCB
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID PurgeWaitingQueue (pUnitCB)
NPUNITCB pUnitCB;
{
NPIORB pIORB;
USHORT AwakeCount;
while (PullWaitingQueue (pUnitCB, (NPIORB FAR *)&pIORB) == NO_ERROR)
{
pIORB->Status = IORB_DONE + IORB_ERROR;
pIORB->ErrorCode = IOERR_MEDIA_CHANGED;
DevHelp_ProcRun((ULONG)pIORB, &AwakeCount);
}
}
/****************************************************************************
*
* FUNCTION NAME = RemoveWaitingQueue
*
* DESCRIPTION = Remove an entry from the waiting queue.
*
* USHORT RemoveWaitingQueue (NPUNITCB pUnitCB, NPIORB pIORB)
*
* INPUT = pUnitCB - Pointer to UnitCB
* pIORB - Pointer to IORB
*
* OUTPUT = USHORT - YES, iorb removed
* NO, iorb not removed
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT RemoveWaitingQueue (pUnitCB, pIORB)
NPUNITCB pUnitCB;
NPIORB pIORB;
{
NPIORB pCurReq, pPrevReq;
NPIORB_DMWORK pDMWorkCur, pDMWorkPrev;
USHORT removed = NO;
PUSHFLAGS;
DISABLE;
/*
** Make sure the waiting queue isnt empty
*/
if (pUnitCB->NumReqsWaiting == 0)
goto RemoveRet;
/*
** If it's at the head simply remove it from the head
*/
if (pUnitCB->WaitingQueue.Head == pIORB)
{
pDMWorkCur = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
pUnitCB->WaitingQueue.Head = pDMWorkCur->WaitingQueueLink;
if (pDMWorkCur->WaitingQueueLink == 0)
pUnitCB->WaitingQueue.Tail = 0;
else
pDMWorkCur->WaitingQueueLink = 0;
removed = YES;
pUnitCB->NumReqsWaiting--;
CD_NumReqsWaiting--;
goto RemoveRet;
}
/*
** Not at the head, must search for it
*/
pCurReq = pUnitCB->WaitingQueue.Head;
pDMWorkCur = (NPIORB_DMWORK) &(pCurReq->DMWorkSpace);
while (pCurReq != 0)
{
if (pCurReq == pIORB)
{
pDMWorkPrev->WaitingQueueLink = pDMWorkCur->WaitingQueueLink;
if (pUnitCB->WaitingQueue.Tail == pCurReq)
pUnitCB->WaitingQueue.Tail = pDMWorkCur->WaitingQueueLink;
removed = YES;
break;
}
pPrevReq = pCurReq;
pDMWorkPrev = (NPIORB_DMWORK) &(pPrevReq->DMWorkSpace);
if (pDMWorkCur->WaitingQueueLink != 0)
{
pCurReq = pDMWorkCur->WaitingQueueLink;
pDMWorkCur = (NPIORB_DMWORK) &(pCurReq->DMWorkSpace);
}
}
RemoveRet:
POPFLAGS;
return(removed);
}
/****************************************************************************
*
* FUNCTION NAME = SubmitIORB_Wait
*
* DESCRIPTION = Submit an IORB, wait till done
*
* This function will submit a request and wait till it's done.
* If the device is idle, the request will be submitted, else the
* request till be queued on the unit's waiting queue.
*
* USHORT SubmitIORB_Wait (pUnitCB, pIORB)
*
* INPUT = pUnitCB - pointer to unit control block
* pIORB - pointer to IORB
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT NEAR SubmitIORB_Wait (pUnitCB, pIORB)
NPUNITCB pUnitCB;
NPIORB pIORB;
{
USHORT rc;
NPIORB pIORBq;
NPIORB_DMWORK pDMWork;
PUSHFLAGS;
DISABLE;
if(pUnitCB->pParentUnitCB) //SD@135221
{ //SD@135221
pUnitCB=pUnitCB->pParentUnitCB; //SD@135221
} /* endif */ //SD@135221
pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
pDMWork->pUnitCB = pUnitCB;
/*
** If the device is idle, then submit the request
*/
if (pUnitCB->NumReqsInProgress == 0)
{
if (pUnitCB->NumReqsWaiting == 0)
{
pIORBq = pIORB;
}
else
{
PullWaitingQueue (pUnitCB, (NPIORB FAR *)&pIORBq);
QueueIORB (pUnitCB, pIORB);
}
pUnitCB->NumReqsInProgress++;
CD_NumReqsInProgress++;
ENABLE;
CallADD(pUnitCB, pIORBq);
}
/*
** else queue the request
*/
else
QueueIORB (pUnitCB, pIORB);
/*
** Block until the request is done
*/
DISABLE;
while ( !( pIORB->Status & IORB_DONE ) )
{
DevHelp_ProcBlock ((ULONG)pIORB, -1L, 1);
DISABLE; /* Block does an enable */
}
ENABLE;
POPFLAGS;
rc = ProcessError(pUnitCB, pIORB);
return (rc);
}
/****************************************************************************
*
* FUNCTION NAME = f_SubmitRequestsToADD
*
* DESCRIPTION = Submit Requests to an Adapter Device Driver
*
* INPUT = pUnitCB - pointer to unit control block
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID FAR f_SubmitRequestsToADD (pUnitCB)
NPUNITCB pUnitCB;
{
SubmitRequestsToADD (pUnitCB);
}
/****************************************************************************
*
* FUNCTION NAME = SubmitRequestsToADD
*
* DESCRIPTION = Submit Requests to an Adapter Device Driver
*
* This function submits requests to the Adapter Device Driver which
* manages this unit. Requests are pulled from the unit's waiting queue
* and submitted to the ADD if the ADD's recommended queuing count
* has not been exceeded.
*
* USHORT SubmitRequestsToADD (pUnitCB)
*
* INPUT = pUnitCB - pointer to unit control block
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID NEAR SubmitRequestsToADD (pUnitCB)
NPUNITCB pUnitCB;
{
NPIORB pIORB;
USHORT i;
USHORT NumIORBsBuilt = 0;
PUSHFLAGS;
DISABLE;
/*
** If the number of requests already submitted to the ADD is
** less than the ADD's recommended queuing count, then submit
** additional requests.
*/
for (i=pUnitCB->NumReqsInProgress; i < pUnitCB->UnitInfo.QueuingCount; i++)
{
if (PullWaitingQueue (pUnitCB, (NPIORB FAR *)&pIORB) != NO_ERROR)
break;
/*
** We've pulled another request from the queue, so build the IORB
** for it and chain it to the previous if we've built more than one.
*/
pUnitCB->NumReqsInProgress++;
CD_NumReqsInProgress++;
NumIORBsBuilt++;
ENABLE;
CallADD(pUnitCB, pIORB);
DISABLE;
}
ENABLE;
POPFLAGS;
}
/****************************************************************************
*
* FUNCTION NAME = CallADD
*
* DESCRIPTION = Call the Adapter Driver Entry Point
*
* This function calls the adapter driver entry point with the
* specified IORB chain.
*
* VOID CallADD (pUnitCB, pIORB)
*
* INPUT = pUnitCB - pointer to unit control block
* pIORB - pointer to IORB chain
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID CallADD (pUnitCB, pIORB)
NPUNITCB pUnitCB;
NPIORB pIORB;
{
/*
** if (TraceFlags != 0)
** Trace(TRACE_IORB | TRACE_ENTRY, (PBYTE)pIORB, pUnitCB);
*/
/*
** If we're issuing a request to a PANSONIC 501 and it's one
** one of the vendor unique audio commands, then just turn on
** the high bit of the command byte so the command opcode is right.
*/
if (pUnitCB->DeviceInfo.product_id_code == PANASONIC_501)
{
if ( ( ((NPIORB_CDB)pIORB)->CDB.byte_0 >= SCSI_READ_SUB_CHAN) &&
( ((NPIORB_CDB)pIORB)->CDB.byte_0 <= SCSI_PAUSE_RESUME) )
{
((NPIORB_CDB)pIORB)->CDB.byte_0 |= 0x80;
}
}
/*
** If ATAPI command, change CDB command length to 12.
*/
if ( (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI) &&
(pIORB->CommandCode == IOCC_ADAPTER_PASSTHRU) )
{
((NPIORB_CDB)pIORB)->apt.ControllerCmdLen = ATAPI_CDB_LENGTH;
if ((( (NPIORB_CDB)pIORB)->CDB.byte_0 == ATAPI_CHANGER_LOAD)) //SD@135221
{ //SD@135221
if(pUnitCB->DeviceInfo.product_id_code==TORISAN_C3G) //SD@135221
{ //SD@135221
((NPIORB_CDB)pIORB)->CDB.byte_0 = SANYO_ATAPI_CHANGER_LOAD;//SD@135221
} /* endif */ //SD@135221
} //SD@135221
}
/*
** Call the adapter device driver.
*/
(pUnitCB->AdapterDriverEP) ((PVOID) pIORB);
}
/****************************************************************************
*
* FUNCTION NAME = NotifyDoneIORB
*
* DESCRIPTION = Notify routine when IORB is done in ADD
*
* This function is the notification routine called by an Adapter Device
* Driver when an IORB is done. Error status and blocks transferred
* are updated in the associated Request Packet or Request List entry. If
* the request is a Strategy-2 Request List Entry, the file system is
* notified that the request has completed. If the request is a
* Strategy-1 Request Packet, the thread waiting on the request is woken up.
*
* VOID NotifyDoneIORB (PIORB fpIORB)
*
* INPUT = fpIORB - far pointer to completed IORB
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID _loadds FAR NotifyDoneIORB (fpIORB)
PIORB fpIORB;
{
NPUNITCB pUnitCB;
NPIORB pIORB;
USHORT AwakeCount;
NPIORB_DMWORK pDMWork;
pIORB = (NPIORB) (OFFSETOF(fpIORB));
pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
pUnitCB = (NPUNITCB) pDMWork->pUnitCB;
if(pUnitCB->pParentUnitCB) //SD@135221
{ //SD@135221
pUnitCB=pUnitCB->pParentUnitCB; //SD@135221
} /* endif */ //SD@135221
if ( (pIORB->Status & IORB_ERROR) &&
!(pIORB->Status & IORB_RECOV_ERROR) )
{
/*
** If media changed error, then purge the waiting queue
*/
if (pIORB->ErrorCode == IOERR_MEDIA_CHANGED)
PurgeWaitingQueue (pUnitCB);
else if (pDMWork->pCoReqIORB != 0)
{
if (RemoveWaitingQueue (pUnitCB, pDMWork->pCoReqIORB) == YES)
{
pDMWork->pCoReqIORB->Status = IORB_DONE | IORB_ERROR;
pDMWork->pCoReqIORB->ErrorCode = pIORB->ErrorCode;
DevHelp_ProcRun((ULONG)pDMWork->pCoReqIORB, &AwakeCount);
}
}
}
if (pDMWork->pCoReqIORB == 0)
DevHelp_ProcRun((ULONG)pIORB, &AwakeCount);
PUSHFLAGS;
DISABLE;
pUnitCB->NumReqsInProgress --;
CD_NumReqsInProgress--;
POPFLAGS;
SubmitRequestsToADD(pUnitCB);
}
/****************************************************************************
*
* FUNCTION NAME = ProcessError
*
* DESCRIPTION = Post process a completed IORB's error code
*
* USHORT ProcessError (pUnitCB, pIORB)
*
* INPUT = pUnitCB - pointer to unit control block
* pIORB - pointer to IORB
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT ProcessError (pUnitCB, pIORB)
NPUNITCB pUnitCB;
NPIORB pIORB;
{
USHORT RP_Status;
UCHAR asc,ascq; /*SD135221*/
RP_Status = STDON;
if ( (pIORB->Status & IORB_ERROR) &&
!(pIORB->Status & IORB_RECOV_ERROR) )
{
RP_Status = MapSenseData(pIORB);
if(pUnitCB->DeviceInfo.Audio.capabilities & //SD@135221
(DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER)) //SD@135221
{ //SD@135221
// only ATAPI devices support this flag today //SD@135221
if(pUnitCB->DeviceInfo.Slots.LoadInProgress==FALSE) //SD@135221
{ //SD@135221
if(pUnitCB->DeviceInfo.product_id_code==TORISAN_C3G) //SD@135221
{ //SD@135221
asc=((NPIORB_CDB)pIORB)->sense_data.additional_sense_code; //SD@135221
ascq=((NPIORB_CDB)pIORB)->sense_data.additional_sense_code_qualifier;//SD@135221
// if load in progress reported //SD@135221
// disc changing/changed from under us //SD@135221
if( (asc==ASC_UNIT_NOT_READY && ascq==1) ) //SD@135221
{ //SD@135221
// if we have a parent //SD@135221
if(pUnitCB->pParentUnitCB) //SD@135221
{ //SD@135221
if(!(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_SINGLE_MODE))//SD@135221
{ //SD@135221
// mark the current slot unknown //SD@135221
pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current=0xff;//SD@135221
} //SD@135221
} /* endif */ //SD@135221
} //SD@135221
} //SD@135221
} //SD@135221
} //SD@135221
if (RP_Status == 0)
(UCHAR) RP_Status = MapIORBError(pIORB->ErrorCode);
RP_Status |= STDON + STERR;
if (RP_Status == STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA)
{
pUnitCB->Flags |= UCF_UNCERTAIN_MEDIA;
pUnitCB->DeviceInfo.Audio.status.paused = FALSE;
pUnitCB->DeviceInfo.Audio.status.last_start_location.min = 0;
pUnitCB->DeviceInfo.Audio.status.last_start_location.sec = 0;
pUnitCB->DeviceInfo.Audio.status.last_start_location.frame = 0;
pUnitCB->DeviceInfo.Audio.status.last_end_location.min = 0;
pUnitCB->DeviceInfo.Audio.status.last_end_location.sec = 0;
pUnitCB->DeviceInfo.Audio.status.last_end_location.frame = 0;
/* PurgeWaitingQueue(pUnitCB, ERROR_I24_UNCERTAIN_MEDIA); */
}
/*
** If a reset condition occurred, then reset lock and volume settings
*/
if ( (((NPIORB_CDB)pIORB)->sense_data.sense_key == SCSI_SK_UNITATTN) &&
(((NPIORB_CDB)pIORB)->sense_data.additional_sense_code == ASC_RESET))
{
pUnitCB->DeviceInfo.Audio.capabilities &= ~DCAPS_DOOR_LOCKED;
pUnitCB->DeviceInfo.Audio.channel.input_0 = 0;
pUnitCB->DeviceInfo.Audio.channel.volume_0 = 0xFF;
pUnitCB->DeviceInfo.Audio.channel.input_1 = 1;
pUnitCB->DeviceInfo.Audio.channel.volume_1 = 0xFF;
}
TraceError( (NPIORB_CDB) pIORB);
}
return(RP_Status);
}
/****************************************************************************
*
* FUNCTION NAME = MapSenseData
*
* DESCRIPTION = Maps a SCSI sense data to an ERROR_I24 error code.
*
* USHORT MapSenseData (NPIORB IORBErrorCode)
*
* INPUT = IORBError - IORB error code
*
* OUTPUT = UCHAR - ERROR_I24 error code
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
typedef struct _ASC_TABLE_ENTRY
{
UCHAR additional_sense_code;
USHORT I24_ErrorCode;
} ASC_TABLE_ENTRY;
typedef struct _SK_TABLE_ENTRY
{
UCHAR asc_count;
USHORT I24_ErrorCode;
} SK_TABLE_ENTRY;
USHORT MapSenseData (pIORB)
NPIORB pIORB;
{
static ASC_TABLE_ENTRY ASCT_NotRdy[] =
{
{ASC_INCOMPATIBLE_CARTRIDGE, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
{0xFF, STDON + STERR + ERROR_I24_NOT_READY}
};
static ASC_TABLE_ENTRY ASCT_MediumError[] =
{
{ASC_UNRECOVERED_ERROR, STDON + STERR + ERROR_I24_CRC},
{ASC_NO_ADDRESS_MARK, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
{ASC_SEEK_POSITIONING_ERROR, STDON + STERR + ERROR_I24_SEEK},
{ASC_DATA_SYNC_ERROR, STDON + STERR + ERROR_I24_READ_FAULT},
{ASC_INCOMPATIBLE_CARTRIDGE, STDON + STERR + ERROR_I24_NOT_DOS_DISK},
{0xFF, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
};
static ASC_TABLE_ENTRY ASCT_HardwareError[] =
{
{ASC_SEEK_POSITIONING_ERROR, STDON + STERR + ERROR_I24_SEEK},
};
static ASC_TABLE_ENTRY ASCT_IllegalRequest[] =
{
{ASC_ILLEGAL_MODE_FOR_TRACK, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
{ASC_ILLEGAL_LBA, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
{ASCV_NOT_AUDIO_TRACK, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
{ASCV_NOT_DATA_TRACK, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
{ASCV_NOT_AUDIO_PLAY_STATE, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
{0xFF, STDON + STERR + ERROR_I24_INVALID_PARAMETER},
};
static ASC_TABLE_ENTRY ASCT_UnitAttention[] =
{
{ASC_MEDIUM_CHANGED, STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA},
{ASC_RESET, STDON + STERR + ERROR_I24_GEN_FAILURE},
{0xFF, STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA},
};
static ASC_TABLE_ENTRY ASCT_BlankCheck[] =
{
{ASC_ILLEGAL_MODE_FOR_TRACK, STDON + STERR + ERROR_I24_BAD_COMMAND},
};
static SK_TABLE_ENTRY SenseKeyTable[] =
{
{ 0, STDON }, /* 0 - NOSENSE */
{ 0, STDON }, /* 1 - RECERR */
// { 0, STDON + STERR + ERROR_I24_NOT_READY }, /* 2 - NOTRDY */
{ sizeof(ASCT_NotRdy)/sizeof(ASC_TABLE_ENTRY),
(USHORT) ASCT_NotRdy }, /* 2 - NOTRDY */
{ sizeof(ASCT_MediumError)/sizeof(ASC_TABLE_ENTRY),
(USHORT) ASCT_MediumError }, /* 3 - MEDIUMERR */
{ sizeof(ASCT_HardwareError)/sizeof(ASC_TABLE_ENTRY),
(USHORT) ASCT_HardwareError }, /* 4 - HARDWAREERR */
{ sizeof(ASCT_IllegalRequest)/sizeof(ASC_TABLE_ENTRY),
(USHORT) ASCT_IllegalRequest }, /* 5 - ILLEGALREQ */
{ sizeof(ASCT_UnitAttention)/sizeof(ASC_TABLE_ENTRY),
(USHORT) ASCT_UnitAttention }, /* 6 - UNITATTN */
{ 0, STDON + STERR + ERROR_I24_GEN_FAILURE}, /* 7 - DATAPROTECT */
{ sizeof(ASCT_BlankCheck)/sizeof(ASC_TABLE_ENTRY),
(USHORT) ASCT_BlankCheck }, /* 8 - BLANKCHK */
{ 0, STDON + STERR + ERROR_I24_GEN_FAILURE}, /* 9 - Vendor Spec */
{ 0, STDON + STERR + ERROR_I24_GEN_FAILURE}, /* A - COPYABORT */
{ 0, STDON + STERR + ERROR_I24_GEN_FAILURE}, /* B - ABORTEDCMD */
{ 0, STDON + STERR + ERROR_I24_GEN_FAILURE}, /* C - EQUAL */
{ 0, STDON + STERR + ERROR_I24_GEN_FAILURE}, /* D - VOLOVERFLOW */
{ 0, STDON + STERR + ERROR_I24_GEN_FAILURE}, /* E - MISCOMPARE */
};
UCHAR rc, sense_key, additional_sense_code, asc_count;
USHORT i;
ASC_TABLE_ENTRY NEAR *pTable;
rc = 0;
/*
** Make sure sense data is available
*/
if ( (pIORB->Status & IORB_STATUSBLOCK_AVAIL) &&
( ((NPSCSI_STATUS_BLOCK)pIORB->pStatusBlock)->Flags &
STATUS_SENSEDATA_VALID) &&
( ((NPIORB_CDB) pIORB)->sense_data.error_code == 0x70 ||
((NPIORB_CDB) pIORB)->sense_data.error_code == 0x71) )
{
sense_key = ((NPIORB_CDB)pIORB)->sense_data.sense_key;
additional_sense_code =
((NPIORB_CDB)pIORB)->sense_data.additional_sense_code;
if (sense_key > 0x0E)
return (STDON + STERR + ERROR_I24_GEN_FAILURE);
asc_count = SenseKeyTable[sense_key].asc_count;
if (asc_count == 0)
return (SenseKeyTable[sense_key].I24_ErrorCode);
(USHORT) pTable = SenseKeyTable[sense_key].I24_ErrorCode;
for (i = 0; i < asc_count; i++)
if (pTable[i].additional_sense_code == additional_sense_code)
{
return (pTable[i].I24_ErrorCode);
}
if (pTable[i-1].additional_sense_code == 0xFF)
return (pTable[i-1].I24_ErrorCode);
return (STDON + STERR + ERROR_I24_GEN_FAILURE);
}
return(0);
}
/****************************************************************************
*
* FUNCTION NAME = MapIORBError
*
* DESCRIPTION = Maps an IORB error code to an ERROR_I24 error code.
*
* UCHAR MapIORBError (USHORT IORBErrorCode)
*
* INPUT = IORBError - IORB error code
*
* OUTPUT = UCHAR - ERROR_I24 error code
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
typedef struct _ERROR_TABLE_ENTRY
{
USHORT IORB_ErrorCode;
UCHAR I24_ErrorCode;
} ERROR_TABLE_ENTRY;
UCHAR MapIORBError(IORB_ErrorCode)
USHORT IORB_ErrorCode;
{
static ERROR_TABLE_ENTRY ErrorTable[] =
{
{IOERR_UNIT_NOT_READY, ERROR_I24_NOT_READY},
{IOERR_RBA_ADDRESSING_ERROR, ERROR_I24_SECTOR_NOT_FOUND},
{IOERR_RBA_LIMIT, ERROR_I24_SECTOR_NOT_FOUND},
{IOERR_RBA_CRC_ERROR, ERROR_I24_CRC},
{IOERR_MEDIA_NOT_FORMATTED, ERROR_I24_SECTOR_NOT_FOUND},
{IOERR_MEDIA_NOT_SUPPORTED, ERROR_I24_SECTOR_NOT_FOUND},
{IOERR_MEDIA_WRITE_PROTECT, ERROR_I24_WRITE_PROTECT},
{IOERR_MEDIA_CHANGED, ERROR_I24_UNCERTAIN_MEDIA},
{IOERR_MEDIA_NOT_PRESENT, ERROR_I24_NOT_READY},
{IOERR_CMD_NOT_SUPPORTED, ERROR_I24_BAD_COMMAND},
{IOERR_CMD_SYNTAX, ERROR_I24_BAD_COMMAND},
{-1,-1},
};
USHORT i;
/*
** Map the IORB error to the corresponding ERROR_I24 error code
*/
for (i = 0; ErrorTable[i].IORB_ErrorCode != -1; i++)
if (ErrorTable[i].IORB_ErrorCode == IORB_ErrorCode)
return(ErrorTable[i].I24_ErrorCode);
return(ERROR_I24_GEN_FAILURE);
}
/****************************************************************************
*
* FUNCTION NAME = TraceError
*
* DESCRIPTION = Logs an error in the trace buffer
*
* VOID TraceError (NPIORB pIORB)
*
* INPUT = pIORB - pointer to IORB
*
* OUTPUT = VOID
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID TraceError (pIORB)
NPIORB_CDB pIORB;
{
USHORT i;
UCHAR NEAR *pCDB;
UCHAR NEAR *pSenseData;
pCDB = (UCHAR NEAR *) &pIORB->CDB;
pSenseData = (UCHAR NEAR *) &pIORB->sense_data;
/*
** Only trace adapter passthru commands
*/
if (pIORB->apt.iorbh.CommandCode == IOCC_ADAPTER_PASSTHRU)
{
(USHORT) *pCDTraceHead = pIORB->apt.iorbh.UnitHandle;
(USHORT) *(pCDTraceHead+2) = pIORB->apt.iorbh.ErrorCode;
for (i = 0; i < 12; i++)
*(pCDTraceHead+4+i) = *(pCDB+i);
for (i = 0; i < 16; i++)
*(pCDTraceHead+16+i) = *(pSenseData+i);
pCDTraceHead += 32;
if (pCDTraceHead >= pCDTraceEnd)
pCDTraceHead = pCDTraceBuf;
}
}