Example #1
0
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
int main(int argc, char *argv[])
{
	message m_out;
	int r, ipc_status;
	size_t size;

	/* SEF local startup. */
	env_setargs(argc, argv);
	sef_local_startup();

	for (;;) {
		/* Wait for request. */
		if(driver_receive(ANY, &m_in, &ipc_status) != OK) {
			panic("driver_receive failed");
		}

#if DEBUG2
		printf("Filter: got request %d from %d\n",
			m_in.m_type, m_in.m_source);
#endif

		if(m_in.m_source == DS_PROC_NR && is_ipc_notify(ipc_status)) {
			ds_event();
			continue;
		}

		who_e = m_in.m_source;
		req_id = m_in.BDEV_ID;
		grant_id = m_in.BDEV_GRANT;
		size = 0;

		/* Forword the request message to the drivers. */
		switch(m_in.m_type) {
		case BDEV_OPEN:		/* open/close is a noop for filter. */
		case BDEV_CLOSE:	r = OK;				break;
		case BDEV_READ:		r = do_rdwt(FLT_READ);		break;
		case BDEV_WRITE:	r = do_rdwt(FLT_WRITE);		break;
		case BDEV_GATHER:	r = do_vrdwt(FLT_READ);		break;
		case BDEV_SCATTER:	r = do_vrdwt(FLT_WRITE);	break;
		case BDEV_IOCTL:	r = do_ioctl(&m_in);		break;

		default:
			printf("Filter: ignoring unknown request %d from %d\n", 
				m_in.m_type, m_in.m_source);
			continue;
		}

#if DEBUG2
		printf("Filter: replying with code %d\n", r);
#endif

		/* Send back reply message. */
		m_out.m_type = BDEV_REPLY;
		m_out.BDEV_ID = req_id;
		m_out.BDEV_STATUS = r;
		send(who_e, &m_out);
	}

	return 0;
}
Example #2
0
/*===========================================================================*
 *				floppy_task				     * 
 *===========================================================================*/
PUBLIC floppy_task()
{
/* Main program of the floppy disk driver task. */

  int r, caller, proc_nr;

  /* Here is the main loop of the disk task.  It waits for a message, carries
   * it out, and sends a reply.
   */
  while (TRUE) {
	/* First wait for a request to read or write a disk block. */
	receive(ANY, &mess);	/* get a request to do some work */
	if (mess.m_source < 0)
		panic("disk task got message from ", mess.m_source);
	caller = mess.m_source;
	proc_nr = mess.PROC_NR;

	/* Now carry out the work. */
	switch(mess.m_type) {
	    case DISK_READ:	r = do_rdwt(&mess);	break;
	    case DISK_WRITE:	r = do_rdwt(&mess);	break;
	    default:		r = EINVAL;		break;
	}

	/* Finally, prepare and send the reply message. */
	mess.m_type = TASK_REPLY;	
	mess.REP_PROC_NR = proc_nr;
	mess.REP_STATUS = r;	/* # of bytes transferred or error code */
	send(caller, &mess);	/* send reply to caller */
  }
}
/*===========================================================================*
 *				driver_task				     *
 *===========================================================================*/
PUBLIC void driver_task(void)
{
	/* Main program of any device driver task. */

	int r;
	message mess;

	/* Here is the main loop of the disk task.  It waits for a message, carries
	* it out, and sends a reply.
	*/
	while (TRUE) {
		printf("CD: waiting for messages\n");
		/* Wait for a request to read or write a disk block. */
		if(receive(ANY, &mess) != OK) continue;
	
		device_caller = mess.m_source;
        proc_nr = mess.PROC_NR;
        
		printf("CD: message from %u, type %u\n",device_caller,proc_nr,mess.m_type);
		/* Now carry out the work. */
		
		switch(mess.m_type) {
				case DEV_OPEN:		
				case DEV_CLOSE:			
				case CANCEL:		
				case DEV_SELECT:	
					/* forwards message to diskdriver and  forwards response to caller*/
					mess.m_source = thispid; /*make this the source*/
					if(OK != sendrec(DRVR_PROC_NR, &mess))
						panic("CryptcDrive","2 Message not sent back",s);
					printf("CD: waiting for diskdriver\n");	
					
					mess.m_source = thispid; /*make this the source*/
					if(OK != send(device_caller, &mess))
						panic("CryptDrive","3 Message not sent back",s);
					printf("CD: message to %u\n",device_caller);
					break;
					
				case DEV_IOCTL:	
						doioctl(&mess);

				case DEV_READ:	
				case DEV_WRITE:	 		
						do_rdwt(&mess);
						break;
				case DEV_GATHER: 
				case DEV_SCATTER:
						do_vrdwt(&mess);				
						break;

				case HARD_INT:
				case SYS_SIG:
				case SYN_ALARM:	break;	/* don't reply */
				
			
		}
	}
}
Example #4
0
/*===========================================================================*
 *				blockdriver_handle_request		     *
 *===========================================================================*/
int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr,
	thread_id_t id)
{
/* Call the appropiate driver function, based on the type of request. Return
 * the result code that is to be sent back to the caller, or EDONTREPLY if no
 * reply is to be sent.
 */
  int r;

  /* We might get spurious requests if the driver has been restarted. Deny any
   * requests on devices that have not previously been opened, signaling the
   * caller that something went wrong.
   */
  if (IS_BDEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->BDEV_MINOR)) {
	/* Reply ERESTART to spurious requests for unopened devices. */
	if (m_ptr->m_type != BDEV_OPEN)
		return ERESTART;

	/* Mark the device as opened otherwise. */
	set_open_dev(m_ptr->BDEV_MINOR);
  }

  trace_start(id, m_ptr);

  /* Call the appropriate function(s) for this request. */
  switch (m_ptr->m_type) {
  case BDEV_OPEN:	r = do_open(bdp, m_ptr);	break;
  case BDEV_CLOSE:	r = do_close(bdp, m_ptr);	break;
  case BDEV_READ:
  case BDEV_WRITE:	r = do_rdwt(bdp, m_ptr);	break;
  case BDEV_GATHER:
  case BDEV_SCATTER:	r = do_vrdwt(bdp, m_ptr, id);	break;
  case BDEV_IOCTL:	r = do_ioctl(bdp, m_ptr);	break;
  default:
	if (bdp->bdr_other)
		r = bdp->bdr_other(m_ptr);
	else
		r = EINVAL;
  }

  /* Let the driver perform any cleanup. */
  if (bdp->bdr_cleanup != NULL)
	(*bdp->bdr_cleanup)();

  trace_finish(id, r);

  return r;
}
Example #5
0
/*===========================================================================*
 *				handle_request				     *
 *===========================================================================*/
static int handle_request(struct chardriver *cdp, message *m_ptr)
{
/* Call the appropiate driver function, based on the type of request. Return
 * the result code that is to be sent back to the caller, or EDONTREPLY if no
 * reply is to be sent.
 */
  int r;

  /* We might get spurious requests if the driver has been restarted. Deny any
   * requests on devices that have not previously been opened, signaling the
   * caller that something went wrong.
   */
  if (IS_CDEV_MINOR_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) {
	/* Reply ERESTART to spurious requests for unopened devices. */
	if (m_ptr->m_type != DEV_OPEN)
		return ERESTART;

	/* Mark the device as opened otherwise. */
	set_open_dev(m_ptr->DEVICE);
  }

  /* Call the appropriate function(s) for this request. */
  switch (m_ptr->m_type) {
  case DEV_OPEN:	r = (*cdp->cdr_open)(m_ptr);	break;
  case DEV_CLOSE:	r = (*cdp->cdr_close)(m_ptr);	break;
  case DEV_IOCTL_S:	r = (*cdp->cdr_ioctl)(m_ptr);	break;
  case CANCEL:		r = (*cdp->cdr_cancel)(m_ptr);	break;
  case DEV_SELECT:	r = (*cdp->cdr_select)(m_ptr);	break;
  case DEV_READ_S:
  case DEV_WRITE_S:	r = do_rdwt(cdp, m_ptr);	break;
  case DEV_GATHER_S:
  case DEV_SCATTER_S:	r = do_vrdwt(cdp, m_ptr);	break;
  default:
	if (cdp->cdr_other)
		r = cdp->cdr_other(m_ptr);
	else
		r = EINVAL;
  }

  /* Let the driver perform any cleanup. */
  if (cdp->cdr_cleanup)
	(*cdp->cdr_cleanup)();

  return r;
}
Example #6
0
/**************************************************************************************************
 * 					task_fs
 **************************************************************************************************
 * <Ring 1> Main loop of Task FS.
 *************************************************************************************************/
PUBLIC void task_fs(){
	init_fs();

	while(TRUE){
		send_recv(RECEIVE, ANY, &fs_msg);
		int src	= fs_msg.source;
		pcaller	= &proc_table[src];

		switch(fs_msg.type){
			case OPEN:
			fs_msg.FD	= do_open();
			break;
		case CLOSE:
			fs_msg.RETVAL	= do_close();
			break;
		case READ:
		case WRITE:
			fs_msg.CNT	= do_rdwt();
			break;
		case UNLINK:
			fs_msg.RETVAL	= do_unlink();
			break;
		case RESUME_PROC:
			src = fs_msg.PROC_NR;
			break;
		case FORK:
			fs_msg.RETVAL	= fs_fork();
			break;
		default:
			dump_msg("FS::unkown message:", &fs_msg);
			assert(0);
			break;
		}
		/* reply */
		if(fs_msg.type != SUSPEND_PROC){
			fs_msg.type	= SYSCALL_RET;
			send_recv(SEND, src, &fs_msg);
		}
	}
	spin("FS");
}
Example #7
0
/*===========================================================================*
 *				floppy_task				     *
 *===========================================================================*/
PUBLIC void floppy_task()
{
  register r, drive, caller, procno;

  /*
   * The main loop of the disk task.
   * It waits for a message, carries it out, and sends a reply.
   */
  TRACE(printf("fd: task started\n"));
  dmagrab(FLOPPY, fdcint);
  dmawdat(FDC_CS, IRUPT, FDC_DELAY);		/* reset controller */
  dmafree(FLOPPY);
  for (drive = 0; drive < NR_FLOPDRIVES; drive++)
	curcyl[drive] = -1;	/* uncalibrated */
  while (TRUE) {
	receive(ANY, &mess);
	ASSERT(mess.m_source >= 0);
	TRACE(printf("fd: received %d from %d\n",mess.m_type,mess.m_source));
	caller = mess.m_source;
	procno = mess.PROC_NR;

	/* Now carry out the work. */
	switch (mess.m_type) {
	    case DISK_READ:
	    case DISK_WRITE:	r = do_rdwt(&mess);	break;
	    case SCATTERED_IO:	r = do_vrdwt(&mess, do_rdwt); break;
	    default:		r = EINVAL;		break;
	}

	/* Finally, prepare and send the reply message. */
	mess.m_type = TASK_REPLY;	
	mess.REP_PROC_NR = procno;
	mess.REP_STATUS = r;	/* # of bytes transferred or error code */
	send(caller, &mess);	/* send reply to caller */
  }
}
Example #8
0
/*===========================================================================*
 *				blockdriver_process_on_thread		     *
 *===========================================================================*/
void blockdriver_process_on_thread(struct blockdriver *bdp, message *m_ptr,
	int ipc_status, thread_id_t id)
{
/* Call the appropiate driver function, based on the type of request. Send
 * a result code to the caller. The call is processed in the context of the
 * given thread ID, which may be SINGLE_THREAD for single-threaded callers.
 */
  int r;

  /* Check for notifications first. We never reply to notifications. */
  if (is_ipc_notify(ipc_status)) {
	switch (_ENDPOINT_P(m_ptr->m_source)) {
	case HARDWARE:
		if (bdp->bdr_intr)
			(*bdp->bdr_intr)(m_ptr->m_notify.interrupts);
		break;

	case CLOCK:
		if (bdp->bdr_alarm)
			(*bdp->bdr_alarm)(m_ptr->m_notify.timestamp);
		break;

	default:
		if (bdp->bdr_other)
			(*bdp->bdr_other)(m_ptr, ipc_status);
	}

	return; /* do not send a reply */
  }

  /* Reply to character driver open requests with an error code. Otherwise, if
   * someone creates a character device node for a block driver, opening that
   * device node will cause the corresponding VFS thread to block forever.
   */
  if (m_ptr->m_type == CDEV_OPEN) {
	do_char_open(m_ptr, ipc_status);

	return;
  }

  /* We might get spurious requests if the driver has been restarted. Deny any
   * requests on devices that have not previously been opened, signaling the
   * caller that something went wrong.
   */
  if (IS_BDEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->m_lbdev_lblockdriver_msg.minor)) {
	/* Reply ERESTART to spurious requests for unopened devices. */
	if (m_ptr->m_type != BDEV_OPEN) {
		blockdriver_reply(m_ptr, ipc_status, ERESTART);

		return;
	}

	/* Mark the device as opened otherwise. */
	set_open_dev(m_ptr->m_lbdev_lblockdriver_msg.minor);
  }

  trace_start(id, m_ptr);

  /* Call the appropriate function(s) for this request. */
  switch (m_ptr->m_type) {
  case BDEV_OPEN:	r = do_open(bdp, m_ptr);	break;
  case BDEV_CLOSE:	r = do_close(bdp, m_ptr);	break;
  case BDEV_READ:
  case BDEV_WRITE:	r = do_rdwt(bdp, m_ptr);	break;
  case BDEV_GATHER:
  case BDEV_SCATTER:	r = do_vrdwt(bdp, m_ptr, id);	break;
  case BDEV_IOCTL:	r = do_ioctl(bdp, m_ptr);	break;
  default:
	if (bdp->bdr_other != NULL)
		(*bdp->bdr_other)(m_ptr, ipc_status);

	return;	/* do not send a reply */
  }

  /* Let the driver perform any cleanup. */
  if (bdp->bdr_cleanup != NULL)
	(*bdp->bdr_cleanup)();

  trace_finish(id, r);

  blockdriver_reply(m_ptr, ipc_status, r);
}
Example #9
0
/**
 * <Ring 1> The main loop of TASK FS.
 * 
 *****************************************************************************/
PUBLIC void task_fs()
{
	printl("{FS} Task FS begins.\n");

	init_fs();

	while (1) {
		send_recv(RECEIVE, ANY, &fs_msg);

		int msgtype = fs_msg.type;
		int src = fs_msg.source;
		pcaller = &proc_table[src];

		switch (msgtype) {
		case OPEN:
			fs_msg.FD = do_open();
			break;
		case CLOSE:
			fs_msg.RETVAL = do_close();
			break;
		case READ:
		case WRITE:
			fs_msg.CNT = do_rdwt();
			break;
		case UNLINK:
			fs_msg.RETVAL = do_unlink();
			break;
		case RESUME_PROC:
			src = fs_msg.PROC_NR;
			break;
		case FORK:
			fs_msg.RETVAL = fs_fork();
			break;
		case EXIT:
			fs_msg.RETVAL = fs_exit();
			break;
		/* case LSEEK: */
		/* 	fs_msg.OFFSET = do_lseek(); */
		/* 	break; */
		case STAT:
			fs_msg.RETVAL = do_stat();
			break;
		default:
			dump_msg("FS::unknown message:", &fs_msg);
			assert(0);
			break;
		}

#ifdef ENABLE_DISK_LOG
		char * msg_name[128];
		msg_name[OPEN]   = "OPEN";
		msg_name[CLOSE]  = "CLOSE";
		msg_name[READ]   = "READ";
		msg_name[WRITE]  = "WRITE";
		msg_name[LSEEK]  = "LSEEK";
		msg_name[UNLINK] = "UNLINK";
		/* msg_name[FORK]   = "FORK"; */
		/* msg_name[EXIT]   = "EXIT"; */
		/* msg_name[STAT]   = "STAT"; */

		switch (msgtype) {
		case UNLINK:
			dump_fd_graph("%s just finished. (pid:%d)",
				      msg_name[msgtype], src);
			//panic("");
		case OPEN:
		case CLOSE:
		case READ:
		case WRITE:
		case FORK:
		case EXIT:
		/* case LSEEK: */
		case STAT:
			break;
		case RESUME_PROC:
			break;
		default:
			assert(0);
		}
#endif

		/* reply */
		if (fs_msg.type != SUSPEND_PROC) {
			fs_msg.type = SYSCALL_RET;
			send_recv(SEND, src, &fs_msg);
		}
	}
}
Example #10
0
PUBLIC void task_fs()
{
    printl("Task FS begins.\n");

    init_fs();

    while (1) {
        send_recv(RECEIVE, ANY, &fs_msg);

        int src = fs_msg.source;
        pcaller = &proc_table[src];

        switch (fs_msg.type) {
            case OPEN:
                fs_msg.FD = do_open();
                break;

            case CLOSE:
                fs_msg.RETVAL = do_close();
                break;

            case READ:
            case WRITE:
                fs_msg.CNT = do_rdwt();
                break;

            case UNLINK:
                fs_msg.RETVAL = do_unlink();
                break;

            case RESUME_PROC:
                src = fs_msg.PROC_NR; // 恢复最初请求的进程,如 TestB
                break;

            case FORK:
                fs_msg.RETVAL = fs_fork();
                break;

            case EXIT:
                fs_msg.RETVAL = fs_exit();
                break;

            case STAT:
                fs_msg.RETVAL = do_stat();
                break;

            default:
                dump_msg("FS::unknown message:", &fs_msg);
                assert(0);
                break;
        }

        /* 如果发送者要求挂起,则不回送消息 */
        if (fs_msg.type != SUSPEND_PROC) {
            fs_msg.type = SYSCALL_RET;
            send_recv(SEND, src, &fs_msg);
        }
    }

    spin("FS");
}