minix/lib/libblockdriver/driver_st.c
David van Moolenbroek fd4c2b74f3 Add block device tracing facility
The implementation is in libblockdriver, and works transparently for
all block drivers. The new btrace(8) tool can be used to control block
tracing; see ``man btrace'' for details.
2011-11-25 13:47:21 +01:00

98 lines
3.1 KiB
C

/* This file contains the singlethreaded device driver interface.
*
* Changes:
* Aug 27, 2011 extracted from driver.c (A. Welzel)
*
* The entry points into this file are:
* blockdriver_task: the main message loop of the driver
* blockdriver_terminate: break out of the main message loop
* blockdriver_handle_msg: handle a single received message
* blockdriver_receive_mq: message receive interface with message queueing
* blockdriver_mq_queue: queue an incoming message for later processing
*/
#include <minix/drivers.h>
#include <minix/blockdriver.h>
#include "driver.h"
#include "mq.h"
PRIVATE int running;
/*===========================================================================*
* blockdriver_receive_mq *
*===========================================================================*/
PUBLIC int blockdriver_receive_mq(message *m_ptr, int *status_ptr)
{
/* receive() interface for drivers with message queueing. */
/* Any queued messages? */
if (mq_dequeue(SINGLE_THREAD, m_ptr, status_ptr))
return OK;
/* Fall back to standard receive() interface otherwise. */
return driver_receive(ANY, m_ptr, status_ptr);
}
/*===========================================================================*
* blockdriver_terminate *
*===========================================================================*/
PUBLIC void blockdriver_terminate(void)
{
/* Break out of the main driver loop after finishing the current request. */
running = FALSE;
}
/*===========================================================================*
* blockdriver_task *
*===========================================================================*/
PUBLIC void blockdriver_task(struct blockdriver *bdp)
{
/* Main program of any block device driver task. */
int r, ipc_status;
message mess;
running = TRUE;
/* Here is the main loop of the disk task. It waits for a message, carries
* it out, and sends a reply.
*/
while (running) {
if ((r = blockdriver_receive_mq(&mess, &ipc_status)) != OK)
panic("blockdriver_receive_mq failed: %d", r);
blockdriver_process(bdp, &mess, ipc_status);
}
}
/*===========================================================================*
* 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);
}
}
/*===========================================================================*
* blockdriver_mq_queue *
*===========================================================================*/
PUBLIC int blockdriver_mq_queue(message *m, int status)
{
/* Queue a message for later processing. */
return mq_enqueue(SINGLE_THREAD, m, status);
}