home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- *
- * SOURCE FILE NAME = NEIORB2.C
- *
- * DESCRIPTIVE NAME = IORB handling for NEC Filter
- *
- * 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 conters
- * them to the vendor unique NEC Command Descriptor Blocks.
- *
- * 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>
-
- /*
- ** FUNCTION PROTOTYPES
- */
-
- USHORT NotifyReadSubChannel (PIORB_CDB pIORB);
- USHORT NotifyReadTrack (PIORB_CDB pIORB);
- USHORT NotifyReadMinMax (PIORB_CDB pIORB);
- USHORT NotifyAudioSearch (PIORB_CDB pIORB);
- USHORT NotifyResume (PIORB_CDB pIORB);
- USHORT NotifySeek6 (PIORB_CDB pIORB);
- USHORT NotifyTestUnitReady (PIORB_CDB pIORB);
-
-
- /*
- ** CODE STARTS HERE
- */
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_TestUnitReady
- *
- * DESCRIPTION = This routine filters Test Unit Ready. The CDR-35, 77 and 80
- * does not generate a media changes check condition for this
- * command. We must issue a Request Sense prior to the
- * Test Unit Ready to make sure the check condition is reported.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_TestUnitReady (PIORB_CDB pIORB)
- {
-
- NPUNITCB pUnitCB;
-
- struct CDB_RequestSense FAR *pCDB1;
- PIORB_FLTWORK pFilter_workspace;
-
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
- pUnitCB = pFilter_workspace->pUnitCB;
-
- if ( ( pUnitCB->product_id[12] != ' ' ) &&
- ( pUnitCB->product_id[6] != '2' ) )
- {
- return(CALL_ADD_AND_RET);
- }
-
- pCDB1 = (struct CDB_RequestSense FAR *) pIORB->apt.pControllerCmd;
-
- pCDB1->OpCode = SCSI_REQUEST_SENSE;
-
- pCDB1->reserved_1 = 0;
- pCDB1->reserved_2 = 0;
- pCDB1->reserved_3 = 0;
- pCDB1->alloc_length = sizeof(struct Sense_Data);
- pCDB1->control = 0;
-
- pIORB->apt.cSGList = 1;
- pIORB->apt.pSGList->XferBufLen = sizeof(struct Sense_Data);
- pIORB->apt.Flags |= PT_DIRECTION_IN;
-
- /*
- ** Replace callback address with ours.
- */
- pFilter_workspace->completion_address = NotifyTestUnitReady;
-
- return (CALL_ADD_AND_NOTIFY_FILTER);
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = NotifyTestUnitReady
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT NotifyTestUnitReady (PIORB_CDB pIORB)
- {
-
- struct Sense_Data FAR *pSense_Data;
- pSense_Data = (struct Sense_Data FAR *) pIORB->CDB_data;
-
- if ( pSense_Data->sense_key != SK_NO_SENSE )
- {
- pIORB->sense_data = *pSense_Data;
- pIORB->apt.iorbh.Status = IORB_DONE | IORB_ERROR |
- IORB_STATUSBLOCK_AVAIL;
-
- pIORB->status_block.Flags = STATUS_SENSEDATA_VALID;
- NEC_Sense_Fix (pIORB);
- }
-
- return(NOTIFY_CDM);
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_Seek_6
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_Seek_6 (PIORB_CDB pIORB)
- {
- PIORB_FLTWORK pFilter_workspace;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
-
-
- /*
- ** Replace callback address with ours.
- */
-
- pFilter_workspace->completion_address = NotifySeek6;
- pFilter_workspace->flags |= FWF_SKIP_ERROR_CHECK;
-
- return CALL_ADD_AND_NOTIFY_FILTER;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = NotifySeek6
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT NotifySeek6 (PIORB_CDB pIORB)
- {
- pNEC_CDB_AudioTrackSearch pCDB1;
- struct CDB_Seek_6 FAR *pCDB2;
-
- if ( (pIORB->apt.iorbh.Status & IORB_ERROR) &&
- ( !(pIORB->apt.iorbh.Status & IORB_RECOV_ERROR) ) &&
- (pIORB->sense_data.sense_key == 3) &&
- pIORB->sense_data.command_specific_info[1] == 0x1D)
- {
-
- pCDB1 = (pNEC_CDB_AudioTrackSearch) pIORB->apt.pControllerCmd;
- pCDB2 = (struct CDB_Seek_6 FAR *) pCDB1;
-
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_AudioTrackSearch);
-
- pCDB1->OpCode = NEC_AUDIO_TRACK_SEARCH;
-
- pCDB1->play = 0; /* pause after search */
-
- pCDB1->search_zero = pCDB2->LBA.usbytes.byte_1;
- pCDB1->search_frame = pCDB2->LBA.usbytes.byte_0;
- pCDB1->search_sec = pCDB2->LBA_msb;
- pCDB1->search_min = 0;
-
- pCDB1->addr_type = NEC_ADDR_HSG;
-
- pCDB1->reserved_1 = 0;
- pCDB1->reserved_2 = 0;
- pCDB1->reserved_3 = 0;
- pCDB1->reserved_4 = 0;
- pCDB1->reserved_5 = 0;
- return CALL_ADD_AND_NOTIFY_CDM;
- }
- else
- return NOTIFY_CDM;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_ModeSelect
- *
- * DESCRIPTION = This routine converts the Audio Control Mode Page to an NEC
- * Play Audio command. (audio channel control is changed by
- * setting the play mode bits in the NEC Play Audio command).
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_ModeSelect (PIORB_CDB pIORB)
- {
- UCHAR play_mode, out_chan0, out_chan1, out_vol0, out_vol1;
- UCHAR left_off, right_off, transfer_length;
- UCHAR block_length_lsb, block_length_msb;
- USHORT i, rc;
-
- pNEC_CDB_PlayAudio pCDB1;
- struct CDB_ModeSelect FAR *pCDB2;
- struct ModeSelectParmList FAR *pCDBData2;
- PIORB_FLTWORK pFilter_workspace;
- NPUNITCB pUnitCB;
-
- pCDB1 = (pNEC_CDB_PlayAudio) pIORB->apt.pControllerCmd;
- pCDB2 = (struct CDB_ModeSelect FAR *) pCDB1;
- pCDBData2 = (struct ModeSelectParmList FAR *) pIORB->CDB_data;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
- pUnitCB = pFilter_workspace->pUnitCB;
-
- *((PBYTE) pCDB2+1) = 0; /* Byte 1 of the command block must be zero */
-
- rc = NOTIFY_CDM;
-
- /*
- ** Check for Block Descriptor Header.
- */
- if ( pCDBData2->ModeSelectHdr.block_descriptor_len == 8 )
- {
- /*
- ** The NEC CDR-35 drive expects 11 bytes of information. The last
- ** byte must be zero.
- */
- if ( pUnitCB->product_id[6] == '2' )
- transfer_length = 11;
- else
- transfer_length = 10;
-
- pCDB2->parm_length = transfer_length;
- pIORB->apt.pSGList->XferBufLen = transfer_length;
-
- pCDBData2->ModeSelectHdr.block_descriptor_len = 0;
-
- block_length_lsb = pCDBData2->Descriptors.BlockDescriptor.block_length_2;
- block_length_msb = pCDBData2->Descriptors.BlockDescriptor.block_length_1;
-
- /*
- ** Test for block size of 2048 or 2340 bytes. Return an error for
- ** any other block size.
- **
- ** NOTE: The NEC CDR-35 drive only supports a block size of 2048 bytes.
- */
- if ( block_length_msb == 0x08 && block_length_lsb == 0x00 )
- {
- if ( pCDBData2->Descriptors.BlockDescriptor.density_code != 0x81 )
- pCDBData2->Descriptors.BlockDescriptor.density_code = 0;
- }
- else if ( (block_length_msb == 0x09 && block_length_lsb == 0x24) &&
- (pUnitCB->product_id[6] != '2') )
- {
- pCDBData2->Descriptors.BlockDescriptor.density_code = 3;
- }
- else
- {
- return NOTIFY_CDM_WITH_ERROR;
- }
-
- /*
- ** Remaining 4 bytes should be zero and the last byte should be
- ** set to 5 for the retry count.
- */
- pCDBData2->Descriptors.BlockDescriptor.block_count_0 = 0;
- pCDBData2->Descriptors.BlockDescriptor.block_count_1 = 0;
- pCDBData2->Descriptors.BlockDescriptor.block_count_2 = 0;
- pCDBData2->Descriptors.BlockDescriptor.reserved_1 = 0;
-
- if ( pUnitCB->product_id[6] != '2' )
- pCDBData2->Descriptors.BlockDescriptor.block_length_0 = 5;
- else
- pCDBData2->Descriptors.BlockDescriptor.block_length_0 = 0;
-
- pCDBData2->Descriptors.BlockDescriptor.block_length_1 = 0;
-
- rc = CALL_ADD_AND_RET;
- }
-
-
- /*
- ** Check for Audio Channel Control page.
- */
-
-
- if ( (pCDBData2->ModeSelectHdr.block_descriptor_len == 0) &&
- (pCDBData2->Descriptors.audio_control.page_code == PAGE_AUDIO_CONTROL) )
- {
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_PlayAudio);
- pIORB->apt.cSGList = 0;
- pIORB->apt.pSGList = 0;
- pIORB->apt.ppSGLIST = 0;
-
- out_chan0 = pCDBData2->Descriptors.audio_control.output0_select;
- out_vol0 = pCDBData2->Descriptors.audio_control.output0_volume;
- out_chan1 = pCDBData2->Descriptors.audio_control.output1_select;
- out_vol1 = pCDBData2->Descriptors.audio_control.output1_volume;
-
- left_off = right_off = FALSE;
-
- /*
- ** Check for volume control of zero and output channel of zero.
- */
- if ( out_chan0 != 1 || out_vol0 == PCS_MUTED )
- left_off = TRUE;
-
- if ( out_chan1 != 2 || out_vol1 == PCS_MUTED )
- right_off = TRUE;
-
- /*
- ** If audio channels are switched, continue to play in stereo.
- */
- if ( out_chan0 == 2 && out_chan1 == 1 )
- left_off = right_off = FALSE;
-
- /*
- ** The NEC CDR-35 drive only supports Stereo & Mute mode. If only
- ** one channel is muted, we must set the audio mode to Stereo for
- ** this drive.
- */
- if ( pUnitCB->product_id[6] == '2' && !(left_off & right_off) )
- left_off = right_off = FALSE;
-
- if ( left_off & right_off )
- play_mode = NEC_PLAY_MUTE;
- else if ( left_off )
- play_mode = NEC_PLAY_RIGHT;
- else if ( right_off )
- play_mode = NEC_PLAY_LEFT;
- else
- play_mode = NEC_PLAY_STEREO;
-
- pUnitCB->play_mode = play_mode;
-
- /*
- ** issue a play command if drive is in play mode
- */
- if ( pFilter_workspace->input_parm_0 == 1 )
- {
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_PlayAudio);
-
- pCDB1->OpCode = NEC_PLAY_AUDIO;
-
- pCDB1->play_mode = play_mode;
-
- for (i=2;i<9;i++)
- *((PBYTE) pCDB1+i) = 0;
-
- pCDB1->reserved_5 = 0;
-
- pCDB1->addr_type = NEC_ADDR_PRV;
-
- rc = CALL_ADD_AND_RET;
- }
- }
-
- return rc;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_StartStopUnit
- *
- * DESCRIPTION = This routine checks the SCSI-2 Start/Stop command block for
- * for eject bit and if set, sends down an NEC eject command.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_StartStopUnit (PIORB_CDB pIORB)
-
- {
- USHORT i;
-
- pNEC_CDB_Eject pCDB1;
- struct CDB_StartStopUnit FAR *pCDB2;
-
- pCDB1 = (pNEC_CDB_Eject) pIORB->apt.pControllerCmd;
- pCDB2 = (struct CDB_StartStopUnit FAR *) pCDB1;
-
- /*
- ** If eject reqested, build an NEC eject command.
- */
- if ( (pCDB2->LoEj) && !(pCDB2->start) )
- {
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_Eject);
-
- pCDB1->OpCode = NEC_EJECT;
-
- for (i=2;i<10;i++)
- *((PBYTE) pCDB1+i) = 0;
- }
-
- return CALL_ADD_AND_RET;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_PreventAllowRemoval
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_PreventAllowRemoval (PIORB_CDB pIORB)
- {
- /*
- ** No conversion needed, pass along to ADD.
- */
-
- return CALL_ADD_AND_RET;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_ReadCapacity
- *
- * DESCRIPTION = For the NEC-CDR 35, we have to hard code the Read Capcity
- * Data since this device does not support this command.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_ReadCapacity (PIORB_CDB pIORB)
- {
- struct ReadCapacity_Data FAR *pCDBData1;
- PIORB_FLTWORK pFilter_workspace;
- NPUNITCB pUnitCB;
-
- pCDBData1 = (struct ReadCapacity_Data FAR *) pIORB->CDB_data;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
- pUnitCB = pFilter_workspace->pUnitCB;
-
- if ( pUnitCB->product_id[6] != '2' )
- return CALL_ADD_AND_RET;
-
- /*
- ** Set Total Blocks to 276,480.
- */
- pCDBData1->capacity_LBA.ulbytes.byte_0 = 0x00;
- pCDBData1->capacity_LBA.ulbytes.byte_1 = 0x04;
- pCDBData1->capacity_LBA.ulbytes.byte_2 = 0x38;
- pCDBData1->capacity_LBA.ulbytes.byte_3 = 0x00;
-
- /*
- ** Set Block Length to 2048.
- */
- pCDBData1->capacity_block_length.ulbytes.byte_0 = 0x00;
- pCDBData1->capacity_block_length.ulbytes.byte_1 = 0x00;
- pCDBData1->capacity_block_length.ulbytes.byte_2 = 0x08;
- pCDBData1->capacity_block_length.ulbytes.byte_3 = 0x00;
-
- return NOTIFY_CDM;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_Seek_10
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_Seek_10 (PIORB_CDB pIORB)
- {
- /*
- ** No conversion needed, pass along to ADD.
- */
-
- return CALL_ADD_AND_RET;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_ReadSubChannel
- *
- * DESCRIPTION = This routine converts the SCSI-2 Read Sub Channel command to
- * an NEC Read Subcode Q command.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_ReadSubChannel (PIORB_CDB pIORB)
- {
- USHORT i, rc;
-
- pNEC_CDB_ReadSubQ pCDB1;
- struct CDB_ReadSubChannel FAR *pCDB2;
- PIORB_FLTWORK pFilter_workspace;
-
- pCDB1 = (pNEC_CDB_ReadSubQ) pIORB->apt.pControllerCmd;
- pCDB2 = (struct CDB_ReadSubChannel FAR *) pCDB1;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
-
- if ( pCDB2->data_format == RSC_CURRENT_POSITION )
- {
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_ReadSubQ);
- pIORB->apt.pSGList->XferBufLen = sizeof (NEC_DATA_SubQChannel);
-
- pCDB1->OpCode = NEC_READ_SUB_Q;
-
- pCDB1->alloc_length = sizeof (NEC_DATA_SubQChannel);
-
- for (i=2;i<10;i++)
- *((PBYTE) pCDB1+i) = 0;
-
- /*
- ** Replace callback address with ours.
- */
- pFilter_workspace->completion_address = NotifyReadSubChannel;
-
- rc = CALL_ADD_AND_NOTIFY_FILTER;
- }
- else
- {
- rc = NOTIFY_CDM_WITH_ERROR;
- }
-
- return rc;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = NotifyReadSubChannel
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT NotifyReadSubChannel (PIORB_CDB pIORB)
- {
- UCHAR audio_status, control, track_number, index;
-
- pNEC_DATA_SubQChannel pCDBData1;
- struct SubChannel_Position FAR *pCDBData2;
-
- pCDBData1 = (pNEC_DATA_SubQChannel) pIORB->CDB_data;
- pCDBData2 = (struct SubChannel_Position FAR *) pIORB->CDB_data;
-
- /*
- ** convert NEC play status byte to SCSI-2
- */
- switch (pCDBData1->playback_status )
- {
- case NEC_PLAY_IN_PROGRESS:
- audio_status = AS_PLAY_IN_PROGRESS;
- break;
-
- case NEC_PLAY_STILL:
- audio_status = AS_PLAY_PAUSED;
- break;
-
- case NEC_PLAY_PAUSED:
- audio_status = AS_PLAY_PAUSED;
- break;
-
- case NEC_PLAY_COMPLETE:
- audio_status = AS_PLAY_COMPLETE;
- break;
-
- default:
- audio_status = AS_NO_STATUS;
- break;
- }
-
- control = pCDBData1->control;
- track_number = BCDtoBinary(pCDBData1->tno);
- index = BCDtoBinary(pCDBData1->point);
-
- /*
- ** fill in Current Position data block
- */
- pCDBData2->rel_address.redbook.zero = 0;
- pCDBData2->rel_address.redbook.min = BCDtoBinary(pCDBData1->min);
- pCDBData2->rel_address.redbook.sec = BCDtoBinary(pCDBData1->sec);
- pCDBData2->rel_address.redbook.frame = BCDtoBinary(pCDBData1->frame);
-
- pCDBData2->abs_address.redbook.frame = BCDtoBinary(pCDBData1->aframe);
- pCDBData2->abs_address.redbook.sec = BCDtoBinary(pCDBData1->asec);
- pCDBData2->abs_address.redbook.min = BCDtoBinary(pCDBData1->amin);
- pCDBData2->abs_address.redbook.zero = 0;
-
- pCDBData2->data_format_code = 1;
- pCDBData2->control = control;
- pCDBData2->ADR = ADR_CURRENT_POSITION;
- pCDBData2->track_number = track_number;
- pCDBData2->index_number = index;
-
- /*
- ** fill in sub-channel header
- */
- pCDBData2->sub_channel_hdr.reserved_1 = 0;
- pCDBData2->sub_channel_hdr.audio_status = audio_status;
- pCDBData2->sub_channel_hdr.data_length.usbytes.byte_0 = 0;
- pCDBData2->sub_channel_hdr.data_length.usbytes.byte_1 =
- sizeof(struct SubChannel_Position) -
- sizeof(struct SubChannel_Hdr);
-
- return NOTIFY_CDM;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_ReadTOC
- *
- * DESCRIPTION = This routine converts the SCSI-2 Read TOC command to an NEC
- * Read TOC.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_ReadTOC (PIORB_CDB pIORB)
- {
- USHORT i;
-
- pNEC_CDB_ReadTOC pCDB1;
- struct CDB_ReadTOC FAR *pCDB2;
- PIORB_FLTWORK pFilter_workspace;
-
- pCDB1 = (pNEC_CDB_ReadTOC) pIORB->apt.pControllerCmd;
- pCDB2 = (struct CDB_ReadTOC FAR *) pCDB1;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
-
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_ReadTOC);
- pIORB->apt.pSGList->XferBufLen = sizeof (NEC_DATA_TrackInfo);
-
- pCDB1->OpCode = NEC_READ_TOC;
-
- /*
- ** we first want to get the track information
- */
- if ( pCDB2->starting_track == 0xAA )
- pCDB1->data_type = NEC_LEADOUT_INFO;
- else
- pCDB1->data_type = NEC_TRACK_INFO;
-
- pCDB1->TNO = BinarytoBCD (pCDB2->starting_track);
- pCDB1->control = 0;
-
- for (i=3;i<9;i++)
- *((PBYTE) pCDB1+i) = 0;
-
- /*
- ** Replace callback address with ours.
- */
- pFilter_workspace->completion_address = NotifyReadTrack;
-
- return CALL_ADD_AND_NOTIFY_FILTER;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = NotifyReadTrack
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT NotifyReadTrack (PIORB_CDB pIORB)
- {
- USHORT i;
-
- pNEC_CDB_ReadTOC pCDB1;
- pNEC_DATA_TrackInfo pCDBData1;
- struct CDB_ReadTOC FAR *pCDB2;
- struct ReadTOC_Data FAR *pCDBData2;
- PIORB_FLTWORK pFilter_workspace;
-
- pCDB1 = (pNEC_CDB_ReadTOC) pIORB->apt.pControllerCmd;
- pCDBData1 = (pNEC_DATA_TrackInfo) pIORB->CDB_data;
- pCDB2 = (struct CDB_ReadTOC FAR *) pCDB1;
- pCDBData2 = (struct ReadTOC_Data FAR *) pIORB->CDB_data;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
-
- pCDBData2->toc_descriptor[0].control = pCDBData1->control;
- pCDBData2->toc_descriptor[0].ADR = ADR_CURRENT_POSITION;
-
- pCDBData2->toc_descriptor[0].track_num = pCDB1->TNO;
-
- pCDBData2->toc_descriptor[0].abs_address.redbook.zero = 0;
- pCDBData2->toc_descriptor[0].abs_address.redbook.min =
- BCDtoBinary(pCDBData1->amin);
- pCDBData2->toc_descriptor[0].abs_address.redbook.sec =
- BCDtoBinary(pCDBData1->asec);
- pCDBData2->toc_descriptor[0].abs_address.redbook.frame =
- BCDtoBinary(pCDBData1->aframe);
-
- pCDB1->data_type = NEC_MINMAX_INFO;
-
- pFilter_workspace->completion_address = NotifyReadMinMax;
-
- return CALL_ADD_AND_NOTIFY_FILTER;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = NotifyReadMinMax
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT NotifyReadMinMax (PIORB_CDB pIORB)
- {
- pNEC_DATA_MinMax pCDBData1;
- struct ReadTOC_Data FAR *pCDBData2;
-
- pCDBData1 = (pNEC_DATA_MinMax) pIORB->CDB_data;
- pCDBData2 = (struct ReadTOC_Data FAR *) pIORB->CDB_data;
-
- pCDBData2->toc_hdr.first_track = BCDtoBinary(pCDBData1->min_tno);
- pCDBData2->toc_hdr.last_track = BCDtoBinary(pCDBData1->max_tno);
-
- pCDBData2->toc_hdr.toc_datalength.usbytes.byte_0 = 0;
- pCDBData2->toc_hdr.toc_datalength.usbytes.byte_1 =
- sizeof (struct ReadTOC_Data) - 2;
-
- pCDBData2->toc_descriptor[0].reserved_1 = 0;
- pCDBData2->toc_descriptor[0].reserved_3 = 0;
-
- return NOTIFY_CDM;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_ReadHeader
- *
- * DESCRIPTION = Because the NEC drive does not support the Read Header
- * command or equevalent, we always return a density code of 1.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_ReadHeader (PIORB_CDB pIORB)
- {
- USHORT i;
-
- struct CDB_ReadHeader FAR *pCDB1;
- struct ReadHeader_Data FAR *pCDBData1;
-
- pCDB1 = (struct CDB_ReadHeader FAR *) pIORB->apt.pControllerCmd;
- pCDBData1 = (struct ReadHeader_Data FAR *) pIORB->CDB_data;
-
- pCDBData1->cdrom_data_mode = 1;
-
- for (i=1;i<8;i++)
- *((PBYTE) pCDB1+i) = 0;
-
- return NOTIFY_CDM;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_PlayAudio_MSF
- *
- * DESCRIPTION = This routine converts the SCSI-2 Play MSF command to an NEC
- * Audio Search command and then a Audio Play command.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_PlayAudio_MSF (PIORB_CDB pIORB)
- {
- pNEC_CDB_AudioTrackSearch pCDB1;
- struct CDB_PlayAudio_MSF FAR *pCDB2;
- PIORB_FLTWORK pFilter_workspace;
-
- pCDB1 = (pNEC_CDB_AudioTrackSearch) pIORB->apt.pControllerCmd;
- pCDB2 = (struct CDB_PlayAudio_MSF FAR *) pCDB1;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
-
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_AudioTrackSearch);
-
- pCDB1->OpCode = NEC_AUDIO_TRACK_SEARCH;
-
- pCDB1->play = 0; /* pause after search */
-
- pCDB1->search_min = BinarytoBCD (pCDB2->starting_M);
- pCDB1->search_sec = BinarytoBCD (pCDB2->starting_S);
- pCDB1->search_frame = BinarytoBCD (pCDB2->starting_F);
- pCDB1->search_zero = 0;
-
- pFilter_workspace->end_play_address.redbook.min =
- BinarytoBCD (pCDB2->ending_M);
- pFilter_workspace->end_play_address.redbook.sec =
- BinarytoBCD (pCDB2->ending_S);
- pFilter_workspace->end_play_address.redbook.frame =
- BinarytoBCD (pCDB2->ending_F);
-
- pCDB1->addr_type = NEC_ADDR_MSF;
-
- pCDB1->reserved_1 = 0;
- pCDB1->reserved_2 = 0;
- pCDB1->reserved_3 = 0;
- pCDB1->reserved_4 = 0;
- pCDB1->reserved_5 = 0;
-
- /*
- ** Replace callback address with ours.
- */
- pFilter_workspace->completion_address = NotifyAudioSearch;
-
- return CALL_ADD_AND_NOTIFY_FILTER;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = NotifyAudioSearch
- *
- * DESCRIPTION =
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT NotifyAudioSearch (PIORB_CDB pIORB)
- {
- pNEC_CDB_PlayAudio pCDB1;
- PIORB_FLTWORK pFilter_workspace;
- NPUNITCB pUnitCB;
-
- pCDB1 = (pNEC_CDB_PlayAudio) pIORB->apt.pControllerCmd;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
- pUnitCB = pFilter_workspace->pUnitCB;
-
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_PlayAudio);
-
- pCDB1->OpCode = NEC_PLAY_AUDIO;
-
- pCDB1->play_mode = pUnitCB->play_mode;
-
- pCDB1->completion_min = pFilter_workspace->end_play_address.redbook.min;
- pCDB1->completion_sec = pFilter_workspace->end_play_address.redbook.sec;
- pCDB1->completion_frame = pFilter_workspace->end_play_address.redbook.frame;
- pCDB1->completion_zero = 0;
-
- pCDB1->addr_type = NEC_ADDR_MSF;
-
- return CALL_ADD_AND_NOTIFY_CDM;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION NAME = Filter_Pause_Resume
- *
- * DESCRIPTION = This routine converts the SCSI-2 Pause/Resume CDB to a NEC
- * Still or Play CDB.
- *
- * INPUT = pIORB - pointer to IORB
- *
- * OUTPUT =
- *
- * RETURN-NORMAL =
- * RETURN-ERROR =
- *
- ****************************************************************************/
-
- USHORT Filter_Pause_Resume (PIORB_CDB pIORB)
- {
- UCHAR i, rc;
-
- pNEC_CDB_Still pCDB1;
- pNEC_CDB_PlayAudio pCDB1a;
- struct CDB_PauseResume FAR *pCDB2;
- PIORB_FLTWORK pFilter_workspace;
-
- pCDB1 = (pNEC_CDB_Still) pIORB->apt.pControllerCmd;
- pCDB1a = (pNEC_CDB_PlayAudio) pIORB->apt.pControllerCmd;
- pCDB2 = (struct CDB_PauseResume FAR *) pCDB1;
- pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
-
- /*
- ** If SCSI-2 resume request, issue Audio Search followed by Play command.
- */
-
- if ( pCDB2->resume )
- {
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_PlayAudio);
-
- pCDB1a->OpCode = NEC_PLAY_AUDIO;
-
- pCDB1a->play_mode = NEC_PLAY_PREVIOUS_MODE;
-
- pCDB1a->completion_min = 0;
- pCDB1a->completion_sec = 0;
- pCDB1a->completion_frame = 0;
- pCDB1a->completion_zero = 0;
-
- pCDB1a->addr_type = NEC_ADDR_PRV;
-
- rc = CALL_ADD_AND_NOTIFY_CDM;
- }
- else
- {
- /*
- ** Convert SCSI-2 Pause to NEC Still command.
- */
- pIORB->apt.ControllerCmdLen = sizeof (NEC_CDB_Still);
-
- pCDB1->OpCode = NEC_STILL;
-
- for (i=2;i<10;i++)
- *((PBYTE) pCDB1+i) = 0;
-
- rc = CALL_ADD_AND_RET;
- }
- return rc;
- }
-
-