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