Cleanup and locking for the IDE driver.
This commit is contained in:
parent
ff2be2e406
commit
b8b91d3e33
@ -1,4 +1,5 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/kassert.h>
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/spinlock.h>
|
||||
@ -23,7 +24,7 @@ Console_Init()
|
||||
|
||||
Console_Puts("Castor Operating System\n");
|
||||
|
||||
Spinlock_Init(&consoleLock, "Console");
|
||||
Spinlock_Init(&consoleLock, "Console Lock");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <sys/kassert.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/spinlock.h>
|
||||
#include <sys/disk.h>
|
||||
|
||||
#include "ioport.h"
|
||||
@ -57,6 +58,7 @@ typedef struct IDE
|
||||
{
|
||||
uint16_t base; // Base Port
|
||||
uint16_t devctl; // Device Control
|
||||
Spinlock lock;
|
||||
} IDE;
|
||||
|
||||
typedef struct IDEDrive
|
||||
@ -75,23 +77,26 @@ int IDE_Write(Disk *disk, void *buf, SGArray *sga, DiskCB, void *arg);
|
||||
int IDE_Flush(Disk *disk, void *buf, SGArray *sga, DiskCB, void *arg);
|
||||
int IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len);
|
||||
|
||||
IDE primary;
|
||||
IDEDrive primaryDrives[2];
|
||||
|
||||
void
|
||||
IDE_Init()
|
||||
{
|
||||
IDE ide;
|
||||
|
||||
ASSERT(sizeof(ATAIdentifyDevice) == 512);
|
||||
|
||||
ide.base = IDE_PRIMARY_BASE;
|
||||
ide.devctl = IDE_PRIMARY_DEVCTL;
|
||||
primary.base = IDE_PRIMARY_BASE;
|
||||
primary.devctl = IDE_PRIMARY_DEVCTL;
|
||||
Spinlock_Init(&primary.lock, "IDE Primary Controller Lock");
|
||||
|
||||
if (!IDE_HasController(&ide)) {
|
||||
if (!IDE_HasController(&primary)) {
|
||||
kprintf("IDE: No controller detected\n");
|
||||
return;
|
||||
}
|
||||
IDE_Reset(&ide);
|
||||
IDE_Identify(&ide, 0);
|
||||
IDE_Identify(&ide, 1);
|
||||
|
||||
IDE_Reset(&primary);
|
||||
IDE_Identify(&primary, 0);
|
||||
IDE_Identify(&primary, 1);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -207,13 +212,18 @@ IDE_Identify(IDE *ide, int drive)
|
||||
kprintf("IDE: Drive %d %llu Sectors (%llu MBs)\n",
|
||||
drive, ident.lbaSectors, ident.lbaSectors / 2048ULL);
|
||||
|
||||
primaryDrives[drive].ide = &primary;
|
||||
primaryDrives[drive].drive = drive;
|
||||
primaryDrives[drive].lba48 = (ident.lbaSectors > (1 << 24));
|
||||
primaryDrives[drive].size = ident.lbaSectors;
|
||||
|
||||
// Register Disk
|
||||
Disk *disk = PAlloc_AllocPage();
|
||||
if (!disk) {
|
||||
Panic("IDE: No memory!\n");
|
||||
}
|
||||
|
||||
disk->handle = 0;
|
||||
disk->handle = &primaryDrives[drive];
|
||||
disk->ctrlNo = 0;
|
||||
disk->diskNo = drive;
|
||||
disk->sectorSize = IDE_SECTOR_SIZE;
|
||||
@ -231,6 +241,8 @@ IDEWaitForBusy(IDE *ide)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
ASSERT(Spinlock_IsHeld(&ide->lock));
|
||||
|
||||
while (1) {
|
||||
status = inb(ide->base + IDE_STATUS);
|
||||
if ((status & IDE_STATUS_BSY) == 0)
|
||||
@ -245,21 +257,15 @@ IDE_Read(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
||||
{
|
||||
int i;
|
||||
int status;
|
||||
IDE ide;
|
||||
IDEDrive idedrive;
|
||||
IDEDrive *idedrive;
|
||||
|
||||
ide.base = IDE_PRIMARY_BASE;
|
||||
ide.devctl = IDE_PRIMARY_DEVCTL;
|
||||
idedrive.ide = &ide;
|
||||
idedrive.drive = disk->diskNo;
|
||||
idedrive.lba48 = true;
|
||||
idedrive.size = disk->sectorCount;
|
||||
idedrive = disk->handle;
|
||||
|
||||
for (i = 0; i < sga->len; i++) {
|
||||
status = IDE_ReadOne(&idedrive,
|
||||
status = IDE_ReadOne(idedrive,
|
||||
buf,
|
||||
sga->entries[i].offset,
|
||||
sga->entries[i].length / disk->sectorSize);
|
||||
sga->entries[i].length / 512);
|
||||
buf += sga->entries[i].offset;
|
||||
if (status < 0)
|
||||
return status;
|
||||
@ -278,25 +284,23 @@ int
|
||||
IDE_Flush(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
||||
{
|
||||
uint8_t driveCode;
|
||||
IDE ide;
|
||||
IDEDrive idedrive;
|
||||
IDE *ide;
|
||||
IDEDrive *idedrive;
|
||||
|
||||
ide.base = IDE_PRIMARY_BASE;
|
||||
ide.devctl = IDE_PRIMARY_DEVCTL;
|
||||
idedrive.ide = &ide;
|
||||
idedrive.drive = disk->diskNo;
|
||||
idedrive.lba48 = true;
|
||||
idedrive.size = disk->sectorCount;
|
||||
idedrive = disk->handle;
|
||||
ide = idedrive->ide;
|
||||
|
||||
if (idedrive.drive == 0)
|
||||
if (idedrive->drive == 0)
|
||||
driveCode = 0xA0;
|
||||
else
|
||||
driveCode = 0xB0;
|
||||
|
||||
outb(ide.base + IDE_DRIVE, driveCode);
|
||||
outb(ide.base + IDE_COMMAND, IDE_CMD_FLUSH);
|
||||
Spinlock_Lock(&ide->lock);
|
||||
outb(ide->base + IDE_DRIVE, driveCode);
|
||||
outb(ide->base + IDE_COMMAND, IDE_CMD_FLUSH);
|
||||
|
||||
IDEWaitForBusy(&ide);
|
||||
IDEWaitForBusy(ide);
|
||||
Spinlock_Unlock(&ide->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -320,6 +324,7 @@ IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
||||
|
||||
ASSERT(len < 0x10000);
|
||||
|
||||
Spinlock_Lock(&ide->lock);
|
||||
outb(ide->base + IDE_DRIVE, driveCode);
|
||||
if (lba48) {
|
||||
outb(ide->base + IDE_SECTORCOUNT, len >> 8);
|
||||
@ -339,6 +344,7 @@ IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
||||
|
||||
status = IDEWaitForBusy(ide);
|
||||
if ((status & IDE_STATUS_ERR) != 0) {
|
||||
Spinlock_Unlock(&ide->lock);
|
||||
kprintf("IDE: Error trying read from drive %d\n", drive->drive);
|
||||
return -1;
|
||||
}
|
||||
@ -349,6 +355,7 @@ IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
||||
uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
|
||||
insw(ide->base, b, 256);
|
||||
}
|
||||
Spinlock_Unlock(&ide->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -370,6 +377,7 @@ IDE_WriteOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
||||
|
||||
ASSERT(len < 0x10000);
|
||||
|
||||
Spinlock_Lock(&ide->lock);
|
||||
outb(ide->base + IDE_DRIVE, driveCode);
|
||||
outb(ide->base + IDE_SECTORCOUNT, len >> 8);
|
||||
outb(ide->base + IDE_LBALOW, off >> 24);
|
||||
@ -389,9 +397,11 @@ IDE_WriteOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
||||
}
|
||||
|
||||
if ((status & IDE_STATUS_ERR) != 0) {
|
||||
Spinlock_Unlock(&ide->lock);
|
||||
kprintf("IDE: Error trying write from drive %d\n", drive);
|
||||
return;
|
||||
}
|
||||
Spinlock_Unlock(&ide->lock);
|
||||
|
||||
// XXX: Loop on outw(ide->base, b + sectorOffset);
|
||||
|
||||
|
@ -25,6 +25,7 @@ void Spinlock_Init(Spinlock *lock, const char *name);
|
||||
void Spinlock_Destroy(Spinlock *lock);
|
||||
void Spinlock_Lock(Spinlock *lock);
|
||||
void Spinlock_Unlock(Spinlock *lock);
|
||||
bool Spinlock_IsHeld(Spinlock *lock);
|
||||
|
||||
#endif /* __SPINLOCK_H__ */
|
||||
|
||||
|
@ -67,6 +67,12 @@ Spinlock_Unlock(Spinlock *lock)
|
||||
Critical_Exit();
|
||||
}
|
||||
|
||||
bool
|
||||
Spinlock_IsHeld(Spinlock *lock)
|
||||
{
|
||||
return (lock->cpu == CPU()) && (lock->lock == 1);
|
||||
}
|
||||
|
||||
void
|
||||
Debug_Spinlocks(int argc, const char *argv[])
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user