ATA Add Read function
This commit is contained in:
parent
4fe87718b1
commit
1a337881f3
@ -383,17 +383,19 @@ static struct ata_controller controllers[MAX_ATA_CONTROLLER] = {{
|
|||||||
.base = 0x1F0,
|
.base = 0x1F0,
|
||||||
.dev_ctl = 0x3F6,
|
.dev_ctl = 0x3F6,
|
||||||
.present = 0,
|
.present = 0,
|
||||||
|
.last_device_used = -1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = 1,
|
.id = 1,
|
||||||
.base = 0x170,
|
.base = 0x170,
|
||||||
.dev_ctl = 0x376,
|
.dev_ctl = 0x376,
|
||||||
.present = 0,
|
.present = 0,
|
||||||
|
.last_device_used = -1,
|
||||||
}};
|
}};
|
||||||
int ATADetectDevice(struct ata_device *dev)
|
int ATADetectDevice(struct ata_device *dev)
|
||||||
{
|
{
|
||||||
struct ata_controller *ctl = dev->ctl;
|
struct ata_controller *ctl = dev->ctl;
|
||||||
outb(ctl->base + ATA_PIO_DRIVE, 0xA0 | dev->isSlave << 4);
|
outb(ctl->base + ATA_PIO_DRIVE, ATA_PIO_DRIVE_IBM | dev->isSlave? ATA_PIO_DRIVE_SLAVE: ATA_PIO_DRIVE_MASTER);
|
||||||
unsigned st = inb(ctl->base + ATA_PIO_STATUS);
|
unsigned st = inb(ctl->base + ATA_PIO_STATUS);
|
||||||
if (st & ATA_PIO_STATUS_DRIVE_BUSY)
|
if (st & ATA_PIO_STATUS_DRIVE_BUSY)
|
||||||
goto no_disk;
|
goto no_disk;
|
||||||
@ -425,7 +427,7 @@ int ATAGetDeviceInfo(struct ata_device *dev)
|
|||||||
struct ata_controller *ctl = dev->ctl;
|
struct ata_controller *ctl = dev->ctl;
|
||||||
struct _IDENTIFY_DEVICE_DATA *deviceInfo;
|
struct _IDENTIFY_DEVICE_DATA *deviceInfo;
|
||||||
|
|
||||||
outb(ctl->base + ATA_PIO_DRIVE, 0xA0 | dev->isSlave << 4);
|
outb(ctl->base + ATA_PIO_DRIVE, ATA_PIO_DRIVE_IBM | dev->isSlave? ATA_PIO_DRIVE_SLAVE: ATA_PIO_DRIVE_MASTER);
|
||||||
outb(ctl->base + ATA_PIO_CMD, ATA_PIO_CMD_IDENTIFY);
|
outb(ctl->base + ATA_PIO_CMD, ATA_PIO_CMD_IDENTIFY);
|
||||||
|
|
||||||
/* Wait for command completion (wait while busy bit is set) */
|
/* Wait for command completion (wait while busy bit is set) */
|
||||||
@ -456,11 +458,13 @@ int ATAGetDeviceInfo(struct ata_device *dev)
|
|||||||
|
|
||||||
int ATADetectController(struct ata_controller *controller)
|
int ATADetectController(struct ata_controller *controller)
|
||||||
{
|
{
|
||||||
|
|
||||||
controller->devices[0].id = 0;
|
controller->devices[0].id = 0;
|
||||||
controller->devices[0].isSlave = 0;
|
controller->devices[0].isSlave = 0;
|
||||||
controller->devices[0].ctl = controller;
|
controller->devices[0].ctl = controller;
|
||||||
controller->devices[0].type = ATADetectDevice(&controllers->devices[0]);
|
controller->devices[0].type = ATADetectDevice(&controllers->devices[0]);
|
||||||
|
|
||||||
|
|
||||||
if (controller->devices[0].type == ATA_DEV_PATA ||
|
if (controller->devices[0].type == ATA_DEV_PATA ||
|
||||||
controller->devices[0].type == ATA_DEV_SATA) {
|
controller->devices[0].type == ATA_DEV_SATA) {
|
||||||
ATAGetDeviceInfo(&controller->devices[0]);
|
ATAGetDeviceInfo(&controller->devices[0]);
|
||||||
@ -486,3 +490,36 @@ int ATAInit()
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ATARead(struct ata_device *dev, int lba, int size, void *buf)
|
||||||
|
{
|
||||||
|
struct ata_controller *ctl = dev->ctl;
|
||||||
|
uint nb_block = DIV_ROUND_UP(size, DISK_SECTOR_SIZE);
|
||||||
|
|
||||||
|
mutexLock(&ctl->mutex);
|
||||||
|
|
||||||
|
if (ctl->last_device_used != dev->id) {
|
||||||
|
outb(ctl->base + ATA_PIO_DRIVE, ATA_PIO_DRIVE_IBM | dev->isSlave << 4);
|
||||||
|
while(inb(ctl->base +ATA_PIO_STATUS)&ATA_PIO_STATUS_DRIVE_BUSY);
|
||||||
|
ctl->last_device_used = dev->id;
|
||||||
|
}
|
||||||
|
outb(ctl->base + ATA_PIO_DRIVE, lba >> 24 | ATA_PIO_DRIVE_IBM | ATA_PIO_DRIVE_LBA);
|
||||||
|
outb(ctl->base + ATA_PIO_SEC_COUNT, nb_block);
|
||||||
|
outb(ctl->base + ATA_PIO_LBALO, lba & 0xff);
|
||||||
|
outb(ctl->base + ATA_PIO_LBAMID, (lba >> 8) & 0xff);
|
||||||
|
outb(ctl->base + ATA_PIO_LBAHI, (lba >> 16) & 0xff);
|
||||||
|
|
||||||
|
uint16_t *ptr = (uint16_t *)buf;
|
||||||
|
for(uint block = 0; block < nb_block ; block ++){
|
||||||
|
while(inb(ctl->base +ATA_PIO_STATUS)&ATA_PIO_STATUS_DRIVE_BUSY);
|
||||||
|
for(int i = 0; i< 256 && size >0; i++, size --){
|
||||||
|
*ptr = inw(ctl->base +ATA_PIO_DATA);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mutexUnlock(&ctl->mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
|
#include "synchro.h"
|
||||||
|
|
||||||
#define ATA_PIO_DATA 0
|
#define ATA_PIO_DATA 0
|
||||||
#define ATA_PIO_ERR 1
|
#define ATA_PIO_ERR 1
|
||||||
@ -16,7 +17,20 @@
|
|||||||
|
|
||||||
// cmd details
|
// cmd details
|
||||||
// https://people.freebsd.org/~imp/asiabsdcon2015/works/d2161r5-ATAATAPI_Command_Set_-_3.pdf
|
// https://people.freebsd.org/~imp/asiabsdcon2015/works/d2161r5-ATAATAPI_Command_Set_-_3.pdf
|
||||||
#define ATA_PIO_CMD_IDENTIFY 0xEC
|
#define ATA_PIO_CMD_IDENTIFY 0xEC /* get ATA params */
|
||||||
|
#define ATA_PIO_CMD_ATAPI_IDENTIFY 0xA1 /* get ATAPI params*/
|
||||||
|
#define ATA_PIO_CMD_READ 0x20 /* read command */
|
||||||
|
#define ATA_PIO_CMD_WRITE 0x30 /* write command */
|
||||||
|
#define ATA_PIO_CMD_READ_MULTI 0xC4 /* read multi command */
|
||||||
|
#define ATA_PIO_CMD_WRITE_MULTI 0xC5 /* write multi command */
|
||||||
|
#define ATA_PIO_CMD_SET_MULTI 0xC6 /* set multi size command */
|
||||||
|
#define ATA_PIO_CMD_PACKET_CMD 0xA0 /* set multi size command */
|
||||||
|
|
||||||
|
#define ATA_PIO_DRIVE_IBM 0xA0 /* bits that must be set */
|
||||||
|
#define ATA_PIO_DRIVE_LBA 0x40 /* use LBA ? */
|
||||||
|
#define ATA_PIO_DRIVE_MASTER 0x00 /* select master */
|
||||||
|
#define ATA_PIO_DRIVE_SLAVE 0x10 /* select slave */
|
||||||
|
|
||||||
|
|
||||||
#define ATA_PIO_ERROR_ADDR_MARK_NOT_FOUND 0
|
#define ATA_PIO_ERROR_ADDR_MARK_NOT_FOUND 0
|
||||||
#define ATA_PIO_ERROR_TRACK_ZERO_NOT_FOUND 1
|
#define ATA_PIO_ERROR_TRACK_ZERO_NOT_FOUND 1
|
||||||
@ -65,6 +79,8 @@ struct ata_controller {
|
|||||||
int16_t dev_ctl;
|
int16_t dev_ctl;
|
||||||
int present;
|
int present;
|
||||||
struct ata_device devices[MAX_ATA_DEVICES];
|
struct ata_device devices[MAX_ATA_DEVICES];
|
||||||
|
struct mutex mutex;
|
||||||
|
int last_device_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
int ATAInit();
|
int ATAInit();
|
||||||
|
Loading…
Reference in New Issue
Block a user