diff options
| -rw-r--r-- | arch/xtensa/configs/iss_defconfig | 531 | ||||
| -rw-r--r-- | arch/xtensa/platform-iss/Makefile | 13 | ||||
| -rw-r--r-- | arch/xtensa/platform-iss/console.c | 303 | ||||
| -rw-r--r-- | arch/xtensa/platform-iss/io.c | 32 | ||||
| -rw-r--r-- | arch/xtensa/platform-iss/network.c | 855 | ||||
| -rw-r--r-- | arch/xtensa/platform-iss/setup.c | 112 | ||||
| -rw-r--r-- | include/asm-xtensa/platform-iss/hardware.h | 29 | ||||
| -rw-r--r-- | include/asm-xtensa/platform.h | 92 |
8 files changed, 1967 insertions, 0 deletions
diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig new file mode 100644 index 000000000000..802621dd4867 --- /dev/null +++ b/arch/xtensa/configs/iss_defconfig | |||
| @@ -0,0 +1,531 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.11-rc2 | ||
| 4 | # Fri Feb 25 19:21:24 2005 | ||
| 5 | # | ||
| 6 | CONFIG_FRAME_POINTER=y | ||
| 7 | CONFIG_XTENSA=y | ||
| 8 | # CONFIG_UID16 is not set | ||
| 9 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
| 10 | CONFIG_HAVE_DEC_LOCK=y | ||
| 11 | CONFIG_GENERIC_HARDIRQS=y | ||
| 12 | |||
| 13 | # | ||
| 14 | # Code maturity level options | ||
| 15 | # | ||
| 16 | CONFIG_EXPERIMENTAL=y | ||
| 17 | CONFIG_CLEAN_COMPILE=y | ||
| 18 | CONFIG_BROKEN_ON_SMP=y | ||
| 19 | |||
| 20 | # | ||
| 21 | # General setup | ||
| 22 | # | ||
| 23 | CONFIG_LOCALVERSION="" | ||
| 24 | CONFIG_SWAP=y | ||
| 25 | CONFIG_SYSVIPC=y | ||
| 26 | # CONFIG_POSIX_MQUEUE is not set | ||
| 27 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 28 | CONFIG_SYSCTL=y | ||
| 29 | # CONFIG_AUDIT is not set | ||
| 30 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 31 | # CONFIG_HOTPLUG is not set | ||
| 32 | # CONFIG_KOBJECT_UEVENT is not set | ||
| 33 | # CONFIG_IKCONFIG is not set | ||
| 34 | CONFIG_EMBEDDED=y | ||
| 35 | CONFIG_KALLSYMS=y | ||
| 36 | # CONFIG_KALLSYMS_ALL is not set | ||
| 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
| 38 | CONFIG_FUTEX=y | ||
| 39 | CONFIG_EPOLL=y | ||
| 40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 41 | CONFIG_SHMEM=y | ||
| 42 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
| 43 | CONFIG_CC_ALIGN_LABELS=0 | ||
| 44 | CONFIG_CC_ALIGN_LOOPS=0 | ||
| 45 | CONFIG_CC_ALIGN_JUMPS=0 | ||
| 46 | # CONFIG_TINY_SHMEM is not set | ||
| 47 | |||
| 48 | # | ||
| 49 | # Loadable module support | ||
| 50 | # | ||
| 51 | # CONFIG_MODULES is not set | ||
| 52 | |||
| 53 | # | ||
| 54 | # Processor type and features | ||
| 55 | # | ||
| 56 | CONFIG_XTENSA_ARCH_LINUX_BE=y | ||
| 57 | # CONFIG_XTENSA_ARCH_LINUX_LE is not set | ||
| 58 | # CONFIG_XTENSA_ARCH_LINUX_TEST is not set | ||
| 59 | # CONFIG_XTENSA_ARCH_S5 is not set | ||
| 60 | # CONFIG_XTENSA_CUSTOM is not set | ||
| 61 | CONFIG_MMU=y | ||
| 62 | # CONFIG_XTENSA_UNALIGNED_USER is not set | ||
| 63 | # CONFIG_PREEMPT is not set | ||
| 64 | # CONFIG_MATH_EMULATION is not set | ||
| 65 | # CONFIG_HIGHMEM is not set | ||
| 66 | |||
| 67 | # | ||
| 68 | # Platform options | ||
| 69 | # | ||
| 70 | CONFIG_XTENSA_PLATFORM_ISS=y | ||
| 71 | # CONFIG_XTENSA_PLATFORM_XT2000 is not set | ||
| 72 | # CONFIG_XTENSA_PLATFORM_ARUBA is not set | ||
| 73 | # CONFIG_XTENSA_CALIBRATE_CCOUNT is not set | ||
| 74 | CONFIG_XTENSA_CPU_CLOCK=10 | ||
| 75 | # CONFIG_GENERIC_CALIBRATE_DELAY is not set | ||
| 76 | CONFIG_CMDLINE_BOOL=y | ||
| 77 | CONFIG_CMDLINE="console=ttyS0,38400 eth0=tuntap,,tap0 ip=192.168.168.5:192.168.168.1 root=nfs nfsroot=192.168.168.1:/opt/montavista/pro/devkit/xtensa/linux_be/target" | ||
| 78 | CONFIG_SERIAL_CONSOLE=y | ||
| 79 | CONFIG_XTENSA_ISS_NETWORK=y | ||
| 80 | |||
| 81 | # | ||
| 82 | # Bus options | ||
| 83 | # | ||
| 84 | |||
| 85 | # | ||
| 86 | # PCCARD (PCMCIA/CardBus) support | ||
| 87 | # | ||
| 88 | # CONFIG_PCCARD is not set | ||
| 89 | |||
| 90 | # | ||
| 91 | # PC-card bridges | ||
| 92 | # | ||
| 93 | |||
| 94 | # | ||
| 95 | # PCI Hotplug Support | ||
| 96 | # | ||
| 97 | |||
| 98 | # | ||
| 99 | # Exectuable file formats | ||
| 100 | # | ||
| 101 | CONFIG_KCORE_ELF=y | ||
| 102 | CONFIG_BINFMT_ELF=y | ||
| 103 | # CONFIG_BINFMT_MISC is not set | ||
| 104 | |||
| 105 | # | ||
| 106 | # Device Drivers | ||
| 107 | # | ||
| 108 | |||
| 109 | # | ||
| 110 | # Generic Driver Options | ||
| 111 | # | ||
| 112 | # CONFIG_STANDALONE is not set | ||
| 113 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 114 | # CONFIG_FW_LOADER is not set | ||
| 115 | # CONFIG_DEBUG_DRIVER is not set | ||
| 116 | |||
| 117 | # | ||
| 118 | # Memory Technology Devices (MTD) | ||
| 119 | # | ||
| 120 | # CONFIG_MTD is not set | ||
| 121 | |||
| 122 | # | ||
| 123 | # Parallel port support | ||
| 124 | # | ||
| 125 | # CONFIG_PARPORT is not set | ||
| 126 | |||
| 127 | # | ||
| 128 | # Plug and Play support | ||
| 129 | # | ||
| 130 | |||
| 131 | # | ||
| 132 | # Block devices | ||
| 133 | # | ||
| 134 | # CONFIG_BLK_DEV_FD is not set | ||
| 135 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 136 | # CONFIG_BLK_DEV_LOOP is not set | ||
| 137 | # CONFIG_BLK_DEV_NBD is not set | ||
| 138 | # CONFIG_BLK_DEV_RAM is not set | ||
| 139 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 140 | CONFIG_INITRAMFS_SOURCE="" | ||
| 141 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 142 | |||
| 143 | # | ||
| 144 | # IO Schedulers | ||
| 145 | # | ||
| 146 | CONFIG_IOSCHED_NOOP=y | ||
| 147 | # CONFIG_IOSCHED_AS is not set | ||
| 148 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 149 | # CONFIG_IOSCHED_CFQ is not set | ||
| 150 | # CONFIG_ATA_OVER_ETH is not set | ||
| 151 | |||
| 152 | # | ||
| 153 | # ATA/ATAPI/MFM/RLL support | ||
| 154 | # | ||
| 155 | # CONFIG_IDE is not set | ||
| 156 | |||
| 157 | # | ||
| 158 | # SCSI device support | ||
| 159 | # | ||
| 160 | # CONFIG_SCSI is not set | ||
| 161 | |||
| 162 | # | ||
| 163 | # Multi-device support (RAID and LVM) | ||
| 164 | # | ||
| 165 | # CONFIG_MD is not set | ||
| 166 | |||
| 167 | # | ||
| 168 | # Fusion MPT device support | ||
| 169 | # | ||
| 170 | |||
| 171 | # | ||
| 172 | # IEEE 1394 (FireWire) support | ||
| 173 | # | ||
| 174 | |||
| 175 | # | ||
| 176 | # I2O device support | ||
| 177 | # | ||
| 178 | |||
| 179 | # | ||
| 180 | # Networking support | ||
| 181 | # | ||
| 182 | CONFIG_NET=y | ||
| 183 | |||
| 184 | # | ||
| 185 | # Networking options | ||
| 186 | # | ||
| 187 | CONFIG_PACKET=y | ||
| 188 | # CONFIG_PACKET_MMAP is not set | ||
| 189 | # CONFIG_NETLINK_DEV is not set | ||
| 190 | CONFIG_UNIX=y | ||
| 191 | # CONFIG_NET_KEY is not set | ||
| 192 | CONFIG_INET=y | ||
| 193 | # CONFIG_IP_MULTICAST is not set | ||
| 194 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
| 195 | CONFIG_IP_PNP=y | ||
| 196 | CONFIG_IP_PNP_DHCP=y | ||
| 197 | CONFIG_IP_PNP_BOOTP=y | ||
| 198 | CONFIG_IP_PNP_RARP=y | ||
| 199 | # CONFIG_NET_IPIP is not set | ||
| 200 | # CONFIG_NET_IPGRE is not set | ||
| 201 | # CONFIG_ARPD is not set | ||
| 202 | # CONFIG_SYN_COOKIES is not set | ||
| 203 | # CONFIG_INET_AH is not set | ||
| 204 | # CONFIG_INET_ESP is not set | ||
| 205 | # CONFIG_INET_IPCOMP is not set | ||
| 206 | # CONFIG_INET_TUNNEL is not set | ||
| 207 | # CONFIG_IP_TCPDIAG is not set | ||
| 208 | # CONFIG_IP_TCPDIAG_IPV6 is not set | ||
| 209 | # CONFIG_IPV6 is not set | ||
| 210 | # CONFIG_NETFILTER is not set | ||
| 211 | |||
| 212 | # | ||
| 213 | # SCTP Configuration (EXPERIMENTAL) | ||
| 214 | # | ||
| 215 | # CONFIG_IP_SCTP is not set | ||
| 216 | # CONFIG_SCTP_HMAC_NONE is not set | ||
| 217 | # CONFIG_SCTP_HMAC_SHA1 is not set | ||
| 218 | # CONFIG_SCTP_HMAC_MD5 is not set | ||
| 219 | # CONFIG_ATM is not set | ||
| 220 | # CONFIG_BRIDGE is not set | ||
| 221 | # CONFIG_VLAN_8021Q is not set | ||
| 222 | # CONFIG_DECNET is not set | ||
| 223 | # CONFIG_LLC2 is not set | ||
| 224 | # CONFIG_IPX is not set | ||
| 225 | # CONFIG_ATALK is not set | ||
| 226 | # CONFIG_X25 is not set | ||
| 227 | # CONFIG_LAPB is not set | ||
| 228 | # CONFIG_NET_DIVERT is not set | ||
| 229 | # CONFIG_ECONET is not set | ||
| 230 | # CONFIG_WAN_ROUTER is not set | ||
| 231 | |||
| 232 | # | ||
| 233 | # QoS and/or fair queueing | ||
| 234 | # | ||
| 235 | # CONFIG_NET_SCHED is not set | ||
| 236 | # CONFIG_NET_SCH_CLK_JIFFIES is not set | ||
| 237 | # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set | ||
| 238 | # CONFIG_NET_SCH_CLK_CPU is not set | ||
| 239 | # CONFIG_NET_CLS_ROUTE is not set | ||
| 240 | |||
| 241 | # | ||
| 242 | # Network testing | ||
| 243 | # | ||
| 244 | # CONFIG_NET_PKTGEN is not set | ||
| 245 | # CONFIG_NETPOLL is not set | ||
| 246 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 247 | # CONFIG_HAMRADIO is not set | ||
| 248 | # CONFIG_IRDA is not set | ||
| 249 | # CONFIG_BT is not set | ||
| 250 | # CONFIG_NETDEVICES is not set | ||
| 251 | |||
| 252 | # | ||
| 253 | # ISDN subsystem | ||
| 254 | # | ||
| 255 | # CONFIG_ISDN is not set | ||
| 256 | |||
| 257 | # | ||
| 258 | # Telephony Support | ||
| 259 | # | ||
| 260 | # CONFIG_PHONE is not set | ||
| 261 | |||
| 262 | # | ||
| 263 | # Input device support | ||
| 264 | # | ||
| 265 | CONFIG_INPUT=y | ||
| 266 | |||
| 267 | # | ||
| 268 | # Userland interfaces | ||
| 269 | # | ||
| 270 | # CONFIG_INPUT_MOUSEDEV is not set | ||
| 271 | # CONFIG_INPUT_JOYDEV is not set | ||
| 272 | # CONFIG_INPUT_TSDEV is not set | ||
| 273 | # CONFIG_INPUT_EVDEV is not set | ||
| 274 | # CONFIG_INPUT_EVBUG is not set | ||
| 275 | |||
| 276 | # | ||
| 277 | # Input I/O drivers | ||
| 278 | # | ||
| 279 | # CONFIG_GAMEPORT is not set | ||
| 280 | CONFIG_SOUND_GAMEPORT=y | ||
| 281 | # CONFIG_SERIO is not set | ||
| 282 | # CONFIG_SERIO_I8042 is not set | ||
| 283 | |||
| 284 | # | ||
| 285 | # Input Device Drivers | ||
| 286 | # | ||
| 287 | # CONFIG_INPUT_KEYBOARD is not set | ||
| 288 | # CONFIG_INPUT_MOUSE is not set | ||
| 289 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 290 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 291 | # CONFIG_INPUT_MISC is not set | ||
| 292 | |||
| 293 | # | ||
| 294 | # Character devices | ||
| 295 | # | ||
| 296 | CONFIG_VT=y | ||
| 297 | CONFIG_VT_CONSOLE=y | ||
| 298 | CONFIG_HW_CONSOLE=y | ||
| 299 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 300 | |||
| 301 | # | ||
| 302 | # Serial drivers | ||
| 303 | # | ||
| 304 | # CONFIG_SERIAL_8250 is not set | ||
| 305 | |||
| 306 | # | ||
| 307 | # Non-8250 serial port support | ||
| 308 | # | ||
| 309 | CONFIG_UNIX98_PTYS=y | ||
| 310 | CONFIG_LEGACY_PTYS=y | ||
| 311 | CONFIG_LEGACY_PTY_COUNT=256 | ||
| 312 | |||
| 313 | # | ||
| 314 | # IPMI | ||
| 315 | # | ||
| 316 | # CONFIG_IPMI_HANDLER is not set | ||
| 317 | |||
| 318 | # | ||
| 319 | # Watchdog Cards | ||
| 320 | # | ||
| 321 | CONFIG_WATCHDOG=y | ||
| 322 | CONFIG_WATCHDOG_NOWAYOUT=y | ||
| 323 | |||
| 324 | # | ||
| 325 | # Watchdog Device Drivers | ||
| 326 | # | ||
| 327 | CONFIG_SOFT_WATCHDOG=y | ||
| 328 | # CONFIG_RTC is not set | ||
| 329 | # CONFIG_GEN_RTC is not set | ||
| 330 | # CONFIG_DTLK is not set | ||
| 331 | # CONFIG_R3964 is not set | ||
| 332 | |||
| 333 | # | ||
| 334 | # Ftape, the floppy tape device driver | ||
| 335 | # | ||
| 336 | # CONFIG_DRM is not set | ||
| 337 | # CONFIG_RAW_DRIVER is not set | ||
| 338 | |||
| 339 | # | ||
| 340 | # I2C support | ||
| 341 | # | ||
| 342 | # CONFIG_I2C is not set | ||
| 343 | |||
| 344 | # | ||
| 345 | # Dallas's 1-wire bus | ||
| 346 | # | ||
| 347 | # CONFIG_W1 is not set | ||
| 348 | |||
| 349 | # | ||
| 350 | # Misc devices | ||
| 351 | # | ||
| 352 | |||
| 353 | # | ||
| 354 | # Multimedia devices | ||
| 355 | # | ||
| 356 | # CONFIG_VIDEO_DEV is not set | ||
| 357 | |||
| 358 | # | ||
| 359 | # Digital Video Broadcasting Devices | ||
| 360 | # | ||
| 361 | # CONFIG_DVB is not set | ||
| 362 | |||
| 363 | # | ||
| 364 | # Graphics support | ||
| 365 | # | ||
| 366 | # CONFIG_FB is not set | ||
| 367 | |||
| 368 | # | ||
| 369 | # Console display driver support | ||
| 370 | # | ||
| 371 | # CONFIG_VGA_CONSOLE is not set | ||
| 372 | CONFIG_DUMMY_CONSOLE=y | ||
| 373 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 374 | |||
| 375 | # | ||
| 376 | # Sound | ||
| 377 | # | ||
| 378 | # CONFIG_SOUND is not set | ||
| 379 | |||
| 380 | # | ||
| 381 | # USB support | ||
| 382 | # | ||
| 383 | # CONFIG_USB_ARCH_HAS_HCD is not set | ||
| 384 | # CONFIG_USB_ARCH_HAS_OHCI is not set | ||
| 385 | |||
| 386 | # | ||
| 387 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | ||
| 388 | # | ||
| 389 | |||
| 390 | # | ||
| 391 | # USB Gadget Support | ||
| 392 | # | ||
| 393 | # CONFIG_USB_GADGET is not set | ||
| 394 | |||
| 395 | # | ||
| 396 | # MMC/SD Card support | ||
| 397 | # | ||
| 398 | # CONFIG_MMC is not set | ||
| 399 | |||
| 400 | # | ||
| 401 | # InfiniBand support | ||
| 402 | # | ||
| 403 | # CONFIG_INFINIBAND is not set | ||
| 404 | |||
| 405 | # | ||
| 406 | # File systems | ||
| 407 | # | ||
| 408 | # CONFIG_EXT2_FS is not set | ||
| 409 | # CONFIG_EXT3_FS is not set | ||
| 410 | # CONFIG_JBD is not set | ||
| 411 | # CONFIG_REISERFS_FS is not set | ||
| 412 | # CONFIG_JFS_FS is not set | ||
| 413 | # CONFIG_XFS_FS is not set | ||
| 414 | # CONFIG_MINIX_FS is not set | ||
| 415 | # CONFIG_ROMFS_FS is not set | ||
| 416 | # CONFIG_QUOTA is not set | ||
| 417 | # CONFIG_DNOTIFY is not set | ||
| 418 | # CONFIG_AUTOFS_FS is not set | ||
| 419 | # CONFIG_AUTOFS4_FS is not set | ||
| 420 | |||
| 421 | # | ||
| 422 | # CD-ROM/DVD Filesystems | ||
| 423 | # | ||
| 424 | # CONFIG_ISO9660_FS is not set | ||
| 425 | # CONFIG_UDF_FS is not set | ||
| 426 | |||
| 427 | # | ||
| 428 | # DOS/FAT/NT Filesystems | ||
| 429 | # | ||
| 430 | # CONFIG_MSDOS_FS is not set | ||
| 431 | # CONFIG_VFAT_FS is not set | ||
| 432 | # CONFIG_NTFS_FS is not set | ||
| 433 | |||
| 434 | # | ||
| 435 | # Pseudo filesystems | ||
| 436 | # | ||
| 437 | CONFIG_PROC_FS=y | ||
| 438 | CONFIG_PROC_KCORE=y | ||
| 439 | CONFIG_SYSFS=y | ||
| 440 | CONFIG_DEVFS_FS=y | ||
| 441 | CONFIG_DEVFS_MOUNT=y | ||
| 442 | # CONFIG_DEVFS_DEBUG is not set | ||
| 443 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
| 444 | CONFIG_TMPFS=y | ||
| 445 | # CONFIG_TMPFS_XATTR is not set | ||
| 446 | # CONFIG_HUGETLB_PAGE is not set | ||
| 447 | CONFIG_RAMFS=y | ||
| 448 | |||
| 449 | # | ||
| 450 | # Miscellaneous filesystems | ||
| 451 | # | ||
| 452 | # CONFIG_ADFS_FS is not set | ||
| 453 | # CONFIG_AFFS_FS is not set | ||
| 454 | # CONFIG_HFS_FS is not set | ||
| 455 | # CONFIG_HFSPLUS_FS is not set | ||
| 456 | # CONFIG_BEFS_FS is not set | ||
| 457 | # CONFIG_BFS_FS is not set | ||
| 458 | # CONFIG_EFS_FS is not set | ||
| 459 | # CONFIG_CRAMFS is not set | ||
| 460 | # CONFIG_VXFS_FS is not set | ||
| 461 | # CONFIG_HPFS_FS is not set | ||
| 462 | # CONFIG_QNX4FS_FS is not set | ||
| 463 | # CONFIG_SYSV_FS is not set | ||
| 464 | # CONFIG_UFS_FS is not set | ||
| 465 | |||
| 466 | # | ||
| 467 | # Network File Systems | ||
| 468 | # | ||
| 469 | CONFIG_NFS_FS=y | ||
| 470 | CONFIG_NFS_V3=y | ||
| 471 | # CONFIG_NFS_V4 is not set | ||
| 472 | CONFIG_NFS_DIRECTIO=y | ||
| 473 | # CONFIG_NFSD is not set | ||
| 474 | CONFIG_ROOT_NFS=y | ||
| 475 | CONFIG_LOCKD=y | ||
| 476 | CONFIG_LOCKD_V4=y | ||
| 477 | # CONFIG_EXPORTFS is not set | ||
| 478 | CONFIG_SUNRPC=y | ||
| 479 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
| 480 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
| 481 | # CONFIG_SMB_FS is not set | ||
| 482 | # CONFIG_CIFS is not set | ||
| 483 | # CONFIG_NCP_FS is not set | ||
| 484 | # CONFIG_CODA_FS is not set | ||
| 485 | # CONFIG_AFS_FS is not set | ||
| 486 | |||
| 487 | # | ||
| 488 | # Partition Types | ||
| 489 | # | ||
| 490 | # CONFIG_PARTITION_ADVANCED is not set | ||
| 491 | CONFIG_MSDOS_PARTITION=y | ||
| 492 | |||
| 493 | # | ||
| 494 | # Native Language Support | ||
| 495 | # | ||
| 496 | # CONFIG_NLS is not set | ||
| 497 | |||
| 498 | # | ||
| 499 | # Kernel hacking | ||
| 500 | # | ||
| 501 | CONFIG_DEBUG_KERNEL=y | ||
| 502 | # CONFIG_DEBUG_STACKOVERFLOW is not set | ||
| 503 | # CONFIG_DEBUG_SLAB is not set | ||
| 504 | # CONFIG_MAGIC_SYSRQ is not set | ||
| 505 | # CONFIG_DEBUG_SPINLOCK is not set | ||
| 506 | # CONFIG_DEBUG_PAGEALLOC is not set | ||
| 507 | # CONFIG_DEBUG_INFO is not set | ||
| 508 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
| 509 | # CONFIG_KGDB is not set | ||
| 510 | |||
| 511 | # | ||
| 512 | # Security options | ||
| 513 | # | ||
| 514 | # CONFIG_KEYS is not set | ||
| 515 | # CONFIG_SECURITY is not set | ||
| 516 | |||
| 517 | # | ||
| 518 | # Cryptographic options | ||
| 519 | # | ||
| 520 | # CONFIG_CRYPTO is not set | ||
| 521 | |||
| 522 | # | ||
| 523 | # Hardware crypto devices | ||
| 524 | # | ||
| 525 | |||
| 526 | # | ||
| 527 | # Library routines | ||
| 528 | # | ||
| 529 | # CONFIG_CRC_CCITT is not set | ||
| 530 | # CONFIG_CRC32 is not set | ||
| 531 | # CONFIG_LIBCRC32C is not set | ||
diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platform-iss/Makefile new file mode 100644 index 000000000000..5b394e9620e5 --- /dev/null +++ b/arch/xtensa/platform-iss/Makefile | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | # $Id: Makefile,v 1.1.1.1 2002/08/28 16:10:14 aroll Exp $ | ||
| 2 | # | ||
| 3 | # Makefile for the Xtensa Instruction Set Simulator (ISS) | ||
| 4 | # "prom monitor" library routines under Linux. | ||
| 5 | # | ||
| 6 | # Note! Dependencies are done automagically by 'make dep', which also | ||
| 7 | # removes any old dependencies. DON'T put your own dependencies here | ||
| 8 | # unless it's something special (ie not a .c file). | ||
| 9 | # | ||
| 10 | # Note 2! The CFLAGS definitions are in the main makefile... | ||
| 11 | |||
| 12 | obj-y = io.o console.o setup.o network.o | ||
| 13 | |||
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c new file mode 100644 index 000000000000..9e2b53f6a907 --- /dev/null +++ b/arch/xtensa/platform-iss/console.c | |||
| @@ -0,0 +1,303 @@ | |||
| 1 | /* | ||
| 2 | * arch/xtensa/platform-iss/console.c | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2001-2005 Tensilica Inc. | ||
| 9 | * Authors Christian Zankel, Joe Taylor | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/sched.h> | ||
| 16 | #include <linux/console.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/mm.h> | ||
| 20 | #include <linux/major.h> | ||
| 21 | #include <linux/param.h> | ||
| 22 | #include <linux/serial.h> | ||
| 23 | #include <linux/serialP.h> | ||
| 24 | #include <linux/console.h> | ||
| 25 | |||
| 26 | #include <asm/uaccess.h> | ||
| 27 | #include <asm/irq.h> | ||
| 28 | |||
| 29 | #include <xtensa/simcall.h> | ||
| 30 | |||
| 31 | #include <linux/tty.h> | ||
| 32 | #include <linux/tty_flip.h> | ||
| 33 | |||
| 34 | #ifdef SERIAL_INLINE | ||
| 35 | #define _INLINE_ inline | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #define SERIAL_MAX_NUM_LINES 1 | ||
| 39 | #define SERIAL_TIMER_VALUE (20 * HZ) | ||
| 40 | |||
| 41 | static struct tty_driver *serial_driver; | ||
| 42 | static struct timer_list serial_timer; | ||
| 43 | |||
| 44 | static DEFINE_SPINLOCK(timer_lock); | ||
| 45 | |||
| 46 | int errno; | ||
| 47 | |||
| 48 | static int __simc (int a, int b, int c, int d, int e, int f) | ||
| 49 | { | ||
| 50 | int ret; | ||
| 51 | __asm__ __volatile__ ("simcall\n" | ||
| 52 | "mov %0, a2\n" | ||
| 53 | "mov %1, a3\n" : "=a" (ret), "=a" (errno) | ||
| 54 | : : "a2", "a3"); | ||
| 55 | return ret; | ||
| 56 | } | ||
| 57 | |||
| 58 | static char *serial_version = "0.1"; | ||
| 59 | static char *serial_name = "ISS serial driver"; | ||
| 60 | |||
| 61 | /* | ||
| 62 | * This routine is called whenever a serial port is opened. It | ||
| 63 | * enables interrupts for a serial port, linking in its async structure into | ||
| 64 | * the IRQ chain. It also performs the serial-specific | ||
| 65 | * initialization for the tty structure. | ||
| 66 | */ | ||
| 67 | |||
| 68 | static void rs_poll(unsigned long); | ||
| 69 | |||
| 70 | static int rs_open(struct tty_struct *tty, struct file * filp) | ||
| 71 | { | ||
| 72 | int line = tty->index; | ||
| 73 | |||
| 74 | if ((line < 0) || (line >= SERIAL_MAX_NUM_LINES)) | ||
| 75 | return -ENODEV; | ||
| 76 | |||
| 77 | spin_lock(&timer_lock); | ||
| 78 | |||
| 79 | if (tty->count == 1) { | ||
| 80 | init_timer(&serial_timer); | ||
| 81 | serial_timer.data = (unsigned long) tty; | ||
| 82 | serial_timer.function = rs_poll; | ||
| 83 | mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); | ||
| 84 | } | ||
| 85 | spin_unlock(&timer_lock); | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | |||
| 91 | /* | ||
| 92 | * ------------------------------------------------------------ | ||
| 93 | * iss_serial_close() | ||
| 94 | * | ||
| 95 | * This routine is called when the serial port gets closed. First, we | ||
| 96 | * wait for the last remaining data to be sent. Then, we unlink its | ||
| 97 | * async structure from the interrupt chain if necessary, and we free | ||
| 98 | * that IRQ if nothing is left in the chain. | ||
| 99 | * ------------------------------------------------------------ | ||
| 100 | */ | ||
| 101 | static void rs_close(struct tty_struct *tty, struct file * filp) | ||
| 102 | { | ||
| 103 | spin_lock(&timer_lock); | ||
| 104 | if (tty->count == 1) | ||
| 105 | del_timer_sync(&serial_timer); | ||
| 106 | spin_unlock(&timer_lock); | ||
| 107 | } | ||
| 108 | |||
| 109 | |||
| 110 | static int rs_write(struct tty_struct * tty, | ||
| 111 | const unsigned char *buf, int count) | ||
| 112 | { | ||
| 113 | /* see drivers/char/serialX.c to reference original version */ | ||
| 114 | |||
| 115 | __simc (SYS_write, 1, (unsigned long)buf, count, 0, 0); | ||
| 116 | return count; | ||
| 117 | } | ||
| 118 | |||
| 119 | static void rs_poll(unsigned long priv) | ||
| 120 | { | ||
| 121 | struct tty_struct* tty = (struct tty_struct*) priv; | ||
| 122 | |||
| 123 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | ||
| 124 | int i = 0; | ||
| 125 | unsigned char c; | ||
| 126 | |||
| 127 | spin_lock(&timer_lock); | ||
| 128 | |||
| 129 | while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){ | ||
| 130 | __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0); | ||
| 131 | tty->flip.count++; | ||
| 132 | *tty->flip.char_buf_ptr++ = c; | ||
| 133 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
| 134 | i++; | ||
| 135 | } | ||
| 136 | |||
| 137 | if (i) | ||
| 138 | tty_flip_buffer_push(tty); | ||
| 139 | |||
| 140 | |||
| 141 | mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); | ||
| 142 | spin_unlock(&timer_lock); | ||
| 143 | } | ||
| 144 | |||
| 145 | |||
| 146 | static void rs_put_char(struct tty_struct *tty, unsigned char ch) | ||
| 147 | { | ||
| 148 | char buf[2]; | ||
| 149 | |||
| 150 | if (!tty) | ||
| 151 | return; | ||
| 152 | |||
| 153 | buf[0] = ch; | ||
| 154 | buf[1] = '\0'; /* Is this NULL necessary? */ | ||
| 155 | __simc (SYS_write, 1, (unsigned long) buf, 1, 0, 0); | ||
| 156 | } | ||
| 157 | |||
| 158 | static void rs_flush_chars(struct tty_struct *tty) | ||
| 159 | { | ||
| 160 | } | ||
| 161 | |||
| 162 | static int rs_write_room(struct tty_struct *tty) | ||
| 163 | { | ||
| 164 | /* Let's say iss can always accept 2K characters.. */ | ||
| 165 | return 2 * 1024; | ||
| 166 | } | ||
| 167 | |||
| 168 | static int rs_chars_in_buffer(struct tty_struct *tty) | ||
| 169 | { | ||
| 170 | /* the iss doesn't buffer characters */ | ||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | |||
| 174 | static void rs_hangup(struct tty_struct *tty) | ||
| 175 | { | ||
| 176 | /* Stub, once again.. */ | ||
| 177 | } | ||
| 178 | |||
| 179 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | ||
| 180 | { | ||
| 181 | /* Stub, once again.. */ | ||
| 182 | } | ||
| 183 | |||
| 184 | static int rs_read_proc(char *page, char **start, off_t off, int count, | ||
| 185 | int *eof, void *data) | ||
| 186 | { | ||
| 187 | int len = 0; | ||
| 188 | off_t begin = 0; | ||
| 189 | |||
| 190 | len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); | ||
| 191 | *eof = 1; | ||
| 192 | |||
| 193 | if (off >= len + begin) | ||
| 194 | return 0; | ||
| 195 | |||
| 196 | *start = page + (off - begin); | ||
| 197 | return ((count < begin + len - off) ? count : begin + len - off); | ||
| 198 | } | ||
| 199 | |||
| 200 | |||
| 201 | int register_serial(struct serial_struct*); | ||
| 202 | void unregister_serial(int); | ||
| 203 | |||
| 204 | static struct tty_operations serial_ops = { | ||
| 205 | .open = rs_open, | ||
| 206 | .close = rs_close, | ||
| 207 | .write = rs_write, | ||
| 208 | .put_char = rs_put_char, | ||
| 209 | .flush_chars = rs_flush_chars, | ||
| 210 | .write_room = rs_write_room, | ||
| 211 | .chars_in_buffer = rs_chars_in_buffer, | ||
| 212 | .hangup = rs_hangup, | ||
| 213 | .wait_until_sent = rs_wait_until_sent, | ||
| 214 | .read_proc = rs_read_proc | ||
| 215 | }; | ||
| 216 | |||
| 217 | int __init rs_init(void) | ||
| 218 | { | ||
| 219 | serial_driver = alloc_tty_driver(1); | ||
| 220 | |||
| 221 | printk ("%s %s\n", serial_name, serial_version); | ||
| 222 | |||
| 223 | /* Initialize the tty_driver structure */ | ||
| 224 | |||
| 225 | serial_driver->owner = THIS_MODULE; | ||
| 226 | serial_driver->driver_name = "iss_serial"; | ||
| 227 | serial_driver->name = "ttyS"; | ||
| 228 | serial_driver->major = TTY_MAJOR; | ||
| 229 | serial_driver->minor_start = 64; | ||
| 230 | serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
| 231 | serial_driver->subtype = SERIAL_TYPE_NORMAL; | ||
| 232 | serial_driver->init_termios = tty_std_termios; | ||
| 233 | serial_driver->init_termios.c_cflag = | ||
| 234 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
| 235 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | ||
| 236 | |||
| 237 | tty_set_operations(serial_driver, &serial_ops); | ||
| 238 | |||
| 239 | if (tty_register_driver(serial_driver)) | ||
| 240 | panic("Couldn't register serial driver\n"); | ||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | |||
| 244 | |||
| 245 | static __exit void rs_exit(void) | ||
| 246 | { | ||
| 247 | int error; | ||
| 248 | |||
| 249 | if ((error = tty_unregister_driver(serial_driver))) | ||
| 250 | printk("ISS_SERIAL: failed to unregister serial driver (%d)\n", | ||
| 251 | error); | ||
| 252 | put_tty_driver(serial_driver); | ||
| 253 | } | ||
| 254 | |||
| 255 | |||
| 256 | /* We use `late_initcall' instead of just `__initcall' as a workaround for | ||
| 257 | * the fact that (1) simcons_tty_init can't be called before tty_init, | ||
| 258 | * (2) tty_init is called via `module_init', (3) if statically linked, | ||
| 259 | * module_init == device_init, and (4) there's no ordering of init lists. | ||
| 260 | * We can do this easily because simcons is always statically linked, but | ||
| 261 | * other tty drivers that depend on tty_init and which must use | ||
| 262 | * `module_init' to declare their init routines are likely to be broken. | ||
| 263 | */ | ||
| 264 | |||
| 265 | late_initcall(rs_init); | ||
| 266 | |||
| 267 | |||
| 268 | #ifdef CONFIG_SERIAL_CONSOLE | ||
| 269 | |||
| 270 | static void iss_console_write(struct console *co, const char *s, unsigned count) | ||
| 271 | { | ||
| 272 | int len = strlen(s); | ||
| 273 | |||
| 274 | if (s != 0 && *s != 0) | ||
| 275 | __simc (SYS_write, 1, (unsigned long)s, | ||
| 276 | count < len ? count : len,0,0); | ||
| 277 | } | ||
| 278 | |||
| 279 | static struct tty_driver* iss_console_device(struct console *c, int *index) | ||
| 280 | { | ||
| 281 | *index = c->index; | ||
| 282 | return serial_driver; | ||
| 283 | } | ||
| 284 | |||
| 285 | |||
| 286 | static struct console sercons = { | ||
| 287 | .name = "ttyS", | ||
| 288 | .write = iss_console_write, | ||
| 289 | .device = iss_console_device, | ||
| 290 | .flags = CON_PRINTBUFFER, | ||
| 291 | .index = -1 | ||
| 292 | }; | ||
| 293 | |||
| 294 | static int __init iss_console_init(void) | ||
| 295 | { | ||
| 296 | register_console(&sercons); | ||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | console_initcall(iss_console_init); | ||
| 301 | |||
| 302 | #endif /* CONFIG_SERIAL_CONSOLE */ | ||
| 303 | |||
diff --git a/arch/xtensa/platform-iss/io.c b/arch/xtensa/platform-iss/io.c new file mode 100644 index 000000000000..5b161a5cb65f --- /dev/null +++ b/arch/xtensa/platform-iss/io.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* This file isn't really needed right now. */ | ||
| 2 | |||
| 3 | #if 0 | ||
| 4 | |||
| 5 | #include <asm/io.h> | ||
| 6 | #include <xtensa/simcall.h> | ||
| 7 | |||
| 8 | extern int __simc (); | ||
| 9 | |||
| 10 | |||
| 11 | char iss_serial_getc() | ||
| 12 | { | ||
| 13 | char c; | ||
| 14 | __simc( SYS_read, 0, &c, 1 ); | ||
| 15 | return c; | ||
| 16 | } | ||
| 17 | |||
| 18 | void iss_serial_putc( char c ) | ||
| 19 | { | ||
| 20 | __simc( SYS_write, 1, &c, 1 ); | ||
| 21 | } | ||
| 22 | |||
| 23 | void iss_serial_puts( char *s ) | ||
| 24 | { | ||
| 25 | if( s != 0 && *s != 0 ) | ||
| 26 | __simc( SYS_write, 1, s, strlen(s) ); | ||
| 27 | } | ||
| 28 | |||
| 29 | /*#error Need I/O ports to specific hardware!*/ | ||
| 30 | |||
| 31 | #endif | ||
| 32 | |||
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c new file mode 100644 index 000000000000..498d7dced1f4 --- /dev/null +++ b/arch/xtensa/platform-iss/network.c | |||
| @@ -0,0 +1,855 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * arch/xtensa/platform-iss/network.c | ||
| 4 | * | ||
| 5 | * Platform specific initialization. | ||
| 6 | * | ||
| 7 | * Authors: Chris Zankel <chris@zankel.net> | ||
| 8 | * Based on work form the UML team. | ||
| 9 | * | ||
| 10 | * Copyright 2005 Tensilica Inc. | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify it | ||
| 13 | * under the terms of the GNU General Public License as published by the | ||
| 14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 15 | * option) any later version. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/config.h> | ||
| 20 | #include <linux/list.h> | ||
| 21 | #include <linux/irq.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/timer.h> | ||
| 25 | #include <linux/if_ether.h> | ||
| 26 | #include <linux/inetdevice.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/if_tun.h> | ||
| 29 | #include <linux/etherdevice.h> | ||
| 30 | #include <linux/interrupt.h> | ||
| 31 | #include <linux/ioctl.h> | ||
| 32 | #include <linux/bootmem.h> | ||
| 33 | #include <linux/ethtool.h> | ||
| 34 | #include <linux/rtnetlink.h> | ||
| 35 | #include <linux/timer.h> | ||
| 36 | |||
| 37 | #include <xtensa/simcall.h> | ||
| 38 | |||
| 39 | #define DRIVER_NAME "iss-netdev" | ||
| 40 | #define ETH_MAX_PACKET 1500 | ||
| 41 | #define ETH_HEADER_OTHER 14 | ||
| 42 | #define ISS_NET_TIMER_VALUE (2 * HZ) | ||
| 43 | |||
| 44 | |||
| 45 | static DEFINE_SPINLOCK(opened_lock); | ||
| 46 | static LIST_HEAD(opened); | ||
| 47 | |||
| 48 | static DEFINE_SPINLOCK(devices_lock); | ||
| 49 | static LIST_HEAD(devices); | ||
| 50 | |||
| 51 | /* ------------------------------------------------------------------------- */ | ||
| 52 | |||
| 53 | /* We currently only support the TUNTAP transport protocol. */ | ||
| 54 | |||
| 55 | #define TRANSPORT_TUNTAP_NAME "tuntap" | ||
| 56 | #define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET | ||
| 57 | |||
| 58 | struct tuntap_info { | ||
| 59 | char dev_name[IFNAMSIZ]; | ||
| 60 | int fixed_config; | ||
| 61 | unsigned char gw[ETH_ALEN]; | ||
| 62 | int fd; | ||
| 63 | }; | ||
| 64 | |||
| 65 | /* ------------------------------------------------------------------------- */ | ||
| 66 | |||
| 67 | |||
| 68 | /* This structure contains out private information for the driver. */ | ||
| 69 | |||
| 70 | struct iss_net_private { | ||
| 71 | |||
| 72 | struct list_head device_list; | ||
| 73 | struct list_head opened_list; | ||
| 74 | |||
| 75 | spinlock_t lock; | ||
| 76 | struct net_device *dev; | ||
| 77 | struct platform_device pdev; | ||
| 78 | struct timer_list tl; | ||
| 79 | struct net_device_stats stats; | ||
| 80 | |||
| 81 | struct timer_list timer; | ||
| 82 | unsigned int timer_val; | ||
| 83 | |||
| 84 | int index; | ||
| 85 | int mtu; | ||
| 86 | |||
| 87 | unsigned char mac[ETH_ALEN]; | ||
| 88 | int have_mac; | ||
| 89 | |||
| 90 | struct { | ||
| 91 | union { | ||
| 92 | struct tuntap_info tuntap; | ||
| 93 | } info; | ||
| 94 | |||
| 95 | int (*open)(struct iss_net_private *lp); | ||
| 96 | void (*close)(struct iss_net_private *lp); | ||
| 97 | int (*read)(struct iss_net_private *lp, struct sk_buff **skb); | ||
| 98 | int (*write)(struct iss_net_private *lp, struct sk_buff **skb); | ||
| 99 | unsigned short (*protocol)(struct sk_buff *skb); | ||
| 100 | int (*poll)(struct iss_net_private *lp); | ||
| 101 | } tp; | ||
| 102 | |||
| 103 | }; | ||
| 104 | |||
| 105 | /* ======================= ISS SIMCALL INTERFACE =========================== */ | ||
| 106 | |||
| 107 | /* Note: __simc must _not_ be declared inline! */ | ||
| 108 | |||
| 109 | static int errno; | ||
| 110 | |||
| 111 | static int __simc (int a, int b, int c, int d, int e, int f) | ||
| 112 | { | ||
| 113 | int ret; | ||
| 114 | __asm__ __volatile__ ("simcall\n" | ||
| 115 | "mov %0, a2\n" | ||
| 116 | "mov %1, a3\n" : "=a" (ret), "=a" (errno) | ||
| 117 | : : "a2", "a3"); | ||
| 118 | return ret; | ||
| 119 | } | ||
| 120 | |||
| 121 | static int inline simc_open(char *file, int flags, int mode) | ||
| 122 | { | ||
| 123 | return __simc(SYS_open, (int) file, flags, mode, 0, 0); | ||
| 124 | } | ||
| 125 | |||
| 126 | static int inline simc_close(int fd) | ||
| 127 | { | ||
| 128 | return __simc(SYS_close, fd, 0, 0, 0, 0); | ||
| 129 | } | ||
| 130 | |||
| 131 | static int inline simc_ioctl(int fd, int request, void *arg) | ||
| 132 | { | ||
| 133 | return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); | ||
| 134 | } | ||
| 135 | |||
| 136 | static int inline simc_read(int fd, void *buf, size_t count) | ||
| 137 | { | ||
| 138 | return __simc(SYS_read, fd, (int) buf, count, 0, 0); | ||
| 139 | } | ||
| 140 | |||
| 141 | static int inline simc_write(int fd, void *buf, size_t count) | ||
| 142 | { | ||
| 143 | return __simc(SYS_write, fd, (int) buf, count, 0, 0); | ||
| 144 | } | ||
| 145 | |||
| 146 | static int inline simc_poll(int fd) | ||
| 147 | { | ||
| 148 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | ||
| 149 | |||
| 150 | return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,0,0); | ||
| 151 | } | ||
| 152 | |||
| 153 | /* ================================ HELPERS ================================ */ | ||
| 154 | |||
| 155 | |||
| 156 | static char *split_if_spec(char *str, ...) | ||
| 157 | { | ||
| 158 | char **arg, *end; | ||
| 159 | va_list ap; | ||
| 160 | |||
| 161 | va_start(ap, str); | ||
| 162 | while ((arg = va_arg(ap, char**)) != NULL) { | ||
| 163 | if (*str == '\0') | ||
| 164 | return NULL; | ||
| 165 | end = strchr(str, ','); | ||
| 166 | if (end != str) | ||
| 167 | *arg = str; | ||
| 168 | if (end == NULL) | ||
| 169 | return NULL; | ||
| 170 | *end ++ = '\0'; | ||
| 171 | str = end; | ||
| 172 | } | ||
| 173 | va_end(ap); | ||
| 174 | return str; | ||
| 175 | } | ||
| 176 | |||
| 177 | |||
| 178 | #if 0 | ||
| 179 | /* Adjust SKB. */ | ||
| 180 | |||
| 181 | struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra) | ||
| 182 | { | ||
| 183 | if ((skb != NULL) && (skb_tailroom(skb) < extra)) { | ||
| 184 | struct sk_buff *skb2; | ||
| 185 | |||
| 186 | skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC); | ||
| 187 | dev_kfree_skb(skb); | ||
| 188 | skb = skb2; | ||
| 189 | } | ||
| 190 | if (skb != NULL) | ||
| 191 | skb_put(skb, extra); | ||
| 192 | |||
| 193 | return skb; | ||
| 194 | } | ||
| 195 | #endif | ||
| 196 | |||
| 197 | /* Return the IP address as a string for a given device. */ | ||
| 198 | |||
| 199 | static void dev_ip_addr(void *d, char *buf, char *bin_buf) | ||
| 200 | { | ||
| 201 | struct net_device *dev = d; | ||
| 202 | struct in_device *ip = dev->ip_ptr; | ||
| 203 | struct in_ifaddr *in; | ||
| 204 | u32 addr; | ||
| 205 | |||
| 206 | if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) { | ||
| 207 | printk(KERN_WARNING "Device not assigned an IP address!\n"); | ||
| 208 | return; | ||
| 209 | } | ||
| 210 | |||
| 211 | addr = in->ifa_address; | ||
| 212 | sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, | ||
| 213 | (addr >> 16) & 0xff, addr >> 24); | ||
| 214 | |||
| 215 | if (bin_buf) { | ||
| 216 | bin_buf[0] = addr & 0xff; | ||
| 217 | bin_buf[1] = (addr >> 8) & 0xff; | ||
| 218 | bin_buf[2] = (addr >> 16) & 0xff; | ||
| 219 | bin_buf[3] = addr >> 24; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | /* Set Ethernet address of the specified device. */ | ||
| 224 | |||
| 225 | static void inline set_ether_mac(void *d, unsigned char *addr) | ||
| 226 | { | ||
| 227 | struct net_device *dev = d; | ||
| 228 | memcpy(dev->dev_addr, addr, ETH_ALEN); | ||
| 229 | } | ||
| 230 | |||
| 231 | |||
| 232 | /* ======================= TUNTAP TRANSPORT INTERFACE ====================== */ | ||
| 233 | |||
| 234 | static int tuntap_open(struct iss_net_private *lp) | ||
| 235 | { | ||
| 236 | struct ifreq ifr; | ||
| 237 | char *dev_name = lp->tp.info.tuntap.dev_name; | ||
| 238 | int err = -EINVAL; | ||
| 239 | int fd; | ||
| 240 | |||
| 241 | /* We currently only support a fixed configuration. */ | ||
| 242 | |||
| 243 | if (!lp->tp.info.tuntap.fixed_config) | ||
| 244 | return -EINVAL; | ||
| 245 | |||
| 246 | if ((fd = simc_open("/dev/net/tun", 02, 0)) < 0) { /* O_RDWR */ | ||
| 247 | printk("Failed to open /dev/net/tun, returned %d " | ||
| 248 | "(errno = %d)\n", fd, errno); | ||
| 249 | return fd; | ||
| 250 | } | ||
| 251 | |||
| 252 | memset(&ifr, 0, sizeof ifr); | ||
| 253 | ifr.ifr_flags = IFF_TAP | IFF_NO_PI; | ||
| 254 | strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name - 1); | ||
| 255 | |||
| 256 | if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) { | ||
| 257 | printk("Failed to set interface, returned %d " | ||
| 258 | "(errno = %d)\n", err, errno); | ||
| 259 | simc_close(fd); | ||
| 260 | return err; | ||
| 261 | } | ||
| 262 | |||
| 263 | lp->tp.info.tuntap.fd = fd; | ||
| 264 | return err; | ||
| 265 | } | ||
| 266 | |||
| 267 | static void tuntap_close(struct iss_net_private *lp) | ||
| 268 | { | ||
| 269 | #if 0 | ||
| 270 | if (lp->tp.info.tuntap.fixed_config) | ||
| 271 | iter_addresses(lp->tp.info.tuntap.dev, close_addr, lp->host.dev_name); | ||
| 272 | #endif | ||
| 273 | simc_close(lp->tp.info.tuntap.fd); | ||
| 274 | lp->tp.info.tuntap.fd = -1; | ||
| 275 | } | ||
| 276 | |||
| 277 | static int tuntap_read (struct iss_net_private *lp, struct sk_buff **skb) | ||
| 278 | { | ||
| 279 | #if 0 | ||
| 280 | *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); | ||
| 281 | if (*skb == NULL) | ||
| 282 | return -ENOMEM; | ||
| 283 | #endif | ||
| 284 | |||
| 285 | return simc_read(lp->tp.info.tuntap.fd, | ||
| 286 | (*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER); | ||
| 287 | } | ||
| 288 | |||
| 289 | static int tuntap_write (struct iss_net_private *lp, struct sk_buff **skb) | ||
| 290 | { | ||
| 291 | return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); | ||
| 292 | } | ||
| 293 | |||
| 294 | unsigned short tuntap_protocol(struct sk_buff *skb) | ||
| 295 | { | ||
| 296 | return eth_type_trans(skb, skb->dev); | ||
| 297 | } | ||
| 298 | |||
| 299 | static int tuntap_poll(struct iss_net_private *lp) | ||
| 300 | { | ||
| 301 | return simc_poll(lp->tp.info.tuntap.fd); | ||
| 302 | } | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Currently only a device name is supported. | ||
| 306 | * ethX=tuntap[,[mac address][,[device name]]] | ||
| 307 | */ | ||
| 308 | |||
| 309 | static int tuntap_probe(struct iss_net_private *lp, int index, char *init) | ||
| 310 | { | ||
| 311 | const int len = strlen(TRANSPORT_TUNTAP_NAME); | ||
| 312 | char *dev_name = NULL, *mac_str = NULL, *rem = NULL; | ||
| 313 | |||
| 314 | /* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */ | ||
| 315 | |||
| 316 | if (strncmp(init, TRANSPORT_TUNTAP_NAME, len)) | ||
| 317 | return 0; | ||
| 318 | |||
| 319 | if (*(init += strlen(TRANSPORT_TUNTAP_NAME)) == ',') { | ||
| 320 | if ((rem=split_if_spec(init+1, &mac_str, &dev_name)) != NULL) { | ||
| 321 | printk("Extra garbage on specification : '%s'\n", rem); | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | } else if (*init != '\0') { | ||
| 325 | printk("Invalid argument: %s. Skipping device!\n", init); | ||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | if (dev_name) { | ||
| 330 | strncpy(lp->tp.info.tuntap.dev_name, dev_name, | ||
| 331 | sizeof lp->tp.info.tuntap.dev_name); | ||
| 332 | lp->tp.info.tuntap.fixed_config = 1; | ||
| 333 | } else | ||
| 334 | strcpy(lp->tp.info.tuntap.dev_name, TRANSPORT_TUNTAP_NAME); | ||
| 335 | |||
| 336 | |||
| 337 | #if 0 | ||
| 338 | if (setup_etheraddr(mac_str, lp->mac)) | ||
| 339 | lp->have_mac = 1; | ||
| 340 | #endif | ||
| 341 | lp->mtu = TRANSPORT_TUNTAP_MTU; | ||
| 342 | |||
| 343 | //lp->info.tuntap.gate_addr = gate_addr; | ||
| 344 | |||
| 345 | lp->tp.info.tuntap.fd = -1; | ||
| 346 | |||
| 347 | lp->tp.open = tuntap_open; | ||
| 348 | lp->tp.close = tuntap_close; | ||
| 349 | lp->tp.read = tuntap_read; | ||
| 350 | lp->tp.write = tuntap_write; | ||
| 351 | lp->tp.protocol = tuntap_protocol; | ||
| 352 | lp->tp.poll = tuntap_poll; | ||
| 353 | |||
| 354 | printk("TUN/TAP backend - "); | ||
| 355 | #if 0 | ||
| 356 | if (lp->host.gate_addr != NULL) | ||
| 357 | printk("IP = %s", lp->host.gate_addr); | ||
| 358 | #endif | ||
| 359 | printk("\n"); | ||
| 360 | |||
| 361 | return 1; | ||
| 362 | } | ||
| 363 | |||
| 364 | /* ================================ ISS NET ================================ */ | ||
| 365 | |||
| 366 | static int iss_net_rx(struct net_device *dev) | ||
| 367 | { | ||
| 368 | struct iss_net_private *lp = dev->priv; | ||
| 369 | int pkt_len; | ||
| 370 | struct sk_buff *skb; | ||
| 371 | |||
| 372 | /* Check if there is any new data. */ | ||
| 373 | |||
| 374 | if (lp->tp.poll(lp) == 0) | ||
| 375 | return 0; | ||
| 376 | |||
| 377 | /* Try to allocate memory, if it fails, try again next round. */ | ||
| 378 | |||
| 379 | if ((skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER)) == NULL) { | ||
| 380 | lp->stats.rx_dropped++; | ||
| 381 | return 0; | ||
| 382 | } | ||
| 383 | |||
| 384 | skb_reserve(skb, 2); | ||
| 385 | |||
| 386 | /* Setup skb */ | ||
| 387 | |||
| 388 | skb->dev = dev; | ||
| 389 | skb->mac.raw = skb->data; | ||
| 390 | pkt_len = lp->tp.read(lp, &skb); | ||
| 391 | skb_put(skb, pkt_len); | ||
| 392 | |||
| 393 | if (pkt_len > 0) { | ||
| 394 | skb_trim(skb, pkt_len); | ||
| 395 | skb->protocol = lp->tp.protocol(skb); | ||
| 396 | // netif_rx(skb); | ||
| 397 | netif_rx_ni(skb); | ||
| 398 | |||
| 399 | lp->stats.rx_bytes += skb->len; | ||
| 400 | lp->stats.rx_packets++; | ||
| 401 | return pkt_len; | ||
| 402 | } | ||
| 403 | kfree_skb(skb); | ||
| 404 | return pkt_len; | ||
| 405 | } | ||
| 406 | |||
| 407 | static int iss_net_poll(void) | ||
| 408 | { | ||
| 409 | struct list_head *ele; | ||
| 410 | int err, ret = 0; | ||
| 411 | |||
| 412 | spin_lock(&opened_lock); | ||
| 413 | |||
| 414 | list_for_each(ele, &opened) { | ||
| 415 | struct iss_net_private *lp; | ||
| 416 | |||
| 417 | lp = list_entry(ele, struct iss_net_private, opened_list); | ||
| 418 | |||
| 419 | if (!netif_running(lp->dev)) | ||
| 420 | break; | ||
| 421 | |||
| 422 | spin_lock(&lp->lock); | ||
| 423 | |||
| 424 | while ((err = iss_net_rx(lp->dev)) > 0) | ||
| 425 | ret++; | ||
| 426 | |||
| 427 | spin_unlock(&lp->lock); | ||
| 428 | |||
| 429 | if (err < 0) { | ||
| 430 | printk(KERN_ERR "Device '%s' read returned %d, " | ||
| 431 | "shutting it down\n", lp->dev->name, err); | ||
| 432 | dev_close(lp->dev); | ||
| 433 | } else { | ||
| 434 | // FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ); | ||
| 435 | } | ||
| 436 | } | ||
| 437 | |||
| 438 | spin_unlock(&opened_lock); | ||
| 439 | return ret; | ||
| 440 | } | ||
| 441 | |||
| 442 | |||
| 443 | static void iss_net_timer(unsigned long priv) | ||
| 444 | { | ||
| 445 | struct iss_net_private* lp = (struct iss_net_private*) priv; | ||
| 446 | |||
| 447 | spin_lock(&lp->lock); | ||
| 448 | |||
| 449 | iss_net_poll(); | ||
| 450 | |||
| 451 | mod_timer(&lp->timer, jiffies + lp->timer_val); | ||
| 452 | |||
| 453 | spin_unlock(&lp->lock); | ||
| 454 | } | ||
| 455 | |||
| 456 | |||
| 457 | static int iss_net_open(struct net_device *dev) | ||
| 458 | { | ||
| 459 | struct iss_net_private *lp = dev->priv; | ||
| 460 | char addr[sizeof "255.255.255.255\0"]; | ||
| 461 | int err; | ||
| 462 | |||
| 463 | spin_lock(&lp->lock); | ||
| 464 | |||
| 465 | if ((err = lp->tp.open(lp)) < 0) | ||
| 466 | goto out; | ||
| 467 | |||
| 468 | if (!lp->have_mac) { | ||
| 469 | dev_ip_addr(dev, addr, &lp->mac[2]); | ||
| 470 | set_ether_mac(dev, lp->mac); | ||
| 471 | } | ||
| 472 | |||
| 473 | netif_start_queue(dev); | ||
| 474 | |||
| 475 | /* clear buffer - it can happen that the host side of the interface | ||
| 476 | * is full when we gethere. In this case, new data is never queued, | ||
| 477 | * SIGIOs never arrive, and the net never works. | ||
| 478 | */ | ||
| 479 | while ((err = iss_net_rx(dev)) > 0) | ||
| 480 | ; | ||
| 481 | |||
| 482 | spin_lock(&opened_lock); | ||
| 483 | list_add(&lp->opened_list, &opened); | ||
| 484 | spin_unlock(&opened_lock); | ||
| 485 | |||
| 486 | init_timer(&lp->timer); | ||
| 487 | lp->timer_val = ISS_NET_TIMER_VALUE; | ||
| 488 | lp->timer.data = (unsigned long) lp; | ||
| 489 | lp->timer.function = iss_net_timer; | ||
| 490 | mod_timer(&lp->timer, jiffies + lp->timer_val); | ||
| 491 | |||
| 492 | out: | ||
| 493 | spin_unlock(&lp->lock); | ||
| 494 | return err; | ||
| 495 | } | ||
| 496 | |||
| 497 | static int iss_net_close(struct net_device *dev) | ||
| 498 | { | ||
| 499 | struct iss_net_private *lp = dev->priv; | ||
| 500 | printk("iss_net_close!\n"); | ||
| 501 | netif_stop_queue(dev); | ||
| 502 | spin_lock(&lp->lock); | ||
| 503 | |||
| 504 | spin_lock(&opened_lock); | ||
| 505 | list_del(&opened); | ||
| 506 | spin_unlock(&opened_lock); | ||
| 507 | |||
| 508 | del_timer_sync(&lp->timer); | ||
| 509 | |||
| 510 | lp->tp.close(lp); | ||
| 511 | |||
| 512 | spin_unlock(&lp->lock); | ||
| 513 | return 0; | ||
| 514 | } | ||
| 515 | |||
| 516 | static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
| 517 | { | ||
| 518 | struct iss_net_private *lp = dev->priv; | ||
| 519 | unsigned long flags; | ||
| 520 | int len; | ||
| 521 | |||
| 522 | netif_stop_queue(dev); | ||
| 523 | spin_lock_irqsave(&lp->lock, flags); | ||
| 524 | |||
| 525 | len = lp->tp.write(lp, &skb); | ||
| 526 | |||
| 527 | if (len == skb->len) { | ||
| 528 | lp->stats.tx_packets++; | ||
| 529 | lp->stats.tx_bytes += skb->len; | ||
| 530 | dev->trans_start = jiffies; | ||
| 531 | netif_start_queue(dev); | ||
| 532 | |||
| 533 | /* this is normally done in the interrupt when tx finishes */ | ||
| 534 | netif_wake_queue(dev); | ||
| 535 | |||
| 536 | } else if (len == 0) { | ||
| 537 | netif_start_queue(dev); | ||
| 538 | lp->stats.tx_dropped++; | ||
| 539 | |||
| 540 | } else { | ||
| 541 | netif_start_queue(dev); | ||
| 542 | printk(KERN_ERR "iss_net_start_xmit: failed(%d)\n", len); | ||
| 543 | } | ||
| 544 | |||
| 545 | spin_unlock_irqrestore(&lp->lock, flags); | ||
| 546 | |||
| 547 | dev_kfree_skb(skb); | ||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | |||
| 552 | static struct net_device_stats *iss_net_get_stats(struct net_device *dev) | ||
| 553 | { | ||
| 554 | struct iss_net_private *lp = dev->priv; | ||
| 555 | return &lp->stats; | ||
| 556 | } | ||
| 557 | |||
| 558 | static void iss_net_set_multicast_list(struct net_device *dev) | ||
| 559 | { | ||
| 560 | #if 0 | ||
| 561 | if (dev->flags & IFF_PROMISC) | ||
| 562 | return; | ||
| 563 | else if (dev->mc_count) | ||
| 564 | dev->flags |= IFF_ALLMULTI; | ||
| 565 | else | ||
| 566 | dev->flags &= ~IFF_ALLMULTI; | ||
| 567 | #endif | ||
| 568 | } | ||
| 569 | |||
| 570 | static void iss_net_tx_timeout(struct net_device *dev) | ||
| 571 | { | ||
| 572 | #if 0 | ||
| 573 | dev->trans_start = jiffies; | ||
| 574 | netif_wake_queue(dev); | ||
| 575 | #endif | ||
| 576 | } | ||
| 577 | |||
| 578 | static int iss_net_set_mac(struct net_device *dev, void *addr) | ||
| 579 | { | ||
| 580 | #if 0 | ||
| 581 | struct iss_net_private *lp = dev->priv; | ||
| 582 | struct sockaddr *hwaddr = addr; | ||
| 583 | |||
| 584 | spin_lock(&lp->lock); | ||
| 585 | memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); | ||
| 586 | spin_unlock(&lp->lock); | ||
| 587 | #endif | ||
| 588 | |||
| 589 | return 0; | ||
| 590 | } | ||
| 591 | |||
| 592 | static int iss_net_change_mtu(struct net_device *dev, int new_mtu) | ||
| 593 | { | ||
| 594 | #if 0 | ||
| 595 | struct iss_net_private *lp = dev->priv; | ||
| 596 | int err = 0; | ||
| 597 | |||
| 598 | spin_lock(&lp->lock); | ||
| 599 | |||
| 600 | // FIXME not needed new_mtu = transport_set_mtu(new_mtu, &lp->user); | ||
| 601 | |||
| 602 | if (new_mtu < 0) | ||
| 603 | err = new_mtu; | ||
| 604 | else | ||
| 605 | dev->mtu = new_mtu; | ||
| 606 | |||
| 607 | spin_unlock(&lp->lock); | ||
| 608 | return err; | ||
| 609 | #endif | ||
| 610 | return -EINVAL; | ||
| 611 | } | ||
| 612 | |||
| 613 | static int iss_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
| 614 | { | ||
| 615 | #if 0 | ||
| 616 | static const struct ethtool_drvinfo info = { | ||
| 617 | .cmd = ETHTOOL_GDRVINFO, | ||
| 618 | .driver = DRIVER_NAME, | ||
| 619 | .version = "42", | ||
| 620 | }; | ||
| 621 | void *useraddr; | ||
| 622 | u32 ethcmd; | ||
| 623 | |||
| 624 | switch (cmd) { | ||
| 625 | case SIOCETHTOOL: | ||
| 626 | useraddr = ifr->ifr_data; | ||
| 627 | if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) | ||
| 628 | return -EFAULT; | ||
| 629 | |||
| 630 | switch (ethcmd) { | ||
| 631 | case ETHTOOL_GDRVINFO: | ||
| 632 | if (copy_to_user(useraddr, &info, sizeof(info))) | ||
| 633 | return -EFAULT; | ||
| 634 | return 0; | ||
| 635 | default: | ||
| 636 | return -EOPNOTSUPP; | ||
| 637 | } | ||
| 638 | default: | ||
| 639 | return -EINVAL; | ||
| 640 | } | ||
| 641 | #endif | ||
| 642 | return -EINVAL; | ||
| 643 | } | ||
| 644 | |||
| 645 | void iss_net_user_timer_expire(unsigned long _conn) | ||
| 646 | { | ||
| 647 | } | ||
| 648 | |||
| 649 | |||
| 650 | static struct device_driver iss_net_driver = { | ||
| 651 | .name = DRIVER_NAME, | ||
| 652 | .bus = &platform_bus_type, | ||
| 653 | }; | ||
| 654 | |||
| 655 | static int driver_registered; | ||
| 656 | |||
| 657 | static int iss_net_configure(int index, char *init) | ||
| 658 | { | ||
| 659 | struct net_device *dev; | ||
| 660 | struct iss_net_private *lp; | ||
| 661 | int err; | ||
| 662 | |||
| 663 | if ((dev = alloc_etherdev(sizeof *lp)) == NULL) { | ||
| 664 | printk(KERN_ERR "eth_configure: failed to allocate device\n"); | ||
| 665 | return 1; | ||
| 666 | } | ||
| 667 | |||
| 668 | /* Initialize private element. */ | ||
| 669 | |||
| 670 | lp = dev->priv; | ||
| 671 | *lp = ((struct iss_net_private) { | ||
| 672 | .device_list = LIST_HEAD_INIT(lp->device_list), | ||
| 673 | .opened_list = LIST_HEAD_INIT(lp->opened_list), | ||
| 674 | .lock = SPIN_LOCK_UNLOCKED, | ||
| 675 | .dev = dev, | ||
| 676 | .index = index, | ||
| 677 | //.fd = -1, | ||
| 678 | .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 }, | ||
| 679 | .have_mac = 0, | ||
| 680 | }); | ||
| 681 | |||
| 682 | /* | ||
| 683 | * Try all transport protocols. | ||
| 684 | * Note: more protocols can be added by adding '&& !X_init(lp, eth)'. | ||
| 685 | */ | ||
| 686 | |||
| 687 | if (!tuntap_probe(lp, index, init)) { | ||
| 688 | printk("Invalid arguments. Skipping device!\n"); | ||
| 689 | goto errout; | ||
| 690 | } | ||
| 691 | |||
| 692 | printk(KERN_INFO "Netdevice %d ", index); | ||
| 693 | if (lp->have_mac) | ||
| 694 | printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", | ||
| 695 | lp->mac[0], lp->mac[1], | ||
| 696 | lp->mac[2], lp->mac[3], | ||
| 697 | lp->mac[4], lp->mac[5]); | ||
| 698 | printk(": "); | ||
| 699 | |||
| 700 | /* sysfs register */ | ||
| 701 | |||
| 702 | if (!driver_registered) { | ||
| 703 | driver_register(&iss_net_driver); | ||
| 704 | driver_registered = 1; | ||
| 705 | } | ||
| 706 | |||
| 707 | spin_lock(&devices_lock); | ||
| 708 | list_add(&lp->device_list, &devices); | ||
| 709 | spin_unlock(&devices_lock); | ||
| 710 | |||
| 711 | lp->pdev.id = index; | ||
| 712 | lp->pdev.name = DRIVER_NAME; | ||
| 713 | platform_device_register(&lp->pdev); | ||
| 714 | SET_NETDEV_DEV(dev,&lp->pdev.dev); | ||
| 715 | |||
| 716 | /* | ||
| 717 | * If this name ends up conflicting with an existing registered | ||
| 718 | * netdevice, that is OK, register_netdev{,ice}() will notice this | ||
| 719 | * and fail. | ||
| 720 | */ | ||
| 721 | snprintf(dev->name, sizeof dev->name, "eth%d", index); | ||
| 722 | |||
| 723 | dev->mtu = lp->mtu; | ||
| 724 | dev->open = iss_net_open; | ||
| 725 | dev->hard_start_xmit = iss_net_start_xmit; | ||
| 726 | dev->stop = iss_net_close; | ||
| 727 | dev->get_stats = iss_net_get_stats; | ||
| 728 | dev->set_multicast_list = iss_net_set_multicast_list; | ||
| 729 | dev->tx_timeout = iss_net_tx_timeout; | ||
| 730 | dev->set_mac_address = iss_net_set_mac; | ||
| 731 | dev->change_mtu = iss_net_change_mtu; | ||
| 732 | dev->do_ioctl = iss_net_ioctl; | ||
| 733 | dev->watchdog_timeo = (HZ >> 1); | ||
| 734 | dev->irq = -1; | ||
| 735 | |||
| 736 | rtnl_lock(); | ||
| 737 | err = register_netdevice(dev); | ||
| 738 | rtnl_unlock(); | ||
| 739 | |||
| 740 | if (err) { | ||
| 741 | printk("Error registering net device!\n"); | ||
| 742 | /* XXX: should we call ->remove() here? */ | ||
| 743 | free_netdev(dev); | ||
| 744 | return 1; | ||
| 745 | } | ||
| 746 | |||
| 747 | init_timer(&lp->tl); | ||
| 748 | lp->tl.function = iss_net_user_timer_expire; | ||
| 749 | |||
| 750 | #if 0 | ||
| 751 | if (lp->have_mac) | ||
| 752 | set_ether_mac(dev, lp->mac); | ||
| 753 | #endif | ||
| 754 | return 0; | ||
| 755 | |||
| 756 | errout: | ||
| 757 | // FIXME: unregister; free, etc.. | ||
| 758 | return -EIO; | ||
| 759 | |||
| 760 | } | ||
| 761 | |||
| 762 | /* ------------------------------------------------------------------------- */ | ||
| 763 | |||
| 764 | /* Filled in during early boot */ | ||
| 765 | |||
| 766 | struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line); | ||
| 767 | |||
| 768 | struct iss_net_init { | ||
| 769 | struct list_head list; | ||
| 770 | char *init; /* init string */ | ||
| 771 | int index; | ||
| 772 | }; | ||
| 773 | |||
| 774 | /* | ||
| 775 | * Parse the command line and look for 'ethX=...' fields, and register all | ||
| 776 | * those fields. They will be later initialized in iss_net_init. | ||
| 777 | */ | ||
| 778 | |||
| 779 | #define ERR KERN_ERR "iss_net_setup: " | ||
| 780 | |||
| 781 | static int iss_net_setup(char *str) | ||
| 782 | { | ||
| 783 | struct iss_net_private *device = NULL; | ||
| 784 | struct iss_net_init *new; | ||
| 785 | struct list_head *ele; | ||
| 786 | char *end; | ||
| 787 | int n; | ||
| 788 | |||
| 789 | n = simple_strtoul(str, &end, 0); | ||
| 790 | if (end == str) { | ||
| 791 | printk(ERR "Failed to parse '%s'\n", str); | ||
| 792 | return 1; | ||
| 793 | } | ||
| 794 | if (n < 0) { | ||
| 795 | printk(ERR "Device %d is negative\n", n); | ||
| 796 | return 1; | ||
| 797 | } | ||
| 798 | if (*(str = end) != '=') { | ||
| 799 | printk(ERR "Expected '=' after device number\n"); | ||
| 800 | return 1; | ||
| 801 | } | ||
| 802 | |||
| 803 | spin_lock(&devices_lock); | ||
| 804 | |||
| 805 | list_for_each(ele, &devices) { | ||
| 806 | device = list_entry(ele, struct iss_net_private, device_list); | ||
| 807 | if (device->index == n) | ||
| 808 | break; | ||
| 809 | } | ||
| 810 | |||
| 811 | spin_unlock(&devices_lock); | ||
| 812 | |||
| 813 | if (device && device->index == n) { | ||
| 814 | printk(ERR "Device %d already configured\n", n); | ||
| 815 | return 1; | ||
| 816 | } | ||
| 817 | |||
| 818 | if ((new = alloc_bootmem(sizeof new)) == NULL) { | ||
| 819 | printk("Alloc_bootmem failed\n"); | ||
| 820 | return 1; | ||
| 821 | } | ||
| 822 | |||
| 823 | INIT_LIST_HEAD(&new->list); | ||
| 824 | new->index = n; | ||
| 825 | new->init = str + 1; | ||
| 826 | |||
| 827 | list_add_tail(&new->list, ð_cmd_line); | ||
| 828 | return 1; | ||
| 829 | } | ||
| 830 | |||
| 831 | #undef ERR | ||
| 832 | |||
| 833 | __setup("eth", iss_net_setup); | ||
| 834 | |||
| 835 | /* | ||
| 836 | * Initialize all ISS Ethernet devices previously registered in iss_net_setup. | ||
| 837 | */ | ||
| 838 | |||
| 839 | static int iss_net_init(void) | ||
| 840 | { | ||
| 841 | struct list_head *ele, *next; | ||
| 842 | |||
| 843 | /* Walk through all Ethernet devices specified in the command line. */ | ||
| 844 | |||
| 845 | list_for_each_safe(ele, next, ð_cmd_line) { | ||
| 846 | struct iss_net_init *eth; | ||
| 847 | eth = list_entry(ele, struct iss_net_init, list); | ||
| 848 | iss_net_configure(eth->index, eth->init); | ||
| 849 | } | ||
| 850 | |||
| 851 | return 1; | ||
| 852 | } | ||
| 853 | |||
| 854 | module_init(iss_net_init); | ||
| 855 | |||
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c new file mode 100644 index 000000000000..2e6dcbf0cc04 --- /dev/null +++ b/arch/xtensa/platform-iss/setup.c | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * arch/xtensa/platform-iss/setup.c | ||
| 4 | * | ||
| 5 | * Platform specific initialization. | ||
| 6 | * | ||
| 7 | * Authors: Chris Zankel <chris@zankel.net> | ||
| 8 | * Joe Taylor <joe@tensilica.com> | ||
| 9 | * | ||
| 10 | * Copyright 2001 - 2005 Tensilica Inc. | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify it | ||
| 13 | * under the terms of the GNU General Public License as published by the | ||
| 14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 15 | * option) any later version. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | #include <linux/config.h> | ||
| 19 | #include <linux/stddef.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/errno.h> | ||
| 23 | #include <linux/reboot.h> | ||
| 24 | #include <linux/pci.h> | ||
| 25 | #include <linux/kdev_t.h> | ||
| 26 | #include <linux/types.h> | ||
| 27 | #include <linux/major.h> | ||
| 28 | #include <linux/blkdev.h> | ||
| 29 | #include <linux/console.h> | ||
| 30 | #include <linux/delay.h> | ||
| 31 | #include <linux/stringify.h> | ||
| 32 | #include <linux/notifier.h> | ||
| 33 | |||
| 34 | #include <asm/platform.h> | ||
| 35 | #include <asm/bootparam.h> | ||
| 36 | |||
| 37 | |||
| 38 | void __init platform_init(bp_tag_t* bootparam) | ||
| 39 | { | ||
| 40 | |||
| 41 | } | ||
| 42 | |||
| 43 | void platform_halt(void) | ||
| 44 | { | ||
| 45 | printk (" ** Called platform_halt(), looping forever! **\n"); | ||
| 46 | while (1); | ||
| 47 | } | ||
| 48 | |||
| 49 | void platform_power_off(void) | ||
| 50 | { | ||
| 51 | printk (" ** Called platform_power_off(), looping forever! **\n"); | ||
| 52 | while (1); | ||
| 53 | } | ||
| 54 | void platform_restart(void) | ||
| 55 | { | ||
| 56 | /* Flush and reset the mmu, simulate a processor reset, and | ||
| 57 | * jump to the reset vector. */ | ||
| 58 | |||
| 59 | __asm__ __volatile__("movi a2, 15\n\t" | ||
| 60 | "wsr a2, " __stringify(ICOUNTLEVEL) "\n\t" | ||
| 61 | "movi a2, 0\n\t" | ||
| 62 | "wsr a2, " __stringify(ICOUNT) "\n\t" | ||
| 63 | "wsr a2, " __stringify(IBREAKENABLE) "\n\t" | ||
| 64 | "wsr a2, " __stringify(LCOUNT) "\n\t" | ||
| 65 | "movi a2, 0x1f\n\t" | ||
| 66 | "wsr a2, " __stringify(PS) "\n\t" | ||
| 67 | "isync\n\t" | ||
| 68 | "jx %0\n\t" | ||
| 69 | : | ||
| 70 | : "a" (XCHAL_RESET_VECTOR_VADDR) | ||
| 71 | : "a2"); | ||
| 72 | |||
| 73 | /* control never gets here */ | ||
| 74 | } | ||
| 75 | |||
| 76 | extern void iss_net_poll(void); | ||
| 77 | |||
| 78 | const char twirl[]="|/-\\|/-\\"; | ||
| 79 | |||
| 80 | void platform_heartbeat(void) | ||
| 81 | { | ||
| 82 | #if 0 | ||
| 83 | static int i = 0, j = 0; | ||
| 84 | |||
| 85 | if (--i < 0) { | ||
| 86 | i = 99; | ||
| 87 | printk("\r%c\r", twirl[j++]); | ||
| 88 | if (j == 8) | ||
| 89 | j = 0; | ||
| 90 | } | ||
| 91 | #endif | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | |||
| 96 | static int | ||
| 97 | iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
| 98 | { | ||
| 99 | __asm__ __volatile__("movi a2, -1; simcall\n"); | ||
| 100 | return NOTIFY_DONE; | ||
| 101 | } | ||
| 102 | |||
| 103 | static struct notifier_block iss_panic_block = { | ||
| 104 | iss_panic_event, | ||
| 105 | NULL, | ||
| 106 | 0 | ||
| 107 | }; | ||
| 108 | |||
| 109 | void __init platform_setup(char **p_cmdline) | ||
| 110 | { | ||
| 111 | notifier_chain_register(&panic_notifier_list, &iss_panic_block); | ||
| 112 | } | ||
diff --git a/include/asm-xtensa/platform-iss/hardware.h b/include/asm-xtensa/platform-iss/hardware.h new file mode 100644 index 000000000000..22240f001803 --- /dev/null +++ b/include/asm-xtensa/platform-iss/hardware.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * include/asm-xtensa/platform-iss/hardware.h | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2001 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * This file contains the default configuration of ISS. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __ASM_XTENSA_ISS_HARDWARE | ||
| 16 | #define __ASM_XTENSA_ISS_HARDWARE | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Memory configuration. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #define PLATFORM_DEFAULT_MEM_START XSHAL_RAM_PADDR | ||
| 23 | #define PLATFORM_DEFAULT_MEM_SIZE XSHAL_RAM_VSIZE | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Interrupt configuration. | ||
| 27 | */ | ||
| 28 | |||
| 29 | #endif /* __ASM_XTENSA_ISS_HARDWARE */ | ||
diff --git a/include/asm-xtensa/platform.h b/include/asm-xtensa/platform.h new file mode 100644 index 000000000000..36163894bc20 --- /dev/null +++ b/include/asm-xtensa/platform.h | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /* | ||
| 2 | * include/asm-xtensa/platform.h | ||
| 3 | * | ||
| 4 | * Platform specific functions | ||
| 5 | * | ||
| 6 | * This file is subject to the terms and conditions of the GNU General | ||
| 7 | * Public License. See the file "COPYING" in the main directory of | ||
| 8 | * this archive for more details. | ||
| 9 | * | ||
| 10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef _XTENSA_PLATFORM_H | ||
| 14 | #define _XTENSA_PLATFORM_H | ||
| 15 | |||
| 16 | #include <linux/config.h> | ||
| 17 | #include <linux/types.h> | ||
| 18 | #include <linux/pci.h> | ||
| 19 | |||
| 20 | #include <asm/bootparam.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * platform_init is called before the mmu is initialized to give the | ||
| 24 | * platform a early hook-up. bp_tag_t is a list of configuration tags | ||
| 25 | * passed from the boot-loader. | ||
| 26 | */ | ||
| 27 | extern void platform_init(bp_tag_t*); | ||
| 28 | |||
| 29 | /* | ||
| 30 | * platform_setup is called from setup_arch with a pointer to the command-line | ||
| 31 | * string. | ||
| 32 | */ | ||
| 33 | extern void platform_setup (char **); | ||
| 34 | |||
| 35 | /* | ||
| 36 | * platform_init_irq is called from init_IRQ. | ||
| 37 | */ | ||
| 38 | extern void platform_init_irq (void); | ||
| 39 | |||
| 40 | /* | ||
| 41 | * platform_restart is called to restart the system. | ||
| 42 | */ | ||
| 43 | extern void platform_restart (void); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * platform_halt is called to stop the system and halt. | ||
| 47 | */ | ||
| 48 | extern void platform_halt (void); | ||
| 49 | |||
| 50 | /* | ||
| 51 | * platform_power_off is called to stop the system and power it off. | ||
| 52 | */ | ||
| 53 | extern void platform_power_off (void); | ||
| 54 | |||
| 55 | /* | ||
| 56 | * platform_idle is called from the idle function. | ||
| 57 | */ | ||
| 58 | extern void platform_idle (void); | ||
| 59 | |||
| 60 | /* | ||
| 61 | * platform_heartbeat is called every HZ | ||
| 62 | */ | ||
| 63 | extern void platform_heartbeat (void); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * platform_pcibios_init is called to allow the platform to setup the pci bus. | ||
| 67 | */ | ||
| 68 | extern void platform_pcibios_init (void); | ||
| 69 | |||
| 70 | /* | ||
| 71 | * platform_pcibios_fixup allows to modify the PCI configuration. | ||
| 72 | */ | ||
| 73 | extern int platform_pcibios_fixup (void); | ||
| 74 | |||
| 75 | /* | ||
| 76 | * platform_calibrate_ccount calibrates cpu clock freq (CONFIG_XTENSA_CALIBRATE) | ||
| 77 | */ | ||
| 78 | extern void platform_calibrate_ccount (void); | ||
| 79 | |||
| 80 | /* | ||
| 81 | * platform_get_rtc_time returns RTC seconds (returns 0 for no error) | ||
| 82 | */ | ||
| 83 | extern int platform_get_rtc_time(time_t*); | ||
| 84 | |||
| 85 | /* | ||
| 86 | * platform_set_rtc_time set RTC seconds (returns 0 for no error) | ||
| 87 | */ | ||
| 88 | extern int platform_set_rtc_time(time_t); | ||
| 89 | |||
| 90 | |||
| 91 | #endif /* _XTENSA_PLATFORM_H */ | ||
| 92 | |||
