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