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;
}