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}"); }
static void Sys_Usleep(struct Interrupt_State *state) { Micro_Delay(state->ebx); //Start_Timer(state->ebx, NULL); }
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, §or); 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; }