📄 sr.c
字号:
r= (*sr_fd->srf_select)(sr_fd->srf_fd, i_ops); if (r < 0) return r; m_ops= 0; if (r & SR_SELECT_READ) m_ops |= SEL_RD; if (r & SR_SELECT_WRITE) m_ops |= SEL_WR; if (r & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR; return m_ops;}PRIVATE void sr_status(m)message *m;{ int fd, result; unsigned m_ops; sr_fd_t *sr_fd; mq_t *mq; mq= repl_queue; if (mq != NULL) { repl_queue= mq->mq_next; mq->mq_mess.m_type= DEV_REVIVE; result= send(mq->mq_mess.m_source, &mq->mq_mess); if (result != OK) ip_panic(("unable to send")); mq_free(mq); return; } for (fd=0, sr_fd= sr_fd_table; fd<FD_NR; fd++, sr_fd++) { if ((sr_fd->srf_flags & (SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X)) == 0) { /* Nothing to report */ continue; } if (sr_fd->srf_select_proc != m->m_source) { /* Wrong process */ continue; } m_ops= 0; if (sr_fd->srf_flags & SFF_SELECT_R) m_ops |= SEL_RD; if (sr_fd->srf_flags & SFF_SELECT_W) m_ops |= SEL_WR; if (sr_fd->srf_flags & SFF_SELECT_X) m_ops |= SEL_ERR; sr_fd->srf_flags &= ~(SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X); m->m_type= DEV_IO_READY; m->DEV_MINOR= fd; m->DEV_SEL_OPS= m_ops; result= send(m->m_source, m); if (result != OK) ip_panic(("unable to send")); return; } m->m_type= DEV_NO_STATUS; result= send(m->m_source, m); if (result != OK) ip_panic(("unable to send"));}#endifPRIVATE int walk_queue(sr_fd, q_head_ptr, q_tail_ptr, type, proc_nr, ref, first_flag)sr_fd_t *sr_fd;mq_t **q_head_ptr;mq_t **q_tail_ptr;int type;int proc_nr;int ref;int first_flag;{ mq_t *q_ptr_prv, *q_ptr; int result; for(q_ptr_prv= NULL, q_ptr= *q_head_ptr; q_ptr; q_ptr_prv= q_ptr, q_ptr= q_ptr->mq_next) { if (q_ptr->mq_mess.NDEV_PROC != proc_nr) continue;#ifdef __minix_vmd if (q_ptr->mq_mess.NDEV_REF != ref) continue;#endif if (!q_ptr_prv) { assert(!(sr_fd->srf_flags & first_flag)); sr_fd->srf_flags |= first_flag; result= (*sr_fd->srf_cancel)(sr_fd->srf_fd, type); assert(result == OK); *q_head_ptr= q_ptr->mq_next; mq_free(q_ptr); assert(sr_fd->srf_flags & first_flag); sr_fd->srf_flags &= ~first_flag; return OK; } q_ptr_prv->mq_next= q_ptr->mq_next; mq_free(q_ptr); if (!q_ptr_prv->mq_next) *q_tail_ptr= q_ptr_prv; return EINTR; } return EAGAIN;}PRIVATE sr_fd_t *sr_getchannel(minor)int minor;{ sr_fd_t *loc_fd; compare(minor, >=, 0); compare(minor, <, FD_NR); loc_fd= &sr_fd_table[minor]; assert (!(loc_fd->srf_flags & SFF_MINOR) && (loc_fd->srf_flags & SFF_INUSE)); return loc_fd;}PRIVATE void sr_reply_(mq, status, is_revive)mq_t *mq;int status;int is_revive;{ int result, proc, ref,operation; message reply, *mp; proc= mq->mq_mess.NDEV_PROC;#ifdef __minix_vmd ref= mq->mq_mess.NDEV_REF;#else /* Minix 3 */ ref= 0;#endif operation= mq->mq_mess.m_type;#ifdef __minix_vmd assert(operation != DEV_CANCEL);#endif if (is_revive) mp= &mq->mq_mess; else mp= &reply; mp->m_type= DEVICE_REPLY; mp->REP_PROC_NR= proc; mp->REP_STATUS= status;#ifdef __minix_vmd mp->REP_REF= ref; mp->REP_OPERATION= operation;#endif if (is_revive) { notify(mq->mq_mess.m_source); result= ELOCKED; } else result= send(mq->mq_mess.m_source, mp); if (result == ELOCKED && is_revive) { mq->mq_next= NULL; if (repl_queue) repl_queue_tail->mq_next= mq; else repl_queue= mq; repl_queue_tail= mq; return; } if (result != OK) ip_panic(("unable to send")); if (is_revive) mq_free(mq);}PRIVATE acc_t *sr_get_userdata (fd, offset, count, for_ioctl)int fd;vir_bytes offset;vir_bytes count;int for_ioctl;{ sr_fd_t *loc_fd; mq_t **head_ptr, *m, *mq; int ip_flag, susp_flag, first_flag; int result, suspended, is_revive; char *src; acc_t *acc; event_t *evp; ev_arg_t arg; loc_fd= &sr_fd_table[fd]; if (for_ioctl) { head_ptr= &loc_fd->srf_ioctl_q; evp= &loc_fd->srf_ioctl_ev; ip_flag= SFF_IOCTL_IP; susp_flag= SFF_IOCTL_SUSP; first_flag= SFF_IOCTL_FIRST; } else { head_ptr= &loc_fd->srf_write_q; evp= &loc_fd->srf_write_ev; ip_flag= SFF_WRITE_IP; susp_flag= SFF_WRITE_SUSP; first_flag= SFF_WRITE_FIRST; } assert (loc_fd->srf_flags & ip_flag); if (!count) { m= *head_ptr; mq= m->mq_next; *head_ptr= mq; result= (int)offset; is_revive= !(loc_fd->srf_flags & first_flag); sr_reply_(m, result, is_revive); suspended= (loc_fd->srf_flags & susp_flag); loc_fd->srf_flags &= ~(ip_flag|susp_flag); if (suspended) { if (mq) { arg.ev_ptr= loc_fd; ev_enqueue(evp, sr_event, arg); } } return NULL; } src= (*head_ptr)->mq_mess.NDEV_BUFFER + offset; result= cp_u2b ((*head_ptr)->mq_mess.NDEV_PROC, src, &acc, count); return result<0 ? NULL : acc;}PRIVATE int sr_put_userdata (fd, offset, data, for_ioctl)int fd;vir_bytes offset;acc_t *data;int for_ioctl;{ sr_fd_t *loc_fd; mq_t **head_ptr, *m, *mq; int ip_flag, susp_flag, first_flag; int result, suspended, is_revive; char *dst; event_t *evp; ev_arg_t arg; loc_fd= &sr_fd_table[fd]; if (for_ioctl) { head_ptr= &loc_fd->srf_ioctl_q; evp= &loc_fd->srf_ioctl_ev; ip_flag= SFF_IOCTL_IP; susp_flag= SFF_IOCTL_SUSP; first_flag= SFF_IOCTL_FIRST; } else { head_ptr= &loc_fd->srf_read_q; evp= &loc_fd->srf_read_ev; ip_flag= SFF_READ_IP; susp_flag= SFF_READ_SUSP; first_flag= SFF_READ_FIRST; } assert (loc_fd->srf_flags & ip_flag); if (!data) { m= *head_ptr; mq= m->mq_next; *head_ptr= mq; result= (int)offset; is_revive= !(loc_fd->srf_flags & first_flag); sr_reply_(m, result, is_revive); suspended= (loc_fd->srf_flags & susp_flag); loc_fd->srf_flags &= ~(ip_flag|susp_flag); if (suspended) { if (mq) { arg.ev_ptr= loc_fd; ev_enqueue(evp, sr_event, arg); } } return OK; } dst= (*head_ptr)->mq_mess.NDEV_BUFFER + offset; return cp_b2u (data, (*head_ptr)->mq_mess.NDEV_PROC, dst);}#ifndef __minix_vmd /* Minix 3 */PRIVATE void sr_select_res(fd, ops)int fd;unsigned ops;{ sr_fd_t *sr_fd; sr_fd= &sr_fd_table[fd]; if (ops & SR_SELECT_READ) sr_fd->srf_flags |= SFF_SELECT_R; if (ops & SR_SELECT_WRITE) sr_fd->srf_flags |= SFF_SELECT_W; if (ops & SR_SELECT_EXCEPTION) sr_fd->srf_flags |= SFF_SELECT_X; notify(sr_fd->srf_select_proc);}#endifPRIVATE void process_req_q(mq, tail, tail_ptr)mq_t *mq, *tail, **tail_ptr;{ mq_t *m; int result; for(;mq;) { m= mq; mq= mq->mq_next; result= sr_rwio(m); if (result == SUSPEND) { if (mq) { (*tail_ptr)->mq_next= mq; *tail_ptr= tail; } return; } } return;}PRIVATE void sr_event(evp, arg)event_t *evp;ev_arg_t arg;{ sr_fd_t *sr_fd; int r; sr_fd= arg.ev_ptr; if (evp == &sr_fd->srf_write_ev) { while(sr_fd->srf_write_q) { r= sr_restart_write(sr_fd); if (r == SUSPEND) return; } return; } if (evp == &sr_fd->srf_read_ev) { while(sr_fd->srf_read_q) { r= sr_restart_read(sr_fd); if (r == SUSPEND) return; } return; } if (evp == &sr_fd->srf_ioctl_ev) { while(sr_fd->srf_ioctl_q) { r= sr_restart_ioctl(sr_fd); if (r == SUSPEND) return; } return; } ip_panic(("sr_event: unkown event\n"));}PRIVATE int cp_u2b (proc, src, var_acc_ptr, size)int proc;char *src;acc_t **var_acc_ptr;int size;{ static message mess; acc_t *acc; int i; acc= bf_memreq(size); *var_acc_ptr= acc; i=0; while (acc) { size= (vir_bytes)acc->acc_length;#ifdef __minix_vmd cpvec[i].cpv_src= (vir_bytes)src; cpvec[i].cpv_dst= (vir_bytes)ptr2acc_data(acc); cpvec[i].cpv_size= size;#else /* Minix 3 */ vir_cp_req[i].count= size; vir_cp_req[i].src.proc_nr = proc; vir_cp_req[i].src.segment = D; vir_cp_req[i].src.offset = (vir_bytes) src; vir_cp_req[i].dst.proc_nr = this_proc; vir_cp_req[i].dst.segment = D; vir_cp_req[i].dst.offset = (vir_bytes) ptr2acc_data(acc);#endif src += size; acc= acc->acc_next; i++; if (i == CPVEC_NR || acc == NULL) {#ifdef __minix_vmd mess.m_type= SYS_VCOPY; mess.m1_i1= proc; mess.m1_i2= this_proc; mess.m1_i3= i; mess.m1_p1= (char *)cpvec;#else /* Minix 3 */ mess.m_type= SYS_VIRVCOPY; mess.VCP_VEC_SIZE= i; mess.VCP_VEC_ADDR= (char *)vir_cp_req;#endif if (sendrec(SYSTASK, &mess) <0) ip_panic(("unable to sendrec")); if (mess.m_type <0) { bf_afree(*var_acc_ptr); *var_acc_ptr= 0; return mess.m_type; } i= 0; } } return OK;}PRIVATE int cp_b2u (acc_ptr, proc, dest)acc_t *acc_ptr;int proc;char *dest;{ static message mess; acc_t *acc; int i, size; acc= acc_ptr; i=0; while (acc) { size= (vir_bytes)acc->acc_length; if (size) {#ifdef __minix_vmd cpvec[i].cpv_src= (vir_bytes)ptr2acc_data(acc); cpvec[i].cpv_dst= (vir_bytes)dest; cpvec[i].cpv_size= size;#else /* Minix 3 */ vir_cp_req[i].src.proc_nr = this_proc; vir_cp_req[i].src.segment = D; vir_cp_req[i].src.offset= (vir_bytes)ptr2acc_data(acc); vir_cp_req[i].dst.proc_nr = proc; vir_cp_req[i].dst.segment = D; vir_cp_req[i].dst.offset= (vir_bytes)dest; vir_cp_req[i].count= size;#endif i++; } dest += size; acc= acc->acc_next; if (i == CPVEC_NR || acc == NULL) {#ifdef __minix_vmd mess.m_type= SYS_VCOPY; mess.m1_i1= this_proc; mess.m1_i2= proc; mess.m1_i3= i; mess.m1_p1= (char *)cpvec;#else /* Minix 3 */ mess.m_type= SYS_VIRVCOPY; mess.VCP_VEC_SIZE= i; mess.VCP_VEC_ADDR= (char *) vir_cp_req;#endif if (sendrec(SYSTASK, &mess) <0) ip_panic(("unable to sendrec")); if (mess.m_type <0) { bf_afree(acc_ptr); return mess.m_type; } i= 0; } } bf_afree(acc_ptr); return OK;}PRIVATE int sr_repl_queue(proc, ref, operation)int proc;int ref;int operation;{ mq_t *m, *m_cancel, *m_tmp; int result; m_cancel= NULL; for (m= repl_queue; m;) {#ifdef __minix_vmd if (m->mq_mess.REP_PROC_NR == proc && m->mq_mess.REP_REF ==ref && (m->mq_mess.REP_OPERATION == operation || operation == CANCEL_ANY))#else /* Minix 3 */ if (m->mq_mess.REP_PROC_NR == proc)#endif {assert(!m_cancel); m_cancel= m; m= m->mq_next; continue; } result= send(m->mq_mess.m_source, &m->mq_mess); if (result != OK) ip_panic(("unable to send: %d", result)); m_tmp= m; m= m->mq_next; mq_free(m_tmp); } repl_queue= NULL; if (m_cancel) { result= send(m_cancel->mq_mess.m_source, &m_cancel->mq_mess); if (result != OK) ip_panic(("unable to send: %d", result)); mq_free(m_cancel); return 1; } return 0;}/* * $PchId: sr.c,v 1.17 2005/06/28 14:26:16 philip Exp $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -