Exemple #1
0
void Init_IDE(void) {
    int errorCode;

    Print("Initializing IDE controller...\n");

    /* Reset the controller and drives */
    Out_Byte(IDE_DEVICE_CONTROL_REGISTER,
             IDE_DCR_NOINTERRUPT | IDE_DCR_RESET);
    Micro_Delay(100);
    Out_Byte(IDE_DEVICE_CONTROL_REGISTER, IDE_DCR_NOINTERRUPT);

/*
 * FIXME: This code doesn't work on Bochs 2.0.
 *    while ((In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_READY) == 0)
 *	;
 */

    /* This code does work on Bochs 2.0. */
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ;

    if(ideDebug)
        Print("About to run drive Diagnosis\n");

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_DIAGNOSTIC);
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ;
    errorCode = In_Byte(IDE_ERROR_REGISTER);
    if(ideDebug > 1)
        Print("ide: ide error register = %x\n", errorCode);

    /* Probe and register drives */
    int i;
    for(i = 0; i < IDE_MAX_DRIVES; i++) {
        if(readDriveConfig(i) == 0)
            ++numDrives;
    }
    if(ideDebug)
        Print("Found %d IDE drives\n", numDrives);

    /* Start request thread */
    if(numDrives > 0)
        Start_Kernel_Thread(IDE_Request_Thread, 0, PRIORITY_NORMAL, true,
                            "{IDE}");
}
Exemple #2
0
static void Sys_Usleep(struct Interrupt_State *state)
{
	Micro_Delay(state->ebx);
	//Start_Timer(state->ebx, NULL);
}
Exemple #3
0
static int Floppy_Transfer(int direction, int driveNum, int blockNum, char *buf)
{
    struct Floppy_Drive *drive = &s_driveTable[driveNum];
    struct Floppy_Parameters *params = drive->params;
    int cylinder, head, sector;
    enum DMA_Direction dmaDirection =
	direction == FLOPPY_READ ? DMA_READ : DMA_WRITE;
    uchar_t command;
    uchar_t st0, st1, st2;
    int result = -1;

    KASSERT(driveNum == 0);  /* FIXME */
    KASSERT(direction == FLOPPY_READ || direction == FLOPPY_WRITE);
    KASSERT(params != 0);

    LBA_To_CHS(&s_driveTable[driveNum], blockNum, &cylinder, &head, &sector);

    if (!Floppy_Seek(driveNum, cylinder, head))
	return -1;

    Disable_Interrupts();

    /* Set up DMA for transfer */
    Setup_DMA(dmaDirection, FDC_DMA, s_transferBuf, SECTOR_SIZE);

    /* Turn the floppy motor on */
    Start_Motor(driveNum);

    /*
     * According to The Undocumented PC, we should wait 8 millis
     * before attempting a read or write.
     */
    Micro_Delay(8000);

    if (direction == FLOPPY_READ)
	command = FDC_COMMAND_READ_SECTOR | FDC_MFM | FDC_SKIP_DELETED;
    else
	command = FDC_COMMAND_WRITE_SECTOR | FDC_MFM;
 
    /* Issue the command */
    Floppy_Out(command);
    Floppy_Out((head << 2) | (driveNum & 3));
    Floppy_Out(cylinder);
    Floppy_Out(head);
    Floppy_Out(sector);
    Floppy_Out(params->sectorSizeCode);
    Floppy_Out(params->sectors);
    Floppy_Out(params->gapLengthCode);
    Floppy_Out(0xFF);  /* DTL */

    /* Controller will issue an interrupt when the command is complete */
    Wait_For_Interrupt();
    Debug("Floppy_Transfer: received interrupt!\n");

    /* Read results */
    st0 = Floppy_In();
    st1 = Floppy_In();
    st2 = Floppy_In();
    Floppy_In();  /* cylinder */
    Floppy_In();  /* head */
    Floppy_In();  /* sector number */
    Floppy_In();  /* sector size */

    Stop_Motor(driveNum);

    if (FDC_ST0_IS_SUCCESS(st0)) {
	Debug("Floppy_Transfer: successful transfer!\n");
	result = 0;
    }

    Enable_Interrupts();

    /*STOP(); */
    return result;
}