From 684fc27f6389f44102b5a3b31f62badc35a9a9ce Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Wed, 1 Apr 2015 20:32:27 -0400 Subject: as of 2013-12-04 --- io.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 io.c (limited to 'io.c') diff --git a/io.c b/io.c new file mode 100644 index 0000000..aa9b027 --- /dev/null +++ b/io.c @@ -0,0 +1,192 @@ +/* + * IO functionality + * for MPX-OS + * Ben Burwell & Averill Morash + * CSI350 - Fall 2013 + */ + +#include +#include +#include "mpx.h" + +#define DS_OFFSET 6 // was 3 before + +int count = 0; +void IO_sup(pcb *p) { + char far *buffer; + int far *length; + unsigned *ds_add; + int con_w = 0; + int rc; + + disable(); + + if (DEBUG_PRINTS) { printf("in io_sup \n");} + + //make the far pointers (see page 107) + ds_add = p->stack_ptr + DS_OFFSET; + buffer = MK_FP(*ds_add, p->parm_add->buffer); + length = MK_FP(*ds_add, p->parm_add->length); + + //call com_read or equivalent + switch (p->parm_add->op_number){ + case COM: + // IO_sched should have validated input + // Assume that op_type is either read or write + if (p->parm_add->op_type == READ) { + if (DEBUG_PRINTS){printf("com read req \n");} + com_eflag = 0; + rc = com_read(buffer, length); + } else { + if (DEBUG_PRINTS) {printf("com write req \n");} + com_eflag = 0; + rc = com_write(buffer, length); + } + break; + case CON: + if (p->parm_add->op_type == READ) { + if (DEBUG_PRINTS){printf("con read req\n");} + con_eflag = 0; + con.current_op = READ_OP; + rc = con_read(buffer, length); + } else { + if (DEBUG_PRINTS){printf("con_write req\n");} + con_w = 1; + rc = con_write(buffer, length); + } + break; + case PRT: + if (DEBUG_PRINTS){printf("prt write req\n");} + prt_eflag = 0; + rc = prt_write(buffer, length); + break; + } + + if (rc < 0) { + printf("Somthing went wrong in io_sup\n"); + } + + // put the pcb back in the ready queue, if it was a con_write + if (con_w == 1) { + insert_pcb(&ready_queue_locked, p,0); + } + enable(); + return; +} + +// Handle completion of an IO request +int IO_complete(int device, int *stk_ptr) { + + pcb *current; + dcb *d; + + disable(); + switch (device){ + case CON: + d = &con; + d->current_op = NO_OP; + break; + case COM: + d = &com; + break; + case PRT: + d = &prt; + break; + } + + if (DEBUG_PRINTS){printf("in io complete\n");} + + // save interrupted process's stack pointer + cop->stack_ptr = stk_ptr; + + // insert running process into ready queue + insert_pcb(&ready_queue_locked, cop, 0); + + // set running process to ready state + cop->state = READY; + + // get address of PCB whose IO just completed + current = d->current_pcb; + + // insert into ready queue + insert_pcb(&ready_queue_locked, current, 0); + + // set its state to ready + current->state = READY; + + if (strcmp(d->current_pcb->name, "iocom2")==0) { + count++; + if (count > 20) { + d = &com; + } + } + if (d->pcb_head != NULL) { + // if there are pending IO requests for this device + //schedule them (IO_sched) + remove_pcb(&(d->pcb_head), d->pcb_head); + IO_sched(d->pcb_head); + } + + outportb(0x20,0x20); // EOI signal + enable(); + dispatch(); + + return 0; +} + +// Service an IO request +// Returns: +// 0 for success +// -1 for invalid operation +// -2 for invalid device +int IO_sched(pcb *p) { + + dcb *d; + int op_num; + int op_type; + + if (DEBUG_PRINTS) {printf("in io sched\n");} + + // determine which device is requested + op_num = p->parm_add->op_number; + op_type = p->parm_add->op_type; + + switch (op_num) { + case CON: + if (op_type != READ + && op_type != WRITE) { + return -1; + } + d = &con; + break; + case COM: + if (op_type != READ + && op_type != WRITE) { + return -1; + } + d = &com; + break; + case PRT: + if (op_type != WRITE) { + return -1; + } + d = &prt; + break; + default: + return -2; + } + + if (d->current_op != NO_OP) { + disable(); + // put pcb in IO queue + insert_pcb(&(d->pcb_head), p, 1); + // take pcb out of ready q + remove_pcb(&ready_queue_locked, p); + enable(); + } else { + d->current_pcb = p; + IO_sup(p); + } + + return 0; +} -- cgit v1.2.3