aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/dev/pciide.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-03-04 11:51:30 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-03-04 11:51:30 +0100
commit503f176e001ddf15e6e32bc912cf10b5764bc23b (patch)
tree2595bc45e582df3ede9241c00656b65866301e38 /src/kernel/dev/pciide.c
parent0934f9943ef7bdec8c2eee3ea31b5e0f1e8a3faf (diff)
downloadkogata-503f176e001ddf15e6e32bc912cf10b5764bc23b.tar.gz
kogata-503f176e001ddf15e6e32bc912cf10b5764bc23b.zip
Process exiting & thread termination. IMPORTANT NOTE FOLLOWS.
Threads may now communicate via wait_on(void* ressource) and resume_on (void* ressource). Previous pause() is replaced by wait_on(current_thread) and resume(thread) by resume_on(thread). wait_on(x) may return false, indicating that the reason for returning is NOT that resume_on(x) was called but something else happenned. Typically false indicates that the curent thread is being killed and must terminate its kernel-land processing as soon as possible.
Diffstat (limited to 'src/kernel/dev/pciide.c')
-rw-r--r--src/kernel/dev/pciide.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/kernel/dev/pciide.c b/src/kernel/dev/pciide.c
index 05c0b28..c357190 100644
--- a/src/kernel/dev/pciide.c
+++ b/src/kernel/dev/pciide.c
@@ -144,6 +144,8 @@ static uint8_t ide_print_error(ide_controller_t *c, int drive, uint8_t err) {
} else if (err == 4) {
dbg_printf("- Write Protected\n ");
err = 8;
+ } else if (err == 5) {
+ dbg_printf("- Interrupted\n ");
}
dbg_printf("- [%s %s] %s\n",
(const char *[]){"Primary", "Secondary"}[c->devices[drive].channel],
@@ -167,7 +169,7 @@ void irq14_handler(registers_t *regs) {
if (wait_irq14) {
thread_t *t = wait_irq14;
wait_irq14 = 0;
- resume_thread(t);
+ resume_on(t);
}
}
@@ -175,7 +177,7 @@ void irq15_handler(registers_t *regs) {
if (wait_irq15) {
thread_t *t = wait_irq15;
wait_irq15 = 0;
- resume_thread(t);
+ resume_on(t);
}
}
@@ -183,7 +185,7 @@ void pciirq_handler(int pci_id) {
if (wait_pciirq) {
thread_t *t = wait_pciirq;
wait_pciirq = 0;
- resume_thread(t);
+ resume_on(t);
}
}
@@ -201,22 +203,26 @@ static void ide_prewait_irq(ide_controller_t *c, int channel) {
}
}
-static void ide_wait_irq(ide_controller_t *c, int channel) {
+static bool ide_wait_irq(ide_controller_t *c, int channel) {
+ bool ret = true;
+
int st = enter_critical(CL_NOINT);
int irq = c->channels[channel].irq;
if (irq == 14) {
- if (wait_irq14) pause();
+ if (wait_irq14) ret = wait_on(current_thread);
mutex_unlock(&on_irq14);
} else if (irq == 15) {
- if (wait_irq15) pause();
+ if (wait_irq15) ret = wait_on(current_thread);
mutex_unlock(&on_irq15);
} else {
- if (wait_pciirq) pause();
+ if (wait_pciirq) ret = wait_on(current_thread);
mutex_unlock(&on_pciirq);
}
exit_critical(st);
+
+ return ret;
}
// ===================================== //
@@ -352,7 +358,7 @@ static uint8_t ide_ata_access(ide_controller_t *c, int direction,
}
}
- return 0; // Easy, isn't it?
+ return 0;
}
@@ -413,7 +419,7 @@ static uint8_t ide_atapi_read(ide_controller_t *c, uint8_t drive, uint32_t lba,
// (IX): Receiving Data:
for (int i = 0; i < numsects; i++) {
- ide_wait_irq(c, channel); // Wait for an IRQ.
+ if (!ide_wait_irq(c, channel)) goto must_terminate; // Wait for an IRQ.
ide_prewait_irq(c, channel);
err = ide_polling(c, channel, 1);
if (err) return err; // Polling and return if error.
@@ -423,12 +429,17 @@ static uint8_t ide_atapi_read(ide_controller_t *c, uint8_t drive, uint32_t lba,
}
// (X): Waiting for an IRQ:
- ide_wait_irq(c, channel);
+ if (!ide_wait_irq(c, channel)) goto must_terminate;
// (XI): Waiting for BSY & DRQ to clear:
while (ide_read(c, channel, ATA_REG_STATUS) & (ATA_SR_BSY | ATA_SR_DRQ));
- return 0; // Easy, ... Isn't it?
+ return 0;
+
+must_terminate:
+ // TODO : end communication with device...
+ dbg_printf("TODO (pciide may be stuck)\n");
+ return 5;
}
static uint8_t ide_read_sectors(ide_controller_t *c, uint8_t drive,