libdriver without mandatory driver main loop

This commit is contained in:
Dirk Vogt 2010-11-17 15:10:20 +00:00
parent c22564335f
commit 6208131459
2 changed files with 90 additions and 79 deletions

View File

@ -68,6 +68,8 @@ _PROTOTYPE( void driver_announce, (void) );
_PROTOTYPE( int driver_receive, (endpoint_t src, message *m_ptr, _PROTOTYPE( int driver_receive, (endpoint_t src, message *m_ptr,
int *status_ptr) ); int *status_ptr) );
_PROTOTYPE( int driver_receive_mq, (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_terminate, (void) );
_PROTOTYPE( void driver_task, (struct driver *dr, int type) ); _PROTOTYPE( void driver_task, (struct driver *dr, int type) );
_PROTOTYPE( int driver_mq_queue, (message *m_ptr, int status) ); _PROTOTYPE( int driver_mq_queue, (message *m_ptr, int status) );

View File

@ -355,91 +355,100 @@ int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */
* it out, and sends a reply. * it out, and sends a reply.
*/ */
while (driver_running) { 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); panic("driver_receive_mq failed: %d", r);
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(dp, type, &mess, ipc_status);
}
}
switch(mess.m_type) { /*===========================================================================*
case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break; * driver_handle_msg *
case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break; *===========================================================================*/
case DEV_IOCTL_S: r = (*dp->dr_ioctl)(dp, &mess); break; PUBLIC int driver_handle_msg(dp, type, m_ptr, ipc_status)
case CANCEL: r = (*dp->dr_cancel)(dp, &mess);break; struct driver *dp; /* Device dependent entry points. */
case DEV_SELECT: r = (*dp->dr_select)(dp, &mess);break; 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(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_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_GATHER_S:
case DEV_SCATTER_S: r = do_vrdwt(dp, &mess); break; case DEV_SCATTER_S: r = do_vrdwt(dp, m_ptr); break;
default: default:
if(dp->dr_other) if(dp->dr_other)
r = (*dp->dr_other)(dp, &mess); r = (*dp->dr_other)(dp, m_ptr);
else else
r = EINVAL; r = EINVAL;
break; break;
} }
send_reply: send_reply:
/* Clean up leftover state. */ /* Clean up leftover state. */
(*dp->dr_cleanup)(); (*dp->dr_cleanup)();
/* Finally, prepare and send the reply message. */ /* Finally, prepare and send the reply m_ptrage. */
if (r == EDONTREPLY) if (r == EDONTREPLY)
continue; return 0;
switch (type) { switch (type) {
case DRIVER_STD: case DRIVER_STD:
mess.m_type = TASK_REPLY; m_ptr->m_type = TASK_REPLY;
mess.REP_ENDPT = proc_nr; m_ptr->REP_ENDPT = proc_nr;
/* Status is # of bytes transferred or error code. */ /* 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); r = driver_reply(device_caller, ipc_status, m_ptr);
if (r != OK)
{ if (r != OK) {
printf("driver_task: unable to send reply to %d: %d\n", printf("driver_task: unable to send reply to %d: %d\n",
device_caller, r); device_caller, r);
} }
break; break;
case DRIVER_ASYN: case DRIVER_ASYN:
asyn_reply(&mess, proc_nr, r); asyn_reply(m_ptr, proc_nr, r);
break; break;
default: default:
panic("unknown driver type: %d", type); panic("unknown driver type: %d", type);
}
} }
return 0;
} }
/*===========================================================================* /*===========================================================================*
* driver_init_buffer * * driver_init_buffer *
*===========================================================================*/ *===========================================================================*/