int dsk1interrupt(void) { request_desc_p target, prev; disk_desc *ptr; int ticks; double seek_time, rotate_time, transfer_time; STATWORD ps; disable(ps); ptr = (disk_desc *)devtab[DISK1].dvioblk; if(!ptr) { restore(ps); return SYSERR; } if(!ptr -> request_head) { disk1_preempt = MAXINT; restore(ps); return OK; } for(target = ptr -> request_head, prev = NULL;target -> next;prev = target, target = target -> next); if(prev != NULL) prev -> next = NULL; else ptr -> request_head = NULL; if(target -> type == READ_OPERATION) { ptr -> no_of_reads++; memncpy(target -> buffer, ptr -> disk + target -> block_no * ptr -> block_size, ptr -> block_size * target -> count); } else { ptr -> no_of_writes++; memncpy(ptr -> disk + target -> block_no * ptr -> block_size, target -> buffer, ptr -> block_size * target -> count); } ptr -> head_sector = target -> block_no + target -> count; ready(target -> process_id, RESCHNO); freemem(target, sizeof(request_desc)); // Disk Schedule dskschedule(ptr, PA4_DISK_SCHEDULE); if(ptr -> request_head) { for(target = ptr -> request_head;target -> next;target = target -> next); calculate_time(ptr, target -> block_no, &seek_time, &rotate_time); calculate_transfer_time(ptr, target -> block_no, target -> count, &transfer_time); ticks = ms_to_ticks(seek_time + rotate_time + transfer_time); target -> ticks = ticks; disk1_preempt = ticks; } else disk1_preempt = MAXINT; restore(ps); return OK; }
/* * dskread() is responsible for serving each read request. * It does: * check simple parameter integrity, * calculate seek time, rotate time, and transfer time * insert the current request into each queue * schedule the interrupt related to this request * make the current process into block state. * This function supports multiple continuous blocks. * Please notice that when calling this function, block_no + count does not have to * exceed the last block number. This function does not guarantee that block_no + count * does not exceed. * parameter: * pdev: device descriptor * buffer: a buffer to store read blocks * block_no: the start block number to be read * count: the number of continuous blocks to be read */ int dskread(struct devsw *pdev, char *buffer, int block_no, int count) { disk_desc *ptr; double seek_time = 0.0; double rotate_time = 0.0; double read_time = 0.0; int code, ticks; request_desc_p request; STATWORD ps; disable(ps); if(!pdev || !buffer || count <= 0) { restore(ps); return SYSERR; } ptr = (disk_desc *)pdev -> dvioblk; if(block_no < 0 || block_no + count > ptr -> logical_blocks) { restore(ps); return SYSERR; } request = (request_desc_p)getmem(sizeof(request_desc)); if(request == (request_desc_p)SYSERR) { restore(ps); return (int)request; } if(!ptr -> request_head) { calculate_time(ptr, block_no, &seek_time, &rotate_time); calculate_transfer_time(ptr, block_no, count, &read_time); ticks = ms_to_ticks(seek_time + rotate_time + read_time); if(pdev == &devtab[DISK0]) disk0_preempt = ticks; else if(pdev == &devtab[DISK1]) disk1_preempt = ticks; request -> ticks = ticks; } //kprintf("\n------------dsk read\n"); request -> type = READ_OPERATION; request -> block_no = block_no; request -> process_id = currpid; request -> buffer = buffer; request -> count = count; request -> next = ptr -> request_head; ptr -> request_head = request; //kprintf("\n req buf is %s\n", request->buffer); restore(ps); if(dskresched() == SYSERR) { return SYSERR; } return OK; }