?? ip_strm_mod.c
字號:
} case M_IOCTL: if (ip_to_streams_ioctl(q, mp)) /* forward */ putnext(q, mp); break; case M_FLUSH: if (*mp->b_rptr & FLUSHW) { flushq(q, FLUSHDATA); } if (*mp->b_rptr & FLUSHR) { flushq(RD(q), FLUSHDATA); *mp->b_rptr &= ~FLUSHW; qreply(q, mp); } else freemsg(mp); break; default: freemsg(mp) ; break; } /* switch */ return(0) ;} /* ip_to_streams_wput *//************************************************************************* ip_to_streams_allocb *************************************************************************** ** Allocate a STREAMS buffer. Trigger retry mechanism if fail. ** ** Parameters: ** q The queue to use for retries. ** NULL q defeats retry procedure. ** mp The message to insert into the queue if retrying. ** A NULL mp means nothing to insert into the queue ** but the retry occurs anyway. ** type The type of message to allocate (M_PROTO, ...) ** size The size of the STREAMS buffer to allocate. ** priority The buffer allocation priority. ** head Queue the buffer at the head of the queue, not tail. ** bufcall_id Pointer to integer where bufcall id is to be stored. ** ** Returns: ** ptr If buffer was allocated. ** NULL If buffer not allocated. bufcall() has been called ** and the 'mp' has been placed into the 'q'. ** *************************************************************************/mblk_t *ip_to_streams_allocb(queue_t *q, mblk_t *mp, int type, int size, int priority, int head, int *bufcall_id){ mblk_t *msg ; if ( ip_to_streams_debug_mask & DBG_ALLOCB ) cmn_err(CE_CONT, "\nip_to_streams_allocb: called\n"); msg = allocb(size, priority) ; if (msg != (mblk_t *) NULL) { /* buffer allocated */ msg->b_datap->db_type = type ; return(msg) ; } return((mblk_t *) NULL) ;} /* ip_to_streams_allocb *//************************************************************************* ip_to_streams_merror *************************************************************************** ** Send an M_ERROR upstream. ** ** We will use the mp given to us if we can. ** *************************************************************************/intip_to_streams_m_error(ip_to_streams_minor_t *minor_ptr, mblk_t *mp, int errno, int retry){ if ( ip_to_streams_debug_mask & DBG_SQUAWK ) cmn_err(CE_CONT, "\nip_to_streams_m_error: called\n"); if ( minor_ptr == (ip_to_streams_minor_t *) NULL) { if (ip_to_streams_debug_mask & DBG_SQUAWK) cmn_err(CE_NOTE, "ip_to_streams_m_error: bad or detached minor %x", minor_ptr) ; if (mp != (mblk_t *) NULL) freemsg(mp) ; return(1) ; /* message "sent" */ } flushq(minor_ptr->dl_rdq, FLUSHALL); /* ensure queue empty */ minor_ptr->dl_retry_proto = 0 ; /* TLI proto to retry */ minor_ptr->dl_err_prim = -1 ; /* for error ack retry */ minor_ptr->dlstate = 0 ; /* go to null state */ if (mp == (mblk_t *) NULL) { mp = ip_to_streams_allocb(minor_ptr->dl_wrq, mp, M_ERROR, 1, BPRI_HI, retry, &minor_ptr->dl_bufcall_id) ; minor_ptr->dl_m_error = errno | 0x100 ; /* set retry flag */ if (mp == (mblk_t *) NULL) return(0) ; /* deferred */ } else { mp->b_datap->db_type = M_ERROR ; mp->b_rptr = mp->b_wptr = mp->b_datap->db_base ; } *mp->b_wptr++ = errno ; /* plant error code */ minor_ptr->dl_m_error = 0 ; /* unset retry flag */#ifdef GCOM if ( ip_to_streams_debug_mask & (DBG_UPR_PROTOS | DBG_MERROR) ) rsys_decode_msg(rsys_nextq_name(minor_ptr->dl_rdq), "ip_to_streams_m_error: To", mp, 0) ;#endif putnext(minor_ptr->dl_rdq, mp); return(0);} /* ip_to_streams_merror *//************************************************************************* ip_to_streams_error_ack *************************************************************************** ** Send an error_ack upstream. ** ** Return 1 if succeed, 0 if deferred. ** *************************************************************************/intip_to_streams_error_ack(ip_to_streams_minor_t *minor_ptr, mblk_t *mp, long err_prim, long tli_error, long unix_error, int retry){ dl_error_ack_t *p ; if ( ip_to_streams_debug_mask & DBG_SQUAWK ) cmn_err(CE_CONT, "\nip_to_streams_error_ack: called\n"); if ( mp == (mblk_t *) NULL || mp->b_datap->db_lim - mp->b_datap->db_base < sizeof(*p) || (!retry && (ip_to_streams_debug_mask & DBG_ALLOCB)) ) { /* must allocate a buffer */ if (mp != (mblk_t *) NULL) freemsg(mp) ; mp = ip_to_streams_allocb(minor_ptr->dl_rdq, (mblk_t *) NULL, M_PCPROTO, sizeof(*p), BPRI_MED, retry, &minor_ptr->dl_bufcall_id) ; if (mp == (mblk_t *) NULL) { minor_ptr->dl_err_prim = err_prim ; minor_ptr->dl_tli_err = tli_error ; minor_ptr->dl_unix_err = unix_error ; return(0) ; /* deferred */ } } else { mp->b_datap->db_type = M_PCPROTO ; mp->b_rptr = mp->b_wptr = mp->b_datap->db_base ; } minor_ptr->dl_err_prim = -1 ; /* ensure no retry */ /* * Have a buffer, build error_ack and send it */ mp->b_rptr = mp->b_datap->db_base ; mp->b_wptr = mp->b_datap->db_base ; p = (dl_error_ack_t *) mp->b_wptr ; p->dl_primitive = DL_ERROR_ACK ; p->dl_error_primitive = err_prim ; p->dl_errno = tli_error ; p->dl_unix_errno = unix_error ; mp->b_wptr += sizeof(*p) ; putnext(minor_ptr->dl_rdq, mp); return(1) ; /* succeed */} /* ip_to_streams_error_ack *//************************************************************************* ip_to_streams_ok_ack *************************************************************************** ** Send an ok_ack upstream. ** ** Return 1 if succeed, 0 if deferred. ** *************************************************************************/intip_to_streams_ok_ack(ip_to_streams_minor_t *minor_ptr, mblk_t *mp, long ok_prim, int retry){ dl_ok_ack_t *p ; if ( ip_to_streams_debug_mask & DBG_SQUAWK ) cmn_err(CE_CONT, "\nip_to_streams_ok_ack: called\n"); if ( minor_ptr == (ip_to_streams_minor_t *) NULL || minor_ptr->dl_magic != DL_MAGIC ) { if (ip_to_streams_debug_mask & DBG_SQUAWK) cmn_err(CE_NOTE, "ip_to_streams_ok_ack: bad minor") ; if (mp != (mblk_t *) NULL) freemsg(mp) ; return(1) ; } if ( mp == (mblk_t *) NULL || mp->b_datap->db_lim - mp->b_datap->db_base < sizeof(*p) || (!retry && (ip_to_streams_debug_mask & DBG_ALLOCB)) ) { /* must allocate a buffer */ if (mp != (mblk_t *) NULL) freemsg(mp) ; mp = ip_to_streams_allocb(minor_ptr->dl_rdq, (mblk_t *) NULL, M_PCPROTO, sizeof(*p), BPRI_MED, retry, &minor_ptr->dl_bufcall_id) ; if (mp == (mblk_t *) NULL) { minor_ptr->dl_err_prim = ok_prim ; minor_ptr->dl_tli_err = 0 ; minor_ptr->dl_unix_err = 0 ; return(0) ; /* deferred */ } } else { mp->b_datap->db_type = M_PCPROTO ; mp->b_rptr = mp->b_wptr = mp->b_datap->db_base ; } minor_ptr->dl_err_prim = -1 ; /* ensure no retry */ /* * Have a buffer, build ok_ack and send it */ mp->b_rptr = mp->b_datap->db_base ; mp->b_wptr = mp->b_datap->db_base ; p = (dl_ok_ack_t *) mp->b_wptr ; p->dl_primitive = DL_OK_ACK ; p->dl_correct_primitive = ok_prim ; mp->b_wptr += sizeof(*p) ; putnext(minor_ptr->dl_rdq, mp); return(1) ; /* succeed */} /* ip_to_streams_ok_ack *//************************************************************************* ip_to_streams_rsrv *************************************************************************** ** Upstream retry procedure. ** ** Return 1 for success, 0 for deferred. ** *************************************************************************/int ip_to_streams_rsrv(queue_t *q){ ip_to_streams_minor_t *minor_ptr ; int done ; if ( ip_to_streams_debug_mask & DBG_SVC ) cmn_err(CE_CONT, "\nip_to_streams_rsrv: q=%x\n", q) ; minor_ptr = (ip_to_streams_minor_t *) q->q_ptr ; if ( minor_ptr == (ip_to_streams_minor_t *) NULL || minor_ptr->dl_magic != DL_MAGIC || minor_ptr->dl_rdq != q ) { return(0) ; } done = 1 ; if (minor_ptr->dl_m_error > 0) { flushq(q, FLUSHALL); /* ensure queue empty */ ip_to_streams_m_error(minor_ptr, (mblk_t *) NULL, minor_ptr->dl_m_error, 1) ; return(0) ; } if (minor_ptr->dl_err_prim >= 0) { flushq(q, FLUSHALL); /* ensure queue empty */ if (minor_ptr->dl_tli_err == 0) { done = ip_to_streams_ok_ack(minor_ptr, (mblk_t *) NULL, minor_ptr->dl_err_prim, 1) ; } else { done = ip_to_streams_error_ack(minor_ptr, (mblk_t *) NULL, minor_ptr->dl_err_prim, minor_ptr->dl_tli_err, minor_ptr->dl_unix_err, 1) ; } } if (!done) return(0) ; /* still retrying error/ok acks */ /* * Try other protos */ return(0) ;} /* ip_to_streams_rsrv *//************************************************************************* ip_to_streams_wsrv *************************************************************************** ** This is the downstream retry routine. ** *************************************************************************/int ip_to_streams_wsrv(queue_t *q){ ip_to_streams_minor_t *minor_ptr ; mblk_t *mp ; struct ism_dev *dev ; int wakeup = 0 ; if ( ip_to_streams_debug_mask & DBG_SVC ) cmn_err(CE_CONT, "\nip_to_streams_wsrv: q=%x\n", q) ; minor_ptr = (ip_to_streams_minor_t *) q->q_ptr ; if ( minor_ptr == (ip_to_streams_minor_t *) NULL || minor_ptr->dl_magic != DL_MAGIC ) { return(0) ; /* bad minor */ } dev = &minor_ptr->mydev; for (;;) { if ((mp = getq (minor_ptr -> dl_wrq)) == NULL) { if (netif_queue_stopped(dev)) { netif_start_queue(dev) ; wakeup = 1 ; } break; /* done */ } if (mp -> b_datap -> db_type == M_DATA) { if ( canputnext(q) ) { putnext(q, mp); /* send downstream */ if (netif_queue_stopped(dev)) { netif_start_queue(dev) ; wakeup = 1 ; } } else { netif_stop_queue(dev) ; putbq(q, mp); return(0); /* quit */ } minor_ptr->stats.tx_packets++; } else { if (ip_to_streams_proto(minor_ptr, mp, 1) == 0) { /* deferred, queued */ netif_stop_queue(dev) ; /* stop output from above */ return(0) ; /* quit */ } if (netif_queue_stopped(dev)) { netif_start_queue(dev) ; wakeup = 1 ; } } } if (wakeup) netif_wake_queue(dev) ; /* have netif look at our queue */ return(0) ;} /* ip_to_streams_wsrv *//************************************************************************* ip_to_streams_proto *************************************************************************** ** Handle a DLPI proto message from above. ** ** Return 1 if succeed in handling msg, 0 if deferred. ** *************************************************************************/intip_to_streams_proto(ip_to_streams_minor_t *minor_ptr, mblk_t *mp, int retry){ queue_t *q = minor_ptr->dl_wrq ; long *lp ; if ( ip_to_streams_debug_mask & DBG_SQUAWK ) cmn_err(CE_CONT, "\nip_to_streams_proto: called\n"); lp = (long *) mp->b_rptr ; switch (*lp) { case DL_UNITDATA_REQ: if ( canputnext(q) ) { putnext(q, mp); return(1) ; } putq(q, mp); break ; default: if ( canputnext(q) ) { putnext(q, mp); return(1) ; } putq(q, mp); break ; } return(0); /* deferred */} /* ip_to_streams_proto *//************************************************************************* ip_to_streams_rput *************************************************************************** ** Handle a message from below. ** *************************************************************************/int ip_to_streams_rput(queue_t *q, mblk_t *mp){ ip_to_streams_minor_t *minor_ptr = q->q_ptr; struct ism_dev *dev ; int convert_to_skbuf(ip_to_streams_minor_t *, mblk_t *); if (minor_ptr == NULL) { cmn_err(CE_WARN, "ip_to_streams_rput: q->q_ptr NULL") ; freemsg(mp) ; return(0) ; } dev = &minor_ptr->mydev; if ( ip_to_streams_debug_mask & DBG_PUT ) cmn_err(CE_CONT,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -