ata #2
@ -383,17 +383,19 @@ static struct ata_controller controllers[MAX_ATA_CONTROLLER] = {{
|
||||
.base = 0x1F0,
|
||||
.dev_ctl = 0x3F6,
|
||||
.present = 0,
|
||||
.last_device_used = -1,
|
||||
},
|
||||
{
|
||||
.id = 1,
|
||||
.base = 0x170,
|
||||
.dev_ctl = 0x376,
|
||||
.present = 0,
|
||||
.last_device_used = -1,
|
||||
}};
|
||||
int ATADetectDevice(struct ata_device *dev)
|
||||
{
|
||||
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);
|
||||
if (st & ATA_PIO_STATUS_DRIVE_BUSY)
|
||||
goto no_disk;
|
||||
@ -425,7 +427,7 @@ int ATAGetDeviceInfo(struct ata_device *dev)
|
||||
struct ata_controller *ctl = dev->ctl;
|
||||
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);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
||||
controller->devices[0].id = 0;
|
||||
controller->devices[0].isSlave = 0;
|
||||
controller->devices[0].ctl = controller;
|
||||
controller->devices[0].type = ATADetectDevice(&controllers->devices[0]);
|
||||
|
||||
|
||||
if (controller->devices[0].type == ATA_DEV_PATA ||
|
||||
controller->devices[0].type == ATA_DEV_SATA) {
|
||||
ATAGetDeviceInfo(&controller->devices[0]);
|
||||
@ -486,3 +490,36 @@ int ATAInit()
|
||||
}
|
||||
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
|
||||
#include "stdarg.h"
|
||||
#include "synchro.h"
|
||||
|
||||
#define ATA_PIO_DATA 0
|
||||
#define ATA_PIO_ERR 1
|
||||
@ -16,7 +17,20 @@
|
||||
|
||||
// cmd details
|
||||
// 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_TRACK_ZERO_NOT_FOUND 1
|
||||
@ -65,6 +79,8 @@ struct ata_controller {
|
||||
int16_t dev_ctl;
|
||||
int present;
|
||||
struct ata_device devices[MAX_ATA_DEVICES];
|
||||
struct mutex mutex;
|
||||
int last_device_used;
|
||||
};
|
||||
|
||||
int ATAInit();
|
||||
|
Loading…
Reference in New Issue
Block a user