xref: /minix3/minix/lib/libblockdriver/driver_st.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
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