/* extract a 16-bit word from the bitstream buffer */ int Get_Word() { int Val; Val = Get_Byte(); return (Val<<8) | Get_Byte(); }
NTSTATUS NTAPI HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo, PUCHAR Status) /* * FUNCTION: Get the result of a sense drive status command * ARGUMENTS: * ControllerInfo: controller to query * Status: Status from the drive sense command * RETURNS: * STATUS_SUCCESS if we can successfully read the status * STATUS_UNSUCCESSFUL otherwise * NOTES: * - Called post-interrupt; does not interrupt */ { PAGED_CODE(); if(Get_Byte(ControllerInfo, Status) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwSenseDriveStatus: unable to read fifo\n"); return STATUS_UNSUCCESSFUL; } TRACE_(FLOPPY, "HwSenseDriveStatusResult: ST3: 0x%x\n", *Status); return STATUS_SUCCESS; }
NTSTATUS NTAPI HwGetVersion(PCONTROLLER_INFO ControllerInfo) /* * FUNCTION: Gets the version of the controller * ARGUMENTS: * ControllerInfo: controller to target with the request * ConfigValue: Configuration value to send to the drive (see header) * RETURNS: * Version number returned by the command, or * 0 on failure * NOTE: * - This command doesn't interrupt, so we go right to reading after * we issue the command */ { UCHAR Buffer; PAGED_CODE(); if(Send_Byte(ControllerInfo, COMMAND_VERSION) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwGetVersion: unable to write fifo\n"); return STATUS_UNSUCCESSFUL; } if(Get_Byte(ControllerInfo, &Buffer) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwGetVersion: unable to write fifo\n"); return STATUS_UNSUCCESSFUL; } INFO_(FLOPPY, "HwGetVersion returning version 0x%x\n", Buffer); return Buffer; }
NTSTATUS NTAPI HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo) /* * FUNCTION: Send a sense interrupt status command to a controller * ARGUMENTS: * ControllerInfo: controller to queue the command to * RETURNS: * STATUS_SUCCESS if the command is queued successfully * STATUS_UNSUCCESSFUL if not */ { UCHAR Buffer[2]; int i; PAGED_CODE(); if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwSenseInterruptStatus: failed to write controller\n"); return STATUS_UNSUCCESSFUL; } for(i = 0; i < 2; i++) { if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwSenseInterruptStatus: failed to read controller\n"); return STATUS_UNSUCCESSFUL; } } INFO_(FLOPPY, "HwSenseInterruptStatus returned 0x%x 0x%x\n", Buffer[0], Buffer[1]); return STATUS_SUCCESS; }
NTSTATUS NTAPI HwReadIdResult(PCONTROLLER_INFO ControllerInfo, PUCHAR CurCylinder, PUCHAR CurHead) /* * FUNCTION: Get the result of a read id command * ARGUMENTS: * ControllerInfo: controller to query * CurCylinder: Returns the cylinder that we're at * CurHead: Returns the head that we're at * RETURNS: * STATUS_SUCCESS if the read id was a success * STATUS_UNSUCCESSFUL otherwise * NOTES: * - This function tests the error conditions itself, and boils the * whole thing down to a single SUCCESS or FAILURE result * - Called post-interrupt; does not interrupt * TODO * - perhaps handle more status */ { UCHAR Buffer[7] = {0,0,0,0,0,0,0}; int i; PAGED_CODE(); for(i = 0; i < 7; i++) if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS) { WARN_(FLOPPY, "ReadIdResult(): can't read from the controller\n"); return STATUS_UNSUCCESSFUL; } /* Validate that it did what we told it to */ INFO_(FLOPPY, "ReadId results: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3], Buffer[4], Buffer[5], Buffer[6]); /* Last command successful? */ if((Buffer[0] & SR0_LAST_COMMAND_STATUS) != SR0_LCS_SUCCESS) { WARN_(FLOPPY, "ReadId didn't return last command success\n"); return STATUS_UNSUCCESSFUL; } /* ID mark found? */ if(Buffer[1] & SR1_CANNOT_FIND_ID_ADDRESS) { WARN_(FLOPPY, "ReadId didn't find an address mark\n"); return STATUS_UNSUCCESSFUL; } if(CurCylinder) *CurCylinder = Buffer[3]; if(CurHead) *CurHead = Buffer[4]; return STATUS_SUCCESS; }
NTSTATUS NTAPI HwReadWriteResult(PCONTROLLER_INFO ControllerInfo) /* * FUNCTION: Get the result of a read or write from the controller * ARGUMENTS: * ControllerInfo: controller to query * RETURNS: * STATUS_SUCCESS if the read/write was a success * STATUS_UNSUCCESSFUL otherwise * NOTES: * - This function tests the error conditions itself, and boils the * whole thing down to a single SUCCESS or FAILURE result * - Called post-interrupt; does not interrupt * TODO: * - perhaps handle more status */ { UCHAR Buffer[7]; int i; PAGED_CODE(); for(i = 0; i < 7; i++) if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwReadWriteResult: unable to read fifo\n"); return STATUS_UNSUCCESSFUL; } /* Validate that it did what we told it to */ INFO_(FLOPPY, "HwReadWriteResult results: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3], Buffer[4], Buffer[5], Buffer[6]); /* Last command successful? */ if((Buffer[0] & SR0_LAST_COMMAND_STATUS) != SR0_LCS_SUCCESS) return STATUS_UNSUCCESSFUL; return STATUS_SUCCESS; }
/* parse system layer, ignore everything we don't need */ void Next_Packet() { unsigned int code; int l; for(;;) { code = Get_Long(); /* remove system layer byte stuffing */ while ((code & 0xffffff00) != 0x100) code = (code<<8) | Get_Byte(); switch(code) { case PACK_START_CODE: /* pack header */ /* skip pack header (system_clock_reference and mux_rate) */ ld->Rdptr += 8; break; case VIDEO_ELEMENTARY_STREAM: code = Get_Word(); /* packet_length */ ld->Rdmax = ld->Rdptr + code; code = Get_Byte(); if((code>>6)==0x02) { ld->Rdptr++; code=Get_Byte(); /* parse PES_header_data_length */ ld->Rdptr+=code; /* advance pointer by PES_header_data_length */ //printf("MPEG-2 PES packet\n"); return; } else if(code==0xff) { /* parse MPEG-1 packet header */ while((code=Get_Byte())== 0xFF); } /* stuffing bytes */ if(code>=0x40) { if(code>=0x80) { fprintf(stderr,"Error in packet header\n"); exit(1); } /* skip STD_buffer_scale */ ld->Rdptr++; code = Get_Byte(); } if(code>=0x30) { if(code>=0x40) { fprintf(stderr,"Error in packet header\n"); exit(1); } /* skip presentation and decoding time stamps */ ld->Rdptr += 9; } else if(code>=0x20) { /* skip presentation time stamps */ ld->Rdptr += 4; } else if(code!=0x0f) { fprintf(stderr,"Error in packet header\n"); exit(1); } return; case ISO_END_CODE: /* end */ /* simulate a buffer full of sequence end codes */ l = 0; while (l<2048) { ld->Rdbfr[l++] = SEQUENCE_END_CODE>>24; ld->Rdbfr[l++] = SEQUENCE_END_CODE>>16; ld->Rdbfr[l++] = SEQUENCE_END_CODE>>8; ld->Rdbfr[l++] = SEQUENCE_END_CODE&0xff; } ld->Rdptr = ld->Rdbfr; ld->Rdmax = ld->Rdbfr + 2048; return; default: if(code>=SYSTEM_START_CODE) { /* skip system headers and non-video packets*/ code = Get_Word(); ld->Rdptr += code; } else { fprintf(stderr,"Unexpected startcode %08x in system layer\n",code); exit(1); } break; } }
NTSTATUS NTAPI HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo) /* * FUNCTION: Get the result of a recalibrate command * ARGUMENTS: * ControllerInfo: controller to query * RETURNS: * STATUS_SUCCESS if the recalibratewas a success * STATUS_UNSUCCESSFUL otherwise * NOTES: * - This function tests the error conditions itself, and boils the * whole thing down to a single SUCCESS or FAILURE result * - Called post-interrupt; does not interrupt * TODO * - perhaps handle more status */ { UCHAR Buffer[2]; int i; PAGED_CODE(); if(Send_Byte(ControllerInfo, COMMAND_SENSE_INTERRUPT_STATUS) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwRecalibrateResult: Unable to write the controller\n"); return STATUS_UNSUCCESSFUL; } for(i = 0; i < 2; i++) if(Get_Byte(ControllerInfo, &Buffer[i]) != STATUS_SUCCESS) { WARN_(FLOPPY, "HwRecalibrateResult: unable to read FIFO\n"); return STATUS_UNSUCCESSFUL; } /* Validate that it did what we told it to */ INFO_(FLOPPY, "HwRecalibrateResult results: ST0: 0x%x PCN: 0x%x\n", Buffer[0], Buffer[1]); /* * Buffer[0] = ST0 * Buffer[1] = PCN */ /* Is the PCN 0? */ if(Buffer[1] != 0) { WARN_(FLOPPY, "HwRecalibrateResult: PCN not 0\n"); return STATUS_UNSUCCESSFUL; } /* test seek complete */ if((Buffer[0] & SR0_SEEK_COMPLETE) != SR0_SEEK_COMPLETE) { WARN_(FLOPPY, "HwRecalibrateResult: Failed to complete the seek\n"); return STATUS_UNSUCCESSFUL; } /* Is the equipment check flag set? Could be no disk in drive... */ if((Buffer[0] & SR0_EQUIPMENT_CHECK) == SR0_EQUIPMENT_CHECK) { WARN_(FLOPPY, "HwRecalibrateResult: Seeked to track 0 successfully, but EC is set; returning failure\n"); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; }