netiucv.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:53k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: netiucv.c,v 1.16 2001/12/03 14:28:45 felfert Exp $
  3.  *
  4.  * IUCV network driver
  5.  *
  6.  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7.  * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
  8.  *
  9.  * Documentation used:
  10.  *  the source of the original IUCV driver by:
  11.  *    Stefan Hegewald <hegewald@de.ibm.com>
  12.  *    Hartmut Penner <hpenner@de.ibm.com>
  13.  *    Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
  14.  *    Martin Schwidefsky (schwidefsky@de.ibm.com)
  15.  *    Alan Altmark (Alan_Altmark@us.ibm.com)  Sept. 2000
  16.  *
  17.  * This program is free software; you can redistribute it and/or modify
  18.  * it under the terms of the GNU General Public License as published by
  19.  * the Free Software Foundation; either version 2, or (at your option)
  20.  * any later version.
  21.  *
  22.  * This program is distributed in the hope that it will be useful,
  23.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25.  * GNU General Public License for more details.
  26.  *
  27.  * You should have received a copy of the GNU General Public License
  28.  * along with this program; if not, write to the Free Software
  29.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  *
  31.  * RELEASE-TAG: IUCV network driver $Revision: 1.16 $
  32.  *
  33.  */
  34. #include <linux/version.h>
  35. #include <linux/module.h>
  36. #include <linux/init.h>
  37. #include <linux/kernel.h>
  38. #include <linux/slab.h>
  39. #include <linux/errno.h>
  40. #include <linux/types.h>
  41. #include <linux/interrupt.h>
  42. #include <linux/timer.h>
  43. #include <linux/sched.h>
  44. #include <linux/signal.h>
  45. #include <linux/string.h>
  46. #include <linux/proc_fs.h>
  47. #include <linux/ip.h>
  48. #include <linux/if_arp.h>
  49. #include <linux/tcp.h>
  50. #include <linux/skbuff.h>
  51. #include <linux/ctype.h>
  52. #include <net/dst.h>
  53. #include <asm/io.h>
  54. #include <asm/bitops.h>
  55. #include <asm/uaccess.h>
  56. #include "iucv.h"
  57. #include "fsm.h"
  58. #undef DEBUG
  59. #ifdef MODULE
  60. MODULE_AUTHOR
  61.     ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
  62. MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
  63. MODULE_PARM (iucv, "1s");
  64. MODULE_PARM_DESC (iucv,
  65.   "Specify the initial remote userids for iucv0 .. iucvn:n"
  66.   "iucv=userid0:userid1:...:useridNn");
  67. #endif
  68. static char *iucv = "";
  69. /**
  70.  * compatibility stuff
  71.  */
  72. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
  73. typedef struct net_device net_device;
  74. #else
  75. typedef struct device net_device;
  76. #endif
  77. /**
  78.  * Per connection profiling data
  79.  */
  80. typedef struct connection_profile_t {
  81. unsigned long maxmulti;
  82. unsigned long maxcqueue;
  83. unsigned long doios_single;
  84. unsigned long doios_multi;
  85. unsigned long txlen;
  86. unsigned long tx_time;
  87. struct timeval send_stamp;
  88. } connection_profile;
  89. /**
  90.  * Representation of one iucv connection
  91.  */
  92. typedef struct iucv_connection_t {
  93. struct iucv_connection_t *next;
  94. iucv_handle_t            handle;
  95. __u16                    pathid;
  96. struct sk_buff           *rx_buff;
  97. struct sk_buff           *tx_buff;
  98. struct sk_buff_head      collect_queue;
  99. spinlock_t               collect_lock;
  100. int                      collect_len;
  101. int                      max_buffsize;
  102. int                      flags;
  103. fsm_timer                timer;
  104. int                      retry;
  105. fsm_instance             *fsm;
  106. net_device               *netdev;
  107. connection_profile       prof;
  108. char                     userid[9];
  109. } iucv_connection;
  110. #define CONN_FLAGS_BUFSIZE_CHANGED 1
  111. /**
  112.  * Linked list of all connection structs.
  113.  */
  114. iucv_connection *connections;
  115. /**
  116.  * Representation of event-data for the
  117.  * connection state machine.
  118.  */
  119. typedef struct iucv_event_t {
  120. iucv_connection *conn;
  121. void            *data;
  122. } iucv_event;
  123. /**
  124.  * Private part of the network device structure
  125.  */
  126. typedef struct netiucv_priv_t {
  127. struct net_device_stats stats;
  128. #if LINUX_VERSION_CODE >= 0x02032D
  129. unsigned long           tbusy;
  130. #endif
  131. fsm_instance            *fsm;
  132.         iucv_connection         *conn;
  133. struct proc_dir_entry   *proc_dentry;
  134. struct proc_dir_entry   *proc_stat_entry;
  135. struct proc_dir_entry   *proc_buffer_entry;
  136. struct proc_dir_entry   *proc_user_entry;
  137. int                     proc_registered;
  138. } netiucv_priv;
  139. /**
  140.  * Link level header for a packet.
  141.  */
  142. typedef struct ll_header_t {
  143. __u16 next;
  144. } ll_header;
  145. #define NETIUCV_HDRLEN           (sizeof(ll_header))
  146. #define NETIUCV_BUFSIZE_MAX      32768
  147. #define NETIUCV_BUFSIZE_DEFAULT  NETIUCV_BUFSIZE_MAX
  148. #define NETIUCV_MTU_MAX          (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
  149. #define NETIUCV_MTU_DEFAULT      9216
  150. #define NETIUCV_QUEUELEN_DEFAULT 50
  151. #define NETIUCV_TIMEOUT_5SEC     5000
  152. /**
  153.  * Compatibility macros for busy handling
  154.  * of network devices.
  155.  */
  156. #if LINUX_VERSION_CODE < 0x02032D
  157. static __inline__ void netiucv_clear_busy(net_device *dev)
  158. {
  159. clear_bit(0 ,(void *)&dev->tbusy);
  160. mark_bh(NET_BH);
  161. }
  162. static __inline__ int netiucv_test_and_set_busy(net_device *dev)
  163. {
  164. return(test_and_set_bit(0, (void *)&dev->tbusy));
  165. }
  166. #define SET_DEVICE_START(device, value) dev->start = value
  167. #else
  168. static __inline__ void netiucv_clear_busy(net_device *dev)
  169. {
  170. clear_bit(0, &(((netiucv_priv *)dev->priv)->tbusy));
  171. netif_wake_queue(dev);
  172. }
  173. static __inline__ int netiucv_test_and_set_busy(net_device *dev)
  174. {
  175. netif_stop_queue(dev);
  176. return test_and_set_bit(0, &((netiucv_priv *)dev->priv)->tbusy);
  177. }
  178. #define SET_DEVICE_START(device, value)
  179. #endif
  180. #if LINUX_VERSION_CODE < 0x020400
  181. #  define dev_kfree_skb_irq(a) dev_kfree_skb(a)
  182. #endif
  183. __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  184. __u8 iucvMagic[16] = {
  185. 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
  186. 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
  187. };
  188. /**
  189.  * This mask means the 16-byte IUCV "magic" and the origin userid must
  190.  * match exactly as specified in order to give connection_pending()
  191.  * control.
  192.  */
  193. __u8 mask[] = {
  194. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  195. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  196. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  197. };
  198. /**
  199.  * Convert an iucv userId to its printable
  200.  * form (strip whitespace at end).
  201.  *
  202.  * @param An iucv userId
  203.  *
  204.  * @returns The printable string (static data!!)
  205.  */
  206. static __inline__ char *
  207. netiucv_printname(char *name)
  208. {
  209. static char tmp[9];
  210. char *p = tmp;
  211. memcpy(tmp, name, 8);
  212. tmp[8] = '';
  213. while (*p && (!isspace(*p)))
  214. p++;
  215. *p = '';
  216. return tmp;
  217. }
  218. /**
  219.  * States of the interface statemachine.
  220.  */
  221. enum dev_states {
  222. DEV_STATE_STOPPED,
  223. DEV_STATE_STARTWAIT,
  224. DEV_STATE_STOPWAIT,
  225. DEV_STATE_RUNNING,
  226. /**
  227.  * MUST be always the last element!!
  228.  */
  229. NR_DEV_STATES
  230. };
  231. static const char *dev_state_names[] = {
  232. "Stopped",
  233. "StartWait",
  234. "StopWait",
  235. "Running",
  236. };
  237. /**
  238.  * Events of the interface statemachine.
  239.  */
  240. enum dev_events {
  241. DEV_EVENT_START,
  242. DEV_EVENT_STOP,
  243. DEV_EVENT_CONUP,
  244. DEV_EVENT_CONDOWN,
  245. /**
  246.  * MUST be always the last element!!
  247.  */
  248. NR_DEV_EVENTS
  249. };
  250. static const char *dev_event_names[] = {
  251. "Start",
  252. "Stop",
  253. "Connection up",
  254. "Connection down",
  255. };
  256. /**
  257.  * Events of the connection statemachine
  258.  */
  259. enum conn_events {
  260. /**
  261.  * Events, representing callbacks from
  262.  * lowlevel iucv layer)
  263.  */
  264. CONN_EVENT_CONN_REQ,
  265. CONN_EVENT_CONN_ACK,
  266. CONN_EVENT_CONN_REJ,
  267. CONN_EVENT_CONN_SUS,
  268. CONN_EVENT_CONN_RES,
  269. CONN_EVENT_RX,
  270. CONN_EVENT_TXDONE,
  271. /**
  272.  * Events, representing errors return codes from
  273.  * calls to lowlevel iucv layer
  274.  */
  275. /**
  276.  * Event, representing timer expiry.
  277.  */
  278. CONN_EVENT_TIMER,
  279. /**
  280.  * Events, representing commands from upper levels.
  281.  */
  282. CONN_EVENT_START,
  283. CONN_EVENT_STOP,
  284. /**
  285.  * MUST be always the last element!!
  286.  */
  287. NR_CONN_EVENTS,
  288. };
  289. static const char *conn_event_names[] = {
  290. "Remote connection request",
  291. "Remote connection acknowledge",
  292. "Remote connection reject",
  293. "Connection suspended",
  294. "Connection resumed",
  295. "Data received",
  296. "Data sent",
  297. "Timer",
  298. "Start",
  299. "Stop",
  300. };
  301. /**
  302.  * States of the connection statemachine.
  303.  */
  304. enum conn_states {
  305. /**
  306.  * Connection not assigned to any device,
  307.  * initial state, invalid
  308.  */
  309. CONN_STATE_INVALID,
  310. /**
  311.  * Userid assigned but not operating
  312.  */
  313. CONN_STATE_STOPPED,
  314. /**
  315.  * Connection registered,
  316.  * no connection request sent yet,
  317.  * no connection request received
  318.  */
  319. CONN_STATE_STARTWAIT,
  320. /**
  321.  * Connection registered and connection request sent,
  322.  * no acknowledge and no connection request received yet.
  323.  */
  324. CONN_STATE_SETUPWAIT,
  325. /**
  326.  * Connection up and running idle
  327.  */
  328. CONN_STATE_IDLE,
  329. /**
  330.  * Data sent, awaiting CONN_EVENT_TXDONE
  331.  */
  332. CONN_STATE_TX,
  333. /**
  334.  * Terminating
  335.  */
  336. CONN_STATE_TERM,
  337. /**
  338.  * Error during registration.
  339.  */
  340. CONN_STATE_REGERR,
  341. /**
  342.  * Error during registration.
  343.  */
  344. CONN_STATE_CONNERR,
  345. /**
  346.  * MUST be always the last element!!
  347.  */
  348. NR_CONN_STATES,
  349. };
  350. static const char *conn_state_names[] = {
  351. "Invalid",
  352. "Stopped",
  353. "StartWait",
  354. "SetupWait",
  355. "Idle",
  356. "TX",
  357. "Terminating",
  358. "Registration error",
  359. "Connect error",
  360. };
  361. /**
  362.  * Callback-wrappers, called from lowlevel iucv layer.
  363.  *****************************************************************************/
  364. static void
  365. netiucv_callback_rx(iucv_MessagePending *eib, void *pgm_data)
  366. {
  367. iucv_connection *conn = (iucv_connection *)pgm_data;
  368. iucv_event ev;
  369. ev.conn = conn;
  370. ev.data = (void *)eib;
  371. fsm_event(conn->fsm, CONN_EVENT_RX, &ev);
  372. }
  373. static void
  374. netiucv_callback_txdone(iucv_MessageComplete *eib, void *pgm_data)
  375. {
  376. iucv_connection *conn = (iucv_connection *)pgm_data;
  377. iucv_event ev;
  378. ev.conn = conn;
  379. ev.data = (void *)eib;
  380. fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev);
  381. }
  382. static void
  383. netiucv_callback_connack(iucv_ConnectionComplete *eib, void *pgm_data)
  384. {
  385. iucv_connection *conn = (iucv_connection *)pgm_data;
  386. iucv_event ev;
  387. ev.conn = conn;
  388. ev.data = (void *)eib;
  389. fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev);
  390. }
  391. static void
  392. netiucv_callback_connreq(iucv_ConnectionPending *eib, void *pgm_data)
  393. {
  394. iucv_connection *conn = (iucv_connection *)pgm_data;
  395. iucv_event ev;
  396. ev.conn = conn;
  397. ev.data = (void *)eib;
  398. fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);
  399. }
  400. static void
  401. netiucv_callback_connrej(iucv_ConnectionSevered *eib, void *pgm_data)
  402. {
  403. iucv_connection *conn = (iucv_connection *)pgm_data;
  404. iucv_event ev;
  405. ev.conn = conn;
  406. ev.data = (void *)eib;
  407. fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, &ev);
  408. }
  409. static void
  410. netiucv_callback_connsusp(iucv_ConnectionQuiesced *eib, void *pgm_data)
  411. {
  412. iucv_connection *conn = (iucv_connection *)pgm_data;
  413. iucv_event ev;
  414. ev.conn = conn;
  415. ev.data = (void *)eib;
  416. fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, &ev);
  417. }
  418. static void
  419. netiucv_callback_connres(iucv_ConnectionResumed *eib, void *pgm_data)
  420. {
  421. iucv_connection *conn = (iucv_connection *)pgm_data;
  422. iucv_event ev;
  423. ev.conn = conn;
  424. ev.data = (void *)eib;
  425. fsm_event(conn->fsm, CONN_EVENT_CONN_RES, &ev);
  426. }
  427. static iucv_interrupt_ops_t netiucv_ops = {
  428. ConnectionPending:  netiucv_callback_connreq,
  429. ConnectionComplete: netiucv_callback_connack,
  430. ConnectionSevered:  netiucv_callback_connrej,
  431. ConnectionQuiesced: netiucv_callback_connsusp,
  432. ConnectionResumed:  netiucv_callback_connres,
  433. MessagePending:     netiucv_callback_rx,
  434. MessageComplete:    netiucv_callback_txdone
  435. };
  436. /**
  437.  * Dummy NOP action for all statemachines
  438.  */
  439. static void
  440. fsm_action_nop(fsm_instance *fi, int event, void *arg)
  441. {
  442. }
  443. /**
  444.  * Actions of the connection statemachine
  445.  *****************************************************************************/
  446. /**
  447.  * Helper function for conn_action_rx()
  448.  * Unpack a just received skb and hand it over to
  449.  * upper layers.
  450.  *
  451.  * @param conn The connection where this skb has been received.
  452.  * @param pskb The received skb.
  453.  */
  454. //static __inline__ void
  455. static void
  456. netiucv_unpack_skb(iucv_connection *conn, struct sk_buff *pskb)
  457. {
  458. net_device     *dev = conn->netdev;
  459. netiucv_priv   *privptr = (netiucv_priv *)dev->priv;
  460. __u16          offset = 0;
  461. skb_put(pskb, NETIUCV_HDRLEN);
  462. pskb->dev = dev;
  463. pskb->ip_summed = CHECKSUM_NONE;
  464. pskb->protocol = ntohs(ETH_P_IP);
  465. while (1) {
  466. struct sk_buff *skb;
  467. ll_header *header = (ll_header *)pskb->data;
  468. if (header->next == 0)
  469. break;
  470. skb_pull(pskb, NETIUCV_HDRLEN);
  471. header->next -= offset;
  472. offset += header->next;
  473. header->next -= NETIUCV_HDRLEN;
  474. if (skb_tailroom(pskb) < header->next) {
  475. printk(KERN_WARNING
  476.        "%s: Illegal next field in iucv header: %d > %dn",
  477.        dev->name, header->next, skb_tailroom(pskb));
  478. return;
  479. }
  480. skb_put(pskb, header->next);
  481. pskb->mac.raw = pskb->data;
  482. skb = dev_alloc_skb(pskb->len);
  483. if (!skb) {
  484. printk(KERN_WARNING
  485.        "%s Out of memory in netiucv_unpack_skbn",
  486.        dev->name);
  487. privptr->stats.rx_dropped++;
  488. return;
  489. }
  490. memcpy(skb_put(skb, pskb->len), pskb->data, pskb->len);
  491. skb->mac.raw = skb->data;
  492. skb->dev = pskb->dev;
  493. skb->protocol = pskb->protocol;
  494. pskb->ip_summed = CHECKSUM_UNNECESSARY;
  495. netif_rx(skb);
  496. privptr->stats.rx_packets++;
  497. privptr->stats.rx_bytes += skb->len;
  498. skb_pull(pskb, header->next);
  499. skb_put(pskb, NETIUCV_HDRLEN);
  500. }
  501. }
  502. static void
  503. conn_action_rx(fsm_instance *fi, int event, void *arg)
  504. {
  505. iucv_event *ev = (iucv_event *)arg;
  506. iucv_connection *conn = ev->conn;
  507. iucv_MessagePending *eib = (iucv_MessagePending *)ev->data;
  508. netiucv_priv *privptr = (netiucv_priv *)conn->netdev->priv;
  509. __u16 msglen = eib->ln1msg2.ipbfln1f;
  510. int rc;
  511. #ifdef DEBUG
  512. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  513. #endif
  514. if (!conn->netdev) {
  515. /* FRITZ: How to tell iucv LL to drop the msg? */
  516. printk(KERN_WARNING
  517.        "Received data for unlinked connectionn"); 
  518. return;
  519. }
  520. if (msglen > conn->max_buffsize) {
  521. /* FRITZ: How to tell iucv LL to drop the msg? */
  522. privptr->stats.rx_dropped++;
  523. return;
  524. }
  525. conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head;
  526. conn->rx_buff->len = 0;
  527. rc = iucv_receive(conn->pathid, eib->ipmsgid, eib->iptrgcls,
  528.   conn->rx_buff->data, msglen, NULL, NULL, NULL);
  529. if (rc != 0 || msglen < 5) {
  530. privptr->stats.rx_errors++;
  531. return;
  532. }
  533. netiucv_unpack_skb(conn, conn->rx_buff);
  534. }
  535. static void
  536. conn_action_txdone(fsm_instance *fi, int event, void *arg)
  537. {
  538. iucv_event *ev = (iucv_event *)arg;
  539. iucv_connection *conn = ev->conn;
  540. iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data;
  541. netiucv_priv *privptr = NULL;
  542.          /* Shut up, gcc! skb is always below 2G. */
  543. struct sk_buff *skb = (struct sk_buff *)(unsigned long)eib->ipmsgtag;
  544. __u32 txbytes = 0;
  545. __u32 txpackets = 0;
  546. __u32 stat_maxcq = 0;
  547. unsigned long saveflags;
  548. ll_header header;
  549. #ifdef DEBUG
  550. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  551. #endif
  552. fsm_deltimer(&conn->timer);
  553. if (conn && conn->netdev && conn->netdev->priv)
  554. privptr = (netiucv_priv *)conn->netdev->priv;
  555. if (skb) {
  556. if (privptr) {
  557. privptr->stats.tx_packets++;
  558. privptr->stats.tx_bytes +=
  559. (skb->len - NETIUCV_HDRLEN - NETIUCV_HDRLEN);
  560. }
  561. dev_kfree_skb_any(skb);
  562. }
  563. conn->tx_buff->data = conn->tx_buff->tail = conn->tx_buff->head;
  564. conn->tx_buff->len = 0;
  565. spin_lock_irqsave(&conn->collect_lock, saveflags);
  566. while ((skb = skb_dequeue(&conn->collect_queue))) {
  567. header.next = conn->tx_buff->len + skb->len + NETIUCV_HDRLEN;
  568. memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
  569.        NETIUCV_HDRLEN);
  570. memcpy(skb_put(conn->tx_buff, skb->len), skb->data, skb->len);
  571. txbytes += skb->len;
  572. txpackets++;
  573. stat_maxcq++;
  574. atomic_dec(&skb->users);
  575. dev_kfree_skb_any(skb);
  576. }
  577. if (conn->collect_len > conn->prof.maxmulti)
  578. conn->prof.maxmulti = conn->collect_len;
  579. conn->collect_len = 0;
  580. spin_unlock_irqrestore(&conn->collect_lock, saveflags);
  581. if (conn->tx_buff->len) {
  582. int rc;
  583. header.next = 0;
  584. memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
  585.        NETIUCV_HDRLEN);
  586. fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
  587.      CONN_EVENT_TIMER, conn);
  588. conn->prof.send_stamp = xtime;
  589. rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0,
  590.        conn->tx_buff->data, conn->tx_buff->len);
  591. conn->prof.doios_multi++;
  592. conn->prof.txlen += conn->tx_buff->len;
  593. if (rc != 0) {
  594. fsm_deltimer(&conn->timer);
  595. fsm_newstate(fi, CONN_STATE_IDLE);
  596. if (privptr)
  597. privptr->stats.tx_errors += txpackets;
  598. } else {
  599. if (privptr) {
  600. privptr->stats.tx_packets += txpackets;
  601. privptr->stats.tx_bytes += txbytes;
  602. }
  603. if (stat_maxcq > conn->prof.maxcqueue)
  604. conn->prof.maxcqueue = stat_maxcq;
  605. }
  606. } else
  607. fsm_newstate(fi, CONN_STATE_IDLE);
  608. }
  609. static void
  610. conn_action_connaccept(fsm_instance *fi, int event, void *arg)
  611. {
  612. iucv_event *ev = (iucv_event *)arg;
  613. iucv_connection *conn = ev->conn;
  614. iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
  615. net_device *netdev = conn->netdev;
  616. netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
  617. int rc;
  618. __u16 msglimit;
  619. __u8 udata[16];
  620. #ifdef DEBUG
  621. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  622. #endif
  623. rc = iucv_accept(eib->ippathid, NETIUCV_QUEUELEN_DEFAULT, udata, 0,
  624.  conn->handle, conn, NULL, &msglimit);
  625. if (rc != 0) {
  626. printk(KERN_WARNING
  627.        "%s: IUCV accept failed with error %dn",
  628.        netdev->name, rc);
  629. return;
  630. }
  631. fsm_newstate(fi, CONN_STATE_IDLE);
  632. conn->pathid = eib->ippathid;
  633. netdev->tx_queue_len = msglimit;
  634. fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
  635. }
  636. static void
  637. conn_action_connreject(fsm_instance *fi, int event, void *arg)
  638. {
  639. iucv_event *ev = (iucv_event *)arg;
  640. // iucv_connection *conn = ev->conn;
  641. iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
  642. __u8 udata[16];
  643. #ifdef DEBUG
  644. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  645. #endif
  646. iucv_sever(eib->ippathid, udata);
  647. }
  648. static void
  649. conn_action_connack(fsm_instance *fi, int event, void *arg)
  650. {
  651. iucv_event *ev = (iucv_event *)arg;
  652. iucv_connection *conn = ev->conn;
  653. iucv_ConnectionComplete *eib = (iucv_ConnectionComplete *)ev->data;
  654. net_device *netdev = conn->netdev;
  655. netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
  656. #ifdef DEBUG
  657. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  658. #endif
  659. fsm_newstate(fi, CONN_STATE_IDLE);
  660. conn->pathid = eib->ippathid;
  661. netdev->tx_queue_len = eib->ipmsglim;
  662. fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
  663. }
  664. static void
  665. conn_action_connsever(fsm_instance *fi, int event, void *arg)
  666. {
  667. iucv_event *ev = (iucv_event *)arg;
  668. iucv_connection *conn = ev->conn;
  669. // iucv_ConnectionSevered *eib = (iucv_ConnectionSevered *)ev->data;
  670. net_device *netdev = conn->netdev;
  671. netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
  672. int state = fsm_getstate(fi);
  673. #ifdef DEBUG
  674. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  675. #endif
  676. switch (state) {
  677. case CONN_STATE_IDLE:
  678. case CONN_STATE_TX:
  679. printk(KERN_INFO "%s: Remote dropped connectionn",
  680.        netdev->name);
  681. if (conn->handle)
  682. iucv_unregister_program(conn->handle);
  683. conn->handle = 0;
  684. fsm_newstate(fi, CONN_STATE_STOPPED);
  685. fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
  686. break;
  687. }
  688. }
  689. static void
  690. conn_action_start(fsm_instance *fi, int event, void *arg)
  691. {
  692. iucv_event *ev = (iucv_event *)arg;
  693. iucv_connection *conn = ev->conn;
  694. int rc;
  695. #ifdef DEBUG
  696. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  697. #endif
  698. if (conn->handle == 0) {
  699. conn->handle =
  700. iucv_register_program(iucvMagic, conn->userid, mask,
  701.       &netiucv_ops, conn);
  702. fsm_newstate(fi, CONN_STATE_STARTWAIT);
  703. if (conn->handle <= 0) {
  704. fsm_newstate(fi, CONN_STATE_REGERR);
  705. conn->handle = 0;
  706. return;
  707. }
  708. #ifdef DEBUG
  709. printk(KERN_DEBUG "%s('%s'): registered successfullyn",
  710.        conn->netdev->name, conn->userid);
  711. #endif
  712. }
  713. #ifdef DEBUG
  714. printk(KERN_DEBUG "%s('%s'): connecting ...n",
  715.        conn->netdev->name, conn->userid);
  716. #endif
  717. rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic,
  718.   conn->userid, iucv_host, 0, NULL, NULL, conn->handle,
  719.   conn);
  720. fsm_newstate(fi, CONN_STATE_SETUPWAIT);
  721. switch (rc) {
  722. case 0:
  723. return;
  724. case 11:
  725. printk(KERN_NOTICE
  726.        "%s: User %s is currently not available.n",
  727.        conn->netdev->name,
  728.        netiucv_printname(conn->userid));
  729. fsm_newstate(fi, CONN_STATE_STARTWAIT);
  730. return;
  731. case 12:
  732. printk(KERN_NOTICE
  733.        "%s: User %s is currently not ready.n",
  734.        conn->netdev->name,
  735.        netiucv_printname(conn->userid));
  736. fsm_newstate(fi, CONN_STATE_STARTWAIT);
  737. return;
  738. case 13:
  739. printk(KERN_WARNING
  740.        "%s: Too many IUCV connections.n",
  741.        conn->netdev->name);
  742. fsm_newstate(fi, CONN_STATE_CONNERR);
  743. break;
  744. case 14:
  745. printk(KERN_WARNING
  746.        "%s: User %s has too many IUCV connections.n",
  747.        conn->netdev->name,
  748.        netiucv_printname(conn->userid));
  749. fsm_newstate(fi, CONN_STATE_CONNERR);
  750. break;
  751. case 15:
  752. printk(KERN_WARNING
  753.        "%s: No IUCV authorization in CP directory.n",
  754.        conn->netdev->name);
  755. fsm_newstate(fi, CONN_STATE_CONNERR);
  756. break;
  757. default:
  758. printk(KERN_WARNING
  759.        "%s: iucv_connect returned error %dn",
  760.        conn->netdev->name, rc);
  761. fsm_newstate(fi, CONN_STATE_CONNERR);
  762. break;
  763. }
  764. iucv_unregister_program(conn->handle);
  765. conn->handle = 0;
  766. }
  767. static void
  768. netiucv_purge_skb_queue(struct sk_buff_head *q)
  769. {
  770. struct sk_buff *skb;
  771. while ((skb = skb_dequeue(q))) {
  772. atomic_dec(&skb->users);
  773. dev_kfree_skb_any(skb);
  774. }
  775. }
  776. static void
  777. conn_action_stop(fsm_instance *fi, int event, void *arg)
  778. {
  779. iucv_event *ev = (iucv_event *)arg;
  780. iucv_connection *conn = ev->conn;
  781. net_device *netdev = conn->netdev;
  782. netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
  783. #ifdef DEBUG
  784. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  785. #endif
  786. fsm_newstate(fi, CONN_STATE_STOPPED);
  787. netiucv_purge_skb_queue(&conn->collect_queue);
  788. if (conn->handle)
  789. iucv_unregister_program(conn->handle);
  790. conn->handle = 0;
  791. fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
  792. }
  793. static void
  794. conn_action_inval(fsm_instance *fi, int event, void *arg)
  795. {
  796. iucv_event *ev = (iucv_event *)arg;
  797. iucv_connection *conn = ev->conn;
  798. net_device *netdev = conn->netdev;
  799. printk(KERN_WARNING
  800.        "%s: Cannot connect without usernamen",
  801.        netdev->name);
  802. }
  803. static const fsm_node conn_fsm[] = {
  804. { CONN_STATE_INVALID,   CONN_EVENT_START,    conn_action_inval      },
  805. { CONN_STATE_STOPPED,   CONN_EVENT_START,    conn_action_start      },
  806. { CONN_STATE_STARTWAIT, CONN_EVENT_START,    conn_action_start      },
  807. { CONN_STATE_STARTWAIT, CONN_EVENT_STOP,     conn_action_stop       },
  808. { CONN_STATE_SETUPWAIT, CONN_EVENT_STOP,     conn_action_stop       },
  809. { CONN_STATE_IDLE,      CONN_EVENT_STOP,     conn_action_stop       },
  810. { CONN_STATE_TX,        CONN_EVENT_STOP,     conn_action_stop       },
  811. { CONN_STATE_REGERR,    CONN_EVENT_STOP,     conn_action_stop       },
  812. { CONN_STATE_CONNERR,   CONN_EVENT_STOP,     conn_action_stop       },
  813. { CONN_STATE_STOPPED,   CONN_EVENT_CONN_REQ, conn_action_connreject },
  814.         { CONN_STATE_STARTWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
  815. { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
  816. { CONN_STATE_IDLE,      CONN_EVENT_CONN_REQ, conn_action_connreject },
  817. { CONN_STATE_TX,        CONN_EVENT_CONN_REQ, conn_action_connreject },
  818. { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_ACK, conn_action_connack    },
  819. { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REJ, conn_action_connsever  },
  820. { CONN_STATE_IDLE,      CONN_EVENT_CONN_REJ, conn_action_connsever  },
  821. { CONN_STATE_TX,        CONN_EVENT_CONN_REJ, conn_action_connsever  },
  822. { CONN_STATE_IDLE,      CONN_EVENT_RX,       conn_action_rx         },
  823. { CONN_STATE_TX,        CONN_EVENT_RX,       conn_action_rx         },
  824. { CONN_STATE_TX,        CONN_EVENT_TXDONE,   conn_action_txdone     },
  825. };
  826. static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
  827. /**
  828.  * Actions for interface - statemachine.
  829.  *****************************************************************************/
  830. /**
  831.  * Startup connection by sending CONN_EVENT_START to it.
  832.  *
  833.  * @param fi    An instance of an interface statemachine.
  834.  * @param event The event, just happened.
  835.  * @param arg   Generic pointer, casted from net_device * upon call.
  836.  */
  837. static void
  838. dev_action_start(fsm_instance *fi, int event, void *arg)
  839. {
  840. net_device   *dev = (net_device *)arg;
  841. netiucv_priv *privptr = dev->priv;
  842. iucv_event   ev;
  843. #ifdef DEBUG
  844. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  845. #endif
  846. ev.conn = privptr->conn;
  847. fsm_newstate(fi, DEV_STATE_STARTWAIT);
  848. fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev);
  849. }
  850. /**
  851.  * Shutdown connection by sending CONN_EVENT_STOP to it.
  852.  *
  853.  * @param fi    An instance of an interface statemachine.
  854.  * @param event The event, just happened.
  855.  * @param arg   Generic pointer, casted from net_device * upon call.
  856.  */
  857. static void
  858. dev_action_stop(fsm_instance *fi, int event, void *arg)
  859. {
  860. net_device   *dev = (net_device *)arg;
  861. netiucv_priv *privptr = dev->priv;
  862. iucv_event   ev;
  863. #ifdef DEBUG
  864. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  865. #endif
  866. ev.conn = privptr->conn;
  867. fsm_newstate(fi, DEV_STATE_STOPWAIT);
  868. fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev);
  869. }
  870. /**
  871.  * Called from connection statemachine
  872.  * when a connection is up and running.
  873.  *
  874.  * @param fi    An instance of an interface statemachine.
  875.  * @param event The event, just happened.
  876.  * @param arg   Generic pointer, casted from net_device * upon call.
  877.  */
  878. static void
  879. dev_action_connup(fsm_instance *fi, int event, void *arg)
  880. {
  881. net_device   *dev = (net_device *)arg;
  882. #ifdef DEBUG
  883. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  884. #endif
  885. switch (fsm_getstate(fi)) {
  886. case DEV_STATE_STARTWAIT:
  887. fsm_newstate(fi, DEV_STATE_RUNNING);
  888. printk(KERN_INFO
  889.        "%s: connected with remote siden",
  890.        dev->name);
  891. break;
  892. case DEV_STATE_STOPWAIT:
  893. printk(KERN_INFO
  894.        "%s: got connection UP event during shutdown!!n",
  895.        dev->name);
  896. break;
  897. }
  898. }
  899. /**
  900.  * Called from connection statemachine
  901.  * when a connection has been shutdown.
  902.  *
  903.  * @param fi    An instance of an interface statemachine.
  904.  * @param event The event, just happened.
  905.  * @param arg   Generic pointer, casted from net_device * upon call.
  906.  */
  907. static void
  908. dev_action_conndown(fsm_instance *fi, int event, void *arg)
  909. {
  910. net_device   *dev = (net_device *)arg;
  911. netiucv_priv *privptr = dev->priv;
  912. iucv_event   ev;
  913. #ifdef DEBUG
  914. printk(KERN_DEBUG "%s() calledn", __FUNCTION__);
  915. #endif
  916. switch (fsm_getstate(fi)) {
  917. case DEV_STATE_RUNNING:
  918. fsm_newstate(fi, DEV_STATE_STARTWAIT);
  919. ev.conn = privptr->conn;
  920. fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev);
  921. break;
  922. case DEV_STATE_STARTWAIT:
  923. break;
  924. case DEV_STATE_STOPWAIT:
  925. fsm_newstate(fi, DEV_STATE_STOPPED);
  926. break;
  927. }
  928. }
  929. static const fsm_node dev_fsm[] = {
  930. { DEV_STATE_STOPPED,   DEV_EVENT_START,   dev_action_start    },
  931. { DEV_STATE_STOPWAIT,  DEV_EVENT_START,   dev_action_start    },
  932. { DEV_STATE_STOPWAIT,  DEV_EVENT_CONDOWN, dev_action_conndown },
  933. { DEV_STATE_STARTWAIT, DEV_EVENT_STOP,    dev_action_stop     },
  934. { DEV_STATE_STARTWAIT, DEV_EVENT_CONUP,   dev_action_connup   },
  935. { DEV_STATE_STARTWAIT, DEV_EVENT_CONDOWN, dev_action_conndown },
  936. { DEV_STATE_RUNNING,   DEV_EVENT_STOP,    dev_action_stop     },
  937. { DEV_STATE_RUNNING,   DEV_EVENT_CONDOWN, dev_action_conndown },
  938. { DEV_STATE_RUNNING,   DEV_EVENT_CONUP,   fsm_action_nop      },
  939. };
  940. static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
  941. /**
  942.  * Transmit a packet.
  943.  * This is a helper function for netiucv_tx().
  944.  *
  945.  * @param conn Connection to be used for sending.
  946.  * @param skb Pointer to struct sk_buff of packet to send.
  947.  *            The linklevel header has already been set up
  948.  *            by netiucv_tx().
  949.  *
  950.  * @return 0 on success, -ERRNO on failure. (Never fails.)
  951.  */
  952. static int
  953. netiucv_transmit_skb(iucv_connection *conn, struct sk_buff *skb) {
  954. unsigned long saveflags;
  955. ll_header header;
  956. int       rc = 0;
  957. if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) {
  958. int l = skb->len + NETIUCV_HDRLEN;
  959. spin_lock_irqsave(&conn->collect_lock, saveflags);
  960. if (conn->collect_len + l >
  961.     (conn->max_buffsize - NETIUCV_HDRLEN))
  962. rc = -EBUSY;
  963. else {
  964. atomic_inc(&skb->users);
  965. skb_queue_tail(&conn->collect_queue, skb);
  966. conn->collect_len += l;
  967. }
  968. spin_unlock_irqrestore(&conn->collect_lock, saveflags);
  969. } else {
  970. struct sk_buff *nskb = skb;
  971. /**
  972.  * Copy the skb to a new allocated skb in lowmem only if the
  973.  * data is located above 2G in memory or tailroom is < 2.
  974.  */
  975. unsigned long hi =
  976. ((unsigned long)(skb->tail + NETIUCV_HDRLEN)) >> 31;
  977. int copied = 0;
  978. if (hi || (skb_tailroom(skb) < 2)) {
  979. nskb = alloc_skb(skb->len + NETIUCV_HDRLEN +
  980.  NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA);
  981. if (!nskb) {
  982. printk(KERN_WARNING
  983.        "%s: Could not allocate tx_skbn",
  984.        conn->netdev->name);
  985. rc = -ENOMEM;
  986. } else {
  987. skb_reserve(nskb, NETIUCV_HDRLEN);
  988. memcpy(skb_put(nskb, skb->len),
  989.        skb->data, skb->len);
  990. }
  991. copied = 1;
  992. }
  993. /**
  994.  * skb now is below 2G and has enough room. Add headers.
  995.  */
  996. header.next = nskb->len + NETIUCV_HDRLEN;
  997. memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
  998. header.next = 0;
  999. memcpy(skb_put(nskb, NETIUCV_HDRLEN), &header,  NETIUCV_HDRLEN);
  1000. conn->retry = 0;
  1001. fsm_newstate(conn->fsm, CONN_STATE_TX);
  1002. fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
  1003.      CONN_EVENT_TIMER, conn);
  1004. conn->prof.send_stamp = xtime;
  1005. rc = iucv_send(conn->pathid, NULL, 0, 0,
  1006.        /* Shut up, gcc! nskb is always below 2G. */
  1007.        (__u32)(((unsigned long)nskb)&0xffffffff), 0,
  1008.        nskb->data, nskb->len);
  1009. conn->prof.doios_single++;
  1010. conn->prof.txlen += skb->len;
  1011. if (rc != 0) {
  1012. fsm_deltimer(&conn->timer);
  1013. if (copied)
  1014. dev_kfree_skb(nskb);
  1015. else {
  1016. /**
  1017.  * Remove our headers. They get added
  1018.  * again on retransmit.
  1019.  */
  1020. skb_pull(skb, NETIUCV_HDRLEN);
  1021. skb_trim(skb, skb->len - NETIUCV_HDRLEN);
  1022. }
  1023. } else {
  1024. if (copied)
  1025. dev_kfree_skb(skb);
  1026. }
  1027. }
  1028. return rc;
  1029. }
  1030. /**
  1031.  * Interface API for upper network layers
  1032.  *****************************************************************************/
  1033. /**
  1034.  * Open an interface.
  1035.  * Called from generic network layer when ifconfig up is run.
  1036.  *
  1037.  * @param dev Pointer to interface struct.
  1038.  *
  1039.  * @return 0 on success, -ERRNO on failure. (Never fails.)
  1040.  */
  1041. static int
  1042. netiucv_open(net_device *dev) {
  1043. MOD_INC_USE_COUNT;
  1044. SET_DEVICE_START(dev, 1);
  1045. fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START, dev);
  1046. return 0;
  1047. }
  1048. /**
  1049.  * Close an interface.
  1050.  * Called from generic network layer when ifconfig down is run.
  1051.  *
  1052.  * @param dev Pointer to interface struct.
  1053.  *
  1054.  * @return 0 on success, -ERRNO on failure. (Never fails.)
  1055.  */
  1056. static int
  1057. netiucv_close(net_device *dev) {
  1058. SET_DEVICE_START(dev, 0);
  1059. fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev);
  1060. MOD_DEC_USE_COUNT;
  1061. return 0;
  1062. }
  1063. /**
  1064.  * Start transmission of a packet.
  1065.  * Called from generic network device layer.
  1066.  *
  1067.  * @param skb Pointer to buffer containing the packet.
  1068.  * @param dev Pointer to interface struct.
  1069.  *
  1070.  * @return 0 if packet consumed, !0 if packet rejected.
  1071.  *         Note: If we return !0, then the packet is free'd by
  1072.  *               the generic network layer.
  1073.  */
  1074. static int netiucv_tx(struct sk_buff *skb, net_device *dev)
  1075. {
  1076. int          rc = 0;
  1077. netiucv_priv *privptr = (netiucv_priv *)dev->priv;
  1078. /**
  1079.  * Some sanity checks ...
  1080.  */
  1081. if (skb == NULL) {
  1082. printk(KERN_WARNING "%s: NULL sk_buff passedn", dev->name);
  1083. privptr->stats.tx_dropped++;
  1084. return 0;
  1085. }
  1086. if (skb_headroom(skb) < (NETIUCV_HDRLEN)) {
  1087. printk(KERN_WARNING
  1088.        "%s: Got sk_buff with head room < %ld bytesn",
  1089.        dev->name, NETIUCV_HDRLEN);
  1090. dev_kfree_skb(skb);
  1091. privptr->stats.tx_dropped++;
  1092. return 0;
  1093. }
  1094. /**
  1095.  * If connection is not running, try to restart it
  1096.  * notify anybody about a link failure and throw
  1097.  * away packet. 
  1098.  */
  1099. if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
  1100. fsm_event(privptr->fsm, DEV_EVENT_START, dev);
  1101. dst_link_failure(skb);
  1102. dev_kfree_skb(skb);
  1103. privptr->stats.tx_dropped++;
  1104. privptr->stats.tx_errors++;
  1105. privptr->stats.tx_carrier_errors++;
  1106. return 0;
  1107. }
  1108. if (netiucv_test_and_set_busy(dev))
  1109. return -EBUSY;
  1110. dev->trans_start = jiffies;
  1111. if (netiucv_transmit_skb(privptr->conn, skb) != 0)
  1112. rc = 1;
  1113. netiucv_clear_busy(dev);
  1114. return rc;
  1115. }
  1116. /**
  1117.  * Returns interface statistics of a device.
  1118.  *
  1119.  * @param dev Pointer to interface struct.
  1120.  *
  1121.  * @return Pointer to stats struct of this interface.
  1122.  */
  1123. static struct net_device_stats *
  1124. netiucv_stats (net_device * dev)
  1125. {
  1126. return &((netiucv_priv *)dev->priv)->stats;
  1127. }
  1128. /**
  1129.  * Sets MTU of an interface.
  1130.  *
  1131.  * @param dev     Pointer to interface struct.
  1132.  * @param new_mtu The new MTU to use for this interface.
  1133.  *
  1134.  * @return 0 on success, -EINVAL if MTU is out of valid range.
  1135.  *         (valid range is 576 .. NETIUCV_MTU_MAX).
  1136.  */
  1137. static int
  1138. netiucv_change_mtu (net_device * dev, int new_mtu)
  1139. {
  1140. if ((new_mtu < 576) || (new_mtu > NETIUCV_MTU_MAX))
  1141. return -EINVAL;
  1142. dev->mtu = new_mtu;
  1143. return 0;
  1144. }
  1145. /**
  1146.  * procfs related structures and routines
  1147.  *****************************************************************************/
  1148. static net_device *
  1149. find_netdev_by_ino(unsigned long ino)
  1150. {
  1151. iucv_connection *conn = connections;
  1152. net_device *dev = NULL;
  1153. netiucv_priv *privptr;
  1154. while (conn) {
  1155. if (conn->netdev != dev) {
  1156. dev = conn->netdev;
  1157. privptr = (netiucv_priv *)dev->priv;
  1158. if ((privptr->proc_buffer_entry->low_ino == ino) ||
  1159.     (privptr->proc_user_entry->low_ino == ino)   ||
  1160.     (privptr->proc_stat_entry->low_ino == ino)     )
  1161. return dev;
  1162. }
  1163. conn = conn->next;
  1164. }
  1165. return NULL;
  1166. }
  1167. #if LINUX_VERSION_CODE < 0x020363
  1168. /**
  1169.  * Lock the module, if someone changes into
  1170.  * our proc directory.
  1171.  */
  1172. static void
  1173. netiucv_fill_inode(struct inode *inode, int fill)
  1174. {
  1175. if (fill) {
  1176. MOD_INC_USE_COUNT;
  1177. } else
  1178. MOD_DEC_USE_COUNT;
  1179. }
  1180. #endif
  1181. #define CTRL_BUFSIZE 40
  1182. static int
  1183. netiucv_buffer_open(struct inode *inode, struct file *file)
  1184. {
  1185. file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
  1186. if (file->private_data == NULL)
  1187. return -ENOMEM;
  1188. MOD_INC_USE_COUNT;
  1189. return 0;
  1190. }
  1191. static int
  1192. netiucv_buffer_close(struct inode *inode, struct file *file)
  1193. {
  1194. kfree(file->private_data);
  1195. MOD_DEC_USE_COUNT;
  1196. return 0;
  1197. }
  1198. static ssize_t
  1199. netiucv_buffer_write(struct file *file, const char *buf, size_t count,
  1200.    loff_t *off)
  1201. {
  1202. unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
  1203. net_device   *dev;
  1204. netiucv_priv *privptr;
  1205. char         *e;
  1206. int          bs1;
  1207. char         tmp[CTRL_BUFSIZE];
  1208. if (!(dev = find_netdev_by_ino(ino)))
  1209. return -ENODEV;
  1210. if (off != &file->f_pos)
  1211. return -ESPIPE;
  1212. privptr = (netiucv_priv *)dev->priv;
  1213. if (count >= 39)
  1214. return -EINVAL;
  1215. if (copy_from_user(tmp, buf, count))
  1216. return -EFAULT;
  1217. tmp[count+1] = '';
  1218. bs1 = simple_strtoul(tmp, &e, 0);
  1219. if ((bs1 > NETIUCV_BUFSIZE_MAX) ||
  1220.     (e && (!isspace(*e))))
  1221. return -EINVAL;
  1222. if ((dev->flags & IFF_RUNNING) &&
  1223.     (bs1 < (dev->mtu + NETIUCV_HDRLEN + 2)))
  1224. return -EINVAL;
  1225. if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN))
  1226. return -EINVAL;
  1227. privptr->conn->max_buffsize = bs1;
  1228. if (!(dev->flags & IFF_RUNNING))
  1229. dev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN;
  1230. privptr->conn->flags |= CONN_FLAGS_BUFSIZE_CHANGED;
  1231. return count;
  1232. }
  1233. static ssize_t
  1234. netiucv_buffer_read(struct file *file, char *buf, size_t count, loff_t *off)
  1235. {
  1236. unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
  1237. char *sbuf = (char *)file->private_data;
  1238. net_device *dev;
  1239. netiucv_priv *privptr;
  1240. ssize_t ret = 0;
  1241. char *p = sbuf;
  1242. int l;
  1243. if (!(dev = find_netdev_by_ino(ino)))
  1244. return -ENODEV;
  1245. if (off != &file->f_pos)
  1246. return -ESPIPE;
  1247. privptr = (netiucv_priv *)dev->priv;
  1248. if (file->f_pos == 0)
  1249. sprintf(sbuf, "%dn", privptr->conn->max_buffsize);
  1250. l = strlen(sbuf);
  1251. p = sbuf;
  1252. if (file->f_pos < l) {
  1253. p += file->f_pos;
  1254. l = strlen(p);
  1255. ret = (count > l) ? l : count;
  1256. if (copy_to_user(buf, p, ret))
  1257. return -EFAULT;
  1258. }
  1259. file->f_pos += ret;
  1260. return ret;
  1261. }
  1262. static int
  1263. netiucv_user_open(struct inode *inode, struct file *file)
  1264. {
  1265. file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
  1266. if (file->private_data == NULL)
  1267. return -ENOMEM;
  1268. MOD_INC_USE_COUNT;
  1269. return 0;
  1270. }
  1271. static int
  1272. netiucv_user_close(struct inode *inode, struct file *file)
  1273. {
  1274. kfree(file->private_data);
  1275. MOD_DEC_USE_COUNT;
  1276. return 0;
  1277. }
  1278. static ssize_t
  1279. netiucv_user_write(struct file *file, const char *buf, size_t count,
  1280.    loff_t *off)
  1281. {
  1282. unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
  1283. net_device   *dev;
  1284. netiucv_priv *privptr;
  1285. int          i;
  1286. char         *p;
  1287. char         tmp[CTRL_BUFSIZE];
  1288. char         user[9];
  1289. if (!(dev = find_netdev_by_ino(ino)))
  1290. return -ENODEV;
  1291. if (off != &file->f_pos)
  1292. return -ESPIPE;
  1293. privptr = (netiucv_priv *)dev->priv;
  1294. if (count >= 39)
  1295. return -EINVAL;
  1296. if (copy_from_user(tmp, buf, count))
  1297. return -EFAULT;
  1298. tmp[count+1] = '';
  1299. memset(user, ' ', sizeof(user));
  1300. user[8] = '';
  1301. for (p = tmp, i = 0; *p && (!isspace(*p)); p++) {
  1302. if (i > 7)
  1303. return -EINVAL;
  1304. user[i++] = *p;
  1305. }
  1306. if (memcmp(user, privptr->conn->userid, 8) != 0) {
  1307. /* username changed */
  1308. if (dev->flags & IFF_RUNNING)
  1309. return -EBUSY;
  1310. }
  1311. memcpy(privptr->conn->userid, user, 9);
  1312. return count;
  1313. }
  1314. static ssize_t
  1315. netiucv_user_read(struct file *file, char *buf, size_t count, loff_t *off)
  1316. {
  1317. unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
  1318. char *sbuf = (char *)file->private_data;
  1319. net_device *dev;
  1320. netiucv_priv *privptr;
  1321. ssize_t ret = 0;
  1322. char *p = sbuf;
  1323. int l;
  1324. if (!(dev = find_netdev_by_ino(ino)))
  1325. return -ENODEV;
  1326. if (off != &file->f_pos)
  1327. return -ESPIPE;
  1328. privptr = (netiucv_priv *)dev->priv;
  1329. if (file->f_pos == 0)
  1330. sprintf(sbuf, "%sn",
  1331. netiucv_printname(privptr->conn->userid));
  1332. l = strlen(sbuf);
  1333. p = sbuf;
  1334. if (file->f_pos < l) {
  1335. p += file->f_pos;
  1336. l = strlen(p);
  1337. ret = (count > l) ? l : count;
  1338. if (copy_to_user(buf, p, ret))
  1339. return -EFAULT;
  1340. }
  1341. file->f_pos += ret;
  1342. return ret;
  1343. }
  1344. #define STATS_BUFSIZE 2048
  1345. static int
  1346. netiucv_stat_open(struct inode *inode, struct file *file)
  1347. {
  1348. file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL);
  1349. if (file->private_data == NULL)
  1350. return -ENOMEM;
  1351. MOD_INC_USE_COUNT;
  1352. return 0;
  1353. }
  1354. static int
  1355. netiucv_stat_close(struct inode *inode, struct file *file)
  1356. {
  1357. kfree(file->private_data);
  1358. MOD_DEC_USE_COUNT;
  1359. return 0;
  1360. }
  1361. static ssize_t
  1362. netiucv_stat_write(struct file *file, const char *buf, size_t count, loff_t *off)
  1363. {
  1364. unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
  1365. net_device *dev;
  1366. netiucv_priv *privptr;
  1367. if (!(dev = find_netdev_by_ino(ino)))
  1368. return -ENODEV;
  1369. privptr = (netiucv_priv *)dev->priv;
  1370. privptr->conn->prof.maxmulti = 0;
  1371. privptr->conn->prof.maxcqueue = 0;
  1372. privptr->conn->prof.doios_single = 0;
  1373. privptr->conn->prof.doios_multi = 0;
  1374. privptr->conn->prof.txlen = 0;
  1375. privptr->conn->prof.tx_time = 0;
  1376. return count;
  1377. }
  1378. static ssize_t
  1379. netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off)
  1380. {
  1381. unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
  1382. char *sbuf = (char *)file->private_data;
  1383. net_device *dev;
  1384. netiucv_priv *privptr;
  1385. ssize_t ret = 0;
  1386. char *p = sbuf;
  1387. int l;
  1388. if (!(dev = find_netdev_by_ino(ino)))
  1389. return -ENODEV;
  1390. if (off != &file->f_pos)
  1391. return -ESPIPE;
  1392. privptr = (netiucv_priv *)dev->priv;
  1393. if (file->f_pos == 0) {
  1394. p += sprintf(p, "Device FSM state: %sn",
  1395.      fsm_getstate_str(privptr->fsm));
  1396. p += sprintf(p, "Connection FSM state: %sn",
  1397.      fsm_getstate_str(privptr->conn->fsm));
  1398. p += sprintf(p, "Max. TX buffer used: %ldn",
  1399.      privptr->conn->prof.maxmulti);
  1400. p += sprintf(p, "Max. chained SKBs: %ldn",
  1401.      privptr->conn->prof.maxcqueue);
  1402. p += sprintf(p, "TX single write ops: %ldn",
  1403.      privptr->conn->prof.doios_single);
  1404. p += sprintf(p, "TX multi write ops: %ldn",
  1405.      privptr->conn->prof.doios_multi);
  1406. p += sprintf(p, "Netto bytes written: %ldn",
  1407.      privptr->conn->prof.txlen);
  1408. p += sprintf(p, "Max. TX IO-time: %ldn",
  1409.      privptr->conn->prof.tx_time);
  1410. }
  1411. l = strlen(sbuf);
  1412. p = sbuf;
  1413. if (file->f_pos < l) {
  1414. p += file->f_pos;
  1415. l = strlen(p);
  1416. ret = (count > l) ? l : count;
  1417. if (copy_to_user(buf, p, ret))
  1418. return -EFAULT;
  1419. }
  1420. file->f_pos += ret;
  1421. return ret;
  1422. }
  1423. static struct file_operations netiucv_stat_fops = {
  1424. read:    netiucv_stat_read,
  1425. write:   netiucv_stat_write,
  1426. open:    netiucv_stat_open,
  1427. release: netiucv_stat_close,
  1428. };
  1429. static struct file_operations netiucv_buffer_fops = {
  1430. read:    netiucv_buffer_read,
  1431. write:   netiucv_buffer_write,
  1432. open:    netiucv_buffer_open,
  1433. release: netiucv_buffer_close,
  1434. };
  1435. static struct file_operations netiucv_user_fops = {
  1436. read:    netiucv_user_read,
  1437. write:   netiucv_user_write,
  1438. open:    netiucv_user_open,
  1439. release: netiucv_user_close,
  1440. };
  1441. static struct inode_operations netiucv_stat_iops = {
  1442. #if LINUX_VERSION_CODE < 0x020363
  1443. default_file_ops: &netiucv_stat_fops
  1444. #endif
  1445. };
  1446. static struct inode_operations netiucv_buffer_iops = {
  1447. #if LINUX_VERSION_CODE < 0x020363
  1448. default_file_ops: &netiucv_buffer_fops
  1449. #endif
  1450. };
  1451. static struct inode_operations netiucv_user_iops = {
  1452. #if LINUX_VERSION_CODE < 0x020363
  1453. default_file_ops: &netiucv_user_fops
  1454. #endif
  1455. };
  1456. static struct proc_dir_entry stat_entry = {
  1457. 0,                           /* low_ino */
  1458. 10,                          /* namelen */
  1459. "statistics",                /* name    */
  1460. S_IFREG | S_IRUGO | S_IWUSR, /* mode    */
  1461. 1,                           /* nlink   */
  1462. 0,                           /* uid     */
  1463. 0,                           /* gid     */
  1464. 0,                           /* size    */
  1465. &netiucv_stat_iops           /* ops     */
  1466. };
  1467. static struct proc_dir_entry buffer_entry = {
  1468. 0,                           /* low_ino */
  1469. 10,                          /* namelen */
  1470. "buffersize",                /* name    */
  1471. S_IFREG | S_IRUSR | S_IWUSR, /* mode    */
  1472. 1,                           /* nlink   */
  1473. 0,                           /* uid     */
  1474. 0,                           /* gid     */
  1475. 0,                           /* size    */
  1476. &netiucv_buffer_iops         /* ops     */
  1477. };
  1478. static struct proc_dir_entry user_entry = {
  1479. 0,                           /* low_ino */
  1480. 8,                           /* namelen */
  1481. "username",                  /* name    */
  1482. S_IFREG | S_IRUSR | S_IWUSR, /* mode    */
  1483. 1,                           /* nlink   */
  1484. 0,                           /* uid     */
  1485. 0,                           /* gid     */
  1486. 0,                           /* size    */
  1487. &netiucv_user_iops           /* ops     */
  1488. };
  1489. #if LINUX_VERSION_CODE < 0x020363
  1490. static struct proc_dir_entry netiucv_dir = {
  1491. 0,                           /* low_ino  */
  1492. 4,                           /* namelen  */
  1493. "iucv",                      /* name     */
  1494. S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */
  1495. 2,                           /* nlink    */
  1496. 0,                           /* uid      */
  1497. 0,                           /* gid      */
  1498. 0,                           /* size     */
  1499. 0,                           /* ops      */
  1500. 0,                           /* get_info */
  1501. netiucv_fill_inode           /* fill_ino (for locking) */
  1502. };
  1503. static struct proc_dir_entry netiucv_template =
  1504. {
  1505. 0,                           /* low_ino  */
  1506. 0,                           /* namelen  */
  1507. "",                          /* name     */
  1508. S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */
  1509. 2,                           /* nlink    */
  1510. 0,                           /* uid      */
  1511. 0,                           /* gid      */
  1512. 0,                           /* size     */
  1513. 0,                           /* ops      */
  1514. 0,                           /* get_info */
  1515. netiucv_fill_inode           /* fill_ino (for locking) */
  1516. };
  1517. #else
  1518. static struct proc_dir_entry *netiucv_dir = NULL;
  1519. static struct proc_dir_entry *netiucv_template = NULL;
  1520. #endif
  1521. /**
  1522.  * Create the driver's main directory /proc/net/iucv
  1523.  */
  1524. static void
  1525. netiucv_proc_create_main(void)
  1526. {
  1527. /**
  1528.  * If not registered, register main proc dir-entry now
  1529.  */
  1530. #if LINUX_VERSION_CODE > 0x020362
  1531. if (!netiucv_dir)
  1532. netiucv_dir = proc_mkdir("iucv", proc_net);
  1533. #else
  1534. if (netiucv_dir.low_ino == 0)
  1535. proc_net_register(&netiucv_dir);
  1536. #endif
  1537. }
  1538. #ifdef MODULE
  1539. /**
  1540.  * Destroy /proc/net/iucv
  1541.  */
  1542. static void
  1543. netiucv_proc_destroy_main(void)
  1544. {
  1545. #if LINUX_VERSION_CODE > 0x020362
  1546. remove_proc_entry("iucv", proc_net);
  1547. #else
  1548. proc_net_unregister(netiucv_dir.low_ino);
  1549. #endif
  1550. }
  1551. #endif MODULE
  1552. /**
  1553.  * Create a device specific subdirectory in /proc/net/iucv/ with the
  1554.  * same name like the device. In that directory, create 3 entries
  1555.  * "statistics", "buffersize" and "username".
  1556.  *
  1557.  * @param dev The device for which the subdirectory should be created.
  1558.  *
  1559.  */
  1560. static void
  1561. netiucv_proc_create_sub(net_device *dev) {
  1562. netiucv_priv *privptr = dev->priv;
  1563. #if LINUX_VERSION_CODE > 0x020362
  1564. privptr->proc_dentry = proc_mkdir(dev->name, netiucv_dir);
  1565. privptr->proc_stat_entry =
  1566. create_proc_entry("statistics",
  1567.   S_IFREG | S_IRUSR | S_IWUSR,
  1568.   privptr->proc_dentry);
  1569. privptr->proc_stat_entry->proc_fops = &netiucv_stat_fops;
  1570. privptr->proc_stat_entry->proc_iops = &netiucv_stat_iops;
  1571. privptr->proc_buffer_entry =
  1572. create_proc_entry("buffersize",
  1573.   S_IFREG | S_IRUSR | S_IWUSR,
  1574.   privptr->proc_dentry);
  1575. privptr->proc_buffer_entry->proc_fops = &netiucv_buffer_fops;
  1576. privptr->proc_buffer_entry->proc_iops = &netiucv_buffer_iops;
  1577. privptr->proc_user_entry =
  1578. create_proc_entry("username",
  1579.   S_IFREG | S_IRUSR | S_IWUSR,
  1580.   privptr->proc_dentry);
  1581. privptr->proc_user_entry->proc_fops = &netiucv_user_fops;
  1582. privptr->proc_user_entry->proc_iops = &netiucv_user_iops;
  1583. #else
  1584. privptr->proc_dentry->name = dev->name;
  1585. privptr->proc_dentry->namelen = strlen(dev->name);
  1586. proc_register(&netiucv_dir, privptr->proc_dentry);
  1587. proc_register(privptr->proc_dentry, privptr->proc_stat_entry);
  1588. proc_register(privptr->proc_dentry, privptr->proc_buffer_entry);
  1589. proc_register(privptr->proc_dentry, privptr->proc_user_entry);
  1590. #endif
  1591. privptr->proc_registered = 1;
  1592. }
  1593. /**
  1594.  * Destroy a device specific subdirectory.
  1595.  *
  1596.  * @param privptr Pointer to device private data.
  1597.  */
  1598. static void
  1599. netiucv_proc_destroy_sub(netiucv_priv *privptr) {
  1600. if (!privptr->proc_registered)
  1601. return;
  1602. #if LINUX_VERSION_CODE > 0x020362
  1603. remove_proc_entry("statistics", privptr->proc_dentry);
  1604. remove_proc_entry("buffersize", privptr->proc_dentry);
  1605. remove_proc_entry("username", privptr->proc_dentry);
  1606. remove_proc_entry(privptr->proc_dentry->name, netiucv_dir);
  1607. #else
  1608. proc_unregister(privptr->proc_dentry,
  1609. privptr->proc_stat_entry->low_ino);
  1610. proc_unregister(privptr->proc_dentry,
  1611. privptr->proc_buffer_entry->low_ino);
  1612. proc_unregister(privptr->proc_dentry,
  1613. privptr->proc_user_entry->low_ino);
  1614. proc_unregister(&netiucv_dir,
  1615. privptr->proc_dentry->low_ino);
  1616. #endif
  1617. privptr->proc_registered = 0;
  1618. }
  1619. /**
  1620.  * Allocate and initialize a new connection structure.
  1621.  * Add it to the list of connections;
  1622.  */
  1623. static iucv_connection *
  1624. netiucv_new_connection(net_device *dev, char *username)
  1625. {
  1626. iucv_connection **clist = &connections;
  1627. iucv_connection *conn =
  1628. (iucv_connection *)kmalloc(sizeof(iucv_connection), GFP_KERNEL);
  1629. if (conn) {
  1630. memset(conn, 0, sizeof(iucv_connection));
  1631. skb_queue_head_init(&conn->collect_queue);
  1632. conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
  1633. conn->netdev = dev;
  1634. conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);
  1635. if (!conn->rx_buff) {
  1636. kfree(conn);
  1637. return NULL;
  1638. }
  1639. conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);
  1640. if (!conn->tx_buff) {
  1641. kfree_skb(conn->rx_buff);
  1642. kfree(conn);
  1643. return NULL;
  1644. }
  1645. conn->fsm = init_fsm("netiucvconn", conn_state_names,
  1646.      conn_event_names, NR_CONN_STATES,
  1647.      NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,
  1648.      GFP_KERNEL);
  1649. if (!conn->fsm) {
  1650. kfree_skb(conn->tx_buff);
  1651. kfree_skb(conn->rx_buff);
  1652. kfree(conn);
  1653. return NULL;
  1654. }
  1655. fsm_settimer(conn->fsm, &conn->timer);
  1656. fsm_newstate(conn->fsm, CONN_STATE_INVALID);
  1657. if (username) {
  1658. memcpy(conn->userid, username, 9);
  1659. fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
  1660. }
  1661. conn->next = *clist;
  1662. *clist = conn;
  1663. }
  1664. return conn;
  1665. }
  1666. /**
  1667.  * Release a connection structure and remove it from the
  1668.  * list of connections.
  1669.  */
  1670. static void
  1671. netiucv_remove_connection(iucv_connection *conn)
  1672. {
  1673. iucv_connection **clist = &connections;
  1674. if (conn == NULL)
  1675. return;
  1676. while (*clist) {
  1677. if (*clist == conn) {
  1678. *clist = conn->next;
  1679. if (conn->handle != 0) {
  1680. iucv_unregister_program(conn->handle);
  1681. conn->handle = 0;
  1682. }
  1683. fsm_deltimer(&conn->timer);
  1684. kfree_fsm(conn->fsm);
  1685. kfree_skb(conn->rx_buff);
  1686. kfree_skb(conn->tx_buff);
  1687. return;
  1688. }
  1689. clist = &((*clist)->next);
  1690. }
  1691. }
  1692. /**
  1693.  * Allocate and initialize everything of a net device.
  1694.  */
  1695. static net_device *
  1696. netiucv_init_netdevice(int ifno, char *username)
  1697. {
  1698. netiucv_priv *privptr;
  1699. int          priv_size;
  1700. net_device *dev = kmalloc(sizeof(net_device)
  1701. #if LINUX_VERSION_CODE < 0x020300
  1702.       + 11 /* name + zero */
  1703. #endif
  1704.       , GFP_KERNEL);
  1705. if (!dev)
  1706. return NULL;
  1707. memset(dev, 0, sizeof(net_device));
  1708. #if LINUX_VERSION_CODE < 0x020300
  1709. dev->name = (char *)dev + sizeof(net_device);
  1710. #endif
  1711. sprintf(dev->name, "iucv%d", ifno);
  1712. priv_size = sizeof(netiucv_priv) + sizeof(netiucv_template) +
  1713. sizeof(stat_entry) + sizeof(buffer_entry) + sizeof(user_entry);
  1714. dev->priv = kmalloc(priv_size, GFP_KERNEL);
  1715. if (dev->priv == NULL) {
  1716. kfree(dev);
  1717. return NULL;
  1718. }
  1719.         memset(dev->priv, 0, priv_size);
  1720.         privptr = (netiucv_priv *)dev->priv;
  1721.         privptr->proc_dentry = (struct proc_dir_entry *)
  1722. (((char *)privptr) + sizeof(netiucv_priv));
  1723.         privptr->proc_stat_entry = (struct proc_dir_entry *)
  1724. (((char *)privptr) + sizeof(netiucv_priv) +
  1725.  sizeof(netiucv_template));
  1726.         privptr->proc_buffer_entry = (struct proc_dir_entry *)
  1727. (((char *)privptr) + sizeof(netiucv_priv) +
  1728.  sizeof(netiucv_template) + sizeof(stat_entry));
  1729.         privptr->proc_user_entry = (struct proc_dir_entry *)
  1730. (((char *)privptr) + sizeof(netiucv_priv) +
  1731.  sizeof(netiucv_template) + sizeof(stat_entry) +
  1732.  sizeof(buffer_entry));
  1733. memcpy(privptr->proc_dentry, &netiucv_template,
  1734.        sizeof(netiucv_template));
  1735. memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry));
  1736. memcpy(privptr->proc_buffer_entry, &buffer_entry, sizeof(buffer_entry));
  1737. memcpy(privptr->proc_user_entry, &user_entry, sizeof(user_entry));
  1738. privptr->fsm = init_fsm("netiucvdev", dev_state_names,
  1739. dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
  1740. dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
  1741. if (privptr->fsm == NULL) {
  1742. kfree(privptr);
  1743. kfree(dev);
  1744. return NULL;
  1745. }
  1746. privptr->conn = netiucv_new_connection(dev, username);
  1747. if (!privptr->conn) {
  1748. kfree_fsm(privptr->fsm);
  1749. kfree(privptr);
  1750. kfree(dev);
  1751. return NULL;
  1752. }
  1753. fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
  1754. dev->mtu          = NETIUCV_MTU_DEFAULT;
  1755. dev->hard_start_xmit     = netiucv_tx;
  1756. dev->open          = netiucv_open;
  1757. dev->stop          = netiucv_close;
  1758. dev->get_stats          = netiucv_stats;
  1759. dev->change_mtu          = netiucv_change_mtu;
  1760. dev->hard_header_len     = NETIUCV_HDRLEN;
  1761. dev->addr_len            = 0;
  1762. dev->type                = ARPHRD_SLIP;
  1763. dev->tx_queue_len        = NETIUCV_QUEUELEN_DEFAULT;
  1764. dev_init_buffers(dev);
  1765. dev->flags          = IFF_POINTOPOINT | IFF_NOARP;
  1766. return dev;
  1767. }
  1768. /**
  1769.  * Allocate and initialize everything of a net device.
  1770.  */
  1771. static void
  1772. netiucv_free_netdevice(net_device *dev)
  1773. {
  1774. netiucv_priv *privptr;
  1775. if (!dev)
  1776. return;
  1777. privptr = (netiucv_priv *)dev->priv;
  1778. if (privptr) {
  1779. if (privptr->conn)
  1780. netiucv_remove_connection(privptr->conn);
  1781. if (privptr->fsm)
  1782. kfree_fsm(privptr->fsm);
  1783. netiucv_proc_destroy_sub(privptr);
  1784. kfree(privptr);
  1785. }
  1786. kfree(dev);
  1787. }
  1788. static void
  1789. netiucv_banner(void)
  1790. {
  1791. char vbuf[] = "$Revision: 1.16 $";
  1792. char *version = vbuf;
  1793. if ((version = strchr(version, ':'))) {
  1794. char *p = strchr(version + 1, '$');
  1795. if (p)
  1796. *p = '';
  1797. } else
  1798. version = " ??? ";
  1799. printk(KERN_INFO "NETIUCV driver Version%s initializedn", version);
  1800. }
  1801. #ifndef MODULE
  1802. # if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
  1803. #  define init_return(a) return a
  1804. static int __init
  1805. iucv_setup(char *param)
  1806. # else
  1807. #  define init_return(a) return
  1808. __initfunc (void iucv_setup(char *param, int *ints))
  1809. # endif
  1810. {
  1811. /**
  1812. * We do not parse parameters here because at the time of
  1813. * calling iucv_setup(), the kernel does not yet have
  1814. * memory management running. We delay this until probing
  1815. * is called.
  1816. */
  1817. iucv = param;
  1818. init_return(1);
  1819. }
  1820. # if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
  1821. __setup ("iucv=", iucv_setup);
  1822. # endif
  1823. #else
  1824. static void
  1825. netiucv_exit(void)
  1826. {
  1827. while (connections) {
  1828. net_device *dev = connections->netdev;
  1829. unregister_netdev(dev);
  1830. netiucv_free_netdevice(dev);
  1831. }
  1832. netiucv_proc_destroy_main();
  1833. printk(KERN_INFO "NETIUCV driver unloadedn");
  1834. return;
  1835. }
  1836. #endif
  1837. static int
  1838. netiucv_init(void)
  1839. {
  1840. char *p = iucv;
  1841. int ifno = 0;
  1842. int i = 0;
  1843. char username[10];
  1844. netiucv_proc_create_main();
  1845. while (p) {
  1846. if (isalnum(*p)) {
  1847. username[i++] = *p++;
  1848. username[i] = '';
  1849. if (i > 8) {
  1850. printk(KERN_WARNING
  1851.        "netiucv: Invalid user name '%s'n",
  1852.        username);
  1853. while (*p && (*p != ':') && (*p != ','))
  1854. p++;
  1855. }
  1856. } else {
  1857. if (*p && (*p != ':') && (*p != ',')) {
  1858. printk(KERN_WARNING
  1859.        "netiucv: Invalid delimiter '%c'n",
  1860.        *p);
  1861. while (*p && (*p != ':') && (*p != ','))
  1862. p++;
  1863. } else {
  1864. if (i) {
  1865. net_device *dev;
  1866. while (i < 9)
  1867. username[i++] = ' ';
  1868. username[9] = '';
  1869. dev = netiucv_init_netdevice(ifno,
  1870.      username);
  1871. if (!dev)
  1872. printk(KERN_WARNING
  1873.        "netiucv: Could not allocate network device structure for user '%s'n", netiucv_printname(username));
  1874. else {
  1875. if (register_netdev(dev)) {
  1876. printk(KERN_WARNING
  1877.        "netiucv: Could not register '%s'n", dev->name);
  1878. netiucv_free_netdevice(dev);
  1879. } else {
  1880. printk(KERN_INFO "%s: '%s'n", dev->name, netiucv_printname(username));
  1881. netiucv_proc_create_sub(dev);
  1882. ifno++;
  1883. }
  1884. }
  1885. }
  1886. if (!(*p))
  1887. break;
  1888. i = 0;
  1889. p++;
  1890. }
  1891. }
  1892. }
  1893. netiucv_banner();
  1894. return 0;
  1895. }
  1896. #ifdef MODULE
  1897. module_init(netiucv_init);
  1898. module_exit(netiucv_exit);
  1899. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
  1900. MODULE_LICENSE("GPL");
  1901. #endif
  1902. #endif