1/* 2 * Cronyx-Tau-PCI adapter driver for FreeBSD. 3 * Supports PPP/HDLC, Cisco/HDLC and FrameRelay protocol in synchronous mode, 4 * and asyncronous channels with full modem control. 5 * Keepalive protocol implemented in both Cisco and PPP modes. 6 * 7 * Copyright (C) 1999-2004 Cronyx Engineering. 8 * Author: Kurakin Roman, <rik@cronyx.ru> --- 8 unchanged lines hidden (view full) --- 17 * modify and redistribute this software in source and binary forms, 18 * as long as this message is kept with the software, all derivative 19 * works or modified versions. 20 * 21 * Cronyx Id: if_cp.c,v 1.1.2.41 2004/06/23 17:09:13 rik Exp $ 22 */ 23 24#include <sys/cdefs.h> |
25__FBSDID("$FreeBSD: head/sys/dev/cp/if_cp.c 138673 2004-12-11 05:38:16Z rik $"); |
26 27#include <sys/param.h> |
28#include <sys/ucred.h> 29#include <sys/proc.h> 30#include <sys/systm.h> 31#include <sys/mbuf.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/conf.h> 35#include <sys/malloc.h> 36#include <sys/socket.h> 37#include <sys/sockio.h> 38#include <sys/tty.h> 39#include <sys/bus.h> 40#include <vm/vm.h> 41#include <vm/pmap.h> 42#include <net/if.h> |
43#include <dev/pci/pcivar.h> 44#include <dev/pci/pcireg.h> |
45#include <machine/bus.h> 46#include <sys/rman.h> 47#include "opt_ng_cronyx.h" 48#ifdef NETGRAPH_CRONYX 49# include "opt_netgraph.h" 50# ifndef NETGRAPH 51# error #option NETGRAPH missed from configuration 52# endif 53# include <netgraph/ng_message.h> 54# include <netgraph/netgraph.h> 55# include <dev/cp/ng_cp.h> 56#else 57# include <net/if_sppp.h> 58# define PP_CISCO IFF_LINK2 |
59# include <net/bpf.h> |
60#endif 61#include <dev/cx/machdep.h> 62#include <dev/cp/cpddk.h> 63#include <machine/cserial.h> 64#include <machine/resource.h> 65#include <machine/pmap.h> 66 67/* If we don't have Cronyx's sppp version, we don't have fr support via sppp */ --- 20 unchanged lines hidden (view full) --- 88 89 {0, 0} 90}; 91 92typedef struct _cp_dma_mem_t { 93 unsigned long phys; 94 void *virt; 95 size_t size; |
96 bus_dma_tag_t dmat; 97 bus_dmamap_t mapp; |
98} cp_dma_mem_t; 99 100typedef struct _drv_t { 101 char name [8]; 102 cp_chan_t *chan; 103 cp_board_t *board; 104 cp_dma_mem_t dmamem; 105 int running; --- 169 unchanged lines hidden (view full) --- 275 /* Turn LED off 50 msec later. */ 276 if (!led_timo[b->num].callout) 277 led_timo[b->num] = timeout (cp_led_off, b, hz/20); 278 splx (s); 279} 280 281extern struct cdevsw cp_cdevsw; 282 |
283static void 284cp_bus_dmamap_addr (void *arg, bus_dma_segment_t *segs, int nseg, int error) 285{ 286 unsigned long *addr; 287 288 if (error) 289 return; 290 --- 40 unchanged lines hidden (view full) --- 331 332static void 333cp_bus_dma_mem_free (cp_dma_mem_t *dmem) 334{ 335 bus_dmamap_unload (dmem->dmat, dmem->mapp); 336 bus_dmamem_free (dmem->dmat, dmem->virt, dmem->mapp); 337 bus_dma_tag_destroy (dmem->dmat); 338} |
339 |
340/* 341 * Called if the probe succeeded. 342 */ 343static int cp_attach (device_t dev) 344{ 345 bdrv_t *bd = device_get_softc (dev); 346 int unit = device_get_unit (dev); 347 unsigned short res; --- 80 unchanged lines hidden (view full) --- 428 d->chan = c; 429 c->sys = d; 430#ifdef NETGRAPH 431 if (ng_make_node_common (&typestruct, &d->node) != 0) { 432 printf ("%s: cannot make common node\n", d->name); 433 d->node = NULL; 434 continue; 435 } |
436 NG_NODE_SET_PRIVATE (d->node, d); |
437 sprintf (d->nodename, "%s%d", NG_CP_NODE_TYPE, 438 c->board->num*NCHAN + c->num); 439 if (ng_name_node (d->node, d->nodename)) { 440 printf ("%s: cannot name node\n", d->nodename); |
441 NG_NODE_UNREF (d->node); |
442 continue; 443 } 444 d->queue.ifq_maxlen = IFQ_MAXLEN; 445 d->hi_queue.ifq_maxlen = IFQ_MAXLEN; |
446 mtx_init (&d->queue.ifq_mtx, "cp_queue", NULL, MTX_DEF); 447 mtx_init (&d->hi_queue.ifq_mtx, "cp_queue_hi", NULL, MTX_DEF); |
448#else /*NETGRAPH*/ 449 d->pp.pp_if.if_softc = d; |
450 if_initname (&d->pp.pp_if, "cp", b->num * NCHAN + c->num); |
451 d->pp.pp_if.if_mtu = PP_MTU; 452 d->pp.pp_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST | 453 IFF_NEEDSGIANT; 454 d->pp.pp_if.if_ioctl = cp_sioctl; 455 d->pp.pp_if.if_start = cp_ifstart; 456 d->pp.pp_if.if_watchdog = cp_ifwatchdog; 457 d->pp.pp_if.if_init = cp_initialize; 458 sppp_attach (&d->pp.pp_if); --- 60 unchanged lines hidden (view full) --- 519 untimeout (cp_led_off, b, led_timo[b->num]); 520 521 for (c=b->chan; c<b->chan+NCHAN; ++c) { 522 drv_t *d = (drv_t*) c->sys; 523 524 if (! d || ! d->chan->type) 525 continue; 526#ifndef NETGRAPH |
527 /* Detach from the packet filter list of interfaces. */ 528 bpfdetach (&d->pp.pp_if); |
529 /* Detach from the sync PPP list. */ 530 sppp_detach (&d->pp.pp_if); 531 532 /* Detach from the system list of interfaces. */ 533 if_detach (&d->pp.pp_if); 534#else |
535 if (d->node) { 536 ng_rmnode_self (d->node); 537 NG_NODE_UNREF (d->node); 538 d->node = NULL; 539 } 540 mtx_destroy (&d->queue.ifq_mtx); 541 mtx_destroy (&d->hi_queue.ifq_mtx); |
542#endif |
543 destroy_dev (d->devt); 544 } 545 546 /* Disable the interrupt request. */ 547 bus_teardown_intr (dev, bd->cp_irq, bd->cp_intrhand); 548 bus_deactivate_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq); 549 bus_release_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq); 550 bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->cp_res); --- 163 unchanged lines hidden (view full) --- 714 IF_DEQUEUE (&d->queue, m); 715#else 716 m = sppp_dequeue (&d->pp.pp_if); 717#endif 718 if (! m) 719 return; 720#ifndef NETGRAPH 721 if (d->pp.pp_if.if_bpf) |
722 BPF_MTAP (&d->pp.pp_if, m); |
723#endif |
724 len = m->m_pkthdr.len; 725 if (len >= BUFSZ) 726 printf ("%s: too long packet: %d bytes: ", 727 d->name, len); 728 else if (! m->m_next) 729 cp_send_packet (d->chan, (u_char*) mtod (m, caddr_t), len, 0); 730 else { 731 u_char *buf = d->chan->tbuf[d->chan->te]; --- 63 unchanged lines hidden (view full) --- 795#endif 796 cp_start (d); 797} 798 799static void cp_receive (cp_chan_t *c, unsigned char *data, int len) 800{ 801 drv_t *d = c->sys; 802 struct mbuf *m; |
803#ifdef NETGRAPH |
804 int error; 805#endif 806 807 if (! d->running) 808 return; 809 810 m = makembuf (data, len); 811 if (! m) { 812 CP_DEBUG (d, ("no memory for packet\n")); 813#ifndef NETGRAPH 814 ++d->pp.pp_if.if_iqdrops; 815#endif 816 return; 817 } 818 if (c->debug > 1) 819 printmbuf (m); 820#ifdef NETGRAPH 821 m->m_pkthdr.rcvif = 0; |
822 NG_SEND_DATA_ONLY (error, d->hook, m); 823#else |
824 ++d->pp.pp_if.if_ipackets; 825 m->m_pkthdr.rcvif = &d->pp.pp_if; 826 /* Check if there's a BPF listener on this interface. 827 * If so, hand off the raw packet to bpf. */ 828 if (d->pp.pp_if.if_bpf) |
829 BPF_TAP (&d->pp.pp_if, data, len); |
830 sppp_input (&d->pp.pp_if, m); 831#endif 832} 833 834static void cp_error (cp_chan_t *c, int data) 835{ 836 drv_t *d = c->sys; 837 --- 39 unchanged lines hidden (view full) --- 877 break; 878 } 879} 880 881/* 882 * You also need read, write, open, close routines. 883 * This should get you started 884 */ |
885static int cp_open (struct cdev *dev, int oflags, int devtype, struct thread *td) |
886{ 887 int unit = minor (dev); 888 drv_t *d; 889 890 if (unit >= NBRD*NCHAN || ! (d = channel[unit])) 891 return ENXIO; 892 CP_DEBUG2 (d, ("cp_open\n")); 893 return 0; 894} 895 896/* 897 * Only called on the LAST close. 898 */ |
899static int cp_close (struct cdev *dev, int fflag, int devtype, struct thread *td) |
900{ 901 drv_t *d = channel [minor (dev)]; 902 903 CP_DEBUG2 (d, ("cp_close\n")); 904 return 0; 905} 906 907static int cp_modem_status (cp_chan_t *c) --- 7 unchanged lines hidden (view full) --- 915 if (cp_get_cts (c)) status |= TIOCM_CTS; 916 if (cp_get_dsr (c)) status |= TIOCM_DSR; 917 if (c->dtr) status |= TIOCM_DTR; 918 if (c->rts) status |= TIOCM_RTS; 919 splx (s); 920 return status; 921} 922 |
923static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) |
924{ 925 drv_t *d = channel [minor (dev)]; 926 cp_chan_t *c = d->chan; 927 struct serial_statistics *st; 928 struct e1_statistics *opte1; 929 struct e3_statistics *opte3; 930 int error, s; 931 char mask[16]; --- 13 unchanged lines hidden (view full) --- 945 CP_DEBUG2 (d, ("ioctl: getproto\n")); 946 strcpy ((char*)data, (d->pp.pp_flags & PP_FR) ? "fr" : 947 (d->pp.pp_if.if_flags & PP_CISCO) ? "cisco" : "ppp"); 948 return 0; 949 950 case SERIAL_SETPROTO: 951 CP_DEBUG2 (d, ("ioctl: setproto\n")); 952 /* Only for superuser! */ |
953 error = suser (td); |
954 if (error) 955 return error; 956 if (d->pp.pp_if.if_flags & IFF_RUNNING) 957 return EBUSY; 958 if (! strcmp ("cisco", (char*)data)) { 959 d->pp.pp_flags &= ~(PP_FR); 960 d->pp.pp_flags |= PP_KEEPALIVE; 961 d->pp.pp_if.if_flags |= PP_CISCO; --- 14 unchanged lines hidden (view full) --- 976 (d->pp.pp_if.if_flags & PP_CISCO)) 977 return EINVAL; 978 *(int*)data = (d->pp.pp_flags & PP_KEEPALIVE) ? 1 : 0; 979 return 0; 980 981 case SERIAL_SETKEEPALIVE: 982 CP_DEBUG2 (d, ("ioctl: setkeepalive\n")); 983 /* Only for superuser! */ |
984 error = suser (td); |
985 if (error) 986 return error; 987 if ((d->pp.pp_flags & PP_FR) || 988 (d->pp.pp_if.if_flags & PP_CISCO)) 989 return EINVAL; 990 s = splimp (); 991 if (*(int*)data) 992 d->pp.pp_flags |= PP_KEEPALIVE; --- 5 unchanged lines hidden (view full) --- 998 999 case SERIAL_GETMODE: 1000 CP_DEBUG2 (d, ("ioctl: getmode\n")); 1001 *(int*)data = SERIAL_HDLC; 1002 return 0; 1003 1004 case SERIAL_SETMODE: 1005 /* Only for superuser! */ |
1006 error = suser (td); |
1007 if (error) 1008 return error; 1009 if (*(int*)data != SERIAL_HDLC) 1010 return EINVAL; 1011 return 0; 1012 1013 case SERIAL_GETCFG: 1014 CP_DEBUG2 (d, ("ioctl: getcfg\n")); 1015 if (c->type != T_E1 || c->unfram) 1016 return EINVAL; 1017 *(char*)data = c->board->mux ? 'c' : 'a'; 1018 return 0; 1019 1020 case SERIAL_SETCFG: 1021 CP_DEBUG2 (d, ("ioctl: setcfg\n")); |
1022 error = suser (td); |
1023 if (error) 1024 return error; 1025 if (c->type != T_E1) 1026 return EINVAL; 1027 s = splimp (); 1028 cp_set_mux (c->board, *((char*)data) == 'c'); 1029 splx (s); 1030 return 0; --- 78 unchanged lines hidden (view full) --- 1109 for (s = 0; s < 48; ++s) { 1110 opte3->icv[s] = c->e3icv[s]; 1111 } 1112 return 0; 1113 1114 case SERIAL_CLRSTAT: 1115 CP_DEBUG2 (d, ("ioctl: clrstat\n")); 1116 /* Only for superuser! */ |
1117 error = suser (td); |
1118 if (error) 1119 return error; 1120 c->rintr = 0; 1121 c->tintr = 0; 1122 c->ibytes = 0; 1123 c->obytes = 0; 1124 c->ipkts = 0; 1125 c->opkts = 0; --- 12 unchanged lines hidden (view full) --- 1138 case SERIAL_GETBAUD: 1139 CP_DEBUG2 (d, ("ioctl: getbaud\n")); 1140 *(long*)data = c->baud; 1141 return 0; 1142 1143 case SERIAL_SETBAUD: 1144 CP_DEBUG2 (d, ("ioctl: setbaud\n")); 1145 /* Only for superuser! */ |
1146 error = suser (td); |
1147 if (error) 1148 return error; 1149 s = splimp (); 1150 cp_set_baud (c, *(long*)data); 1151 splx (s); 1152 return 0; 1153 1154 case SERIAL_GETLOOP: 1155 CP_DEBUG2 (d, ("ioctl: getloop\n")); 1156 *(int*)data = c->lloop; 1157 return 0; 1158 1159 case SERIAL_SETLOOP: 1160 CP_DEBUG2 (d, ("ioctl: setloop\n")); 1161 /* Only for superuser! */ |
1162 error = suser (td); |
1163 if (error) 1164 return error; 1165 s = splimp (); 1166 cp_set_lloop (c, *(int*)data); 1167 splx (s); 1168 return 0; 1169 1170 case SERIAL_GETDPLL: 1171 CP_DEBUG2 (d, ("ioctl: getdpll\n")); 1172 if (c->type != T_SERIAL) 1173 return EINVAL; 1174 *(int*)data = c->dpll; 1175 return 0; 1176 1177 case SERIAL_SETDPLL: 1178 CP_DEBUG2 (d, ("ioctl: setdpll\n")); 1179 /* Only for superuser! */ |
1180 error = suser (td); |
1181 if (error) 1182 return error; 1183 if (c->type != T_SERIAL) 1184 return EINVAL; 1185 s = splimp (); 1186 cp_set_dpll (c, *(int*)data); 1187 splx (s); 1188 return 0; 1189 1190 case SERIAL_GETNRZI: 1191 CP_DEBUG2 (d, ("ioctl: getnrzi\n")); 1192 if (c->type != T_SERIAL) 1193 return EINVAL; 1194 *(int*)data = c->nrzi; 1195 return 0; 1196 1197 case SERIAL_SETNRZI: 1198 CP_DEBUG2 (d, ("ioctl: setnrzi\n")); 1199 /* Only for superuser! */ |
1200 error = suser (td); |
1201 if (error) 1202 return error; 1203 if (c->type != T_SERIAL) 1204 return EINVAL; 1205 s = splimp (); 1206 cp_set_nrzi (c, *(int*)data); 1207 splx (s); 1208 return 0; 1209 1210 case SERIAL_GETDEBUG: 1211 CP_DEBUG2 (d, ("ioctl: getdebug\n")); 1212 *(int*)data = d->chan->debug; 1213 return 0; 1214 1215 case SERIAL_SETDEBUG: 1216 CP_DEBUG2 (d, ("ioctl: setdebug\n")); 1217 /* Only for superuser! */ |
1218 error = suser (td); |
1219 if (error) 1220 return error; 1221 d->chan->debug = *(int*)data; 1222#ifndef NETGRAPH 1223 if (d->chan->debug) 1224 d->pp.pp_if.if_flags |= IFF_DEBUG; 1225 else 1226 d->pp.pp_if.if_flags &= ~IFF_DEBUG; --- 5 unchanged lines hidden (view full) --- 1232 if (c->type != T_E1) 1233 return EINVAL; 1234 *(int*)data = c->higain; 1235 return 0; 1236 1237 case SERIAL_SETHIGAIN: 1238 CP_DEBUG2 (d, ("ioctl: sethigain\n")); 1239 /* Only for superuser! */ |
1240 error = suser (td); |
1241 if (error) 1242 return error; 1243 if (c->type != T_E1) 1244 return EINVAL; 1245 s = splimp (); 1246 cp_set_higain (c, *(int*)data); 1247 splx (s); 1248 return 0; 1249 1250 case SERIAL_GETPHONY: 1251 CP_DEBUG2 (d, ("ioctl: getphony\n")); 1252 if (c->type != T_E1) 1253 return EINVAL; 1254 *(int*)data = c->phony; 1255 return 0; 1256 1257 case SERIAL_SETPHONY: 1258 CP_DEBUG2 (d, ("ioctl: setphony\n")); 1259 /* Only for superuser! */ |
1260 error = suser (td); |
1261 if (error) 1262 return error; 1263 if (c->type != T_E1) 1264 return EINVAL; 1265 s = splimp (); 1266 cp_set_phony (c, *(int*)data); 1267 splx (s); 1268 return 0; 1269 1270 case SERIAL_GETUNFRAM: 1271 CP_DEBUG2 (d, ("ioctl: getunfram\n")); 1272 if (c->type != T_E1) 1273 return EINVAL; 1274 *(int*)data = c->unfram; 1275 return 0; 1276 1277 case SERIAL_SETUNFRAM: 1278 CP_DEBUG2 (d, ("ioctl: setunfram\n")); 1279 /* Only for superuser! */ |
1280 error = suser (td); |
1281 if (error) 1282 return error; 1283 if (c->type != T_E1) 1284 return EINVAL; 1285 s = splimp (); 1286 cp_set_unfram (c, *(int*)data); 1287 splx (s); 1288 return 0; 1289 1290 case SERIAL_GETSCRAMBLER: 1291 CP_DEBUG2 (d, ("ioctl: getscrambler\n")); 1292 if (c->type != T_G703 && !c->unfram) 1293 return EINVAL; 1294 *(int*)data = c->scrambler; 1295 return 0; 1296 1297 case SERIAL_SETSCRAMBLER: 1298 CP_DEBUG2 (d, ("ioctl: setscrambler\n")); 1299 /* Only for superuser! */ |
1300 error = suser (td); |
1301 if (error) 1302 return error; 1303 if (c->type != T_G703 && !c->unfram) 1304 return EINVAL; 1305 s = splimp (); 1306 cp_set_scrambler (c, *(int*)data); 1307 splx (s); 1308 return 0; --- 6 unchanged lines hidden (view full) --- 1315 c->type != T_STS1) 1316 return EINVAL; 1317 *(int*)data = c->monitor; 1318 return 0; 1319 1320 case SERIAL_SETMONITOR: 1321 CP_DEBUG2 (d, ("ioctl: setmonitor\n")); 1322 /* Only for superuser! */ |
1323 error = suser (td); |
1324 if (error) 1325 return error; 1326 if (c->type != T_E1) 1327 return EINVAL; 1328 s = splimp (); 1329 cp_set_monitor (c, *(int*)data); 1330 splx (s); 1331 return 0; 1332 1333 case SERIAL_GETUSE16: 1334 CP_DEBUG2 (d, ("ioctl: getuse16\n")); 1335 if (c->type != T_E1 || c->unfram) 1336 return EINVAL; 1337 *(int*)data = c->use16; 1338 return 0; 1339 1340 case SERIAL_SETUSE16: 1341 CP_DEBUG2 (d, ("ioctl: setuse16\n")); 1342 /* Only for superuser! */ |
1343 error = suser (td); |
1344 if (error) 1345 return error; 1346 if (c->type != T_E1) 1347 return EINVAL; 1348 s = splimp (); 1349 cp_set_use16 (c, *(int*)data); 1350 splx (s); 1351 return 0; 1352 1353 case SERIAL_GETCRC4: 1354 CP_DEBUG2 (d, ("ioctl: getcrc4\n")); 1355 if (c->type != T_E1 || c->unfram) 1356 return EINVAL; 1357 *(int*)data = c->crc4; 1358 return 0; 1359 1360 case SERIAL_SETCRC4: 1361 CP_DEBUG2 (d, ("ioctl: setcrc4\n")); 1362 /* Only for superuser! */ |
1363 error = suser (td); |
1364 if (error) 1365 return error; 1366 if (c->type != T_E1) 1367 return EINVAL; 1368 s = splimp (); 1369 cp_set_crc4 (c, *(int*)data); 1370 splx (s); 1371 return 0; --- 14 unchanged lines hidden (view full) --- 1386 case GSYN_RCV2: *(int*)data = E1CLK_RECEIVE_CHAN2; break; 1387 case GSYN_RCV3: *(int*)data = E1CLK_RECEIVE_CHAN3; break; 1388 } 1389 return 0; 1390 1391 case SERIAL_SETCLK: 1392 CP_DEBUG2 (d, ("ioctl: setclk\n")); 1393 /* Only for superuser! */ |
1394 error = suser (td); |
1395 if (error) 1396 return error; 1397 if (c->type != T_E1 && 1398 c->type != T_G703 && 1399 c->type != T_E3 && 1400 c->type != T_T3 && 1401 c->type != T_STS1) 1402 return EINVAL; --- 14 unchanged lines hidden (view full) --- 1417 if ((c->type != T_E1 || c->unfram) && c->type != T_DATA) 1418 return EINVAL; 1419 *(u_long*)data = c->ts; 1420 return 0; 1421 1422 case SERIAL_SETTIMESLOTS: 1423 CP_DEBUG2 (d, ("ioctl: settimeslots\n")); 1424 /* Only for superuser! */ |
1425 error = suser (td); |
1426 if (error) 1427 return error; 1428 if ((c->type != T_E1 || c->unfram) && c->type != T_DATA) 1429 return EINVAL; 1430 s = splimp (); 1431 cp_set_ts (c, *(u_long*)data); 1432 splx (s); 1433 return 0; --- 7 unchanged lines hidden (view full) --- 1441 return EINVAL; 1442 *(int*)data = c->invtxc; 1443 return 0; 1444#endif 1445 1446 case SERIAL_SETINVCLK: 1447 CP_DEBUG2 (d, ("ioctl: setinvclk\n")); 1448 /* Only for superuser! */ |
1449 error = suser (td); |
1450 if (error) 1451 return error; 1452 if (c->type != T_SERIAL) 1453 return EINVAL; 1454 s = splimp (); 1455 cp_set_invtxc (c, *(int*)data); 1456 cp_set_invrxc (c, *(int*)data); 1457 splx (s); --- 4 unchanged lines hidden (view full) --- 1462 if (c->type != T_SERIAL) 1463 return EINVAL; 1464 *(int*)data = c->invtxc; 1465 return 0; 1466 1467 case SERIAL_SETINVTCLK: 1468 CP_DEBUG2 (d, ("ioctl: setinvtclk\n")); 1469 /* Only for superuser! */ |
1470 error = suser (td); |
1471 if (error) 1472 return error; 1473 if (c->type != T_SERIAL) 1474 return EINVAL; 1475 s = splimp (); 1476 cp_set_invtxc (c, *(int*)data); 1477 splx (s); 1478 return 0; 1479 1480 case SERIAL_GETINVRCLK: 1481 CP_DEBUG2 (d, ("ioctl: getinvrclk\n")); 1482 if (c->type != T_SERIAL) 1483 return EINVAL; 1484 *(int*)data = c->invrxc; 1485 return 0; 1486 1487 case SERIAL_SETINVRCLK: 1488 CP_DEBUG2 (d, ("ioctl: setinvrclk\n")); 1489 /* Only for superuser! */ |
1490 error = suser (td); |
1491 if (error) 1492 return error; 1493 if (c->type != T_SERIAL) 1494 return EINVAL; 1495 s = splimp (); 1496 cp_set_invrxc (c, *(int*)data); 1497 splx (s); 1498 return 0; --- 6 unchanged lines hidden (view full) --- 1505 *(int*)data = cp_get_lq (c); 1506 splx (s); 1507 return 0; 1508 1509#if 0 1510 case SERIAL_RESET: 1511 CP_DEBUG2 (d, ("ioctl: reset\n")); 1512 /* Only for superuser! */ |
1513 error = suser (td); |
1514 if (error) 1515 return error; 1516 s = splimp (); 1517 cp_reset (c->board, 0, 0); 1518 splx (s); 1519 return 0; 1520 1521 case SERIAL_HARDRESET: 1522 CP_DEBUG2 (d, ("ioctl: hardreset\n")); 1523 /* Only for superuser! */ |
1524 error = suser (td); |
1525 if (error) 1526 return error; 1527 s = splimp (); 1528 /* hard_reset (c->board); */ 1529 splx (s); 1530 return 0; 1531#endif 1532 --- 11 unchanged lines hidden (view full) --- 1544 if (c->type != T_E1 && c->type != T_DATA) 1545 return EINVAL; 1546 *(int*)data = c->dir; 1547 return 0; 1548 1549 case SERIAL_SETDIR: 1550 CP_DEBUG2 (d, ("ioctl: setdir\n")); 1551 /* Only for superuser! */ |
1552 error = suser (td); |
1553 if (error) 1554 return error; 1555 s = splimp (); 1556 cp_set_dir (c, *(int*)data); 1557 splx (s); 1558 return 0; 1559 1560 case SERIAL_GETRLOOP: --- 6 unchanged lines hidden (view full) --- 1567 *(int*)data = cp_get_rloop (c); 1568 return 0; 1569 1570 case SERIAL_SETRLOOP: 1571 CP_DEBUG2 (d, ("ioctl: setloop\n")); 1572 if (c->type != T_E3 && c->type != T_T3 && c->type != T_STS1) 1573 return EINVAL; 1574 /* Only for superuser! */ |
1575 error = suser (td); |
1576 if (error) 1577 return error; 1578 s = splimp (); 1579 cp_set_rloop (c, *(int*)data); 1580 splx (s); 1581 return 0; 1582 1583 case SERIAL_GETCABLEN: 1584 CP_DEBUG2 (d, ("ioctl: getcablen\n")); 1585 if (c->type != T_T3 && c->type != T_STS1) 1586 return EINVAL; 1587 *(int*)data = c->cablen; 1588 return 0; 1589 1590 case SERIAL_SETCABLEN: 1591 CP_DEBUG2 (d, ("ioctl: setloop\n")); 1592 if (c->type != T_T3 && c->type != T_STS1) 1593 return EINVAL; 1594 /* Only for superuser! */ |
1595 error = suser (td); |
1596 if (error) 1597 return error; 1598 s = splimp (); 1599 cp_set_cablen (c, *(int*)data); 1600 splx (s); 1601 return 0; 1602 1603 case TIOCSDTR: /* Set DTR */ --- 31 unchanged lines hidden (view full) --- 1635 1636 case TIOCMGET: /* Get modem status */ 1637 *(int*)data = cp_modem_status (c); 1638 return 0; 1639 } 1640 return ENOTTY; 1641} 1642 |
1643static struct cdevsw cp_cdevsw = { |
1644 .d_version = D_VERSION, 1645 .d_open = cp_open, 1646 .d_close = cp_close, 1647 .d_ioctl = cp_ioctl, 1648 .d_name = "cp", 1649 .d_maj = CDEV_MAJOR, 1650 .d_flags = D_NEEDGIANT, 1651}; |
1652 1653#ifdef NETGRAPH |
1654static int ng_cp_constructor (node_p node) 1655{ 1656 drv_t *d = NG_NODE_PRIVATE (node); |
1657 CP_DEBUG (d, ("Constructor\n")); 1658 return EINVAL; 1659} 1660 1661static int ng_cp_newhook (node_p node, hook_p hook, const char *name) 1662{ 1663 int s; |
1664 drv_t *d = NG_NODE_PRIVATE (node); |
1665 1666 CP_DEBUG (d, ("Newhook\n")); 1667 /* Attach debug hook */ 1668 if (strcmp (name, NG_CP_HOOK_DEBUG) == 0) { |
1669 NG_HOOK_SET_PRIVATE (hook, NULL); |
1670 d->debug_hook = hook; 1671 return 0; 1672 } 1673 1674 /* Check for raw hook */ 1675 if (strcmp (name, NG_CP_HOOK_RAW) != 0) 1676 return EINVAL; 1677 |
1678 NG_HOOK_SET_PRIVATE (hook, d); |
1679 d->hook = hook; 1680 s = splimp (); 1681 cp_up (d); 1682 splx (s); 1683 return 0; 1684} 1685 1686static char *format_timeslots (u_long s) --- 226 unchanged lines hidden (view full) --- 1913 lq = cp_get_lq (c); 1914 splx (x); 1915 length += sprintf (s + length, " (level=-%.1fdB)", lq / 10.0); 1916 } 1917 length += sprintf (s + length, "\n"); 1918 return length; 1919} 1920 |
1921static int ng_cp_rcvmsg (node_p node, item_p item, hook_p lasthook) 1922{ 1923 drv_t *d = NG_NODE_PRIVATE (node); 1924 struct ng_mesg *msg; |
1925 struct ng_mesg *resp = NULL; 1926 int error = 0; 1927 1928 CP_DEBUG (d, ("Rcvmsg\n")); |
1929 NGI_GET_MSG (item, msg); |
1930 switch (msg->header.typecookie) { 1931 default: 1932 error = EINVAL; 1933 break; 1934 1935 case NGM_CP_COOKIE: 1936 printf ("Not implemented yet\n"); 1937 error = EINVAL; --- 5 unchanged lines hidden (view full) --- 1943 error = EINVAL; 1944 break; 1945 1946 case NGM_TEXT_STATUS: { 1947 char *s; 1948 int l = 0; 1949 int dl = sizeof (struct ng_mesg) + 730; 1950 |
1951 NG_MKRESPONSE (resp, msg, dl, M_NOWAIT); 1952 if (! resp) { 1953 error = ENOMEM; 1954 break; 1955 } |
1956 s = (resp)->data; 1957 if (d) { 1958 l += print_chan (s + l, d->chan); 1959 l += print_stats (s + l, d->chan, 1); 1960 l += print_modems (s + l, d->chan, 1); 1961 l += print_e1_stats (s + l, d->chan); 1962 } else 1963 l += sprintf (s + l, "Error: node not connect to channel"); |
1964 strncpy ((resp)->header.cmdstr, "status", NG_CMDSTRLEN); 1965 } 1966 break; 1967 } 1968 break; 1969 } |
1970 NG_RESPOND_MSG (error, node, item, resp); 1971 NG_FREE_MSG (msg); |
1972 return error; 1973} 1974 |
1975static int ng_cp_rcvdata (hook_p hook, item_p item) 1976{ 1977 drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE(hook)); 1978 struct mbuf *m; 1979 struct ng_tag_prio *ptag; |
1980 struct ifqueue *q; 1981 int s; 1982 1983 CP_DEBUG2 (d, ("Rcvdata\n")); |
1984 NGI_GET_M (item, m); 1985 NG_FREE_ITEM (item); 1986 if (! NG_HOOK_PRIVATE (hook) || ! d) { 1987 NG_FREE_M (m); |
1988 return ENETDOWN; 1989 } 1990 1991 /* Check for high priority data */ 1992 if ((ptag = (struct ng_tag_prio *)m_tag_locate(m, NGM_GENERIC_COOKIE, 1993 NG_TAG_PRIO, NULL)) != NULL && (ptag->priority > NG_PRIO_CUTOFF) ) 1994 q = &d->hi_queue; 1995 else 1996 q = &d->queue; 1997 1998 s = splimp (); |
1999 IF_LOCK (q); 2000 if (_IF_QFULL (q)) { 2001 _IF_DROP (q); 2002 IF_UNLOCK (q); 2003 splx (s); 2004 NG_FREE_M (m); 2005 return ENOBUFS; 2006 } 2007 _IF_ENQUEUE (q, m); 2008 IF_UNLOCK (q); |
2009 cp_start (d); 2010 splx (s); 2011 return 0; 2012} 2013 2014static int ng_cp_rmnode (node_p node) 2015{ |
2016 drv_t *d = NG_NODE_PRIVATE (node); 2017 2018 CP_DEBUG (d, ("Rmnode\n")); 2019 if (d && d->running) { 2020 int s = splimp (); 2021 cp_down (d); 2022 splx (s); 2023 } 2024#ifdef KLD_MODULE 2025 if (node->nd_flags & NGF_REALLY_DIE) { 2026 NG_NODE_SET_PRIVATE (node, NULL); 2027 NG_NODE_UNREF (node); 2028 } 2029 NG_NODE_REVIVE(node); /* Persistant node */ 2030#endif |
2031 return 0; 2032} 2033 2034static void ng_cp_watchdog (void *arg) 2035{ 2036 drv_t *d = arg; 2037 2038 if (d) { 2039 if (d->timeout == 1) 2040 cp_watchdog (d); 2041 if (d->timeout) 2042 d->timeout--; 2043 d->timeout_handle = timeout (ng_cp_watchdog, d, hz); 2044 } 2045} 2046 2047static int ng_cp_connect (hook_p hook) 2048{ |
2049 drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); |
2050 2051 if (d) { 2052 CP_DEBUG (d, ("Connect\n")); 2053 d->timeout_handle = timeout (ng_cp_watchdog, d, hz); 2054 } 2055 2056 return 0; 2057} 2058 2059static int ng_cp_disconnect (hook_p hook) 2060{ |
2061 drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); |
2062 2063 if (d) { 2064 CP_DEBUG (d, ("Disconnect\n")); |
2065 if (NG_HOOK_PRIVATE (hook)) |
2066 { 2067 int s = splimp (); 2068 cp_down (d); 2069 splx (s); 2070 } 2071 untimeout (ng_cp_watchdog, d, d->timeout_handle); 2072 } 2073 return 0; 2074} 2075#endif 2076 2077static int cp_modevent (module_t mod, int type, void *unused) 2078{ 2079 static int load_count = 0; 2080 2081 switch (type) { 2082 case MOD_LOAD: |
2083#ifdef NETGRAPH |
2084 if (ng_newtype (&typestruct)) 2085 printf ("Failed to register ng_cp\n"); 2086#endif 2087 ++load_count; |
2088 timeout_handle = timeout (cp_timeout, 0, hz*5); 2089 break; 2090 case MOD_UNLOAD: 2091 if (load_count == 1) { 2092 printf ("Removing device entry for Tau-PCI\n"); |
2093#ifdef NETGRAPH |
2094 ng_rmtype (&typestruct); 2095#endif 2096 } 2097 untimeout (cp_timeout, 0, timeout_handle); 2098 --load_count; 2099 break; 2100 case MOD_SHUTDOWN: 2101 break; --- 10 unchanged lines hidden (view full) --- 2112 .shutdown = ng_cp_rmnode, 2113 .newhook = ng_cp_newhook, 2114 .connect = ng_cp_connect, 2115 .rcvdata = ng_cp_rcvdata, 2116 .disconnect = ng_cp_disconnect, 2117}; 2118#endif /*NETGRAPH*/ 2119 |
2120#ifdef NETGRAPH 2121MODULE_DEPEND (ng_cp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION); 2122#else 2123MODULE_DEPEND (cp, sppp, 1, 1, 1); 2124#endif 2125#ifdef KLD_MODULE 2126DRIVER_MODULE (cpmod, pci, cp_driver, cp_devclass, cp_modevent, NULL); 2127#else 2128DRIVER_MODULE (cp, pci, cp_driver, cp_devclass, cp_modevent, NULL); 2129#endif |