* dev_open: FS opens a device
* dev_close: FS closes a device
* dev_io: FS does a read or write on a device
+ * dev_status: FS processes callback request alert
* gen_opcl: generic call to a task to perform an open/close
* gen_io: generic call to a task to perform an I/O operation
* no_dev: open/close processing for devices that don't exist
(void) (*dmap[(dev >> MAJOR) & BYTE].dmap_opcl)(DEV_CLOSE, dev, 0, 0);
}
+/*===========================================================================*
+ * dev_status *
+ *===========================================================================*/
+PUBLIC void dev_status(message *m)
+{
+ message st;
+ int d, get_more = 1;
+
+ for(d = 0; d < NR_DEVICES; d++)
+ if(dmap[d].dmap_driver == m->m_source)
+ break;
+
+ if(d >= NR_DEVICES)
+ return;
+
+ do {
+ int r;
+ st.m_type = DEV_STATUS;
+ if((r=sendrec(m->m_source, &st)) != OK)
+ panic(__FILE__,"couldn't sendrec for DEV_STATUS", r);
+
+ switch(st.m_type) {
+ case DEV_REVIVE:
+ revive(st.REP_PROC_NR, st.REP_STATUS);
+ break;
+ case DEV_IO_READY:
+ select_notified(d, st.DEV_MINOR, st.DEV_SEL_OPS);
+ break;
+ default:
+ printf("FS: unrecognized reply %d to DEV_STATUS\n", st.m_type);
+ /* Fall through. */
+ case DEV_NO_STATUS:
+ get_more = 0;
+ break;
+ }
+ } while(get_more);
+
+
+ return;
+}
+
/*===========================================================================*
* dev_io *
*===========================================================================*/
proc_nr = mess_ptr->PROC_NR;
if (! isokprocnr(proc_nr)) {
- printf("FS: warning, got illegal process number from %d.\n",
- mess_ptr->PROC_NR);
+ printf("FS: warning, got illegal process number (%d) from %d\n",
+ mess_ptr->PROC_NR, mess_ptr->m_source);
return;
}
/* Did the process we did the sendrec() for get a result? */
if (mess_ptr->REP_PROC_NR == proc_nr) {
break;
- }
-
- if(mess_ptr->m_type == DEV_SELECTED) {
- /* select() became possible.. This can happen. */
- select_notified(mess_ptr);
} else if(mess_ptr->m_type == REVIVE) {
/* Otherwise it should be a REVIVE. */
revive(mess_ptr->REP_PROC_NR, mess_ptr->REP_STATUS);
"fs: strange device reply from %d, type = %d, proc = %d (2)\n",
mess_ptr->m_source,
mess_ptr->m_type, mess_ptr->REP_PROC_NR);
- continue; /* XXX should this be a continue?? */
+ continue; /* XXX ? */
}
r = receive(task_nr, mess_ptr);
}
return(dev_mess.REP_STATUS);
}
+
*/
fs_expire_timers(m_in.NOTIFY_TIMESTAMP);
} else if (call_nr == DEV_SELECTED) {
- /* Device notify()s us of fd that has become usable. */
- select_notified(&m_in);
+ printf("Old select device callback received - ignored\n");
+ } else if ((call_nr & NOTIFY_MESSAGE)) {
+ /* Device notifies (alert()s) us of an event. */
+ dev_status(&m_in);
} else {
/* Call the internal function that does the work. */
if (call_nr < 0 || call_nr >= NCALLS) {
_PROTOTYPE( void ctty_io, (int task_nr, message *mess_ptr) );
_PROTOTYPE( int do_ioctl, (void) );
_PROTOTYPE( int do_setsid, (void) );
+_PROTOTYPE( void dev_status, (message *) );
/* dmp.c */
_PROTOTYPE( int do_fkey_pressed, (void) );
_PROTOTYPE( void select_forget, (int fproc) );
_PROTOTYPE( void select_timeout_check, (timer_t *) );
_PROTOTYPE( void init_select, (void) );
-_PROTOTYPE( int select_notified, (message *) );
+_PROTOTYPE( int select_notified, (int major, int minor, int ops) );
/* timers.c */
_PROTOTYPE( void fs_set_timer, (timer_t *tp, int delta, tmr_func_t watchdog, int arg));
* make select cancel disappearing fp's
*/
-#define DEBUG_SELECT 0
+#define DEBUG_SELECT 1
#include "fs.h"
#include "dmap.h"
/*===========================================================================*
* int select_notified *
*===========================================================================*/
-PUBLIC int select_notified(message *m)
+PUBLIC int select_notified(int major, int minor, int selected_ops)
{
- int s, f, d, t;
+ int s, f, t;
- for(d = 0; d < NR_DEVICES; d++)
- if(dmap[d].dmap_driver == m->m_source)
- break;
-
- if(d >= NR_DEVICES)
- return OK;
+#if DEBUG_SELECT
+ printf("select callback: %d, %d: %d\n", major, minor, selected_ops);
+#endif
for(t = 0; t < SEL_FDS; t++)
- if(!fdtypes[t].select_match && fdtypes[t].select_major == d)
+ if(!fdtypes[t].select_match && fdtypes[t].select_major == major)
break;
- if(t >= SEL_FDS)
+ if(t >= SEL_FDS) {
+#if DEBUG_SELECT
+ printf("select callback: no fdtype found for device %d\n", major);
+#endif
return OK;
+ }
/* We have a select callback from major device no.
* d, which corresponds to our select type t.
*/
for(s = 0; s < MAXSELECTS; s++) {
- int line, ops;
+ int s_minor, ops;
if(!selecttab[s].requestor)
continue;
for(f = 0; f < selecttab[s].nfds; f++) {
if(!selecttab[s].filps[f] ||
- !select_major_match(d, selecttab[s].filps[f]))
+ !select_major_match(major, selecttab[s].filps[f]))
continue;
ops = tab2ops(f, &selecttab[s]);
- line = selecttab[s].filps[f]->filp_ino->i_zone[0] & BYTE;
- if((line == m->NOTIFY_ARG) &&
- (m->NOTIFY_FLAGS & ops)) {
- select_callback(selecttab[s].filps[f], ops);
+ s_minor = selecttab[s].filps[f]->filp_ino->i_zone[0] & BYTE;
+ if((s_minor == minor) &&
+ (selected_ops & ops)) {
+ select_callback(selecttab[s].filps[f], (selected_ops & ops));
}
}
}
return OK;
}
+
/*===========================================================================*
* init_select *
*===========================================================================*/