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 *===========================================================================*/
blockdriver_receive_mq(message * m_ptr,int * status_ptr)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 *===========================================================================*/
blockdriver_terminate(void)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 *===========================================================================*/
blockdriver_task(struct blockdriver * bdp)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 *===========================================================================*/
blockdriver_process(struct blockdriver * bdp,message * m_ptr,int ipc_status)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 *===========================================================================*/
blockdriver_mq_queue(message * m,int status)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