FreeBSD Bugzilla – Attachment 8508 Details for
Bug 17758
Make sl driver dynamicallly expandable.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 10.82 KB, created by
dwmalone
on 2000-04-02 21:40:01 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
dwmalone
Created:
2000-04-02 21:40:01 UTC
Size:
10.82 KB
patch
obsolete
>Index: if_sl.c >=================================================================== >RCS file: /cvs/FreeBSD-CVS/src/sys/net/if_sl.c,v >retrieving revision 1.84 >diff -u -r1.84 if_sl.c >--- if_sl.c 2000/02/21 08:06:18 1.84 >+++ if_sl.c 2000/03/31 22:16:57 >@@ -105,6 +105,8 @@ > > #include <net/bpf.h> > >+static MALLOC_DEFINE(M_SL, "sl", "SLIP Interface"); >+ > static void slattach __P((void *)); > PSEUDO_SET(slattach, if_sl); > >@@ -168,14 +170,17 @@ > #define ABT_COUNT 3 /* count of escapes for abort */ > #define ABT_WINDOW (ABT_COUNT*2+2) /* in seconds - time to count */ > >-static struct sl_softc sl_softc[NSL]; >+LIST_HEAD(sl_list, sl_softc) sl_list; > > #define FRAME_END 0xc0 /* Frame End */ > #define FRAME_ESCAPE 0xdb /* Frame Esc */ > #define TRANS_FRAME_END 0xdc /* transposed frame end */ > #define TRANS_FRAME_ESCAPE 0xdd /* transposed frame esc */ > >-static int slinit __P((struct sl_softc *)); >+static int slisstatic __P((int)); >+static void slmarkstatic __P((int)); >+static struct sl_softc *slcreate __P((void)); >+static void sldestroy __P((struct sl_softc *sc)); > static struct mbuf *sl_btom __P((struct sl_softc *, int)); > static timeout_t sl_keepalive; > static timeout_t sl_outfill; >@@ -201,55 +206,110 @@ > slattach(dummy) > void *dummy; > { >- register struct sl_softc *sc; >- register int i = 0; >- > linesw[SLIPDISC] = slipdisc; > >- for (sc = sl_softc; i < NSL; sc++) { >- sc->sc_if.if_name = "sl"; >- sc->sc_if.if_unit = i++; >- sc->sc_if.if_mtu = SLMTU; >- sc->sc_if.if_flags = >-#ifdef SLIP_IFF_OPTS >- SLIP_IFF_OPTS; >-#else >- IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST; >-#endif >- sc->sc_if.if_type = IFT_SLIP; >- sc->sc_if.if_ioctl = slioctl; >- sc->sc_if.if_output = sloutput; >- sc->sc_if.if_snd.ifq_maxlen = 50; >- sc->sc_fastq.ifq_maxlen = 32; >- sc->sc_if.if_linkmib = sc; >- sc->sc_if.if_linkmiblen = sizeof *sc; >- if_attach(&sc->sc_if); >- bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); >- } >+ LIST_INIT(&sl_list); > } > >-static int >-slinit(sc) >- register struct sl_softc *sc; >+static int *st_unit_list; >+static size_t st_unit_max = 0; >+ >+static >+int slisstatic(unit) >+ int unit; > { >- register caddr_t p; >+ size_t i; > >- if (sc->sc_ep == (u_char *) 0) { >- MCLALLOC(p, M_WAIT); >- if (p) >- sc->sc_ep = (u_char *)p + SLBUFSIZE; >- else { >- printf("sl%ld: can't allocate buffer\n", >- (long)(sc - sl_softc)); >- return (0); >- } >+ for (i = 0; i < st_unit_max; i++) >+ if (st_unit_list[i] == unit) >+ return 1; >+ return 0; >+} >+ >+static >+void slmarkstatic(unit) >+ int unit; >+{ >+ int *t; >+ >+ if (slisstatic(unit)) >+ return; >+ >+ MALLOC(t, int *, sizeof(int) * (st_unit_max+1), M_SL, M_NOWAIT); >+ if (t == NULL) >+ return; >+ >+ if (st_unit_list) { >+ bcopy(st_unit_list, t, sizeof(int) * st_unit_max); >+ FREE(st_unit_list, M_SL); >+ } >+ st_unit_list = t; >+ st_unit_list[st_unit_max] = unit; >+ st_unit_max++; >+} >+ >+static struct sl_softc * >+slcreate() >+{ >+ struct sl_softc *sc, *nc; >+ int unit; >+ caddr_t p; >+ >+ MALLOC(sc, struct sl_softc *, sizeof(*sc), M_SL, M_WAITOK); >+ bzero(sc, sizeof *sc); >+ >+ MCLALLOC(p, M_WAIT); >+ if (p) >+ sc->sc_ep = (u_char *)p + SLBUFSIZE; >+ else { >+ printf("sl: can't allocate buffer\n"); >+ FREE(sc, M_SL); >+ return (NULL); > } >+ > sc->sc_buf = sc->sc_ep - SLRMAX; > sc->sc_mp = sc->sc_buf; > sl_compress_init(&sc->sc_comp, -1); >- return (1); >+ >+ sc->sc_if.if_softc = sc; >+ sc->sc_if.if_name = "sl"; >+ sc->sc_if.if_mtu = SLMTU; >+ sc->sc_if.if_flags = >+#ifdef SLIP_IFF_OPTS >+ SLIP_IFF_OPTS; >+#else >+ IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST; >+#endif >+ sc->sc_if.if_type = IFT_SLIP; >+ sc->sc_if.if_ioctl = slioctl; >+ sc->sc_if.if_output = sloutput; >+ sc->sc_if.if_snd.ifq_maxlen = 50; >+ sc->sc_fastq.ifq_maxlen = 32; >+ sc->sc_if.if_linkmib = sc; >+ sc->sc_if.if_linkmiblen = sizeof *sc; >+ >+ /* >+ * Find a suitable unit number. >+ */ >+ for (unit=0; ; unit++) { >+ if (slisstatic(unit)) >+ continue; >+ LIST_FOREACH(nc, &sl_list, sl_next) { >+ if (nc->sc_if.if_unit == unit) >+ continue; >+ } >+ break; >+ } >+ sc->sc_if.if_unit = unit; >+ LIST_INSERT_HEAD(&sl_list, sc, sl_next); >+ >+ if_attach(&sc->sc_if); >+ bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); >+ >+ return sc; > } > >+ > /* > * Line specific open routine. > * Attach the given tty to the first available sl unit. >@@ -262,7 +322,6 @@ > { > struct proc *p = curproc; /* XXX */ > register struct sl_softc *sc; >- register int nsl; > int s, error; > > error = suser(p); >@@ -272,38 +331,44 @@ > if (tp->t_line == SLIPDISC) > return (0); > >- for (nsl = NSL, sc = sl_softc; --nsl >= 0; sc++) >- if (sc->sc_ttyp == NULL && !(sc->sc_flags & SC_STATIC)) { >- if (slinit(sc) == 0) >- return (ENOBUFS); >- tp->t_sc = (caddr_t)sc; >- sc->sc_ttyp = tp; >- sc->sc_if.if_baudrate = tp->t_ospeed; >- ttyflush(tp, FREAD | FWRITE); >+ if ((sc = slcreate()) == NULL) >+ return (ENOBUFS); > >- tp->t_line = SLIPDISC; >- /* >- * We don't use t_canq or t_rawq, so reduce their >- * cblock resources to 0. Reserve enough cblocks >- * for t_outq to guarantee that we can fit a full >- * packet if the SLIP_HIWAT check allows slstart() >- * to loop. Use the same value for the cblock >- * limit since the reserved blocks should always >- * be enough. Reserving cblocks probably makes >- * the CLISTRESERVE check unnecessary and wasteful. >- */ >- clist_alloc_cblocks(&tp->t_canq, 0, 0); >- clist_alloc_cblocks(&tp->t_outq, >- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, >- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); >- clist_alloc_cblocks(&tp->t_rawq, 0, 0); >+ tp->t_sc = (caddr_t)sc; >+ sc->sc_ttyp = tp; >+ sc->sc_if.if_baudrate = tp->t_ospeed; >+ ttyflush(tp, FREAD | FWRITE); >+ tp->t_line = SLIPDISC; > >- s = splnet(); >- if_up(&sc->sc_if); >- splx(s); >- return (0); >- } >- return (ENXIO); >+ /* >+ * We don't use t_canq or t_rawq, so reduce their >+ * cblock resources to 0. Reserve enough cblocks >+ * for t_outq to guarantee that we can fit a full >+ * packet if the SLIP_HIWAT check allows slstart() >+ * to loop. Use the same value for the cblock >+ * limit since the reserved blocks should always >+ * be enough. Reserving cblocks probably makes >+ * the CLISTRESERVE check unnecessary and wasteful. >+ */ >+ clist_alloc_cblocks(&tp->t_canq, 0, 0); >+ clist_alloc_cblocks(&tp->t_outq, >+ SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, >+ SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); >+ clist_alloc_cblocks(&tp->t_rawq, 0, 0); >+ >+ s = splnet(); >+ if_up(&sc->sc_if); >+ splx(s); >+ return (0); >+} >+ >+void >+sldestroy(struct sl_softc *sc) { >+ bpfdetach(&sc->sc_if); >+ if_detach(&sc->sc_if); >+ LIST_REMOVE(sc, sl_next); >+ MCLFREE((caddr_t)(sc->sc_ep - SLBUFSIZE)); >+ FREE(sc, M_SL); > } > > /* >@@ -338,13 +403,9 @@ > untimeout(sl_keepalive, sc, sc->sc_kahandle); > } > if_down(&sc->sc_if); >- sc->sc_flags &= SC_STATIC; > sc->sc_ttyp = NULL; > tp->t_sc = NULL; >- MCLFREE((caddr_t)(sc->sc_ep - SLBUFSIZE)); >- sc->sc_ep = 0; >- sc->sc_mp = 0; >- sc->sc_buf = 0; >+ sldestroy(sc); > } > splx(s); > return 0; >@@ -363,8 +424,8 @@ > int flag; > struct proc *p; > { >- struct sl_softc *sc = (struct sl_softc *)tp->t_sc, *nc, *tmpnc; >- int s, nsl; >+ struct sl_softc *sc = (struct sl_softc *)tp->t_sc, *nc; >+ int s, unit, wasup; > > s = splimp(); > switch (cmd) { >@@ -373,44 +434,36 @@ > break; > > case SLIOCSUNIT: >- if (sc->sc_if.if_unit != *(u_int *)data) { >- for (nsl = NSL, nc = sl_softc; --nsl >= 0; nc++) { >- if ( nc->sc_if.if_unit == *(u_int *)data >- && nc->sc_ttyp == NULL >- ) { >- tmpnc = malloc(sizeof *tmpnc, M_TEMP, >- M_NOWAIT); >- if (tmpnc == NULL) { >+ unit = *(u_int *)data; >+ if (unit < 0) { >+ splx(s); >+ return (ENXIO); >+ } >+ if (sc->sc_if.if_unit != unit) { >+ LIST_FOREACH(nc, &sl_list, sl_next) { >+ if (nc->sc_if.if_unit == *(u_int *)data) { > splx(s); >- return (ENOMEM); >- } >- *tmpnc = *nc; >- *nc = *sc; >- nc->sc_if = tmpnc->sc_if; >- tmpnc->sc_if = sc->sc_if; >- *sc = *tmpnc; >- free(tmpnc, M_TEMP); >- if (sc->sc_if.if_flags & IFF_UP) { >- if_down(&sc->sc_if); >- if (!(nc->sc_if.if_flags & IFF_UP)) >- if_up(&nc->sc_if); >- } else if (nc->sc_if.if_flags & IFF_UP) >- if_down(&nc->sc_if); >- sc->sc_flags &= ~SC_STATIC; >- sc->sc_flags |= (nc->sc_flags & SC_STATIC); >- tp->t_sc = sc = nc; >- clist_alloc_cblocks(&tp->t_outq, >- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, >- SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); >- sl_compress_init(&sc->sc_comp, -1); >- goto slfound; >+ return (ENXIO); > } > } >- splx(s); >- return (ENXIO); >+ >+ wasup = sc->sc_if.if_flags & IFF_UP; >+ bpfdetach(&sc->sc_if); >+ if_detach(&sc->sc_if); >+ LIST_REMOVE(sc, sl_next); >+ sc->sc_if.if_unit = unit; >+ LIST_INSERT_HEAD(&sl_list, sc, sl_next); >+ if_attach(&sc->sc_if); >+ bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); >+ if (wasup) >+ if_up(&sc->sc_if); >+ else >+ if_down(&sc->sc_if); >+ clist_alloc_cblocks(&tp->t_outq, >+ SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, >+ SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); > } >- slfound: >- sc->sc_flags |= SC_STATIC; >+ slmarkstatic(unit); > break; > > case SLIOCSKEEPAL: >@@ -470,7 +523,7 @@ > struct sockaddr *dst; > struct rtentry *rtp; > { >- register struct sl_softc *sc = &sl_softc[ifp->if_unit]; >+ register struct sl_softc *sc = ifp->if_softc; > register struct ip *ip; > register struct ifqueue *ifq; > int s; >@@ -936,6 +989,7 @@ > register struct ifaddr *ifa = (struct ifaddr *)data; > register struct ifreq *ifr = (struct ifreq *)data; > register int s, error = 0; >+ struct sl_softc *sc = ifp->if_softc; > > s = splimp(); > >@@ -946,7 +1000,7 @@ > * if.c will set the interface up even if we > * don't want it to. > */ >- if (sl_softc[ifp->if_unit].sc_ttyp == NULL) { >+ if (sc->sc_ttyp == NULL) { > ifp->if_flags &= ~IFF_UP; > } > break; >@@ -956,7 +1010,7 @@ > * setting the address. > */ > if (ifa->ifa_addr->sa_family == AF_INET) { >- if (sl_softc[ifp->if_unit].sc_ttyp != NULL) >+ if (sc->sc_ttyp != NULL) > ifp->if_flags |= IFF_UP; > } else { > error = EAFNOSUPPORT; >@@ -982,7 +1036,7 @@ > struct tty *tp; > > ifp->if_mtu = ifr->ifr_mtu; >- tp = sl_softc[ifp->if_unit].sc_ttyp; >+ tp = sc->sc_ttyp; > if (tp != NULL) > clist_alloc_cblocks(&tp->t_outq, > SLIP_HIWAT + 2 * ifp->if_mtu + 1, >Index: if_slvar.h >=================================================================== >RCS file: /cvs/FreeBSD-CVS/src/sys/net/if_slvar.h,v >retrieving revision 1.16 >diff -u -r1.16 if_slvar.h >--- if_slvar.h 1999/08/28 00:48:21 1.16 >+++ if_slvar.h 2000/03/30 00:06:28 >@@ -67,13 +67,13 @@ > struct callout_handle sc_ofhandle; > struct callout_handle sc_kahandle; > struct slcompress sc_comp; /* tcp compression data */ >+ LIST_ENTRY(sl_softc) sl_next; > }; > > /* internal flags */ > #define SC_ERROR 0x0001 /* had an input error */ > #define SC_OUTWAIT 0x0002 /* waiting for output fill */ > #define SC_KEEPALIVE 0x0004 /* input keepalive */ >-#define SC_STATIC 0x0008 /* it is static unit */ > > /* visible flags */ > #define SC_COMPRESS IFF_LINK0 /* compress TCP traffic */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 17758
: 8508