1*433d6423SLionel Sambuc /* This file contains the singlethreaded device driver interface.
2*433d6423SLionel Sambuc *
3*433d6423SLionel Sambuc * Changes:
4*433d6423SLionel Sambuc * Aug 27, 2011 extracted from driver.c (A. Welzel)
5*433d6423SLionel Sambuc *
6*433d6423SLionel Sambuc * The entry points into this file are:
7*433d6423SLionel Sambuc * blockdriver_task: the main message loop of the driver
8*433d6423SLionel Sambuc * blockdriver_terminate: break out of the main message loop
9*433d6423SLionel Sambuc * blockdriver_receive_mq: message receive interface with message queueing
10*433d6423SLionel Sambuc * blockdriver_mq_queue: queue an incoming message for later processing
11*433d6423SLionel Sambuc */
12*433d6423SLionel Sambuc
13*433d6423SLionel Sambuc #include <minix/drivers.h>
14*433d6423SLionel Sambuc #include <minix/blockdriver.h>
15*433d6423SLionel Sambuc
16*433d6423SLionel Sambuc #include "const.h"
17*433d6423SLionel Sambuc #include "driver.h"
18*433d6423SLionel Sambuc #include "mq.h"
19*433d6423SLionel Sambuc
20*433d6423SLionel Sambuc static int running;
21*433d6423SLionel Sambuc
22*433d6423SLionel Sambuc /*===========================================================================*
23*433d6423SLionel Sambuc * blockdriver_receive_mq *
24*433d6423SLionel Sambuc *===========================================================================*/
blockdriver_receive_mq(message * m_ptr,int * status_ptr)25*433d6423SLionel Sambuc int blockdriver_receive_mq(message *m_ptr, int *status_ptr)
26*433d6423SLionel Sambuc {
27*433d6423SLionel Sambuc /* receive() interface for drivers with message queueing. */
28*433d6423SLionel Sambuc
29*433d6423SLionel Sambuc /* Any queued messages? */
30*433d6423SLionel Sambuc if (mq_dequeue(SINGLE_THREAD, m_ptr, status_ptr))
31*433d6423SLionel Sambuc return OK;
32*433d6423SLionel Sambuc
33*433d6423SLionel Sambuc /* Fall back to standard receive() interface otherwise. */
34*433d6423SLionel Sambuc return driver_receive(ANY, m_ptr, status_ptr);
35*433d6423SLionel Sambuc }
36*433d6423SLionel Sambuc
37*433d6423SLionel Sambuc /*===========================================================================*
38*433d6423SLionel Sambuc * blockdriver_terminate *
39*433d6423SLionel Sambuc *===========================================================================*/
blockdriver_terminate(void)40*433d6423SLionel Sambuc void blockdriver_terminate(void)
41*433d6423SLionel Sambuc {
42*433d6423SLionel Sambuc /* Break out of the main driver loop after finishing the current request. */
43*433d6423SLionel Sambuc
44*433d6423SLionel Sambuc running = FALSE;
45*433d6423SLionel Sambuc
46*433d6423SLionel Sambuc sef_cancel();
47*433d6423SLionel Sambuc }
48*433d6423SLionel Sambuc
49*433d6423SLionel Sambuc /*===========================================================================*
50*433d6423SLionel Sambuc * blockdriver_task *
51*433d6423SLionel Sambuc *===========================================================================*/
blockdriver_task(struct blockdriver * bdp)52*433d6423SLionel Sambuc void blockdriver_task(struct blockdriver *bdp)
53*433d6423SLionel Sambuc {
54*433d6423SLionel Sambuc /* Main program of any block device driver task. */
55*433d6423SLionel Sambuc int r, ipc_status;
56*433d6423SLionel Sambuc message mess;
57*433d6423SLionel Sambuc
58*433d6423SLionel Sambuc running = TRUE;
59*433d6423SLionel Sambuc
60*433d6423SLionel Sambuc /* Here is the main loop of the disk task. It waits for a message, carries
61*433d6423SLionel Sambuc * it out, and sends a reply.
62*433d6423SLionel Sambuc */
63*433d6423SLionel Sambuc while (running) {
64*433d6423SLionel Sambuc if ((r = blockdriver_receive_mq(&mess, &ipc_status)) != OK) {
65*433d6423SLionel Sambuc if (r == EINTR && !running)
66*433d6423SLionel Sambuc break;
67*433d6423SLionel Sambuc
68*433d6423SLionel Sambuc panic("blockdriver_receive_mq failed: %d", r);
69*433d6423SLionel Sambuc }
70*433d6423SLionel Sambuc
71*433d6423SLionel Sambuc blockdriver_process(bdp, &mess, ipc_status);
72*433d6423SLionel Sambuc }
73*433d6423SLionel Sambuc }
74*433d6423SLionel Sambuc
75*433d6423SLionel Sambuc /*===========================================================================*
76*433d6423SLionel Sambuc * blockdriver_process *
77*433d6423SLionel Sambuc *===========================================================================*/
blockdriver_process(struct blockdriver * bdp,message * m_ptr,int ipc_status)78*433d6423SLionel Sambuc void blockdriver_process(struct blockdriver *bdp, message *m_ptr,
79*433d6423SLionel Sambuc int ipc_status)
80*433d6423SLionel Sambuc {
81*433d6423SLionel Sambuc /* Handle the given received message. */
82*433d6423SLionel Sambuc
83*433d6423SLionel Sambuc blockdriver_process_on_thread(bdp, m_ptr, ipc_status, SINGLE_THREAD);
84*433d6423SLionel Sambuc }
85*433d6423SLionel Sambuc
86*433d6423SLionel Sambuc /*===========================================================================*
87*433d6423SLionel Sambuc * blockdriver_mq_queue *
88*433d6423SLionel Sambuc *===========================================================================*/
blockdriver_mq_queue(message * m,int status)89*433d6423SLionel Sambuc int blockdriver_mq_queue(message *m, int status)
90*433d6423SLionel Sambuc {
91*433d6423SLionel Sambuc /* Queue a message for later processing. */
92*433d6423SLionel Sambuc
93*433d6423SLionel Sambuc return mq_enqueue(SINGLE_THREAD, m, status);
94*433d6423SLionel Sambuc }
95