feat(atapi): discover and store only one drive
This commit is contained in:
		
							parent
							
								
									ba318bb0e7
								
							
						
					
					
						commit
						9618d0d55a
					
				
							
								
								
									
										49
									
								
								k/atapi.c
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										49
									
								
								k/atapi.c
									
									
									
									
									
								
							@ -1,10 +1,11 @@
 | 
				
			|||||||
#include <k/atapi.h>
 | 
					#include <k/atapi.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "atapi.h"
 | 
					#include "atapi.h"
 | 
				
			||||||
#include "io.h"
 | 
					#include "io.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct atapi_drive drives[4] = { 0 };
 | 
					static struct atapi_drive a_drive = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* wait functions */
 | 
					/* wait functions */
 | 
				
			||||||
static void busy_wait(uint16_t drive)
 | 
					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)
 | 
					static void wait_device_selection(uint16_t drive)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    for (int i = 0; i < 4; ++i)
 | 
					    for (int i = 0; i < 400; ++i)
 | 
				
			||||||
        inb(drive);
 | 
					        inb(drive);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -47,20 +48,7 @@ static uint8_t is_atapi_drive(uint16_t bus, uint8_t slave)
 | 
				
			|||||||
    if (!memcmp(sig, atapi_sig, 4))
 | 
					    if (!memcmp(sig, atapi_sig, 4))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        struct atapi_drive d = { bus, slave };
 | 
					        struct atapi_drive d = { bus, slave };
 | 
				
			||||||
        if (bus == PRIMARY_REG)
 | 
					        memcpy(&a_drive, &d, sizeof(struct atapi_drive));
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (slave)
 | 
					 | 
				
			||||||
                drives[1] = d;
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                drives[0] = d;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (slave)
 | 
					 | 
				
			||||||
                drives[3] = d;
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                drives[2] = d;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -77,12 +65,14 @@ void discover_atapi_drive(void)
 | 
				
			|||||||
    // master_port
 | 
					    // master_port
 | 
				
			||||||
    select_drive(PRIMARY_REG, ATA_PORT_MASTER);
 | 
					    select_drive(PRIMARY_REG, ATA_PORT_MASTER);
 | 
				
			||||||
    wait_device_selection(PRIMARY_REG);
 | 
					    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
 | 
					    // slave port
 | 
				
			||||||
    select_drive(PRIMARY_REG, ATA_PORT_SLAVE);
 | 
					    select_drive(PRIMARY_REG, ATA_PORT_SLAVE);
 | 
				
			||||||
    wait_device_selection(PRIMARY_REG);
 | 
					    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 */
 | 
					    /* secondary_reg */
 | 
				
			||||||
    outb(SECONDARY_DCR, SRST);
 | 
					    outb(SECONDARY_DCR, SRST);
 | 
				
			||||||
@ -91,16 +81,18 @@ void discover_atapi_drive(void)
 | 
				
			|||||||
    // master_port
 | 
					    // master_port
 | 
				
			||||||
    select_drive(SECONDARY_REG, ATA_PORT_MASTER);
 | 
					    select_drive(SECONDARY_REG, ATA_PORT_MASTER);
 | 
				
			||||||
    wait_device_selection(SECONDARY_REG);
 | 
					    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
 | 
					    // slave port
 | 
				
			||||||
    select_drive(SECONDARY_REG, ATA_PORT_SLAVE);
 | 
					    select_drive(SECONDARY_REG, ATA_PORT_SLAVE);
 | 
				
			||||||
    wait_device_selection(SECONDARY_REG);
 | 
					    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 */
 | 
					/* 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
 | 
					    // cpy SCSI_packet into uint16_t array
 | 
				
			||||||
    uint16_t packet[PACKET_SZ / 2];
 | 
					    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];
 | 
					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 };
 | 
					    struct SCSI_packet pkt = { 0 };
 | 
				
			||||||
    pkt.op_code  = READ_12;
 | 
					    pkt.op_code  = READ_12;
 | 
				
			||||||
    pkt.lba_lo   = lba & 0xff;
 | 
					    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.lba_hi   = (lba >> 0x18) & 0xff;
 | 
				
			||||||
    pkt.transfer_length_lo = 1;
 | 
					    pkt.transfer_length_lo = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    send_packet(&pkt, drive, PACKET_SZ);
 | 
					    send_packet(&pkt, a_drive.reg, PACKET_SZ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // we can now read
 | 
					    // we can now read
 | 
				
			||||||
    uint16_t *buf = block;
 | 
					    uint16_t *buf = (uint16_t *)block;
 | 
				
			||||||
    for (int i = 0; i < CD_BLOCK_SZ / 2; ++i)
 | 
					    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;
 | 
					    uint8_t read = 0;
 | 
				
			||||||
    while (read != PACKET_COMMAND_COMPLETE)
 | 
					    while (read != PACKET_COMMAND_COMPLETE)
 | 
				
			||||||
        read = inb(ATA_REG_SECTOR_COUNT(drive));
 | 
					        read = inb(ATA_REG_SECTOR_COUNT(a_drive.reg));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return block;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user