if_plip.c (51646) | if_plip.c (55939) |
---|---|
1/*- 2 * Copyright (c) 1997 Poul-Henning Kamp 3 * 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 --- 10 unchanged lines hidden (view full) --- 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp | 1/*- 2 * Copyright (c) 1997 Poul-Henning Kamp 3 * 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 --- 10 unchanged lines hidden (view full) --- 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp |
27 * $FreeBSD: head/sys/dev/ppbus/if_plip.c 51646 1999-09-25 12:06:01Z phk $ | 27 * $FreeBSD: head/sys/dev/ppbus/if_plip.c 55939 2000-01-14 00:18:06Z nsouch $ |
28 */ 29 30/* 31 * Parallel port TCP/IP interfaces added. I looked at the driver from 32 * MACH but this is a complete rewrite, and btw. incompatible, and it 33 * should perform better too. I have never run the MACH driver though. 34 * 35 * This driver sends two bytes (0x08, 0x00) in front of each packet, --- 36 unchanged lines hidden (view full) --- 72 * the code would be cleaner 73 * 74 * Poul-Henning Kamp <phk@freebsd.org> 75 */ 76 77/* 78 * Update for ppbus, PLIP support only - Nicolas Souchu 79 */ | 28 */ 29 30/* 31 * Parallel port TCP/IP interfaces added. I looked at the driver from 32 * MACH but this is a complete rewrite, and btw. incompatible, and it 33 * should perform better too. I have never run the MACH driver though. 34 * 35 * This driver sends two bytes (0x08, 0x00) in front of each packet, --- 36 unchanged lines hidden (view full) --- 72 * the code would be cleaner 73 * 74 * Poul-Henning Kamp <phk@freebsd.org> 75 */ 76 77/* 78 * Update for ppbus, PLIP support only - Nicolas Souchu 79 */ |
80#include "plip.h" |
|
80 | 81 |
82#if NPLIP > 0 83 84#include "opt_plip.h" 85 |
|
81#include <sys/param.h> 82#include <sys/systm.h> | 86#include <sys/param.h> 87#include <sys/systm.h> |
88#include <sys/module.h> 89#include <sys/bus.h> 90#include <sys/conf.h> |
|
83#include <sys/mbuf.h> 84#include <sys/socket.h> 85#include <sys/sockio.h> 86#include <sys/kernel.h> 87#include <sys/malloc.h> 88 | 91#include <sys/mbuf.h> 92#include <sys/socket.h> 93#include <sys/sockio.h> 94#include <sys/kernel.h> 95#include <sys/malloc.h> 96 |
97#include <machine/clock.h> 98#include <machine/bus.h> 99#include <machine/resource.h> 100#include <sys/rman.h> 101 |
|
89#include <net/if.h> 90#include <net/if_types.h> 91#include <net/netisr.h> 92 93#include <netinet/in.h> 94#include <netinet/in_var.h> 95 96#include <net/bpf.h> 97 98#include <dev/ppbus/ppbconf.h> | 102#include <net/if.h> 103#include <net/if_types.h> 104#include <net/netisr.h> 105 106#include <netinet/in.h> 107#include <netinet/in_var.h> 108 109#include <net/bpf.h> 110 111#include <dev/ppbus/ppbconf.h> |
112#include "ppbus_if.h" 113#include <dev/ppbus/ppbio.h> |
|
99 | 114 |
100#include "opt_plip.h" 101 | |
102#ifndef LPMTU /* MTU for the lp# interfaces */ 103#define LPMTU 1500 104#endif 105 106#ifndef LPMAXSPIN1 /* DELAY factor for the lp# interfaces */ 107#define LPMAXSPIN1 8000 /* Spinning for remote intr to happen */ 108#endif 109 --- 20 unchanged lines hidden (view full) --- 130#define lprintf if (lptflag) printf 131 132#ifdef PLIP_DEBUG 133static int volatile lptflag = 1; 134#else 135static int volatile lptflag = 0; 136#endif 137 | 115#ifndef LPMTU /* MTU for the lp# interfaces */ 116#define LPMTU 1500 117#endif 118 119#ifndef LPMAXSPIN1 /* DELAY factor for the lp# interfaces */ 120#define LPMAXSPIN1 8000 /* Spinning for remote intr to happen */ 121#endif 122 --- 20 unchanged lines hidden (view full) --- 143#define lprintf if (lptflag) printf 144 145#ifdef PLIP_DEBUG 146static int volatile lptflag = 1; 147#else 148static int volatile lptflag = 0; 149#endif 150 |
138struct lpt_softc { | 151struct lp_data { |
139 unsigned short lp_unit; 140 | 152 unsigned short lp_unit; 153 |
141 struct ppb_device lp_dev; 142 | |
143 struct ifnet sc_if; 144 u_char *sc_ifbuf; 145 int sc_iferrs; | 154 struct ifnet sc_if; 155 u_char *sc_ifbuf; 156 int sc_iferrs; |
157 158 struct resource *res_irq; |
|
146}; 147 | 159}; 160 |
148static int nlp = 0; 149#define MAXPLIP 8 /* XXX not much better! */ 150static struct lpt_softc *lpdata[MAXPLIP]; 151 152 | |
153/* Tables for the lp# interface */ 154static u_char *txmith; 155#define txmitl (txmith+(1*LPIPTBLSIZE)) 156#define trecvh (txmith+(2*LPIPTBLSIZE)) 157#define trecvl (txmith+(3*LPIPTBLSIZE)) 158 159static u_char *ctxmith; 160#define ctxmitl (ctxmith+(1*LPIPTBLSIZE)) 161#define ctrecvh (ctxmith+(2*LPIPTBLSIZE)) 162#define ctrecvl (ctxmith+(3*LPIPTBLSIZE)) 163 164/* Functions for the lp# interface */ | 161/* Tables for the lp# interface */ 162static u_char *txmith; 163#define txmitl (txmith+(1*LPIPTBLSIZE)) 164#define trecvh (txmith+(2*LPIPTBLSIZE)) 165#define trecvl (txmith+(3*LPIPTBLSIZE)) 166 167static u_char *ctxmith; 168#define ctxmitl (ctxmith+(1*LPIPTBLSIZE)) 169#define ctrecvh (ctxmith+(2*LPIPTBLSIZE)) 170#define ctrecvl (ctxmith+(3*LPIPTBLSIZE)) 171 172/* Functions for the lp# interface */ |
165static struct ppb_device *lpprobe(struct ppb_data *); 166static int lpattach(struct ppb_device *); | 173static int lp_probe(device_t dev); 174static int lp_attach(device_t dev); |
167 168static int lpinittables(void); 169static int lpioctl(struct ifnet *, u_long, caddr_t); 170static int lpoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 171 struct rtentry *); | 175 176static int lpinittables(void); 177static int lpioctl(struct ifnet *, u_long, caddr_t); 178static int lpoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 179 struct rtentry *); |
172static void lpintr(int); | 180static void lp_intr(void *); |
173 | 181 |
174/* 175 * Make ourselves visible as a ppbus driver 176 */ | 182#define DEVTOSOFTC(dev) \ 183 ((struct lp_data *)device_get_softc(dev)) 184#define UNITOSOFTC(unit) \ 185 ((struct lp_data *)devclass_get_softc(lp_devclass, (unit))) 186#define UNITODEVICE(unit) \ 187 (devclass_get_device(lp_devclass, (unit))) |
177 | 188 |
178static struct ppb_driver lpdriver = { 179 lpprobe, lpattach, "lp" | 189static devclass_t lp_devclass; 190 191static device_method_t lp_methods[] = { 192 /* device interface */ 193 DEVMETHOD(device_probe, lp_probe), 194 DEVMETHOD(device_attach, lp_attach), 195 196 { 0, 0 } |
180}; | 197}; |
181DATA_SET(ppbdriver_set, lpdriver); | |
182 | 198 |
199static driver_t lp_driver = { 200 "plip", 201 lp_methods, 202 sizeof(struct lp_data), 203}; |
|
183 184/* 185 * lpprobe() 186 */ | 204 205/* 206 * lpprobe() 207 */ |
187static struct ppb_device * 188lpprobe(struct ppb_data *ppb) | 208static int 209lp_probe(device_t dev) |
189{ | 210{ |
190 struct lpt_softc *lp; | 211 device_t ppbus = device_get_parent(dev); 212 struct lp_data *lp; 213 int irq, zero = 0; |
191 | 214 |
215 lp = DEVTOSOFTC(dev); 216 bzero(lp, sizeof(struct lp_data)); 217 218 /* retrieve the ppbus irq */ 219 BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq); 220 |
|
192 /* if we haven't interrupts, the probe fails */ | 221 /* if we haven't interrupts, the probe fails */ |
193 if (!ppb->ppb_link->id_irq) { 194 printf("plip: not an interrupt driven port, failed.\n"); 195 return (0); | 222 if (irq == -1) { 223 device_printf(dev, "not an interrupt driven port, failed.\n"); 224 return (ENXIO); |
196 } 197 | 225 } 226 |
198 lp = (struct lpt_softc *) malloc(sizeof(struct lpt_softc), 199 M_TEMP, M_NOWAIT); 200 if (!lp) { 201 printf("lp: cannot malloc!\n"); 202 return (0); | 227 /* reserve the interrupt resource, expecting irq is available to continue */ 228 lp->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, irq, irq, 1, 229 RF_SHAREABLE); 230 if (lp->res_irq == 0) { 231 device_printf(dev, "cannot reserve interrupt, failed.\n"); 232 return (ENXIO); |
203 } | 233 } |
204 bzero(lp, sizeof(struct lpt_softc)); | |
205 | 234 |
206 lpdata[nlp] = lp; 207 | |
208 /* 209 * lp dependent initialisation. 210 */ | 235 /* 236 * lp dependent initialisation. 237 */ |
211 lp->lp_unit = nlp; | 238 lp->lp_unit = device_get_unit(dev); |
212 | 239 |
213 if (bootverbose) 214 printf("plip: irq %d\n", ppb->ppb_link->id_irq); | 240 device_set_desc(dev, "PLIP network interface"); |
215 | 241 |
216 /* 217 * ppbus dependent initialisation. 218 */ 219 lp->lp_dev.id_unit = lp->lp_unit; 220 lp->lp_dev.name = lpdriver.name; 221 lp->lp_dev.ppb = ppb; 222 lp->lp_dev.intr = lpintr; 223 224 /* Ok, go to next device on next probe */ 225 nlp ++; 226 227 return (&lp->lp_dev); | 242 return (0); |
228} 229 230static int | 243} 244 245static int |
231lpattach (struct ppb_device *dev) | 246lp_attach (device_t dev) |
232{ | 247{ |
233 int unit = dev->id_unit; 234 struct lpt_softc *sc = lpdata[unit]; 235 struct ifnet *ifp = &sc->sc_if; | 248 struct lp_data *lp = DEVTOSOFTC(dev); 249 struct ifnet *ifp = &lp->sc_if; |
236 | 250 |
237 /* 238 * Report ourselves 239 */ 240 printf("plip%d: <PLIP network interface> on ppbus %d\n", 241 dev->id_unit, dev->ppb->ppb_link->adapter_unit); 242 243 ifp->if_softc = sc; | 251 ifp->if_softc = lp; |
244 ifp->if_name = "lp"; | 252 ifp->if_name = "lp"; |
245 ifp->if_unit = unit; | 253 ifp->if_unit = device_get_unit(dev); |
246 ifp->if_mtu = LPMTU; 247 ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST; 248 ifp->if_ioctl = lpioctl; 249 ifp->if_output = lpoutput; 250 ifp->if_type = IFT_PARA; 251 ifp->if_hdrlen = 0; 252 ifp->if_addrlen = 0; 253 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 254 if_attach(ifp); 255 256 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); 257 | 254 ifp->if_mtu = LPMTU; 255 ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST; 256 ifp->if_ioctl = lpioctl; 257 ifp->if_output = lpoutput; 258 ifp->if_type = IFT_PARA; 259 ifp->if_hdrlen = 0; 260 ifp->if_addrlen = 0; 261 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 262 if_attach(ifp); 263 264 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); 265 |
258 return (1); | 266 return (0); |
259} 260/* 261 * Build the translation tables for the LPIP (BSD unix) protocol. 262 * We don't want to calculate these nasties in our tight loop, so we 263 * precalculate them when we initialize. 264 */ 265static int 266lpinittables (void) --- 31 unchanged lines hidden (view full) --- 298 299/* 300 * Process an ioctl request. 301 */ 302 303static int 304lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data) 305{ | 267} 268/* 269 * Build the translation tables for the LPIP (BSD unix) protocol. 270 * We don't want to calculate these nasties in our tight loop, so we 271 * precalculate them when we initialize. 272 */ 273static int 274lpinittables (void) --- 31 unchanged lines hidden (view full) --- 306 307/* 308 * Process an ioctl request. 309 */ 310 311static int 312lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data) 313{ |
306 struct lpt_softc *sc = lpdata[ifp->if_unit]; | 314 device_t dev = UNITODEVICE(ifp->if_unit); 315 device_t ppbus = device_get_parent(dev); 316 struct lp_data *sc = DEVTOSOFTC(dev); |
307 struct ifaddr *ifa = (struct ifaddr *)data; 308 struct ifreq *ifr = (struct ifreq *)data; 309 u_char *ptr; | 317 struct ifaddr *ifa = (struct ifaddr *)data; 318 struct ifreq *ifr = (struct ifreq *)data; 319 u_char *ptr; |
320 void *ih; |
|
310 int error; 311 312 switch (cmd) { 313 314 case SIOCSIFDSTADDR: 315 case SIOCAIFADDR: 316 case SIOCSIFADDR: 317 if (ifa->ifa_addr->sa_family != AF_INET) 318 return EAFNOSUPPORT; 319 320 ifp->if_flags |= IFF_UP; 321 /* FALLTHROUGH */ 322 case SIOCSIFFLAGS: 323 if ((!(ifp->if_flags & IFF_UP)) && (ifp->if_flags & IFF_RUNNING)) { 324 | 321 int error; 322 323 switch (cmd) { 324 325 case SIOCSIFDSTADDR: 326 case SIOCAIFADDR: 327 case SIOCSIFADDR: 328 if (ifa->ifa_addr->sa_family != AF_INET) 329 return EAFNOSUPPORT; 330 331 ifp->if_flags |= IFF_UP; 332 /* FALLTHROUGH */ 333 case SIOCSIFFLAGS: 334 if ((!(ifp->if_flags & IFF_UP)) && (ifp->if_flags & IFF_RUNNING)) { 335 |
325 ppb_wctr(&sc->lp_dev, 0x00); | 336 ppb_wctr(ppbus, 0x00); |
326 ifp->if_flags &= ~IFF_RUNNING; 327 328 /* IFF_UP is not set, try to release the bus anyway */ | 337 ifp->if_flags &= ~IFF_RUNNING; 338 339 /* IFF_UP is not set, try to release the bus anyway */ |
329 ppb_release_bus(&sc->lp_dev); | 340 ppb_release_bus(ppbus, dev); |
330 break; 331 } 332 if (((ifp->if_flags & IFF_UP)) && (!(ifp->if_flags & IFF_RUNNING))) { 333 334 /* XXX 335 * Should the request be interruptible? 336 */ | 341 break; 342 } 343 if (((ifp->if_flags & IFF_UP)) && (!(ifp->if_flags & IFF_RUNNING))) { 344 345 /* XXX 346 * Should the request be interruptible? 347 */ |
337 if ((error = ppb_request_bus(&sc->lp_dev, PPB_WAIT|PPB_INTR))) | 348 if ((error = ppb_request_bus(ppbus, dev, PPB_WAIT|PPB_INTR))) |
338 return (error); 339 340 /* Now IFF_UP means that we own the bus */ 341 | 349 return (error); 350 351 /* Now IFF_UP means that we own the bus */ 352 |
342 ppb_set_mode(&sc->lp_dev, PPB_COMPATIBLE); | 353 ppb_set_mode(ppbus, PPB_COMPATIBLE); |
343 344 if (lpinittables()) { | 354 355 if (lpinittables()) { |
345 ppb_release_bus(&sc->lp_dev); | 356 ppb_release_bus(ppbus, dev); |
346 return ENOBUFS; 347 } 348 349 sc->sc_ifbuf = malloc(sc->sc_if.if_mtu + MLPIPHDRLEN, 350 M_DEVBUF, M_WAITOK); 351 if (!sc->sc_ifbuf) { | 357 return ENOBUFS; 358 } 359 360 sc->sc_ifbuf = malloc(sc->sc_if.if_mtu + MLPIPHDRLEN, 361 M_DEVBUF, M_WAITOK); 362 if (!sc->sc_ifbuf) { |
352 ppb_release_bus(&sc->lp_dev); | 363 ppb_release_bus(ppbus, dev); |
353 return ENOBUFS; 354 } 355 | 364 return ENOBUFS; 365 } 366 |
356 ppb_wctr(&sc->lp_dev, IRQENABLE); | 367 /* attach our interrupt handler, later detached when the bus is released */ 368 if ((error = BUS_SETUP_INTR(ppbus, dev, sc->res_irq, 369 INTR_TYPE_NET, lp_intr, dev, &ih))) { 370 ppb_release_bus(ppbus, dev); 371 return (error); 372 } 373 374 ppb_wctr(ppbus, IRQENABLE); |
357 ifp->if_flags |= IFF_RUNNING; 358 } 359 break; 360 361 case SIOCSIFMTU: 362 ptr = sc->sc_ifbuf; 363 sc->sc_ifbuf = malloc(ifr->ifr_mtu+MLPIPHDRLEN, M_DEVBUF, M_NOWAIT); 364 if (!sc->sc_ifbuf) { --- 34 unchanged lines hidden (view full) --- 399 default: 400 lprintf("LP:ioctl(0x%lx)\n", cmd); 401 return EINVAL; 402 } 403 return 0; 404} 405 406static __inline int | 375 ifp->if_flags |= IFF_RUNNING; 376 } 377 break; 378 379 case SIOCSIFMTU: 380 ptr = sc->sc_ifbuf; 381 sc->sc_ifbuf = malloc(ifr->ifr_mtu+MLPIPHDRLEN, M_DEVBUF, M_NOWAIT); 382 if (!sc->sc_ifbuf) { --- 34 unchanged lines hidden (view full) --- 417 default: 418 lprintf("LP:ioctl(0x%lx)\n", cmd); 419 return EINVAL; 420 } 421 return 0; 422} 423 424static __inline int |
407clpoutbyte (u_char byte, int spin, struct ppb_device *dev) | 425clpoutbyte (u_char byte, int spin, device_t ppbus) |
408{ | 426{ |
409 ppb_wdtr(dev, ctxmitl[byte]); 410 while (ppb_rstr(dev) & CLPIP_SHAKE) | 427 ppb_wdtr(ppbus, ctxmitl[byte]); 428 while (ppb_rstr(ppbus) & CLPIP_SHAKE) |
411 if (--spin == 0) { 412 return 1; 413 } | 429 if (--spin == 0) { 430 return 1; 431 } |
414 ppb_wdtr(dev, ctxmith[byte]); 415 while (!(ppb_rstr(dev) & CLPIP_SHAKE)) | 432 ppb_wdtr(ppbus, ctxmith[byte]); 433 while (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) |
416 if (--spin == 0) { 417 return 1; 418 } 419 return 0; 420} 421 422static __inline int | 434 if (--spin == 0) { 435 return 1; 436 } 437 return 0; 438} 439 440static __inline int |
423clpinbyte (int spin, struct ppb_device *dev) | 441clpinbyte (int spin, device_t ppbus) |
424{ 425 u_char c, cl; 426 | 442{ 443 u_char c, cl; 444 |
427 while((ppb_rstr(dev) & CLPIP_SHAKE)) | 445 while((ppb_rstr(ppbus) & CLPIP_SHAKE)) |
428 if(!--spin) { 429 return -1; 430 } | 446 if(!--spin) { 447 return -1; 448 } |
431 cl = ppb_rstr(dev); 432 ppb_wdtr(dev, 0x10); | 449 cl = ppb_rstr(ppbus); 450 ppb_wdtr(ppbus, 0x10); |
433 | 451 |
434 while(!(ppb_rstr(dev) & CLPIP_SHAKE)) | 452 while(!(ppb_rstr(ppbus) & CLPIP_SHAKE)) |
435 if(!--spin) { 436 return -1; 437 } | 453 if(!--spin) { 454 return -1; 455 } |
438 c = ppb_rstr(dev); 439 ppb_wdtr(dev, 0x00); | 456 c = ppb_rstr(ppbus); 457 ppb_wdtr(ppbus, 0x00); |
440 441 return (ctrecvl[cl] | ctrecvh[c]); 442} 443 444static void 445lptap(struct ifnet *ifp, struct mbuf *m) 446{ 447 /* --- 7 unchanged lines hidden (view full) --- 455 456 m0.m_next = m; 457 m0.m_len = sizeof(u_int32_t); 458 m0.m_data = (char *)⁡ 459 bpf_mtap(ifp, &m0); 460} 461 462static void | 458 459 return (ctrecvl[cl] | ctrecvh[c]); 460} 461 462static void 463lptap(struct ifnet *ifp, struct mbuf *m) 464{ 465 /* --- 7 unchanged lines hidden (view full) --- 473 474 m0.m_next = m; 475 m0.m_len = sizeof(u_int32_t); 476 m0.m_data = (char *)⁡ 477 bpf_mtap(ifp, &m0); 478} 479 480static void |
463lpintr (int unit) | 481lp_intr (void *arg) |
464{ | 482{ |
465 struct lpt_softc *sc = lpdata[unit]; | 483 device_t dev = (device_t)arg; 484 device_t ppbus = device_get_parent(dev); 485 struct lp_data *sc = DEVTOSOFTC(dev); |
466 int len, s, j; 467 u_char *bp; 468 u_char c, cl; 469 struct mbuf *top; 470 471 s = splhigh(); 472 473 if (sc->sc_if.if_flags & IFF_LINK0) { 474 475 /* Ack. the request */ | 486 int len, s, j; 487 u_char *bp; 488 u_char c, cl; 489 struct mbuf *top; 490 491 s = splhigh(); 492 493 if (sc->sc_if.if_flags & IFF_LINK0) { 494 495 /* Ack. the request */ |
476 ppb_wdtr(&sc->lp_dev, 0x01); | 496 ppb_wdtr(ppbus, 0x01); |
477 478 /* Get the packet length */ | 497 498 /* Get the packet length */ |
479 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev); | 499 j = clpinbyte(LPMAXSPIN2, ppbus); |
480 if (j == -1) 481 goto err; 482 len = j; | 500 if (j == -1) 501 goto err; 502 len = j; |
483 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev); | 503 j = clpinbyte(LPMAXSPIN2, ppbus); |
484 if (j == -1) 485 goto err; 486 len = len + (j << 8); 487 if (len > sc->sc_if.if_mtu + MLPIPHDRLEN) 488 goto err; 489 490 bp = sc->sc_ifbuf; 491 492 while (len--) { | 504 if (j == -1) 505 goto err; 506 len = len + (j << 8); 507 if (len > sc->sc_if.if_mtu + MLPIPHDRLEN) 508 goto err; 509 510 bp = sc->sc_ifbuf; 511 512 while (len--) { |
493 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev); | 513 j = clpinbyte(LPMAXSPIN2, ppbus); |
494 if (j == -1) { 495 goto err; 496 } 497 *bp++ = j; 498 } 499 /* Get and ignore checksum */ | 514 if (j == -1) { 515 goto err; 516 } 517 *bp++ = j; 518 } 519 /* Get and ignore checksum */ |
500 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev); | 520 j = clpinbyte(LPMAXSPIN2, ppbus); |
501 if (j == -1) { 502 goto err; 503 } 504 505 len = bp - sc->sc_ifbuf; 506 if (len <= CLPIPHDRLEN) 507 goto err; 508 --- 11 unchanged lines hidden (view full) --- 520 if (top) { 521 if (sc->sc_if.if_bpf) 522 lptap(&sc->sc_if, top); 523 IF_ENQUEUE(&ipintrq, top); 524 schednetisr(NETISR_IP); 525 } 526 goto done; 527 } | 521 if (j == -1) { 522 goto err; 523 } 524 525 len = bp - sc->sc_ifbuf; 526 if (len <= CLPIPHDRLEN) 527 goto err; 528 --- 11 unchanged lines hidden (view full) --- 540 if (top) { 541 if (sc->sc_if.if_bpf) 542 lptap(&sc->sc_if, top); 543 IF_ENQUEUE(&ipintrq, top); 544 schednetisr(NETISR_IP); 545 } 546 goto done; 547 } |
528 while ((ppb_rstr(&sc->lp_dev) & LPIP_SHAKE)) { | 548 while ((ppb_rstr(ppbus) & LPIP_SHAKE)) { |
529 len = sc->sc_if.if_mtu + LPIPHDRLEN; 530 bp = sc->sc_ifbuf; 531 while (len--) { 532 | 549 len = sc->sc_if.if_mtu + LPIPHDRLEN; 550 bp = sc->sc_ifbuf; 551 while (len--) { 552 |
533 cl = ppb_rstr(&sc->lp_dev); 534 ppb_wdtr(&sc->lp_dev, 8); | 553 cl = ppb_rstr(ppbus); 554 ppb_wdtr(ppbus, 8); |
535 536 j = LPMAXSPIN2; | 555 556 j = LPMAXSPIN2; |
537 while((ppb_rstr(&sc->lp_dev) & LPIP_SHAKE)) | 557 while((ppb_rstr(ppbus) & LPIP_SHAKE)) |
538 if(!--j) goto err; 539 | 558 if(!--j) goto err; 559 |
540 c = ppb_rstr(&sc->lp_dev); 541 ppb_wdtr(&sc->lp_dev, 0); | 560 c = ppb_rstr(ppbus); 561 ppb_wdtr(ppbus, 0); |
542 543 *bp++= trecvh[cl] | trecvl[c]; 544 545 j = LPMAXSPIN2; | 562 563 *bp++= trecvh[cl] | trecvl[c]; 564 565 j = LPMAXSPIN2; |
546 while (!((cl=ppb_rstr(&sc->lp_dev)) & LPIP_SHAKE)) { | 566 while (!((cl=ppb_rstr(ppbus)) & LPIP_SHAKE)) { |
547 if (cl != c && | 567 if (cl != c && |
548 (((cl = ppb_rstr(&sc->lp_dev)) ^ 0xb8) & 0xf8) == | 568 (((cl = ppb_rstr(ppbus)) ^ 0xb8) & 0xf8) == |
549 (c & 0xf8)) 550 goto end; 551 if (!--j) goto err; 552 } 553 } 554 555 end: 556 len = bp - sc->sc_ifbuf; --- 16 unchanged lines hidden (view full) --- 573 lptap(&sc->sc_if, top); 574 IF_ENQUEUE(&ipintrq, top); 575 schednetisr(NETISR_IP); 576 } 577 } 578 goto done; 579 580 err: | 569 (c & 0xf8)) 570 goto end; 571 if (!--j) goto err; 572 } 573 } 574 575 end: 576 len = bp - sc->sc_ifbuf; --- 16 unchanged lines hidden (view full) --- 593 lptap(&sc->sc_if, top); 594 IF_ENQUEUE(&ipintrq, top); 595 schednetisr(NETISR_IP); 596 } 597 } 598 goto done; 599 600 err: |
581 ppb_wdtr(&sc->lp_dev, 0); | 601 ppb_wdtr(ppbus, 0); |
582 lprintf("R"); 583 sc->sc_if.if_ierrors++; 584 sc->sc_iferrs++; 585 586 /* 587 * We are not able to send receive anything for now, 588 * so stop wasting our time 589 */ 590 if (sc->sc_iferrs > LPMAXERRS) { | 602 lprintf("R"); 603 sc->sc_if.if_ierrors++; 604 sc->sc_iferrs++; 605 606 /* 607 * We are not able to send receive anything for now, 608 * so stop wasting our time 609 */ 610 if (sc->sc_iferrs > LPMAXERRS) { |
591 printf("lp%d: Too many errors, Going off-line.\n", unit); 592 ppb_wctr(&sc->lp_dev, 0x00); | 611 printf("lp%d: Too many errors, Going off-line.\n", device_get_unit(dev)); 612 ppb_wctr(ppbus, 0x00); |
593 sc->sc_if.if_flags &= ~IFF_RUNNING; 594 sc->sc_iferrs=0; 595 } 596 597 done: 598 splx(s); 599 return; 600} 601 602static __inline int | 613 sc->sc_if.if_flags &= ~IFF_RUNNING; 614 sc->sc_iferrs=0; 615 } 616 617 done: 618 splx(s); 619 return; 620} 621 622static __inline int |
603lpoutbyte (u_char byte, int spin, struct ppb_device *dev) | 623lpoutbyte (u_char byte, int spin, device_t ppbus) |
604{ | 624{ |
605 ppb_wdtr(dev, txmith[byte]); 606 while (!(ppb_rstr(dev) & LPIP_SHAKE)) | 625 ppb_wdtr(ppbus, txmith[byte]); 626 while (!(ppb_rstr(ppbus) & LPIP_SHAKE)) |
607 if (--spin == 0) 608 return 1; | 627 if (--spin == 0) 628 return 1; |
609 ppb_wdtr(dev, txmitl[byte]); 610 while (ppb_rstr(dev) & LPIP_SHAKE) | 629 ppb_wdtr(ppbus, txmitl[byte]); 630 while (ppb_rstr(ppbus) & LPIP_SHAKE) |
611 if (--spin == 0) 612 return 1; 613 return 0; 614} 615 616static int 617lpoutput (struct ifnet *ifp, struct mbuf *m, 618 struct sockaddr *dst, struct rtentry *rt) 619{ | 631 if (--spin == 0) 632 return 1; 633 return 0; 634} 635 636static int 637lpoutput (struct ifnet *ifp, struct mbuf *m, 638 struct sockaddr *dst, struct rtentry *rt) 639{ |
620 struct lpt_softc *sc = lpdata[ifp->if_unit]; | 640 device_t dev = UNITODEVICE(ifp->if_unit); 641 device_t ppbus = device_get_parent(dev); |
621 int s, err; 622 struct mbuf *mm; 623 u_char *cp = "\0\0"; 624 u_char chksum = 0; 625 int count = 0; 626 int i, len, spin; 627 628 /* We need a sensible value if we abort */ 629 cp++; 630 ifp->if_flags |= IFF_RUNNING; 631 632 err = 1; /* assume we're aborting because of an error */ 633 634 s = splhigh(); 635 636 /* Suspend (on laptops) or receive-errors might have taken us offline */ | 642 int s, err; 643 struct mbuf *mm; 644 u_char *cp = "\0\0"; 645 u_char chksum = 0; 646 int count = 0; 647 int i, len, spin; 648 649 /* We need a sensible value if we abort */ 650 cp++; 651 ifp->if_flags |= IFF_RUNNING; 652 653 err = 1; /* assume we're aborting because of an error */ 654 655 s = splhigh(); 656 657 /* Suspend (on laptops) or receive-errors might have taken us offline */ |
637 ppb_wctr(&sc->lp_dev, IRQENABLE); | 658 ppb_wctr(ppbus, IRQENABLE); |
638 639 if (ifp->if_flags & IFF_LINK0) { 640 | 659 660 if (ifp->if_flags & IFF_LINK0) { 661 |
641 if (!(ppb_rstr(&sc->lp_dev) & CLPIP_SHAKE)) { | 662 if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) { |
642 lprintf("&"); | 663 lprintf("&"); |
643 lpintr(ifp->if_unit); | 664 lp_intr(dev); |
644 } 645 646 /* Alert other end to pending packet */ 647 spin = LPMAXSPIN1; | 665 } 666 667 /* Alert other end to pending packet */ 668 spin = LPMAXSPIN1; |
648 ppb_wdtr(&sc->lp_dev, 0x08); 649 while ((ppb_rstr(&sc->lp_dev) & 0x08) == 0) | 669 ppb_wdtr(ppbus, 0x08); 670 while ((ppb_rstr(ppbus) & 0x08) == 0) |
650 if (--spin == 0) { 651 goto nend; 652 } 653 654 /* Calculate length of packet, then send that */ 655 656 count += 14; /* Ethernet header len */ 657 658 mm = m; 659 for (mm = m; mm; mm = mm->m_next) { 660 count += mm->m_len; 661 } | 671 if (--spin == 0) { 672 goto nend; 673 } 674 675 /* Calculate length of packet, then send that */ 676 677 count += 14; /* Ethernet header len */ 678 679 mm = m; 680 for (mm = m; mm; mm = mm->m_next) { 681 count += mm->m_len; 682 } |
662 if (clpoutbyte(count & 0xFF, LPMAXSPIN1, &sc->lp_dev)) | 683 if (clpoutbyte(count & 0xFF, LPMAXSPIN1, ppbus)) |
663 goto nend; | 684 goto nend; |
664 if (clpoutbyte((count >> 8) & 0xFF, LPMAXSPIN1, &sc->lp_dev)) | 685 if (clpoutbyte((count >> 8) & 0xFF, LPMAXSPIN1, ppbus)) |
665 goto nend; 666 667 /* Send dummy ethernet header */ 668 for (i = 0; i < 12; i++) { | 686 goto nend; 687 688 /* Send dummy ethernet header */ 689 for (i = 0; i < 12; i++) { |
669 if (clpoutbyte(i, LPMAXSPIN1, &sc->lp_dev)) | 690 if (clpoutbyte(i, LPMAXSPIN1, ppbus)) |
670 goto nend; 671 chksum += i; 672 } 673 | 691 goto nend; 692 chksum += i; 693 } 694 |
674 if (clpoutbyte(0x08, LPMAXSPIN1, &sc->lp_dev)) | 695 if (clpoutbyte(0x08, LPMAXSPIN1, ppbus)) |
675 goto nend; | 696 goto nend; |
676 if (clpoutbyte(0x00, LPMAXSPIN1, &sc->lp_dev)) | 697 if (clpoutbyte(0x00, LPMAXSPIN1, ppbus)) |
677 goto nend; 678 chksum += 0x08 + 0x00; /* Add into checksum */ 679 680 mm = m; 681 do { 682 cp = mtod(mm, u_char *); 683 len = mm->m_len; 684 while (len--) { 685 chksum += *cp; | 698 goto nend; 699 chksum += 0x08 + 0x00; /* Add into checksum */ 700 701 mm = m; 702 do { 703 cp = mtod(mm, u_char *); 704 len = mm->m_len; 705 while (len--) { 706 chksum += *cp; |
686 if (clpoutbyte(*cp++, LPMAXSPIN2, &sc->lp_dev)) | 707 if (clpoutbyte(*cp++, LPMAXSPIN2, ppbus)) |
687 goto nend; 688 } 689 } while ((mm = mm->m_next)); 690 691 /* Send checksum */ | 708 goto nend; 709 } 710 } while ((mm = mm->m_next)); 711 712 /* Send checksum */ |
692 if (clpoutbyte(chksum, LPMAXSPIN2, &sc->lp_dev)) | 713 if (clpoutbyte(chksum, LPMAXSPIN2, ppbus)) |
693 goto nend; 694 695 /* Go quiescent */ | 714 goto nend; 715 716 /* Go quiescent */ |
696 ppb_wdtr(&sc->lp_dev, 0); | 717 ppb_wdtr(ppbus, 0); |
697 698 err = 0; /* No errors */ 699 700 nend: 701 if (err) { /* if we didn't timeout... */ 702 ifp->if_oerrors++; 703 lprintf("X"); 704 } else { 705 ifp->if_opackets++; 706 ifp->if_obytes += m->m_pkthdr.len; 707 if (ifp->if_bpf) 708 lptap(ifp, m); 709 } 710 711 m_freem(m); 712 | 718 719 err = 0; /* No errors */ 720 721 nend: 722 if (err) { /* if we didn't timeout... */ 723 ifp->if_oerrors++; 724 lprintf("X"); 725 } else { 726 ifp->if_opackets++; 727 ifp->if_obytes += m->m_pkthdr.len; 728 if (ifp->if_bpf) 729 lptap(ifp, m); 730 } 731 732 m_freem(m); 733 |
713 if (!(ppb_rstr(&sc->lp_dev) & CLPIP_SHAKE)) { | 734 if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) { |
714 lprintf("^"); | 735 lprintf("^"); |
715 lpintr(ifp->if_unit); | 736 lp_intr(dev); |
716 } 717 (void) splx(s); 718 return 0; 719 } 720 | 737 } 738 (void) splx(s); 739 return 0; 740 } 741 |
721 if (ppb_rstr(&sc->lp_dev) & LPIP_SHAKE) { | 742 if (ppb_rstr(ppbus) & LPIP_SHAKE) { |
722 lprintf("&"); | 743 lprintf("&"); |
723 lpintr(ifp->if_unit); | 744 lp_intr(dev); |
724 } 725 | 745 } 746 |
726 if (lpoutbyte(0x08, LPMAXSPIN1, &sc->lp_dev)) | 747 if (lpoutbyte(0x08, LPMAXSPIN1, ppbus)) |
727 goto end; | 748 goto end; |
728 if (lpoutbyte(0x00, LPMAXSPIN2, &sc->lp_dev)) | 749 if (lpoutbyte(0x00, LPMAXSPIN2, ppbus)) |
729 goto end; 730 731 mm = m; 732 do { 733 cp = mtod(mm,u_char *); 734 len = mm->m_len; 735 while (len--) | 750 goto end; 751 752 mm = m; 753 do { 754 cp = mtod(mm,u_char *); 755 len = mm->m_len; 756 while (len--) |
736 if (lpoutbyte(*cp++, LPMAXSPIN2, &sc->lp_dev)) | 757 if (lpoutbyte(*cp++, LPMAXSPIN2, ppbus)) |
737 goto end; 738 } while ((mm = mm->m_next)); 739 740 err = 0; /* no errors were encountered */ 741 742 end: 743 --cp; | 758 goto end; 759 } while ((mm = mm->m_next)); 760 761 err = 0; /* no errors were encountered */ 762 763 end: 764 --cp; |
744 ppb_wdtr(&sc->lp_dev, txmitl[*cp] ^ 0x17); | 765 ppb_wdtr(ppbus, txmitl[*cp] ^ 0x17); |
745 746 if (err) { /* if we didn't timeout... */ 747 ifp->if_oerrors++; 748 lprintf("X"); 749 } else { 750 ifp->if_opackets++; 751 ifp->if_obytes += m->m_pkthdr.len; 752 if (ifp->if_bpf) 753 lptap(ifp, m); 754 } 755 756 m_freem(m); 757 | 766 767 if (err) { /* if we didn't timeout... */ 768 ifp->if_oerrors++; 769 lprintf("X"); 770 } else { 771 ifp->if_opackets++; 772 ifp->if_obytes += m->m_pkthdr.len; 773 if (ifp->if_bpf) 774 lptap(ifp, m); 775 } 776 777 m_freem(m); 778 |
758 if (ppb_rstr(&sc->lp_dev) & LPIP_SHAKE) { | 779 if (ppb_rstr(ppbus) & LPIP_SHAKE) { |
759 lprintf("^"); | 780 lprintf("^"); |
760 lpintr(ifp->if_unit); | 781 lp_intr(dev); |
761 } 762 763 (void) splx(s); 764 return 0; 765} | 782 } 783 784 (void) splx(s); 785 return 0; 786} |
787 788DRIVER_MODULE(plip, ppbus, lp_driver, lp_devclass, 0, 0); 789 790#endif /* NPLIP > 0 */ |
|