File:  [DragonFly] / src / sys / bus / usb / usb_ethersubr.c
Revision 1.8: download - view: text, annotated - select for diffs
Fri Apr 9 22:34:09 2004 UTC (10 years ago) by hsu
Branches: MAIN
CVS tags: HEAD
Push the lwkt_replymsg() up one level from netisr_service_loop() to
the message handler so we can explicitly reply or not reply as appropriate.

    1: /*
    2:  * Copyright (c) 1997, 1998, 1999, 2000
    3:  *	Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  * 3. All advertising materials mentioning features or use of this software
   14:  *    must display the following acknowledgement:
   15:  *	This product includes software developed by Bill Paul.
   16:  * 4. Neither the name of the author nor the names of any co-contributors
   17:  *    may be used to endorse or promote products derived from this software
   18:  *    without specific prior written permission.
   19:  *
   20:  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23:  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30:  * THE POSSIBILITY OF SUCH DAMAGE.
   31:  *
   32:  *
   33:  * $FreeBSD: src/sys/dev/usb/usb_ethersubr.c,v 1.17 2003/11/14 11:09:45 johan Exp $
   34:  * $DragonFly: src/sys/bus/usb/usb_ethersubr.c,v 1.8 2004/04/09 22:34:09 hsu Exp $
   35:  */
   36: 
   37: /*
   38:  * Callbacks in the USB code operate at splusb() (actually splbio()
   39:  * in FreeBSD). However adding packets to the input queues has to be
   40:  * done at splimp(). It is conceivable that this arrangement could
   41:  * trigger a condition where the splimp() is ignored and the input
   42:  * queues could get trampled in spite of our best effors to prevent
   43:  * it. To work around this, we implement a special input queue for
   44:  * USB ethernet adapter drivers. Rather than passing the frames directly
   45:  * to ether_input(), we pass them here, then schedule a soft interrupt
   46:  * to hand them to ether_input() later, outside of the USB interrupt
   47:  * context.
   48:  *
   49:  * It's questional as to whether this code should be expanded to
   50:  * handle other kinds of devices, or handle USB transfer callbacks
   51:  * in general. Right now, I need USB network interfaces to work
   52:  * properly.
   53:  */
   54: 
   55: #include <sys/param.h>
   56: #include <sys/systm.h>
   57: #include <sys/sockio.h>
   58: #include <sys/mbuf.h>
   59: #include <sys/malloc.h>
   60: #include <sys/socket.h>
   61: 
   62: #include <sys/thread2.h>
   63: #include <sys/msgport2.h>
   64: 
   65: #include <net/if.h>
   66: #include <net/if_types.h>
   67: #include <net/if_arp.h>
   68: #include <net/ethernet.h>
   69: #include <net/netisr.h>
   70: #include <net/bpf.h>
   71: 
   72: #include "usb.h"
   73: #include "usb_ethersubr.h"
   74: 
   75: Static struct ifqueue usbq_rx;
   76: Static struct ifqueue usbq_tx;
   77: Static int mtx_inited = 0;
   78: 
   79: Static void usbintr(struct netmsg *msg)
   80: {
   81: 	struct mbuf *m = ((struct netmsg_packet *)msg)->nm_packet;
   82: 	struct ether_header	*eh;
   83: 	struct usb_qdat		*q;
   84: 	struct ifnet		*ifp;
   85: 	int			s;
   86: 
   87: 	s = splimp();
   88: 
   89: 	/* Check the RX queue */
   90: 	while(1) {
   91: 		IF_DEQUEUE(&usbq_rx, m);
   92: 		if (m == NULL)
   93: 			break;
   94: 		eh = mtod(m, struct ether_header *);
   95: 		q = (struct usb_qdat *)m->m_pkthdr.rcvif;
   96: 		ifp = q->ifp;
   97: 		m->m_pkthdr.rcvif = ifp;
   98: 		m_adj(m, sizeof(struct ether_header));
   99: 		ether_input(ifp, eh, m);
  100: 
  101: 		/* Re-arm the receiver */
  102: 		(*q->if_rxstart)(ifp);
  103: 		if (ifp->if_snd.ifq_head != NULL)
  104: 			(*ifp->if_start)(ifp);
  105: 	}
  106: 
  107: 	/* Check the TX queue */
  108: 	while(1) {
  109: 		IF_DEQUEUE(&usbq_tx, m);
  110: 		if (m == NULL)
  111: 			break;
  112: 		ifp = m->m_pkthdr.rcvif;
  113: 		m_freem(m);
  114: 		if (ifp->if_snd.ifq_head != NULL)
  115: 			(*ifp->if_start)(ifp);
  116: 	}
  117: 
  118: 	splx(s);
  119: 
  120: 	lwkt_replymsg(&msg->nm_lmsg, 0);
  121: 	return;
  122: }
  123: 
  124: void
  125: usb_register_netisr(void)
  126: {
  127: 	if (mtx_inited)
  128: 		return;
  129: 	mtx_inited = 1;
  130: 	netisr_register(NETISR_USB, cpu0_portfn, usbintr);
  131: 	return;
  132: }
  133: 
  134: /*
  135:  * Must be called at splusb() (actually splbio()). This should be
  136:  * the case when called from a transfer callback routine.
  137:  */
  138: void
  139: usb_ether_input(struct mbuf *m)
  140: {
  141: 	netisr_queue(NETISR_USB, m);
  142: }
  143: 
  144: void
  145: usb_tx_done(struct mbuf *m)
  146: {
  147: 	netisr_queue(NETISR_USB, m);
  148: }