Example #1
0
/*===========================================================================*
 *				blockdriver_process			     *
 *===========================================================================*/
PUBLIC void blockdriver_process(struct blockdriver *bdp, message *m_ptr,
  int ipc_status)
{
/* Handle the given received message. */
  int r;

  /* Process the notification or request. */
  if (is_ipc_notify(ipc_status)) {
	blockdriver_handle_notify(bdp, m_ptr);

	/* Do not reply to notifications. */
  } else {
	r = blockdriver_handle_request(bdp, m_ptr, SINGLE_THREAD);

	blockdriver_reply(m_ptr, ipc_status, r);
  }
}
Example #2
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);
}