At the moment I am trying to code an CD Driver in DMA and PIO mode. But my problem is that I do not get an IRQ from the device. But I also get no error message. So does anyone has an idear why I do not get an irq from the atapi deviece ??
Emulator
Code: Select all
QEMU PC emulator version 0.12.3 (qemu-kvm-0.12.3), Copyright (c) 2003-2008 Fabrice Bellard
Code: Select all
bool ATA_ATAPI::check_error(unsigned short channel) {
if((inportb(channel + 7) & 0x1) == 1){
//Scan Error Resgister
if((inportb(channel + 1) & 0x1) == 1)
error_ata_atapi = (char *)"Address Mark Not Found";
else if((inportb(channel + 1) & 0x2) == 2)
error_ata_atapi = (char *)"Track 0 Not Found";
else if((inportb(channel + 1) & 0x4) == 4)
error_ata_atapi = (char *)"command aborted";
else if((inportb(channel + 1) & 0x8) == 8)
error_ata_atapi = (char *)"Media Change Requested";
else if((inportb(channel + 1) & 0x10) == 16)
error_ata_atapi = (char *)"ID mark Not Found";
else if((inportb(channel + 1) & 0x20) == 32)
error_ata_atapi = (char *)"Media Changed";
else if((inportb(channel + 1) & 0x40) == 64)
error_ata_atapi = (char *)"Uncorrectable data error";
else if((inportb(channel + 1) & 0x80) == 128)
error_ata_atapi = (char *)"Bad Block";
return false;
}
else
return true;
}
Code: Select all
void ATA_ATAPI::set_up_irq(int *channel_n)
{
// Paralel IDE uses IRQ 14 and 15
if(pci_interface->results[0].pci_device->Prog_I_F == 0x8A || pci_interface->results[0].pci_device->Prog_I_F == 0x80) {
if(*channel_n == 1) {
outportb(Prim_Device_Control_Register,0x4);
irq_install_handler(14, cd_handler);
}
else if(*channel_n == 2) {
outportb(Sec_Device_Control_Register ,0x4);
irq_install_handler(15, cd_handler);
}
}
// If Serial IDE (not tested yet)
else {
if(*channel_n == 1) {
outportb(Prim_Device_Control_Register,0x4);
irq_install_handler(pci_interface->results[0].pci_device->interupt_line, cd_handler);
}
else if(*channel_n == 2) {
outportb(Sec_Device_Control_Register ,0x4);
irq_install_handler(pci_interface->results[0].pci_device->interupt_line, cd_handler);
}
}
}
Start reading from the device:
Code: Select all
unsigned short ide_offset;
ide_irq_invoked = 0;
//Declare unsigned char which contains the value of a ATAPI command packet ; 0xA8 Atpai read command
uint8_t read_command[12] = { 0xA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// ide_scan();
outportb (0x176, 0xA0 & (1 << 4));
timer_wait(1);
outportb (0x171, 0x0);
//Set Max byte count
outportb (0x174, Atapi_Sector_Size & 0xFF);
outportb (0x175, Atapi_Sector_Size>> 8);
// Start IRQs
set_up_irq(&IDEChannel[ide_offset].channel_n);
outportb (0x177, 0xA0);
bool irq = pol_waiting(IDEChannel[ide_offset].channel);
if(irq == false)
{
error_ata_atapi = (char *)"pol waiting error";
return false;
}
//Fill the ATAPI packet command
read_command[9] = 1; /* 1 sector */
read_command[2] = (lba >> 0x18) & 0xFF; /* most sig. byte of LBA */
read_command[3] = (lba >> 0x10) & 0xFF;
read_command[4] = (lba >> 0x08) & 0xFF;
read_command[5] = (lba >> 0x00) & 0xFF; /* least sig. byte of LBA */
/* Send ATAPI/SCSI command */
outportw (I0x170, ((uint16_t)read_command[0] << 8) |read_command[1]);
outportw (0x170, ((uint16_t)read_command[2] << 8) |read_command[3]);
outportw (0x170, ((uint16_t)read_command[4] << 8) |read_command[5]);
outportw (0x170, ((uint16_t)read_command[6] << 8) |read_command[7]);
outportw (0x170, ((uint16_t)read_command[8] << 8) |read_command[9]);
outportw (0x170, ((uint16_t)read_command[10] << 8) |read_command[11]);
if(!check_error(2))
return false;
//Here I get now no IRQ
wait_irq();
Any idears