diff --git a/k/atapi.c b/k/atapi.c index b2a6916..aed6531 100644 --- a/k/atapi.c +++ b/k/atapi.c @@ -1,10 +1,11 @@ #include #include +#include #include "atapi.h" #include "io.h" -static struct atapi_drive drives[4] = { 0 }; +static struct atapi_drive a_drive = { 0 }; /* wait functions */ static void busy_wait(uint16_t drive) @@ -16,7 +17,7 @@ static void busy_wait(uint16_t drive) static void wait_device_selection(uint16_t drive) { - for (int i = 0; i < 4; ++i) + for (int i = 0; i < 400; ++i) inb(drive); } @@ -47,20 +48,7 @@ static uint8_t is_atapi_drive(uint16_t bus, uint8_t slave) if (!memcmp(sig, atapi_sig, 4)) { struct atapi_drive d = { bus, slave }; - if (bus == PRIMARY_REG) - { - if (slave) - drives[1] = d; - else - drives[0] = d; - } - else - { - if (slave) - drives[3] = d; - else - drives[2] = d; - } + memcpy(&a_drive, &d, sizeof(struct atapi_drive)); return 1; } @@ -77,12 +65,14 @@ void discover_atapi_drive(void) // master_port select_drive(PRIMARY_REG, ATA_PORT_MASTER); wait_device_selection(PRIMARY_REG); - is_atapi_drive(PRIMARY_REG, ATA_PORT_MASTER); + if (is_atapi_drive(PRIMARY_REG, ATA_PORT_MASTER)) + return; // slave port select_drive(PRIMARY_REG, ATA_PORT_SLAVE); wait_device_selection(PRIMARY_REG); - is_atapi_drive(PRIMARY_REG, ATA_PORT_SLAVE); + if (is_atapi_drive(PRIMARY_REG, ATA_PORT_SLAVE)) + return; /* secondary_reg */ outb(SECONDARY_DCR, SRST); @@ -91,16 +81,18 @@ void discover_atapi_drive(void) // master_port select_drive(SECONDARY_REG, ATA_PORT_MASTER); wait_device_selection(SECONDARY_REG); - is_atapi_drive(SECONDARY_REG, ATA_PORT_MASTER); + if (is_atapi_drive(SECONDARY_REG, ATA_PORT_MASTER)) + return; // slave port select_drive(SECONDARY_REG, ATA_PORT_SLAVE); wait_device_selection(SECONDARY_REG); - is_atapi_drive(SECONDARY_REG, ATA_PORT_SLAVE); + if (is_atapi_drive(SECONDARY_REG, ATA_PORT_SLAVE)) + return; } /* IO functions */ -int send_packet(struct SCSI_packet *pkt, uint16_t drive, uint16_t size) +static int send_packet(struct SCSI_packet *pkt, uint16_t drive, uint16_t size) { // cpy SCSI_packet into uint16_t array uint16_t packet[PACKET_SZ / 2]; @@ -127,8 +119,11 @@ int send_packet(struct SCSI_packet *pkt, uint16_t drive, uint16_t size) static char block[CD_BLOCK_SZ]; -void read_block(size_t lba, uint16_t drive) +void *read_block(size_t lba) { + select_drive(a_drive.reg, a_drive.drive); + wait_device_selection(a_drive.reg); + struct SCSI_packet pkt = { 0 }; pkt.op_code = READ_12; pkt.lba_lo = lba & 0xff; @@ -137,14 +132,16 @@ void read_block(size_t lba, uint16_t drive) pkt.lba_hi = (lba >> 0x18) & 0xff; pkt.transfer_length_lo = 1; - send_packet(&pkt, drive, PACKET_SZ); + send_packet(&pkt, a_drive.reg, PACKET_SZ); // we can now read - uint16_t *buf = block; + uint16_t *buf = (uint16_t *)block; for (int i = 0; i < CD_BLOCK_SZ / 2; ++i) - buf[i] = inw(ATA_REG_DATA(drive)); + buf[i] = inw(ATA_REG_DATA(a_drive.reg)); uint8_t read = 0; while (read != PACKET_COMMAND_COMPLETE) - read = inb(ATA_REG_SECTOR_COUNT(drive)); + read = inb(ATA_REG_SECTOR_COUNT(a_drive.reg)); + + return block; }