From 62081314596d205190608589fe11354865a59719 Mon Sep 17 00:00:00 2001 From: Dirk Vogt Date: Wed, 17 Nov 2010 15:10:20 +0000 Subject: [PATCH] libdriver without mandatory driver main loop --- include/minix/driver.h | 2 + lib/libdriver/driver.c | 125 ++++++++++++++++++++++------------------- 2 files changed, 69 insertions(+), 58 deletions(-) diff --git a/include/minix/driver.h b/include/minix/driver.h index 139a00ca9..728818f4a 100644 --- a/include/minix/driver.h +++ b/include/minix/driver.h @@ -68,6 +68,8 @@ _PROTOTYPE( void driver_announce, (void) ); _PROTOTYPE( int driver_receive, (endpoint_t src, message *m_ptr, int *status_ptr) ); _PROTOTYPE( int driver_receive_mq, (message *m_ptr, int *status_ptr) ); +_PROTOTYPE( int driver_handle_msg, (struct driver *dp, int type, message *m_ptr, + int ipc_status)); _PROTOTYPE( void driver_terminate, (void) ); _PROTOTYPE( void driver_task, (struct driver *dr, int type) ); _PROTOTYPE( int driver_mq_queue, (message *m_ptr, int status) ); diff --git a/lib/libdriver/driver.c b/lib/libdriver/driver.c index 357bccc82..10b056b84 100644 --- a/lib/libdriver/driver.c +++ b/lib/libdriver/driver.c @@ -355,91 +355,100 @@ int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */ * it out, and sends a reply. */ while (driver_running) { - if ((r=driver_receive_mq(&mess, &ipc_status)) != OK) + if ((r=driver_receive_mq(&mess, &ipc_status)) != OK) { panic("driver_receive_mq failed: %d", r); + } + driver_handle_msg(dp, type, &mess, ipc_status); + } +} - device_caller = mess.m_source; - proc_nr = mess.IO_ENDPT; - - /* Now carry out the work. */ - if (is_ipc_notify(ipc_status)) { - switch (_ENDPOINT_P(mess.m_source)) { - case HARDWARE: - /* leftover interrupt or expired timer. */ - if(dp->dr_hw_int) { - (*dp->dr_hw_int)(dp, &mess); - } - break; - case CLOCK: - (*dp->dr_alarm)(dp, &mess); - break; - default: - if(dp->dr_other) - r = (*dp->dr_other)(dp, &mess); - else - r = EINVAL; - goto send_reply; - } - - /* done, get a new message */ - continue; +/*===========================================================================* + * driver_handle_msg * + *===========================================================================*/ +PUBLIC int driver_handle_msg(dp, type, m_ptr, ipc_status) +struct driver *dp; /* Device dependent entry points. */ +int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */ +message *m_ptr; /* Pointer to message to handle */ +int ipc_status; +{ + int r, proc_nr; + + device_caller = m_ptr->m_source; + proc_nr = m_ptr->IO_ENDPT; + if (is_ipc_notify(ipc_status)) { + switch (_ENDPOINT_P(m_ptr->m_source)) { + case HARDWARE: + /* leftover interrupt or expired timer. */ + if(dp->dr_hw_int) { + (*dp->dr_hw_int)(dp, m_ptr); + } + break; + case CLOCK: + (*dp->dr_alarm)(dp, m_ptr); + break; + default: + if(dp->dr_other) + r = (*dp->dr_other)(dp, m_ptr); + else + r = EINVAL; + goto send_reply; } + return 0; + } - switch(mess.m_type) { - case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break; - case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break; - case DEV_IOCTL_S: r = (*dp->dr_ioctl)(dp, &mess); break; - case CANCEL: r = (*dp->dr_cancel)(dp, &mess);break; - case DEV_SELECT: r = (*dp->dr_select)(dp, &mess);break; + switch(m_ptr->m_type) { + case DEV_OPEN: r = (*dp->dr_open)(dp, m_ptr); break; + case DEV_CLOSE: r = (*dp->dr_close)(dp, m_ptr); break; + case DEV_IOCTL_S: r = (*dp->dr_ioctl)(dp, m_ptr); break; + case CANCEL: r = (*dp->dr_cancel)(dp, m_ptr);break; + case DEV_SELECT: r = (*dp->dr_select)(dp, m_ptr);break; case DEV_READ_S: - case DEV_WRITE_S: r = do_rdwt(dp, &mess); break; + case DEV_WRITE_S: r = do_rdwt(dp, m_ptr); break; case DEV_GATHER_S: - case DEV_SCATTER_S: r = do_vrdwt(dp, &mess); break; - + case DEV_SCATTER_S: r = do_vrdwt(dp, m_ptr); break; default: if(dp->dr_other) - r = (*dp->dr_other)(dp, &mess); + r = (*dp->dr_other)(dp, m_ptr); else r = EINVAL; break; - } - + } + send_reply: - /* Clean up leftover state. */ - (*dp->dr_cleanup)(); - - /* Finally, prepare and send the reply message. */ - if (r == EDONTREPLY) - continue; - - switch (type) { + /* Clean up leftover state. */ + (*dp->dr_cleanup)(); + + /* Finally, prepare and send the reply m_ptrage. */ + if (r == EDONTREPLY) + return 0; + + switch (type) { case DRIVER_STD: - mess.m_type = TASK_REPLY; - mess.REP_ENDPT = proc_nr; + m_ptr->m_type = TASK_REPLY; + m_ptr->REP_ENDPT = proc_nr; /* Status is # of bytes transferred or error code. */ - mess.REP_STATUS = r; + m_ptr->REP_STATUS = r; - r= driver_reply(device_caller, ipc_status, &mess); - if (r != OK) - { + r = driver_reply(device_caller, ipc_status, m_ptr); + + if (r != OK) { printf("driver_task: unable to send reply to %d: %d\n", - device_caller, r); + device_caller, r); } - + break; case DRIVER_ASYN: - asyn_reply(&mess, proc_nr, r); + asyn_reply(m_ptr, proc_nr, r); break; - + default: panic("unknown driver type: %d", type); - } } + return 0; } - /*===========================================================================* * driver_init_buffer * *===========================================================================*/ -- 2.44.0