12439e4bfSJean-Christophe PLAGNIOL-VILLARD /* 22439e4bfSJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2004 32439e4bfSJean-Christophe PLAGNIOL-VILLARD * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 42439e4bfSJean-Christophe PLAGNIOL-VILLARD * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 62439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 72439e4bfSJean-Christophe PLAGNIOL-VILLARD 82439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 92439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <command.h> 1052cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h> 112439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <net.h> 122439e4bfSJean-Christophe PLAGNIOL-VILLARD 132439e4bfSJean-Christophe PLAGNIOL-VILLARD DECLARE_GLOBAL_DATA_PTR; 142439e4bfSJean-Christophe PLAGNIOL-VILLARD 152c8fe512SJoe Hershberger #ifndef CONFIG_NETCONSOLE_BUFFER_SIZE 162c8fe512SJoe Hershberger #define CONFIG_NETCONSOLE_BUFFER_SIZE 512 172c8fe512SJoe Hershberger #endif 182c8fe512SJoe Hershberger 192c8fe512SJoe Hershberger static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE]; 20e1902ac6SJoe Hershberger static int input_size; /* char count in input buffer */ 21e1902ac6SJoe Hershberger static int input_offset; /* offset to valid chars in input buffer */ 22e1902ac6SJoe Hershberger static int input_recursion; 23e1902ac6SJoe Hershberger static int output_recursion; 242439e4bfSJean-Christophe PLAGNIOL-VILLARD static int net_timeout; 252439e4bfSJean-Christophe PLAGNIOL-VILLARD static uchar nc_ether[6]; /* server enet address */ 26049a95a7SJoe Hershberger static struct in_addr nc_ip; /* server ip */ 277f51898cSJoe Hershberger static short nc_out_port; /* target output port */ 287f51898cSJoe Hershberger static short nc_in_port; /* source input port */ 292439e4bfSJean-Christophe PLAGNIOL-VILLARD static const char *output_packet; /* used by first send udp */ 30e1902ac6SJoe Hershberger static int output_packet_len; 31f8be7d65SJoe Hershberger /* 32f8be7d65SJoe Hershberger * Start with a default last protocol. 33f8be7d65SJoe Hershberger * We are only interested in NETCONS or not. 34f8be7d65SJoe Hershberger */ 35f8be7d65SJoe Hershberger enum proto_t net_loop_last_protocol = BOOTP; 362439e4bfSJean-Christophe PLAGNIOL-VILLARD 3703eb129fSLuca Ceresoli static void nc_wait_arp_handler(uchar *pkt, unsigned dest, 38049a95a7SJoe Hershberger struct in_addr sip, unsigned src, 392439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned len) 402439e4bfSJean-Christophe PLAGNIOL-VILLARD { 4122f6e99dSJoe Hershberger net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */ 422439e4bfSJean-Christophe PLAGNIOL-VILLARD } 432439e4bfSJean-Christophe PLAGNIOL-VILLARD 44049a95a7SJoe Hershberger static void nc_handler(uchar *pkt, unsigned dest, struct in_addr sip, 45049a95a7SJoe Hershberger unsigned src, unsigned len) 462439e4bfSJean-Christophe PLAGNIOL-VILLARD { 472439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_size) 4822f6e99dSJoe Hershberger net_set_state(NETLOOP_SUCCESS); /* got input - quit net loop */ 492439e4bfSJean-Christophe PLAGNIOL-VILLARD } 502439e4bfSJean-Christophe PLAGNIOL-VILLARD 516a38a5f3SJoe Hershberger static void nc_timeout_handler(void) 522439e4bfSJean-Christophe PLAGNIOL-VILLARD { 5322f6e99dSJoe Hershberger net_set_state(NETLOOP_SUCCESS); 542439e4bfSJean-Christophe PLAGNIOL-VILLARD } 552439e4bfSJean-Christophe PLAGNIOL-VILLARD 56049a95a7SJoe Hershberger static int is_broadcast(struct in_addr ip) 57e827fec2SJoe Hershberger { 58049a95a7SJoe Hershberger static struct in_addr netmask; 59049a95a7SJoe Hershberger static struct in_addr our_ip; 60e827fec2SJoe Hershberger static int env_changed_id; 61e827fec2SJoe Hershberger int env_id = get_env_id(); 62e827fec2SJoe Hershberger 63e827fec2SJoe Hershberger /* update only when the environment has changed */ 64e827fec2SJoe Hershberger if (env_changed_id != env_id) { 65049a95a7SJoe Hershberger netmask = getenv_ip("netmask"); 66049a95a7SJoe Hershberger our_ip = getenv_ip("ipaddr"); 67e827fec2SJoe Hershberger 68e827fec2SJoe Hershberger env_changed_id = env_id; 69e827fec2SJoe Hershberger } 70e827fec2SJoe Hershberger 71049a95a7SJoe Hershberger return (ip.s_addr == ~0 || /* 255.255.255.255 (global bcast) */ 72049a95a7SJoe Hershberger ((netmask.s_addr & our_ip.s_addr) == 73049a95a7SJoe Hershberger (netmask.s_addr & ip.s_addr) && /* on the same net and */ 74049a95a7SJoe Hershberger (netmask.s_addr | ip.s_addr) == ~0)); /* bcast to our net */ 75e827fec2SJoe Hershberger } 76e827fec2SJoe Hershberger 77e827fec2SJoe Hershberger static int refresh_settings_from_env(void) 78e827fec2SJoe Hershberger { 79e827fec2SJoe Hershberger const char *p; 80e827fec2SJoe Hershberger static int env_changed_id; 81e827fec2SJoe Hershberger int env_id = get_env_id(); 82e827fec2SJoe Hershberger 83e827fec2SJoe Hershberger /* update only when the environment has changed */ 84e827fec2SJoe Hershberger if (env_changed_id != env_id) { 85e827fec2SJoe Hershberger if (getenv("ncip")) { 86049a95a7SJoe Hershberger nc_ip = getenv_ip("ncip"); 87049a95a7SJoe Hershberger if (!nc_ip.s_addr) 88e827fec2SJoe Hershberger return -1; /* ncip is 0.0.0.0 */ 89e827fec2SJoe Hershberger p = strchr(getenv("ncip"), ':'); 90e827fec2SJoe Hershberger if (p != NULL) { 91e827fec2SJoe Hershberger nc_out_port = simple_strtoul(p + 1, NULL, 10); 92e827fec2SJoe Hershberger nc_in_port = nc_out_port; 93e827fec2SJoe Hershberger } 946a38a5f3SJoe Hershberger } else { 95049a95a7SJoe Hershberger nc_ip.s_addr = ~0; /* ncip is not set, so broadcast */ 966a38a5f3SJoe Hershberger } 97e827fec2SJoe Hershberger 98e827fec2SJoe Hershberger p = getenv("ncoutport"); 99e827fec2SJoe Hershberger if (p != NULL) 100e827fec2SJoe Hershberger nc_out_port = simple_strtoul(p, NULL, 10); 101e827fec2SJoe Hershberger p = getenv("ncinport"); 102e827fec2SJoe Hershberger if (p != NULL) 103e827fec2SJoe Hershberger nc_in_port = simple_strtoul(p, NULL, 10); 104e827fec2SJoe Hershberger 105e827fec2SJoe Hershberger if (is_broadcast(nc_ip)) 106e827fec2SJoe Hershberger /* broadcast MAC address */ 107e827fec2SJoe Hershberger memset(nc_ether, 0xff, sizeof(nc_ether)); 108e827fec2SJoe Hershberger else 109e827fec2SJoe Hershberger /* force arp request */ 110e827fec2SJoe Hershberger memset(nc_ether, 0, sizeof(nc_ether)); 111e827fec2SJoe Hershberger } 112e827fec2SJoe Hershberger return 0; 113e827fec2SJoe Hershberger } 114e827fec2SJoe Hershberger 115e827fec2SJoe Hershberger /** 116bc0571fcSJoe Hershberger * Called from net_loop in net/net.c before each packet 117e827fec2SJoe Hershberger */ 1186a38a5f3SJoe Hershberger void nc_start(void) 1192439e4bfSJean-Christophe PLAGNIOL-VILLARD { 120e827fec2SJoe Hershberger refresh_settings_from_env(); 1210adb5b76SJoe Hershberger if (!output_packet_len || memcmp(nc_ether, net_null_ethaddr, 6)) { 1222439e4bfSJean-Christophe PLAGNIOL-VILLARD /* going to check for input packet */ 123ece223b5SJoe Hershberger net_set_udp_handler(nc_handler); 124bc0571fcSJoe Hershberger net_set_timeout_handler(net_timeout, nc_timeout_handler); 1252439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1262439e4bfSJean-Christophe PLAGNIOL-VILLARD /* send arp request */ 1272439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *pkt; 128ece223b5SJoe Hershberger net_set_arp_handler(nc_wait_arp_handler); 1291203fcceSJoe Hershberger pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + 1301203fcceSJoe Hershberger IP_UDP_HDR_SIZE; 1312439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(pkt, output_packet, output_packet_len); 1321203fcceSJoe Hershberger net_send_udp_packet(nc_ether, nc_ip, nc_out_port, nc_in_port, 133e1902ac6SJoe Hershberger output_packet_len); 1342439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1352439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1362439e4bfSJean-Christophe PLAGNIOL-VILLARD 137049a95a7SJoe Hershberger int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, 1388a0eccb1SJoe Hershberger unsigned src_port, unsigned len) 1392439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1402439e4bfSJean-Christophe PLAGNIOL-VILLARD int end, chunk; 1412439e4bfSJean-Christophe PLAGNIOL-VILLARD 1428a0eccb1SJoe Hershberger if (dest_port != nc_in_port || !len) 1432439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; /* not for us */ 1442439e4bfSJean-Christophe PLAGNIOL-VILLARD 145049a95a7SJoe Hershberger if (src_ip.s_addr != nc_ip.s_addr && !is_broadcast(nc_ip)) 1468a0eccb1SJoe Hershberger return 0; /* not from our client */ 1478a0eccb1SJoe Hershberger 1484ef8d53cSJoe Hershberger debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); 1494ef8d53cSJoe Hershberger 150e1902ac6SJoe Hershberger if (input_size == sizeof(input_buffer)) 1512439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; /* no space */ 152e1902ac6SJoe Hershberger if (len > sizeof(input_buffer) - input_size) 153e1902ac6SJoe Hershberger len = sizeof(input_buffer) - input_size; 1542439e4bfSJean-Christophe PLAGNIOL-VILLARD 1552439e4bfSJean-Christophe PLAGNIOL-VILLARD end = input_offset + input_size; 156e1902ac6SJoe Hershberger if (end > sizeof(input_buffer)) 157e1902ac6SJoe Hershberger end -= sizeof(input_buffer); 1582439e4bfSJean-Christophe PLAGNIOL-VILLARD 1592439e4bfSJean-Christophe PLAGNIOL-VILLARD chunk = len; 160e1902ac6SJoe Hershberger if (end + len > sizeof(input_buffer)) { 161e1902ac6SJoe Hershberger chunk = sizeof(input_buffer) - end; 1622439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(input_buffer, pkt + chunk, len - chunk); 1632439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1642439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(input_buffer + end, pkt, chunk); 1652439e4bfSJean-Christophe PLAGNIOL-VILLARD 1662439e4bfSJean-Christophe PLAGNIOL-VILLARD input_size += len; 1672439e4bfSJean-Christophe PLAGNIOL-VILLARD 1682439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 1692439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1702439e4bfSJean-Christophe PLAGNIOL-VILLARD 1712439e4bfSJean-Christophe PLAGNIOL-VILLARD static void nc_send_packet(const char *buf, int len) 1722439e4bfSJean-Christophe PLAGNIOL-VILLARD { 173*c163e436SBernhard Nortmann #ifdef CONFIG_DM_ETH 174*c163e436SBernhard Nortmann struct udevice *eth; 175*c163e436SBernhard Nortmann #else 1762439e4bfSJean-Christophe PLAGNIOL-VILLARD struct eth_device *eth; 177*c163e436SBernhard Nortmann #endif 1782439e4bfSJean-Christophe PLAGNIOL-VILLARD int inited = 0; 1792439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *pkt; 1802439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *ether; 181049a95a7SJoe Hershberger struct in_addr ip; 1822439e4bfSJean-Christophe PLAGNIOL-VILLARD 1834ef8d53cSJoe Hershberger debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf); 1844ef8d53cSJoe Hershberger 185e1902ac6SJoe Hershberger eth = eth_get_dev(); 186e1902ac6SJoe Hershberger if (eth == NULL) 1872439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1882439e4bfSJean-Christophe PLAGNIOL-VILLARD 1890adb5b76SJoe Hershberger if (!memcmp(nc_ether, net_null_ethaddr, 6)) { 190*c163e436SBernhard Nortmann if (eth_is_active(eth)) 1912439e4bfSJean-Christophe PLAGNIOL-VILLARD return; /* inside net loop */ 1922439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet = buf; 1932439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet_len = len; 194efd9bb9cSSuriyan Ramasami input_recursion = 1; 195bc0571fcSJoe Hershberger net_loop(NETCONS); /* wait for arp reply and send packet */ 196efd9bb9cSSuriyan Ramasami input_recursion = 0; 1972439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet_len = 0; 1982439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1992439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2002439e4bfSJean-Christophe PLAGNIOL-VILLARD 201*c163e436SBernhard Nortmann if (!eth_is_active(eth)) { 202f8be7d65SJoe Hershberger if (eth_is_on_demand_init()) { 203d2eaec60SJoe Hershberger if (eth_init() < 0) 2042439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 205f8be7d65SJoe Hershberger eth_set_last_protocol(NETCONS); 2066a38a5f3SJoe Hershberger } else { 207d2eaec60SJoe Hershberger eth_init_state_only(); 2086a38a5f3SJoe Hershberger } 209f8be7d65SJoe Hershberger 2102439e4bfSJean-Christophe PLAGNIOL-VILLARD inited = 1; 2112439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2121203fcceSJoe Hershberger pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; 2132439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(pkt, buf, len); 2142439e4bfSJean-Christophe PLAGNIOL-VILLARD ether = nc_ether; 2152439e4bfSJean-Christophe PLAGNIOL-VILLARD ip = nc_ip; 2161203fcceSJoe Hershberger net_send_udp_packet(ether, ip, nc_out_port, nc_in_port, len); 2172439e4bfSJean-Christophe PLAGNIOL-VILLARD 218f8be7d65SJoe Hershberger if (inited) { 219f8be7d65SJoe Hershberger if (eth_is_on_demand_init()) 2202439e4bfSJean-Christophe PLAGNIOL-VILLARD eth_halt(); 221f8be7d65SJoe Hershberger else 222f8be7d65SJoe Hershberger eth_halt_state_only(); 223f8be7d65SJoe Hershberger } 2242439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2252439e4bfSJean-Christophe PLAGNIOL-VILLARD 2266a38a5f3SJoe Hershberger static int nc_stdio_start(struct stdio_dev *dev) 2272439e4bfSJean-Christophe PLAGNIOL-VILLARD { 228e827fec2SJoe Hershberger int retval; 2292439e4bfSJean-Christophe PLAGNIOL-VILLARD 2307f51898cSJoe Hershberger nc_out_port = 6666; /* default port */ 2317f51898cSJoe Hershberger nc_in_port = nc_out_port; 2322439e4bfSJean-Christophe PLAGNIOL-VILLARD 233e827fec2SJoe Hershberger retval = refresh_settings_from_env(); 234e827fec2SJoe Hershberger if (retval != 0) 235e827fec2SJoe Hershberger return retval; 2362439e4bfSJean-Christophe PLAGNIOL-VILLARD 237d7310c7eSJoe Hershberger /* 238d7310c7eSJoe Hershberger * Initialize the static IP settings and buffer pointers 239bc0571fcSJoe Hershberger * incase we call net_send_udp_packet before net_loop 240d7310c7eSJoe Hershberger */ 241d7310c7eSJoe Hershberger net_init(); 242d7310c7eSJoe Hershberger 2432439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2442439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2452439e4bfSJean-Christophe PLAGNIOL-VILLARD 2466a38a5f3SJoe Hershberger static void nc_stdio_putc(struct stdio_dev *dev, char c) 2472439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2482439e4bfSJean-Christophe PLAGNIOL-VILLARD if (output_recursion) 2492439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 2502439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 1; 2512439e4bfSJean-Christophe PLAGNIOL-VILLARD 2522439e4bfSJean-Christophe PLAGNIOL-VILLARD nc_send_packet(&c, 1); 2532439e4bfSJean-Christophe PLAGNIOL-VILLARD 2542439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 0; 2552439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2562439e4bfSJean-Christophe PLAGNIOL-VILLARD 2576a38a5f3SJoe Hershberger static void nc_stdio_puts(struct stdio_dev *dev, const char *s) 2582439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2592439e4bfSJean-Christophe PLAGNIOL-VILLARD int len; 2602439e4bfSJean-Christophe PLAGNIOL-VILLARD 2612439e4bfSJean-Christophe PLAGNIOL-VILLARD if (output_recursion) 2622439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 2632439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 1; 2642439e4bfSJean-Christophe PLAGNIOL-VILLARD 2651a9845b4SMichael Walle len = strlen(s); 2661a9845b4SMichael Walle while (len) { 267b4141195SMasahiro Yamada int send_len = min(len, (int)sizeof(input_buffer)); 2681a9845b4SMichael Walle nc_send_packet(s, send_len); 2691a9845b4SMichael Walle len -= send_len; 2701a9845b4SMichael Walle s += send_len; 2711a9845b4SMichael Walle } 2722439e4bfSJean-Christophe PLAGNIOL-VILLARD 2732439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 0; 2742439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2752439e4bfSJean-Christophe PLAGNIOL-VILLARD 2766a38a5f3SJoe Hershberger static int nc_stdio_getc(struct stdio_dev *dev) 2772439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2782439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar c; 2792439e4bfSJean-Christophe PLAGNIOL-VILLARD 2802439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 1; 2812439e4bfSJean-Christophe PLAGNIOL-VILLARD 2822439e4bfSJean-Christophe PLAGNIOL-VILLARD net_timeout = 0; /* no timeout */ 2832439e4bfSJean-Christophe PLAGNIOL-VILLARD while (!input_size) 284bc0571fcSJoe Hershberger net_loop(NETCONS); 2852439e4bfSJean-Christophe PLAGNIOL-VILLARD 2862439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 0; 2872439e4bfSJean-Christophe PLAGNIOL-VILLARD 2882439e4bfSJean-Christophe PLAGNIOL-VILLARD c = input_buffer[input_offset++]; 2892439e4bfSJean-Christophe PLAGNIOL-VILLARD 290e1902ac6SJoe Hershberger if (input_offset >= sizeof(input_buffer)) 291e1902ac6SJoe Hershberger input_offset -= sizeof(input_buffer); 2922439e4bfSJean-Christophe PLAGNIOL-VILLARD input_size--; 2932439e4bfSJean-Christophe PLAGNIOL-VILLARD 2942439e4bfSJean-Christophe PLAGNIOL-VILLARD return c; 2952439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2962439e4bfSJean-Christophe PLAGNIOL-VILLARD 2976a38a5f3SJoe Hershberger static int nc_stdio_tstc(struct stdio_dev *dev) 2982439e4bfSJean-Christophe PLAGNIOL-VILLARD { 299*c163e436SBernhard Nortmann #ifdef CONFIG_DM_ETH 300*c163e436SBernhard Nortmann struct udevice *eth; 301*c163e436SBernhard Nortmann #else 3022439e4bfSJean-Christophe PLAGNIOL-VILLARD struct eth_device *eth; 303*c163e436SBernhard Nortmann #endif 3042439e4bfSJean-Christophe PLAGNIOL-VILLARD 3052439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_recursion) 3062439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 3072439e4bfSJean-Christophe PLAGNIOL-VILLARD 3082439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_size) 3092439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 3102439e4bfSJean-Christophe PLAGNIOL-VILLARD 3112439e4bfSJean-Christophe PLAGNIOL-VILLARD eth = eth_get_dev(); 312*c163e436SBernhard Nortmann if (eth_is_active(eth)) 3132439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; /* inside net loop */ 3142439e4bfSJean-Christophe PLAGNIOL-VILLARD 3152439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 1; 3162439e4bfSJean-Christophe PLAGNIOL-VILLARD 3172439e4bfSJean-Christophe PLAGNIOL-VILLARD net_timeout = 1; 318bc0571fcSJoe Hershberger net_loop(NETCONS); /* kind of poll */ 3192439e4bfSJean-Christophe PLAGNIOL-VILLARD 3202439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 0; 3212439e4bfSJean-Christophe PLAGNIOL-VILLARD 3222439e4bfSJean-Christophe PLAGNIOL-VILLARD return input_size != 0; 3232439e4bfSJean-Christophe PLAGNIOL-VILLARD } 3242439e4bfSJean-Christophe PLAGNIOL-VILLARD 3252439e4bfSJean-Christophe PLAGNIOL-VILLARD int drv_nc_init(void) 3262439e4bfSJean-Christophe PLAGNIOL-VILLARD { 32752cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev dev; 3282439e4bfSJean-Christophe PLAGNIOL-VILLARD int rc; 3292439e4bfSJean-Christophe PLAGNIOL-VILLARD 3302439e4bfSJean-Christophe PLAGNIOL-VILLARD memset(&dev, 0, sizeof(dev)); 3312439e4bfSJean-Christophe PLAGNIOL-VILLARD 3322439e4bfSJean-Christophe PLAGNIOL-VILLARD strcpy(dev.name, "nc"); 3332439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; 3346a38a5f3SJoe Hershberger dev.start = nc_stdio_start; 3356a38a5f3SJoe Hershberger dev.putc = nc_stdio_putc; 3366a38a5f3SJoe Hershberger dev.puts = nc_stdio_puts; 3376a38a5f3SJoe Hershberger dev.getc = nc_stdio_getc; 3386a38a5f3SJoe Hershberger dev.tstc = nc_stdio_tstc; 3392439e4bfSJean-Christophe PLAGNIOL-VILLARD 34052cb4d4fSJean-Christophe PLAGNIOL-VILLARD rc = stdio_register(&dev); 3412439e4bfSJean-Christophe PLAGNIOL-VILLARD 3422439e4bfSJean-Christophe PLAGNIOL-VILLARD return (rc == 0) ? 1 : rc; 3432439e4bfSJean-Christophe PLAGNIOL-VILLARD } 344