My FDC driver wont send me an interrupt
Posted: Tue Feb 26, 2008 2:28 pm
I have tried implementing a decent FDC driver using the resources on the wiki (mainly mystrans tutorial).
But i can't even reset the FDC as it wont send an interrupt, i even waited 10 minutes for one (whilst doing something else... im not THAT sad).
sorry about the length of that snippet, most of the code is the same as in the tutorial, but i thought it would be easier all in one place, rather than having to check back all the time.
the random kprintf's are to see where the code gets to.
it just waits for the interrupt and it never arrives =\
oh... i also get
from bochs. This says that it has been successfully been reset, and the other data looks right, but i don't receive an interrupt.
But i can't even reset the FDC as it wont send an interrupt, i even waited 10 minutes for one (whilst doing something else... im not THAT sad).
Code: Select all
static volatile int floppy_base = 0x03f0;
static volatile int floppy_number_drives;
static volatile int floppy_recieved_int = 1;
static volatile int floppy_motor_ticks = 0;
static volatile int floppy_motor_state = 0;
//Floppy Registers
enum floppy_registers {
FLOPPY_DOR = 2, // digital output register
FLOPPY_MSR = 4, // master status register, read only
FLOPPY_FIFO = 5, // data FIFO, in DMA operation for commands
FLOPPY_CCR = 7 // configuration control register, write only
};
//Floppy Commands
enum floppy_commands {
FLOPPY_CMD_SPECIFY = 3, // SPECIFY
FLOPPY_CMD_WRITE_DATA = 5, // WRITE DATA
FLOPPY_CMD_READ_DATA = 6, // READ DATA
FLOPPY_CMD_RECALIBRATE = 7, // RECALIBRATE
FLOPPY_CMD_SENSE_INTERRUPT = 8, // SENSE INTERRUPT
FLOPPY_CMD_SEEK = 15, // SEEK
};
//Floppy Motor States
enum { floppy_motor_off = 0, floppy_motor_on, floppy_motor_wait };
int initialise_floppy_driver()
{
outb(0x70, 0x10);
unsigned char drives = inb(0x71);
int a,b;
a = drives >> 4;
b = drives & 0xf;
//Check how many floppy drives are installed
if(a != 4)
//None. dont waste our time
return 1;
if(b != 4)
floppy_number_drives = 1;
else
floppy_number_drives = 2;
kprintf("We got %d Floppy(s)!\n",floppy_number_drives);
//Init to primary floppy
floppy_base = 0x03f0;
register_interrupt_handler(6, &floppy_handler);
kprintf("IRQ6 set up\n");
floppy_reset(floppy_base);
return 0;
}
void floppy_wait_for_interrupt()
{
floppy_recieved_int = 1;
while(floppy_recieved_int);
return;
}
int floppy_reset(int base)
{
outb((base + FLOPPY_DOR), 0x00); // disable controller
timer_wait(2); // 20 microsecond wait
outb((base + FLOPPY_DOR), 0x0C); // enable controller
kprintf("waiting for interrupt..\n");
floppy_wait_for_interrupt(); // sleep until interrupt occurs
kprintf("we g0tz in interrupt from FDC.\n");
int st0, cyl; // These value must be read, but can be ignored
floppy_check_interrupt(base, &st0, &cyl);
// set transfer speed 500kb/s
outb((base + FLOPPY_CCR), 0x00);
// These value are for 1.44mb floppy
floppy_write_cmd(base, FLOPPY_CMD_SPECIFY);
floppy_write_cmd(base, 0xdf); /* steprate = 3ms, unload time = 240ms */
floppy_write_cmd(base, 0x02); /* load time = 16ms, no-DMA = 0 */
// This is incase of failure
kprintf("lets calibrate the FDC\n");
if(floppy_calibrate(base)) return -1;
kprintf("braaap\n");
return 0;
}
... The rest of the code is the same
the random kprintf's are to see where the code gets to.
it just waits for the interrupt and it never arrives =\
oh... i also get
Code: Select all
00017031251d[FDD ] write access to port 03f2, value=00
00017031251d[FDD ] DMA and interrupt capabilities disabled
00017031251d[FDD ] io_write: digital output register
00017031251d[FDD ] motor on, drive1 = 0
00017031251d[FDD ] motor on, drive0 = 0
00017031251d[FDD ] dma_and_interrupt_enable=00
00017031251d[FDD ] normal_operation=00
00017031251d[FDD ] drive_select=00
00017507829d[FDD ] write access to port 03f2, value=0c
00017507829d[FDD ] io_write: digital output register
00017507829d[FDD ] motor on, drive1 = 0
00017507829d[FDD ] motor on, drive0 = 0
00017507829d[FDD ] dma_and_interrupt_enable=08
00017507829d[FDD ] normal_operation=04
00017507829d[FDD ] drive_select=00
00017508329i[FDD ] controller reset in software