wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 1 | /* |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 2 | Ported to U-Boot by Christian Pellegrin <chri@ascensit.com> |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 3 | |
| 4 | Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and |
| 5 | eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world |
| 6 | are GPL, so this is, of course, GPL. |
| 7 | |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 8 | ========================================================================== |
| 9 | |
| 10 | dev/if_dp83902a.c |
| 11 | |
| 12 | Ethernet device driver for NS DP83902a ethernet controller |
| 13 | |
| 14 | ========================================================================== |
| 15 | ####ECOSGPLCOPYRIGHTBEGIN#### |
| 16 | ------------------------------------------- |
| 17 | This file is part of eCos, the Embedded Configurable Operating System. |
| 18 | Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
| 19 | |
| 20 | eCos is free software; you can redistribute it and/or modify it under |
| 21 | the terms of the GNU General Public License as published by the Free |
| 22 | Software Foundation; either version 2 or (at your option) any later version. |
| 23 | |
| 24 | eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
| 25 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 26 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 27 | for more details. |
| 28 | |
| 29 | You should have received a copy of the GNU General Public License along |
| 30 | with eCos; if not, write to the Free Software Foundation, Inc., |
| 31 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
| 32 | |
| 33 | As a special exception, if other files instantiate templates or use macros |
| 34 | or inline functions from this file, or you compile this file and link it |
| 35 | with other works to produce a work based on this file, this file does not |
| 36 | by itself cause the resulting work to be covered by the GNU General Public |
| 37 | License. However the source code for this file must still be made available |
| 38 | in accordance with section (3) of the GNU General Public License. |
| 39 | |
| 40 | This exception does not invalidate any other reasons why a work based on |
| 41 | this file might be covered by the GNU General Public License. |
| 42 | |
| 43 | Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
| 44 | at http://sources.redhat.com/ecos/ecos-license/ |
| 45 | ------------------------------------------- |
| 46 | ####ECOSGPLCOPYRIGHTEND#### |
| 47 | ####BSDCOPYRIGHTBEGIN#### |
| 48 | |
| 49 | ------------------------------------------- |
| 50 | |
| 51 | Portions of this software may have been derived from OpenBSD or other sources, |
| 52 | and are covered by the appropriate copyright disclaimers included herein. |
| 53 | |
| 54 | ------------------------------------------- |
| 55 | |
| 56 | ####BSDCOPYRIGHTEND#### |
| 57 | ========================================================================== |
| 58 | #####DESCRIPTIONBEGIN#### |
| 59 | |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 60 | Author(s): gthomas |
| 61 | Contributors: gthomas, jskov, rsandifo |
| 62 | Date: 2001-06-13 |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 63 | Purpose: |
| 64 | Description: |
| 65 | |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 66 | FIXME: Will fail if pinged with large packets (1520 bytes) |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 67 | Add promisc config |
| 68 | Add SNMP |
| 69 | |
| 70 | ####DESCRIPTIONEND#### |
| 71 | |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 72 | ========================================================================== |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 73 | */ |
| 74 | |
| 75 | #include <common.h> |
| 76 | #include <command.h> |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 77 | |
goda.yusuke | 7b603ad | 2008-03-05 17:08:20 +0900 | [diff] [blame] | 78 | /* NE2000 base header file */ |
| 79 | #include "ne2000_base.h" |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 80 | |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 81 | /* find prom (taken from pc_net_cs.c from Linux) */ |
| 82 | |
| 83 | #include "8390.h" |
goda.yusuke | 7b603ad | 2008-03-05 17:08:20 +0900 | [diff] [blame] | 84 | /* |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 85 | typedef struct hw_info_t { |
| 86 | u_int offset; |
| 87 | u_char a0, a1, a2; |
| 88 | u_int flags; |
| 89 | } hw_info_t; |
goda.yusuke | 7b603ad | 2008-03-05 17:08:20 +0900 | [diff] [blame] | 90 | */ |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 91 | #define DELAY_OUTPUT 0x01 |
| 92 | #define HAS_MISC_REG 0x02 |
| 93 | #define USE_BIG_BUF 0x04 |
| 94 | #define HAS_IBM_MISC 0x08 |
| 95 | #define IS_DL10019 0x10 |
| 96 | #define IS_DL10022 0x20 |
| 97 | #define HAS_MII 0x40 |
| 98 | #define USE_SHMEM 0x80 /* autodetected */ |
| 99 | |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 100 | #define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */ |
| 101 | #define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */ |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 102 | #define MII_PHYID_REV_MASK 0xfffffff0 |
| 103 | #define MII_PHYID_REG1 0x02 |
| 104 | #define MII_PHYID_REG2 0x03 |
| 105 | |
| 106 | static hw_info_t hw_info[] = { |
| 107 | { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, |
| 108 | { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, |
| 109 | { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, |
| 110 | { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 111 | DELAY_OUTPUT | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 112 | { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 }, |
| 113 | { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 }, |
| 114 | { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 }, |
| 115 | { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 }, |
| 116 | { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 }, |
| 117 | { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 }, |
| 118 | { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 119 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 120 | { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 }, |
| 121 | { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 }, |
| 122 | { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 123 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 124 | { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 125 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 126 | { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 127 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 128 | { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 129 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 130 | { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 131 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 132 | { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 133 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 134 | { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 135 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 136 | { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 137 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 138 | { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 139 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 140 | { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 141 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 142 | { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 }, |
| 143 | { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 }, |
| 144 | { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 145 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 146 | { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 147 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 148 | { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 }, |
| 149 | { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 }, |
| 150 | { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 }, |
| 151 | { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, |
| 152 | { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 153 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 154 | { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 155 | HAS_MISC_REG | HAS_IBM_MISC }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 156 | { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, |
| 157 | { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, |
| 158 | { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 }, |
| 159 | { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, |
Jean-Christophe PLAGNIOL-VILLARD | 8ec5fcb | 2008-04-24 07:57:16 +0200 | [diff] [blame] | 160 | DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 161 | { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 }, |
| 162 | { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, |
| 163 | { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }, |
| 164 | { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 }, |
Vlad Lungu | 4c113c3 | 2007-10-25 16:08:14 +0300 | [diff] [blame] | 165 | { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }, |
Nobuhiro Iwamatsu | 3292233 | 2010-10-26 20:32:00 +0900 | [diff] [blame] | 166 | { /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 }, |
| 167 | { /* RTL8019AS */ 0x0, 0x0, 0x18, 0x5f, 0 } |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 168 | }; |
| 169 | |
| 170 | #define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t)) |
| 171 | |
wdenk | f806271 | 2005-01-09 23:16:25 +0000 | [diff] [blame] | 172 | #define PCNET_CMD 0x00 |
| 173 | #define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ |
| 174 | #define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ |
| 175 | #define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */ |
| 176 | |
Nobuhiro Iwamatsu | f909daa | 2008-09-30 15:02:53 +0900 | [diff] [blame] | 177 | static void pcnet_reset_8390(u8* addr) |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 178 | { |
| 179 | int i, r; |
| 180 | |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 181 | n2k_outb(E8390_NODMA + E8390_PAGE0+E8390_STOP, E8390_CMD); |
Nobuhiro Iwamatsu | f909daa | 2008-09-30 15:02:53 +0900 | [diff] [blame] | 182 | PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD)); |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 183 | n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD); |
Nobuhiro Iwamatsu | f909daa | 2008-09-30 15:02:53 +0900 | [diff] [blame] | 184 | PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD)); |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 185 | n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); |
Nobuhiro Iwamatsu | f909daa | 2008-09-30 15:02:53 +0900 | [diff] [blame] | 186 | PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD)); |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 187 | n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); |
| 188 | |
| 189 | n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET); |
| 190 | |
| 191 | for (i = 0; i < 100; i++) { |
| 192 | if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0) |
| 193 | break; |
| 194 | PRINTK("got %x in reset\n", r); |
| 195 | udelay(100); |
| 196 | } |
| 197 | n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */ |
| 198 | |
| 199 | if (i == 100) |
| 200 | printf("pcnet_reset_8390() did not complete.\n"); |
| 201 | } /* pcnet_reset_8390 */ |
| 202 | |
Nobuhiro Iwamatsu | f909daa | 2008-09-30 15:02:53 +0900 | [diff] [blame] | 203 | int get_prom(u8* mac_addr, u8* base_addr) |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 204 | { |
| 205 | u8 prom[32]; |
| 206 | int i, j; |
| 207 | struct { |
| 208 | u_char value, offset; |
| 209 | } program_seq[] = { |
| 210 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ |
| 211 | {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ |
| 212 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ |
| 213 | {0x00, EN0_RCNTHI}, |
| 214 | {0x00, EN0_IMR}, /* Mask completion irq. */ |
| 215 | {0xFF, EN0_ISR}, |
| 216 | {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ |
| 217 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ |
| 218 | {32, EN0_RCNTLO}, |
| 219 | {0x00, EN0_RCNTHI}, |
| 220 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ |
| 221 | {0x00, EN0_RSARHI}, |
| 222 | {E8390_RREAD+E8390_START, E8390_CMD}, |
| 223 | }; |
| 224 | |
| 225 | PRINTK ("trying to get MAC via prom reading\n"); |
| 226 | |
Nobuhiro Iwamatsu | f909daa | 2008-09-30 15:02:53 +0900 | [diff] [blame] | 227 | pcnet_reset_8390 (base_addr); |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 228 | |
| 229 | mdelay (10); |
| 230 | |
Axel Lin | 10a72b6 | 2013-07-03 11:24:18 +0800 | [diff] [blame] | 231 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) |
Jean-Christophe PLAGNIOL-VILLARD | d87c24f | 2008-04-24 07:57:17 +0200 | [diff] [blame] | 232 | n2k_outb (program_seq[i].value, program_seq[i].offset); |
| 233 | |
| 234 | PRINTK ("PROM:"); |
| 235 | for (i = 0; i < 32; i++) { |
| 236 | prom[i] = n2k_inb (PCNET_DATAPORT); |
| 237 | PRINTK (" %02x", prom[i]); |
| 238 | } |
| 239 | PRINTK ("\n"); |
| 240 | for (i = 0; i < NR_INFO; i++) { |
| 241 | if ((prom[0] == hw_info[i].a0) && |
| 242 | (prom[2] == hw_info[i].a1) && |
| 243 | (prom[4] == hw_info[i].a2)) { |
| 244 | PRINTK ("matched board %d\n", i); |
| 245 | break; |
| 246 | } |
| 247 | } |
| 248 | if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { |
| 249 | PRINTK ("on exit i is %d/%ld\n", i, NR_INFO); |
| 250 | PRINTK ("MAC address is "); |
| 251 | for (j = 0; j < 6; j++) { |
| 252 | mac_addr[j] = prom[j << 1]; |
| 253 | PRINTK ("%02x:", mac_addr[i]); |
| 254 | } |
| 255 | PRINTK ("\n"); |
| 256 | return (i < NR_INFO) ? i : 0; |
| 257 | } |
| 258 | return 0; |
| 259 | } |