From 7f6760c73e1b9c9cda68478e61d088295916097f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:39:56 -0500 Subject: [PATCH] - pre3: - James Simmons: vgacon "printk()" deadlock with global irq lock. - don't poke blanked console on console output - Ching-Ling: get channels right on ALI audio driver - Dag Brattli and Jean Tourrilhes: big IrDA update - Paul Mackerras: PPC updates - Randy Dunlap: USB ID table support, LEDs with usbkbd, belkin serial converter. - Jeff Garzik: pcnet32 and lance net driver fix/cleanup - Mikael Pettersson: clean up x86 ELF_PLATFORM - Bartlomiej Zolnierkiewicz: sound and drm driver init fixes and cleanups - Al Viro: Jeff missed some kmap()'s. sysctl cleanup - Kai Germaschewski: ISDN updates - Alan Cox: SCSI driver NULL ptr checks - David Miller: networking updates, exclusive waitqueues nest properly, SMP i_shared_lock/page_table_lock lock order fix. --- CREDITS | 9 + Documentation/fb/matroxfb.txt | 2 +- Documentation/isdn/README.act2000 | 2 +- Documentation/isdn/README.eicon | 2 +- Documentation/isdn/README.icn | 2 +- Documentation/networking/lapb-module.txt | 10 +- Documentation/networking/x25-iface.txt | 59 + Documentation/usb/usb-serial.txt | 31 + MAINTAINERS | 8 + arch/alpha/config.in | 1 + arch/alpha/kernel/semaphore.c | 6 +- arch/arm/config.in | 1 + arch/arm/kernel/semaphore.c | 12 +- arch/i386/config.in | 2 + arch/i386/defconfig | 1 + arch/i386/kernel/apm.c | 3 - arch/i386/kernel/i386_ksyms.c | 2 + arch/i386/kernel/semaphore.c | 12 +- arch/i386/kernel/setup.c | 2 + arch/i386/kernel/traps.c | 15 +- arch/i386/mm/fault.c | 14 +- arch/ia64/config.in | 1 + arch/ia64/kernel/semaphore.c | 12 +- arch/m68k/config.in | 1 + arch/m68k/kernel/semaphore.c | 4 +- arch/mips/config.in | 5 +- arch/mips/kernel/semaphore.c | 6 +- arch/mips64/config.in | 3 + arch/mips64/kernel/semaphore.c | 6 +- arch/ppc/8xx_io/commproc.c | 2 +- arch/ppc/config.in | 1 + .../configs/{common_defconfig => apus_defconfig} | 312 +---- arch/ppc/configs/bseip_defconfig | 88 +- arch/ppc/configs/common_defconfig | 46 +- arch/ppc/configs/est8260_defconfig | 21 +- arch/ppc/configs/gemini_defconfig | 150 +- .../configs/{rpxcllf_defconfig => mbx_defconfig} | 51 +- arch/ppc/configs/oak_defconfig | 185 ++- arch/ppc/configs/rpxcllf_defconfig | 22 +- arch/ppc/configs/rpxlite_defconfig | 87 +- arch/ppc/configs/walnut_defconfig | 190 ++- arch/ppc/defconfig | 51 +- arch/ppc/kernel/entry.S | 6 +- arch/ppc/kernel/hashtable.S | 22 +- arch/ppc/kernel/head.S | 27 +- arch/ppc/kernel/irq.c | 5 + arch/ppc/kernel/misc.S | 4 - arch/ppc/kernel/ppc8260_pic.c | 2 +- arch/ppc/kernel/ppc_ksyms.c | 4 + arch/ppc/kernel/process.c | 13 +- arch/ppc/kernel/semaphore.c | 4 +- arch/s390/config.in | 2 + arch/s390/kernel/semaphore.c | 12 +- arch/sh/config.in | 1 + arch/sh/kernel/semaphore.c | 4 +- arch/sparc/config.in | 1 + arch/sparc/kernel/semaphore.c | 6 +- arch/sparc64/config.in | 1 + arch/sparc64/kernel/ioctl32.c | 4 +- arch/sparc64/kernel/semaphore.c | 6 +- drivers/block/ll_rw_blk.c | 2 +- drivers/block/rd.c | 6 +- drivers/char/Config.in | 2 +- drivers/char/console.c | 1 - drivers/char/drm/ffb_drv.c | 8 +- drivers/char/drm/gamma_drv.c | 4 +- drivers/char/drm/i810_drv.c | 4 +- drivers/char/drm/mga_drv.c | 4 +- drivers/char/drm/r128_drv.c | 4 +- drivers/char/drm/tdfx_drv.c | 4 +- drivers/char/joystick/iforce.c | 23 +- drivers/isdn/act2000/module.c | 6 +- drivers/isdn/avmb1/avmcard.h | 11 +- drivers/isdn/avmb1/b1dma.c | 26 +- drivers/isdn/avmb1/c4.c | 18 +- drivers/isdn/avmb1/t1isa.c | 25 +- drivers/isdn/icn/icn.c | 9 +- drivers/isdn/isdn_cards.c | 5 +- drivers/isdn/isdn_common.c | 4 +- drivers/isdn/isdn_net.c | 14 +- drivers/isdn/isdn_ppp.c | 322 ++--- drivers/isdn/sc/debug.c | 2 +- drivers/macintosh/via-pmu.c | 139 +- drivers/md/md.c | 1 + drivers/media/video/cpia_usb.c | 35 +- drivers/net/3c501.c | 5 +- drivers/net/3c503.c | 36 +- drivers/net/3c505.c | 53 +- drivers/net/Config.in | 48 +- drivers/net/acenic.c | 12 +- drivers/net/bagetlance.c | 4 +- drivers/net/bmac.c | 4 +- drivers/net/eth16i.c | 47 +- drivers/net/gmac.c | 33 +- drivers/net/hp-plus.c | 11 +- drivers/net/hp.c | 9 +- drivers/net/ibmlana.c | 38 +- drivers/net/irda/irport.c | 14 +- drivers/net/irda/irtty.c | 17 +- drivers/net/irda/nsc-ircc.c | 27 +- drivers/net/irda/smc-ircc.c | 20 +- drivers/net/irda/toshoboe.c | 13 +- drivers/net/irda/w83977af_ir.c | 19 +- drivers/net/ne2.c | 34 +- drivers/net/pcmcia/Config.in | 3 +- drivers/net/rrunner.c | 28 +- drivers/net/seeq8005.c | 45 +- drivers/net/sis900.c | 21 +- drivers/net/sis900.h | 3 - drivers/net/smc-mca.c | 16 +- drivers/net/smc-ultra.c | 47 +- drivers/net/smc9194.c | 47 +- drivers/net/sunhme.c | 4 +- drivers/net/wan/comx-proto-lapb.c | 7 +- drivers/net/wan/comx.c | 3 + drivers/net/wan/lapbether.c | 5 +- drivers/net/wan/x25_asy.c | 7 +- drivers/scsi/53c7xx.c | 16 +- drivers/scsi/BusLogic.c | 5 + drivers/scsi/a2091.c | 2 + drivers/scsi/a3000.c | 2 + drivers/scsi/advansys.c | 3 + drivers/scsi/aha1542.c | 2 + drivers/scsi/aha1740.c | 5 + drivers/scsi/atari_scsi.c | 6 + drivers/scsi/atp870u.c | 2 + drivers/scsi/cpqfcTSinit.c | 3 + drivers/scsi/dmx3191d.c | 5 + drivers/scsi/dtc.c | 3 + drivers/scsi/eata_dma.c | 25 +- drivers/scsi/eata_dma_proc.c | 11 + drivers/scsi/eata_pio.c | 6 + drivers/scsi/fcal.c | 6 +- drivers/scsi/fdomain.c | 2 + drivers/scsi/g_NCR5380.c | 12 + drivers/scsi/gdth.c | 44 +- drivers/scsi/gdth_proc.c | 10 + drivers/scsi/gvp11.c | 2 + drivers/scsi/imm.c | 2 + drivers/scsi/in2000.c | 4 +- drivers/scsi/ini9100u.c | 5 + drivers/scsi/inia100.c | 4 +- drivers/scsi/mac53c94.c | 4 +- drivers/scsi/mac_scsi.c | 2 + drivers/scsi/pas16.c | 3 + drivers/scsi/pci2000.c | 2 + drivers/scsi/pci2220i.c | 3 + drivers/scsi/pluto.c | 6 +- drivers/scsi/ppa.c | 2 + drivers/scsi/psi240i.c | 2 + drivers/scsi/scsi_debug.c | 17 +- drivers/scsi/seagate.c | 3 + drivers/scsi/sgiwd93.c | 37 +- drivers/scsi/sun3_scsi.c | 3 + drivers/scsi/sym53c416.c | 2 + drivers/scsi/t128.c | 3 + drivers/scsi/wd7000.c | 2 + drivers/sound/724hwmcode.h | 6 +- drivers/sound/cs4232.c | 12 +- drivers/sound/cs4281.c | 3 +- drivers/sound/cs461x_image.h | 2 +- drivers/sound/cs46xx.c | 10 +- drivers/sound/dmasound/dmasound_core.c | 6 +- drivers/sound/gus_midi.c | 6 +- drivers/sound/gus_wave.c | 11 +- drivers/sound/ics2101.c | 4 +- drivers/sound/iwmem.h | 7 +- drivers/sound/maestro.c | 6 +- drivers/sound/maui.c | 4 +- drivers/sound/mpu401.c | 13 +- drivers/sound/msnd.c | 2 +- drivers/sound/msnd_pinnacle.c | 2 +- drivers/sound/nm256_audio.c | 12 +- drivers/sound/pas2_midi.c | 4 +- drivers/sound/pas2_mixer.c | 3 +- drivers/sound/pas2_pcm.c | 3 +- drivers/sound/pss.c | 8 +- drivers/sound/sgalaxy.c | 8 +- drivers/sound/sscape.c | 3 +- drivers/sound/trident.c | 2 +- drivers/sound/vwsnd.c | 19 +- drivers/sound/waveartist.c | 7 +- drivers/sound/wavfront.c | 16 +- drivers/sound/ymf_sb.c | 12 +- drivers/sound/yss225.c | 34 +- drivers/usb/Config.in | 3 +- drivers/usb/acm.c | 164 +-- drivers/usb/audio.c | 40 +- drivers/usb/bluetooth.c | 28 +- drivers/usb/dabusb.c | 28 +- drivers/usb/dc2xx.c | 17 +- drivers/usb/devio.c | 23 +- drivers/usb/dsbr100.c | 22 +- drivers/usb/hid.c | 16 +- drivers/usb/hub.c | 18 +- drivers/usb/ibmcam.c | 41 +- drivers/usb/mdc800.c | 26 +- drivers/usb/microtek.c | 89 +- drivers/usb/net1080.c | 17 +- drivers/usb/ov511.c | 46 +- drivers/usb/pegasus.c | 96 +- drivers/usb/pegasus_devs.h | 89 ++ drivers/usb/printer.c | 28 +- drivers/usb/rio500.c | 34 +- drivers/usb/scanner.c | 95 +- drivers/usb/scanner.h | 75 - drivers/usb/serial/Makefile | 1 + drivers/usb/serial/belkin_sa.c | 561 ++++++++ drivers/usb/serial/belkin_sa.h | 113 ++ drivers/usb/serial/digi_acceleport.c | 75 +- drivers/usb/serial/ftdi_sio.c | 16 +- drivers/usb/serial/keyspan.c | 3 + drivers/usb/serial/keyspan.h | 121 +- drivers/usb/serial/keyspan_pda.c | 28 +- drivers/usb/serial/omninet.c | 16 +- drivers/usb/serial/usb-serial.h | 7 +- drivers/usb/serial/usbserial.c | 38 +- drivers/usb/serial/visor.c | 18 +- drivers/usb/serial/whiteheat.c | 39 +- drivers/usb/storage/scsiglue.c | 30 +- drivers/usb/storage/transport.c | 9 +- drivers/usb/storage/usb.c | 11 +- drivers/usb/usb.c | 237 ++-- drivers/usb/usbkbd.c | 27 +- drivers/usb/usbmouse.c | 28 +- drivers/usb/uss720.c | 28 +- drivers/usb/wacom.c | 113 +- drivers/video/riva/fbdev.c | 51 +- drivers/video/vgacon.c | 40 +- fs/buffer.c | 5 +- fs/ncpfs/mmap.c | 7 +- fs/udf/inode.c | 7 +- include/asm-i386/processor.h | 4 + include/asm-ppc/8xx_immap.h | 2 + include/asm-ppc/amigahw.h | 2 + include/asm-ppc/amigaints.h | 2 + include/asm-ppc/amigappc.h | 2 + include/asm-ppc/backlight.h | 2 + include/asm-ppc/bitops.h | 2 + include/asm-ppc/board.h | 2 + include/asm-ppc/bootinfo.h | 2 + include/asm-ppc/byteorder.h | 9 +- include/asm-ppc/cache.h | 2 + include/asm-ppc/checksum.h | 2 + include/asm-ppc/cpm_8260.h | 2 + include/asm-ppc/current.h | 2 + include/asm-ppc/dbdma.h | 2 + include/asm-ppc/delay.h | 2 + include/asm-ppc/dma.h | 3 + include/asm-ppc/elf.h | 42 +- include/asm-ppc/feature.h | 2 + include/asm-ppc/floppy.h | 2 + include/asm-ppc/gemini.h | 2 + include/asm-ppc/gemini_serial.h | 2 + include/asm-ppc/hardirq.h | 2 + include/asm-ppc/hw_irq.h | 2 + include/asm-ppc/ide.h | 4 +- include/asm-ppc/immap_8260.h | 2 + include/asm-ppc/init.h | 2 + include/asm-ppc/io.h | 9 +- include/asm-ppc/ipcbuf.h | 40 +- include/asm-ppc/irq.h | 5 +- include/asm-ppc/kgdb.h | 2 + include/asm-ppc/kmap_types.h | 2 + include/asm-ppc/linux_logo.h | 2 + include/asm-ppc/machdep.h | 3 +- include/asm-ppc/mbx.h | 3 +- include/asm-ppc/mc146818rtc.h | 2 + include/asm-ppc/md.h | 2 + include/asm-ppc/mediabay.h | 4 +- include/asm-ppc/mmu.h | 2 + include/asm-ppc/mmu_context.h | 2 + include/asm-ppc/mpc8260.h | 2 + include/asm-ppc/mpc8xx.h | 2 + include/asm-ppc/msgbuf.h | 1 - include/asm-ppc/namei.h | 2 + include/asm-ppc/nvram.h | 2 + include/asm-ppc/oak.h | 2 + include/asm-ppc/page.h | 12 +- include/asm-ppc/param.h | 4 + include/asm-ppc/pci-bridge.h | 2 + include/asm-ppc/pci.h | 2 +- include/asm-ppc/pgalloc.h | 29 +- include/asm-ppc/pgtable.h | 2 + include/asm-ppc/pnp.h | 2 + include/asm-ppc/prep_nvram.h | 2 + include/asm-ppc/processor.h | 2 + include/asm-ppc/prom.h | 2 + include/asm-ppc/ptrace.h | 38 +- include/asm-ppc/raven.h | 2 + include/asm-ppc/residual.h | 2 + include/asm-ppc/rpxclassic.h | 2 + include/asm-ppc/rpxlite.h | 2 + include/asm-ppc/scatterlist.h | 2 + include/asm-ppc/semaphore-helper.h | 2 + include/asm-ppc/sembuf.h | 1 - include/asm-ppc/serial.h | 2 + include/asm-ppc/setup.h | 2 + include/asm-ppc/shmbuf.h | 12 +- include/asm-ppc/siginfo.h | 2 - include/asm-ppc/signal.h | 2 + include/asm-ppc/smp.h | 2 + include/asm-ppc/smplock.h | 2 + include/asm-ppc/softirq.h | 2 + include/asm-ppc/spinlock.h | 2 + include/asm-ppc/stat.h | 2 + include/asm-ppc/string.h | 4 + include/asm-ppc/system.h | 2 + include/asm-ppc/termbits.h | 2 - include/asm-ppc/time.h | 2 + include/asm-ppc/timex.h | 2 + include/asm-ppc/tqm860.h | 2 + include/asm-ppc/tqm8xxL.h | 2 + include/asm-ppc/types.h | 8 +- include/asm-ppc/uaccess.h | 2 + include/asm-ppc/unaligned.h | 2 + include/asm-ppc/uninorth.h | 4 +- include/asm-ppc/user.h | 2 + include/asm-ppc/vga.h | 2 + include/asm-ppc/walnut.h | 2 + include/asm-sparc/ethtool.h | 79 -- include/asm-sparc64/ethtool.h | 79 -- include/linux/ethtool.h | 96 ++ include/linux/irda.h | 20 +- include/linux/isdn.h | 5 +- include/linux/kernelcapi.h | 2 +- include/linux/kmod.h | 36 +- include/linux/lapb.h | 2 +- include/linux/mm.h | 3 + include/linux/module.h | 6 + include/linux/netdevice.h | 3 + include/linux/raid/md.h | 1 - include/linux/sched.h | 17 +- include/linux/sockios.h | 1 + include/linux/soundcard.h | 6 +- include/linux/usb.h | 14 +- include/linux/wait.h | 5 +- include/net/ax25.h | 10 +- include/net/irda/discovery.h | 6 +- include/net/irda/ircomm_core.h | 2 +- include/net/irda/ircomm_tty.h | 2 +- include/net/irda/irda.h | 32 +- include/net/irda/irda_device.h | 4 +- include/net/irda/iriap.h | 2 +- include/net/irda/irias_object.h | 18 +- include/net/irda/irlan_client.h | 2 +- include/net/irda/irlan_common.h | 27 +- include/net/irda/irlap.h | 6 +- include/net/irda/irlmp.h | 43 +- include/net/irda/irmod.h | 8 +- include/net/irda/irqueue.h | 29 +- include/net/irda/irttp.h | 4 +- include/net/irda/irtty.h | 2 +- include/net/irda/qos.h | 11 +- include/net/irda/timer.h | 2 + kernel/fork.c | 1 + kernel/sched.c | 18 +- mm/filemap.c | 14 +- mm/highmem.c | 4 - mm/mlock.c | 14 +- mm/mmap.c | 80 +- mm/mprotect.c | 14 +- mm/mremap.c | 4 +- mm/oom_kill.c | 2 +- net/atm/pvc.c | 2 +- net/ax25/sysctl_net_ax25.c | 27 +- net/core/datagram.c | 2 +- net/core/dev.c | 29 +- net/core/sock.c | 4 +- net/ipv4/af_inet.c | 2 +- net/ipv4/tcp.c | 4 +- net/ipv4/tcp_ipv4.c | 6 +- net/irda/Config.in | 1 + net/irda/Makefile | 13 +- net/irda/af_irda.c | 713 +++++++--- net/irda/compressors/irda_deflate.c | 56 +- net/irda/discovery.c | 154 +- net/irda/ircomm/ircomm_core.c | 5 +- net/irda/ircomm/ircomm_tty.c | 14 +- net/irda/ircomm/ircomm_tty_attach.c | 15 +- net/irda/irda_device.c | 8 +- net/irda/iriap.c | 13 +- net/irda/irias_object.c | 55 +- net/irda/irlan/irlan_client.c | 90 +- net/irda/irlan/irlan_common.c | 253 ++-- net/irda/irlan/irlan_eth.c | 41 +- net/irda/irlan/irlan_provider.c | 79 +- net/irda/irlap.c | 49 +- net/irda/irlap_comp.c | 2 +- net/irda/irlap_event.c | 212 ++- net/irda/irlap_frame.c | 64 +- net/irda/irlmp.c | 168 ++- net/irda/irlmp_event.c | 15 +- net/irda/irlmp_frame.c | 67 +- net/irda/irnet/Config.in | 1 + net/irda/irnet/Makefile | 22 + net/irda/irnet/irnet.h | 453 ++++++ net/irda/irnet/irnet_irda.c | 1480 ++++++++++++++++++++ net/irda/irnet/irnet_irda.h | 168 +++ net/irda/irnet/irnet_ppp.c | 1052 ++++++++++++++ net/irda/irnet/irnet_ppp.h | 130 ++ net/irda/irqueue.c | 126 +- net/irda/{irmod.c => irsyms.c} | 301 +--- net/irda/irsysctl.c | 27 +- net/irda/irttp.c | 34 +- net/irda/parameters.c | 10 +- net/irda/qos.c | 86 +- net/irda/timer.c | 31 +- net/irda/wrapper.c | 10 +- net/khttpd/main.c | 4 +- net/lapb/lapb_iface.c | 10 +- net/lapb/lapb_in.c | 16 +- net/netlink/af_netlink.c | 4 +- net/unix/af_unix.c | 4 +- 414 files changed, 9494 insertions(+), 3797 deletions(-) copy arch/ppc/configs/{common_defconfig => apus_defconfig} (62%) copy arch/ppc/configs/{rpxcllf_defconfig => mbx_defconfig} (91%) create mode 100644 drivers/usb/pegasus_devs.h create mode 100644 drivers/usb/serial/belkin_sa.c create mode 100644 drivers/usb/serial/belkin_sa.h rewrite include/asm-ppc/ipcbuf.h (64%) delete mode 100644 include/asm-sparc/ethtool.h delete mode 100644 include/asm-sparc64/ethtool.h create mode 100644 include/linux/ethtool.h create mode 100644 net/irda/irnet/Config.in create mode 100644 net/irda/irnet/Makefile create mode 100644 net/irda/irnet/irnet.h create mode 100644 net/irda/irnet/irnet_irda.c create mode 100644 net/irda/irnet/irnet_irda.h create mode 100644 net/irda/irnet/irnet_ppp.c create mode 100644 net/irda/irnet/irnet_ppp.h rename net/irda/{irmod.c => irsyms.c} (52%) diff --git a/CREDITS b/CREDITS index dc9c00be9..4053679e6 100644 --- a/CREDITS +++ b/CREDITS @@ -912,6 +912,15 @@ S: 8124 Constitution Apt. 7 S: Sterling Heights, Michigan 48313 S: USA +N: William Greathouse +E: wgreathouse@smva.com +E: wgreathouse@myfavoritei.com +D: Current Belkin USB Serial Adapter F5U103 hacker +D: Kernel hacker, embedded systems +S: 7802 Fitzwater Road +S: Brecksville, OH 44141-1334 +S: USA + N: Tristan Greaves E: Tristan.Greaves@icl.com E: tmg296@ecs.soton.ac.uk diff --git a/Documentation/fb/matroxfb.txt b/Documentation/fb/matroxfb.txt index 0b8068dc5..a3bbe6b92 100644 --- a/Documentation/fb/matroxfb.txt +++ b/Documentation/fb/matroxfb.txt @@ -253,7 +253,7 @@ depth:X - Bits per pixel: 0=text, 4,8,15,16,24 or 32. Default depends on `vesa'. If you know capabilities of your monitor, you can specify some (or all) of -`pixclk', `fh' and `fv'. In this case, `pixclock' is computed so that +`maxclk', `fh' and `fv'. In this case, `pixclock' is computed so that pixclock <= maxclk, real_fh <= fh and real_fv <= fv. maxclk:X - maximum dotclock. X can be specified in MHz, kHz or Hz. Default is diff --git a/Documentation/isdn/README.act2000 b/Documentation/isdn/README.act2000 index 0846d96b3..ce7115e7f 100644 --- a/Documentation/isdn/README.act2000 +++ b/Documentation/isdn/README.act2000 @@ -1,4 +1,4 @@ -$Id: README.act2000,v 1.2 1998/04/29 19:49:06 he Exp $ +$Id: README.act2000,v 1.3 2000/08/06 09:22:51 armin Exp $ This document describes the ACT2000 driver for the IBM Active 2000 ISDN card. diff --git a/Documentation/isdn/README.eicon b/Documentation/isdn/README.eicon index a77542a67..16dd09eb9 100644 --- a/Documentation/isdn/README.eicon +++ b/Documentation/isdn/README.eicon @@ -1,4 +1,4 @@ -$Id: README.eicon,v 1.9 2000/06/08 08:50:25 armin Exp $ +$Id: README.eicon,v 1.10 2000/08/13 12:19:15 armin Exp $ (c) 1999,2000 Armin Schindler (mac@melware.de) (c) 1999,2000 Cytronics & Melware (info@melware.de) diff --git a/Documentation/isdn/README.icn b/Documentation/isdn/README.icn index 37aa7f3d0..a5f55eadb 100644 --- a/Documentation/isdn/README.icn +++ b/Documentation/isdn/README.icn @@ -1,4 +1,4 @@ -$Id: README.icn,v 1.6 1998/04/29 19:49:08 he Exp $ +$Id: README.icn,v 1.7 2000/08/06 09:22:51 armin Exp $ You can get the ICN-ISDN-card from: diff --git a/Documentation/networking/lapb-module.txt b/Documentation/networking/lapb-module.txt index 28a000838..d4fc8f221 100644 --- a/Documentation/networking/lapb-module.txt +++ b/Documentation/networking/lapb-module.txt @@ -2,6 +2,8 @@ Jonathan Naylor 29.12.96 +Changed (Henner Eisen, 2000-10-29): int return value for data_indication() + The LAPB module will be a separately compiled module for use by any parts of the Linux operating system that require a LAPB service. This document defines the interfaces to, and the services provided by this module. The @@ -37,7 +39,7 @@ struct lapb_register_struct { void (*connect_indication)(int token, int reason); void (*disconnect_confirmation)(int token, int reason); void (*disconnect_indication)(int token, int reason); - void (*data_indication)(int token, struct sk_buff *skb); + int (*data_indication)(int token, struct sk_buff *skb); void (*data_transmit)(int token, struct sk_buff *skb); }; @@ -240,7 +242,7 @@ LAPB_TIMEDOUT No response was received in N2 tries from the remote system. -void (*data_indication)(void *token, struct sk_buff *skb); +int (*data_indication)(void *token, struct sk_buff *skb); This is called by the LAPB module when data has been received from the remote system that should be passed onto the next layer in the protocol @@ -248,6 +250,10 @@ stack. The skbuff becomes the property of the device driver and the LAPB module will not perform any more actions on it. The skb->data pointer will be pointing to the first byte of data after the LAPB header. +This method should return NET_RX_DROP (as defined in the header +file include/linux/netdevice.h) if and only if the frame was dropped +before it could be delivered to the upper layer. + void (*data_transmit)(void *token, struct sk_buff *skb); diff --git a/Documentation/networking/x25-iface.txt b/Documentation/networking/x25-iface.txt index 14af1b886..975cc87eb 100644 --- a/Documentation/networking/x25-iface.txt +++ b/Documentation/networking/x25-iface.txt @@ -62,3 +62,62 @@ link disconnect_confirmation and a disconnect_indication. First Byte = 0x03 LAPB parameters. To be defined. + + + +Possible Problems +================= + +(Henner Eisen, 2000-10-28) + +The X.25 packet layer protocol depends on a reliable datalink service. +The LAPB protocol provides such reliable service. But this reliability +is not preserved by the Linux network device driver interface: + +- With Linux 2.4.x (and above) SMP kernels, packet ordering is not + preserved. Even if a device driver calls netif_rx(skb1) and later + netif_rx(skb2), skb2 might be delivered to the network layer + earlier that skb1. +- Data passed upstream by means of netif_rx() might be dropped by the + kernel if the backlog queue is congested. + +The X.25 packet layer protocol will detect this and reset the virtual +call in question. But many upper layer protocols are not designed to +handle such N-Reset events gracefully. And frequent N-Reset events +will always degrade performance. + +Thus, driver authors should make netif_rx() as reliable as possible: + +SMP re-ordering will not occur if the driver's interrupt handler is +always executed on the same CPU. Thus, + +- Driver authors should use irq affinity for the interrupt handler. + +The probability of packet loss due to backlog congestion can be +reduced by the following measures or a combination thereof: + +(1) Drivers for kernel versions 2.4.x and above should always check the + return value of netif_rx(). If it returns NET_RX_DROP, the + driver's LAPB protocol must not confirm reception of the frame + to the peer. + This will reliably suppress packet loss. The LAPB protocol will + automatically cause the peer to re-transmit the dropped packet + later. + The lapb module interface was modified to support this. Its + data_indication() method should now transparently pass the + netif_rx() return value to the (lapb mopdule) caller. +(2) Drivers for kernel versions 2.2.x should always check the global + variable netdev_dropping when a new frame is received. The driver + should only call netif_rx() if netdev_dropping is zero. Otherwise + the driver should not confirm delivery of the frame and drop it. + Alternatively, the driver can queue the frame internally and call + netif_rx() later when netif_dropping is 0 again. In that case, delivery + confirmation should also be deferred such that the internal queue + cannot grow to much. + This will not reliably avoid packet loss, but the probability + of packet loss in netif_rx() path will be significantly reduced. +(3) Additionally, driver authors might consider to support + CONFIG_NET_HW_FLOWCONTROL. This allows the driver to be woken up + when a previously congested backlog queue becomes empty again. + The driver could uses this for flow-controlling the peer by means + of the LAPB protocol's flow-control service. diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt index 4ffe021a7..a6efeefa5 100644 --- a/Documentation/usb/usb-serial.txt +++ b/Documentation/usb/usb-serial.txt @@ -151,6 +151,37 @@ Digi AccelePort Driver driver. +Belkin USB Serial Adapter F5U103 + + Single port DB-9/PS-2 serial adapter from Belkin with firmware by eTEK Labs. + +Current status: + The following have been tested and work: + Baud rate 300-230400 + Data bits 5-8 + Stop bits 1-2 + Parity N,E,O,M,S + Handshake None, Software (XON/XOFF), Hardware (CTSRTS,CTSDTR)* + Break Set and clear + Line contrl Input/Output query and control ** + + * Hardware input flow control is only enabled for firmware + levels above 2.06. Read source code comments describing Belkin + firmware errata. Hardware output flow control is working for all + firmware versions. + ** Queries of inputs (CTS,DSR,CD,RI) show the last + reported state. Queries of outputs (DTR,RTS) show the last + requested state and may not reflect current state as set by + automatic hardware flow control. + +TO DO List: + -- Add true modem contol line query capability. Currently tracks the + states reported by the interrupt and the states requested. + -- Add error reporting back to application for UART error conditions. + -- Add support for flush ioctls. + -- Add everything else that is missing :) + + Generic Serial driver If your device is not one of the above listed devices, compatible with diff --git a/MAINTAINERS b/MAINTAINERS index 2b7cfc0a6..0a19a7dbe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1336,6 +1336,14 @@ L: linux-usb-devel@lists.sourceforge.net S: Maintained W: http://www.kroah.com/linux-usb/ +USB SERIAL BELKIN F5U103 DRIVER +P: William Greathouse +M: wgreathouse@smva.com +M: wgreathouse@myfavoritei.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net +S: Maintained + USB MASS STORAGE DRIVER P: Matthew Dharm M: mdharm-usb@one-eyed-alien.net diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 18fdcde8a..203570875 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -68,6 +68,7 @@ unset CONFIG_ALPHA_LARGE_VMALLOC # Most of these machines have ISA slots; not exactly sure which don't, # and this doesn't activate hordes of code, so do it always. define_bool CONFIG_ISA y +define_bool CONFIG_EISA y define_bool CONFIG_SBUS n if [ "$CONFIG_ALPHA_JENSEN" = "y" ] diff --git a/arch/alpha/kernel/semaphore.c b/arch/alpha/kernel/semaphore.c index dc5209531..e6903f41d 100644 --- a/arch/alpha/kernel/semaphore.c +++ b/arch/alpha/kernel/semaphore.c @@ -209,8 +209,7 @@ __down_write(struct rw_semaphore *sem, int count) add_wait_queue_exclusive(&sem->wait, &wait); while (sem->count < 0) { - set_task_state(tsk, (TASK_UNINTERRUPTIBLE - | TASK_EXCLUSIVE)); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (sem->count >= RW_LOCK_BIAS) break; schedule(); @@ -241,8 +240,7 @@ __down_write(struct rw_semaphore *sem, int count) while (1) { if (test_and_clear_bit(1, &sem->granted)) break; - set_task_state(tsk, (TASK_UNINTERRUPTIBLE - | TASK_EXCLUSIVE)); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if ((sem->granted & 2) == 0) schedule(); } diff --git a/arch/arm/config.in b/arch/arm/config.in index fff056940..c59fab74a 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -5,6 +5,7 @@ mainmenu_name "Linux Kernel Configuration" define_bool CONFIG_ARM y +define_bool CONFIG_EISA n define_bool CONFIG_SBUS n define_bool CONFIG_UID16 y diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c index f89852641..aac8be68b 100644 --- a/arch/arm/kernel/semaphore.c +++ b/arch/arm/kernel/semaphore.c @@ -58,7 +58,7 @@ void __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -78,7 +78,7 @@ void __down(struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -92,7 +92,7 @@ int __down_interruptible(struct semaphore * sem) int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -128,7 +128,7 @@ int __down_interruptible(struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -197,7 +197,7 @@ struct rw_semaphore *down_write_failed_biased(struct rw_semaphore *sem) for (;;) { if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) break; - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!sem->write_bias_granted) schedule(); } @@ -255,7 +255,7 @@ struct rw_semaphore *down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (atomic_read(&sem->count) < 0) { - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (atomic_read(&sem->count) >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); diff --git a/arch/i386/config.in b/arch/i386/config.in index 327aa736d..dc1fd202d 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -194,6 +194,8 @@ fi source drivers/pci/Config.in +bool 'EISA support' CONFIG_EISA + if [ "$CONFIG_VISWS" != "y" ]; then bool 'MCA support' CONFIG_MCA fi diff --git a/arch/i386/defconfig b/arch/i386/defconfig index c2e9c07bb..4d34dfee3 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -71,6 +71,7 @@ CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y CONFIG_PCI_NAMES=y +# CONFIG_EISA is not set # CONFIG_MCA is not set CONFIG_HOTPLUG=y diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index b0aa2a7c3..24bf2be75 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -1422,9 +1422,6 @@ static int apm(void *unused) kapmd_running = 1; - exit_files(current); /* daemonize doesn't do exit_files */ - current->files = init_task.files; - atomic_inc(¤t->files->count); daemonize(); strcpy(current->comm, "kapm-idled"); diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index ed3573426..3de4a76d1 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -49,7 +49,9 @@ extern unsigned long get_cmos_time(void); /* platform dependent support */ EXPORT_SYMBOL(boot_cpu_data); +#ifdef CONFIG_EISA EXPORT_SYMBOL(EISA_bus); +#endif EXPORT_SYMBOL(MCA_bus); EXPORT_SYMBOL(__verify_write); EXPORT_SYMBOL(dump_thread); diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c index d70e9e569..f97d3b1ad 100644 --- a/arch/i386/kernel/semaphore.c +++ b/arch/i386/kernel/semaphore.c @@ -59,7 +59,7 @@ void __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -79,7 +79,7 @@ void __down(struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -93,7 +93,7 @@ int __down_interruptible(struct semaphore * sem) int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -129,7 +129,7 @@ int __down_interruptible(struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -315,7 +315,7 @@ struct rw_semaphore *down_write_failed_biased(struct rw_semaphore *sem) for (;;) { if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) break; - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!sem->write_bias_granted) schedule(); } @@ -371,7 +371,7 @@ struct rw_semaphore *down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (atomic_read(&sem->count) < 0) { - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (atomic_read(&sem->count) >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index b22adbd47..e5ace0404 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -107,7 +107,9 @@ unsigned long mmu_cr4_features; /* * Bus types .. */ +#ifdef CONFIG_EISA int EISA_bus; +#endif int MCA_bus; /* for MCA, but anyone else can use it if they want */ diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index aa2deb8ae..b84421374 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -63,6 +63,7 @@ struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; extern int console_loglevel; +extern void bust_spinlocks(void); static inline void console_silent(void) { @@ -394,20 +395,8 @@ static int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); -extern spinlock_t console_lock, timerlist_lock; static spinlock_t nmi_print_lock = SPIN_LOCK_UNLOCKED; -/* - * Unlock any spinlocks which will prevent us from getting the - * message out (timerlist_lock is aquired through the - * console unblank code) - */ -void bust_spinlocks(void) -{ - spin_lock_init(&console_lock); - spin_lock_init(&timerlist_lock); -} - inline void nmi_watchdog_tick(struct pt_regs * regs) { /* @@ -962,8 +951,10 @@ cobalt_init(void) #endif void __init trap_init(void) { +#ifdef CONFIG_EISA if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) EISA_bus = 1; +#endif set_trap_gate(0,÷_error); set_trap_gate(1,&debug); diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 96b67925f..e2a9ee9fe 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -24,7 +24,6 @@ #include extern void die(const char *,struct pt_regs *,long); -extern void bust_spinlocks(void); /* * Ugly, ugly, but the goto's result in better assembly.. @@ -78,6 +77,19 @@ bad_area: return 0; } +extern spinlock_t console_lock, timerlist_lock; + +/* + * Unlock any spinlocks which will prevent us from getting the + * message out (timerlist_lock is aquired through the + * console unblank code) + */ +void bust_spinlocks(void) +{ + spin_lock_init(&console_lock); + spin_lock_init(&timerlist_lock); +} + asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); extern unsigned long idt; diff --git a/arch/ia64/config.in b/arch/ia64/config.in index 33bf47a44..356977116 100644 --- a/arch/ia64/config.in +++ b/arch/ia64/config.in @@ -21,6 +21,7 @@ define_bool CONFIG_IA64 y define_bool CONFIG_SWIOTLB y # for now... define_bool CONFIG_ISA n +define_bool CONFIG_EISA n define_bool CONFIG_SBUS n choice 'IA-64 system type' \ diff --git a/arch/ia64/kernel/semaphore.c b/arch/ia64/kernel/semaphore.c index 84ff34cf6..f26099912 100644 --- a/arch/ia64/kernel/semaphore.c +++ b/arch/ia64/kernel/semaphore.c @@ -50,7 +50,7 @@ __down (struct semaphore *sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -70,7 +70,7 @@ __down (struct semaphore *sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -85,7 +85,7 @@ __down_interruptible (struct semaphore * sem) int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -121,7 +121,7 @@ __down_interruptible (struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -248,7 +248,7 @@ down_write_failed_biased (struct rw_semaphore *sem) for (;;) { if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) break; - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!sem->write_bias_granted) schedule(); } @@ -277,7 +277,7 @@ down_write_failed (struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (sem->count < 0) { - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (sem->count >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); diff --git a/arch/m68k/config.in b/arch/m68k/config.in index b06fdb516..afa5eae2d 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -25,6 +25,7 @@ mainmenu_option next_comment comment 'Platform dependent setup' define_bool CONFIG_ISA n +define_bool CONFIG_EISA n define_bool CONFIG_PCMCIA n bool 'Amiga support' CONFIG_AMIGA diff --git a/arch/m68k/kernel/semaphore.c b/arch/m68k/kernel/semaphore.c index 139a75b64..a3a3e17f1 100644 --- a/arch/m68k/kernel/semaphore.c +++ b/arch/m68k/kernel/semaphore.c @@ -180,7 +180,7 @@ void down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (atomic_read(&sem->count) < 0) { - set_task_state(current, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(current, TASK_UNINTERRUPTIBLE); if (atomic_read(&sem->count) >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); @@ -199,7 +199,7 @@ void down_write_failed_biased(struct rw_semaphore *sem) for (;;) { if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) break; - set_task_state(current, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(current, TASK_UNINTERRUPTIBLE); if (!sem->write_bias_granted) schedule(); } diff --git a/arch/mips/config.in b/arch/mips/config.in index ce9e6c5d1..48828238b 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -33,6 +33,7 @@ bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI # unset CONFIG_ARC32 unset CONFIG_ISA +unset CONFIG_EISA unset CONFIG_PCI unset CONFIG_MIPS_JAZZ unset CONFIG_VIDEO_G364 @@ -59,7 +60,6 @@ if [ "$CONFIG_ACER_PICA_61" = "y" ]; then define_bool CONFIG_PC_KEYB y fi if [ "$CONFIG_COBALT_MICRO_SERVER" = "y" ]; then - define_bool CONFIG_ISA n define_bool CONFIG_COBALT_27 y define_bool CONFIG_COBALT_LCD y define_bool CONFIG_COBALT_SERIAL y @@ -83,6 +83,9 @@ fi if [ "$CONFIG_ISA" != "y" ]; then define_bool CONFIG_ISA n + define_bool CONFIG_EISA n +else + define_bool CONFIG_EISA y fi if [ "$CONFIG_PCI" != "y" ]; then diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c index 1f47bd929..5a9478f03 100644 --- a/arch/mips/kernel/semaphore.c +++ b/arch/mips/kernel/semaphore.c @@ -187,8 +187,7 @@ __down_write(struct rw_semaphore *sem, int count) add_wait_queue_exclusive(&sem->wait, &wait); while (atomic_read(&sem->count) < 0) { - set_task_state(tsk, (TASK_UNINTERRUPTIBLE - | TASK_EXCLUSIVE)); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (atomic_read(&sem->count) >= RW_LOCK_BIAS) break; schedule(); @@ -208,8 +207,7 @@ __down_write(struct rw_semaphore *sem, int count) while (1) { if (test_and_clear_bit(1, &sem->granted)) break; - set_task_state(tsk, (TASK_UNINTERRUPTIBLE - | TASK_EXCLUSIVE)); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if ((sem->granted & 2) == 0) schedule(); } diff --git a/arch/mips64/config.in b/arch/mips64/config.in index ad1bdb570..44960c112 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -57,6 +57,9 @@ fi if [ "$CONFIG_ISA" != "y" ]; then define_bool CONFIG_ISA n + define_bool CONFIG_EISA n +else + define_bool CONFIG_EISA y fi if [ "$CONFIG_PCI" != "y" ]; then diff --git a/arch/mips64/kernel/semaphore.c b/arch/mips64/kernel/semaphore.c index 1f47bd929..5a9478f03 100644 --- a/arch/mips64/kernel/semaphore.c +++ b/arch/mips64/kernel/semaphore.c @@ -187,8 +187,7 @@ __down_write(struct rw_semaphore *sem, int count) add_wait_queue_exclusive(&sem->wait, &wait); while (atomic_read(&sem->count) < 0) { - set_task_state(tsk, (TASK_UNINTERRUPTIBLE - | TASK_EXCLUSIVE)); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (atomic_read(&sem->count) >= RW_LOCK_BIAS) break; schedule(); @@ -208,8 +207,7 @@ __down_write(struct rw_semaphore *sem, int count) while (1) { if (test_and_clear_bit(1, &sem->granted)) break; - set_task_state(tsk, (TASK_UNINTERRUPTIBLE - | TASK_EXCLUSIVE)); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if ((sem->granted & 2) == 0) schedule(); } diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index 4b871c230..0790a81c5 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c @@ -149,7 +149,7 @@ cpm_interrupt(int irq, void * dev, struct pt_regs * regs) /* After servicing the interrupt, we have to remove the status * indicator. */ - ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr |= (1 << vec); + ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr = (1 << vec); } diff --git a/arch/ppc/config.in b/arch/ppc/config.in index ef17e6334..210c5ddf4 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -98,6 +98,7 @@ bool 'High memory support (experimental)' CONFIG_HIGHMEM bool 'Mac-on-Linux support' CONFIG_MOL define_bool CONFIG_ISA n +define_bool CONFIG_EISA n define_bool CONFIG_SBUS n if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \ diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/apus_defconfig similarity index 62% copy from arch/ppc/configs/common_defconfig copy to arch/ppc/configs/apus_defconfig index a9ae80db0..ed930fff2 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/apus_defconfig @@ -12,7 +12,7 @@ CONFIG_EXPERIMENTAL=y # Loadable module support # CONFIG_MODULES=y -CONFIG_MODVERSIONS=y +# CONFIG_MODVERSIONS is not set CONFIG_KMOD=y # @@ -30,12 +30,13 @@ CONFIG_ALL_PPC=y # CONFIG_EST8260 is not set # CONFIG_APUS is not set # CONFIG_SMP is not set -CONFIG_ALTIVEC=y +# CONFIG_ALTIVEC is not set # # General setup # # CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set CONFIG_PCI=y @@ -47,7 +48,7 @@ CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m -CONFIG_PCI_NAMES=y +# CONFIG_PCI_NAMES is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -55,13 +56,12 @@ CONFIG_PCI_NAMES=y # Parallel port support # # CONFIG_PARPORT is not set -CONFIG_VGA_CONSOLE=y +# CONFIG_VGA_CONSOLE is not set CONFIG_FB=y CONFIG_FB_COMPAT_XPMAC=y -CONFIG_PMAC_PBOOK=y -CONFIG_PPC_RTC=y +# CONFIG_PPC_RTC is not set CONFIG_PROC_DEVICETREE=y -CONFIG_BOOTX_TEXT=y +# CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set # CONFIG_CMDLINE_BOOL is not set @@ -83,18 +83,25 @@ CONFIG_BOOTX_TEXT=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -115,7 +122,7 @@ CONFIG_IP_MULTICAST=y # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y +# CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -130,6 +137,7 @@ CONFIG_ATALK=m # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -143,81 +151,9 @@ CONFIG_ATALK=m # # ATA/IDE/MFM/RLL support # -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=y - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_IDEDMA_PCI_AUTO=y -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD7409 is not set -# CONFIG_AMD7409_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_VIA82CXXX_TUNING is not set -CONFIG_BLK_DEV_SL82C105=y -CONFIG_BLK_DEV_IDE_PMAC=y -CONFIG_BLK_DEV_IDEDMA_PMAC=y -CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y -CONFIG_BLK_DEV_IDEDMA=y -CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # # SCSI support @@ -233,7 +169,7 @@ CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 -CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SG is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -262,6 +198,7 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -273,18 +210,9 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set -CONFIG_SCSI_SYM53C8XX=y -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=20 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_SYM53C8XX is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -293,6 +221,8 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -333,7 +263,7 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MACE=y CONFIG_BMAC=y -CONFIG_GMAC=y +# CONFIG_GMAC is not set # CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set @@ -342,45 +272,25 @@ CONFIG_GMAC=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -CONFIG_PCNET32=y -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_TULIP is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -# CONFIG_EEPRO100 is not set -# CONFIG_LNE390 is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_RTL8129 is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_ES3210 is not set -# CONFIG_EPIC100 is not set +# CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_ASYNC is not set # CONFIG_PPP_SYNC_TTY is not set -CONFIG_PPP_DEFLATE=y +# CONFIG_PPP_DEFLATE is not set # CONFIG_PPP_BSDCOMP is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set @@ -444,14 +354,10 @@ CONFIG_FB_CT65550=y CONFIG_FB_IMSTT=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set -CONFIG_FB_MATROX=y -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y -# CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_MATROX is not set CONFIG_FB_ATY=y -CONFIG_FB_ATY128=y -CONFIG_FB_3DFX=y +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_3DFX is not set # CONFIG_FB_SIS is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set @@ -472,28 +378,17 @@ CONFIG_FONT_SUN12x22=y # # Input core support # -CONFIG_INPUT=y -CONFIG_INPUT_KEYBDEV=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT is not set # # Macintosh device drivers # +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set CONFIG_MAC_FLOPPY=y CONFIG_MAC_SERIAL=y # CONFIG_SERIAL_CONSOLE is not set -CONFIG_ADB=y -CONFIG_ADB_CUDA=y -CONFIG_ADB_MACIO=y -CONFIG_ADB_PMU=y -CONFIG_INPUT_ADBHID=y -CONFIG_MAC_HID=y -CONFIG_MAC_ADBKEYCODES=y -CONFIG_MAC_EMUMOUSEBTN=y +# CONFIG_ADB is not set # # Character devices @@ -514,14 +409,8 @@ CONFIG_UNIX98_PTY_COUNT=256 # # Mice # -CONFIG_BUSMOUSE=y -# CONFIG_ATIXL_BUSMOUSE is not set -# CONFIG_LOGIBUSMOUSE is not set -# CONFIG_MS_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set # # Joysticks @@ -561,16 +450,16 @@ CONFIG_NVRAM=y # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set +CONFIG_HFS_FS=y # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set @@ -582,7 +471,7 @@ CONFIG_ISO9660_FS=y # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_FS is not set # CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y @@ -624,26 +513,15 @@ CONFIG_LOCKD=y # # Partition Types # -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y +# CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set CONFIG_NLS=y # # Native Language Support # CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set +CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -681,11 +559,11 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Sound # CONFIG_SOUND=y -CONFIG_DMASOUND_AWACS=y -CONFIG_DMASOUND=y +# CONFIG_DMASOUND_AWACS is not set # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set @@ -695,89 +573,17 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_TRACEINIT is not set -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SOFTOSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set # # USB support # -CONFIG_USB=y -CONFIG_USB_DEBUG=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -CONFIG_USB_OHCI=y - -# -# USB Devices -# -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_USS720 is not set -# CONFIG_USB_DABUSB is not set -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_BLUETOOTH is not set - -# -# USB Human Interface Devices (HID) -# -CONFIG_USB_HID=y -# CONFIG_USB_WACOM is not set +# CONFIG_USB is not set # # Kernel hacking # -CONFIG_MAGIC_SYSRQ=y +# CONFIG_MAGIC_SYSRQ is not set # CONFIG_KGDB is not set -CONFIG_XMON=y +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/bseip_defconfig b/arch/ppc/configs/bseip_defconfig index 7233997fd..f0ff611f4 100644 --- a/arch/ppc/configs/bseip_defconfig +++ b/arch/ppc/configs/bseip_defconfig @@ -9,18 +9,27 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Platform support # CONFIG_PPC=y # CONFIG_6xx is not set # CONFIG_4xx is not set -# CONFIG_PPC64BRIDGE is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set # CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set # CONFIG_RPXCLASSIC is not set CONFIG_BSEIP=y +# CONFIG_TQM8xxL is not set +# CONFIG_TQM860L is not set +# CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set # CONFIG_ALL_PPC is not set @@ -29,15 +38,13 @@ CONFIG_MACH_SPECIFIC=y CONFIG_MATH_EMULATION=y # -# Loadable module support -# -# CONFIG_MODULES is not set - -# # General setup # +# CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -56,6 +63,11 @@ CONFIG_KERNEL_ELF=y # CONFIG_PARPORT is not set # +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# # Plug and Play configuration # # CONFIG_PNP is not set @@ -68,16 +80,25 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set -# CONFIG_RAID15_DANGEROUS is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_INITRD=y +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -96,17 +117,11 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -117,10 +132,11 @@ CONFIG_SKB_LARGE=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -155,6 +171,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -173,6 +190,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -180,8 +198,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -236,6 +255,15 @@ CONFIG_NET_ETHERNET=y # CONFIG_FB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# # Character devices # # CONFIG_VT is not set @@ -260,19 +288,19 @@ CONFIG_UNIX98_PTY_COUNT=256 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -281,9 +309,13 @@ CONFIG_UNIX98_PTY_COUNT=256 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -301,6 +333,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set @@ -360,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set # CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set @@ -375,7 +409,9 @@ CONFIG_SCC_ENET=y # CONFIG_SCC1_ENET is not set CONFIG_SCC2_ENET=y # CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set CONFIG_8xxSMC2=y +# CONFIG_8xx_ALTSMC2 is not set # CONFIG_8xxSCC is not set # diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index a9ae80db0..5574ecbdb 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -36,6 +36,7 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set CONFIG_PCI=y @@ -58,7 +59,6 @@ CONFIG_PCI_NAMES=y CONFIG_VGA_CONSOLE=y CONFIG_FB=y CONFIG_FB_COMPAT_XPMAC=y -CONFIG_PMAC_PBOOK=y CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y CONFIG_BOOTX_TEXT=y @@ -83,18 +83,25 @@ CONFIG_BOOTX_TEXT=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -130,6 +137,7 @@ CONFIG_ATALK=m # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -203,10 +211,11 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set # CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_OSB4 is not set # CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_VIA82CXXX_TUNING is not set CONFIG_BLK_DEV_SL82C105=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDEDMA_PMAC=y @@ -262,6 +271,7 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -273,8 +283,6 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set CONFIG_SCSI_SYM53C8XX=y @@ -293,6 +301,8 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -342,6 +352,7 @@ CONFIG_GMAC=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y @@ -358,26 +369,28 @@ CONFIG_DE4X5=y # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set # CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set -# CONFIG_ES3210 is not set -# CONFIG_EPIC100 is not set +# CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=y CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y CONFIG_PPP_ASYNC=y # CONFIG_PPP_SYNC_TTY is not set CONFIG_PPP_DEFLATE=y @@ -483,13 +496,15 @@ CONFIG_INPUT_EVDEV=y # # Macintosh device drivers # +CONFIG_ADB_CUDA=y +CONFIG_ADB_PMU=y +CONFIG_PMAC_PBOOK=y +CONFIG_PMAC_BACKLIGHT=y CONFIG_MAC_FLOPPY=y CONFIG_MAC_SERIAL=y # CONFIG_SERIAL_CONSOLE is not set CONFIG_ADB=y -CONFIG_ADB_CUDA=y CONFIG_ADB_MACIO=y -CONFIG_ADB_PMU=y CONFIG_INPUT_ADBHID=y CONFIG_MAC_HID=y CONFIG_MAC_ADBKEYCODES=y @@ -686,6 +701,7 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set @@ -715,7 +731,6 @@ CONFIG_SOUND_CS4232=m # CONFIG_SOUND_PAS is not set # CONFIG_PAS_JOYSTICK is not set # CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SOFTOSS is not set # CONFIG_SOUND_SB is not set # CONFIG_SOUND_AWE32_SYNTH is not set # CONFIG_SOUND_WAVEFRONT is not set @@ -768,6 +783,7 @@ CONFIG_USB_OHCI=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_NET1080 is not set # # USB Human Interface Devices (HID) diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig index d317c8517..afb972c03 100644 --- a/arch/ppc/configs/est8260_defconfig +++ b/arch/ppc/configs/est8260_defconfig @@ -38,6 +38,7 @@ CONFIG_MACH_SPECIFIC=y # General setup # # CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set # CONFIG_PCI is not set @@ -81,18 +82,25 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -130,6 +138,7 @@ CONFIG_SYN_COOKIES=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -183,6 +192,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -190,8 +200,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/gemini_defconfig index 522bd5d5d..44147f58c 100644 --- a/arch/ppc/configs/gemini_defconfig +++ b/arch/ppc/configs/gemini_defconfig @@ -9,12 +9,20 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Platform support # CONFIG_PPC=y CONFIG_6xx=y # CONFIG_4xx is not set -# CONFIG_PPC64 is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set # CONFIG_8260 is not set # CONFIG_8xx is not set # CONFIG_ALL_PPC is not set @@ -26,15 +34,10 @@ CONFIG_ALTIVEC=y CONFIG_MACH_SPECIFIC=y # -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# # General setup # +# CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set CONFIG_PCI=y @@ -46,6 +49,7 @@ CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -55,33 +59,47 @@ CONFIG_KERNEL_ELF=y # CONFIG_PARPORT is not set # CONFIG_VGA_CONSOLE is not set # CONFIG_FB is not set -# CONFIG_PMAC_PBOOK is not set -# CONFIG_MAC_FLOPPY is not set -# CONFIG_MAC_SERIAL is not set -# CONFIG_ADB is not set +# CONFIG_PPC_RTC is not set # CONFIG_PROC_DEVICETREE is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set # +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# # Plug and Play configuration # # CONFIG_PNP is not set +# CONFIG_ISAPNP is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set # -# Additional Block Devices +# Multi-device support (RAID and LVM) # -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set -# CONFIG_RAID15_DANGEROUS is not set -# CONFIG_BLK_DEV_RAM is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -98,17 +116,11 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -119,10 +131,11 @@ CONFIG_SKB_LARGE=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -167,6 +180,7 @@ CONFIG_SCSI_CONSTANTS=y # # SCSI low-level drivers # +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AHA152X is not set @@ -178,6 +192,8 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_DMA is not set @@ -185,17 +201,29 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_NCR53C7xx_sync is not set -# CONFIG_SCSI_NCR53C7xx_FAST is not set -# CONFIG_SCSI_NCR53C7xx_DISCONNECT is not set +# CONFIG_SCSI_NCR53C7xx is not set +CONFIG_SCSI_NCR53C8XX=y +# CONFIG_SCSI_SYM53C8XX is not set +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set @@ -203,6 +231,11 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_MAC53C94 is not set # +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -214,6 +247,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -232,6 +266,7 @@ CONFIG_NCR885E=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -239,8 +274,9 @@ CONFIG_NCR885E=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -295,6 +331,15 @@ CONFIG_NCR885E=y # CONFIG_FB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# # Character devices # # CONFIG_VT is not set @@ -320,19 +365,19 @@ CONFIG_UNIX98_PTY_COUNT=256 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -341,8 +386,13 @@ CONFIG_UNIX98_PTY_COUNT=256 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -351,27 +401,39 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y # CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems @@ -379,11 +441,23 @@ CONFIG_EXT2_FS=y # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # # Partition Types diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/mbx_defconfig similarity index 91% copy from arch/ppc/configs/rpxcllf_defconfig copy to arch/ppc/configs/mbx_defconfig index 4dda3d93f..6230f5877 100644 --- a/arch/ppc/configs/rpxcllf_defconfig +++ b/arch/ppc/configs/mbx_defconfig @@ -25,12 +25,12 @@ CONFIG_PPC=y CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set -CONFIG_RPXCLASSIC=y +# CONFIG_RPXCLASSIC is not set # CONFIG_BSEIP is not set # CONFIG_TQM8xxL is not set # CONFIG_TQM860L is not set # CONFIG_TQM860 is not set -# CONFIG_MBX is not set +CONFIG_MBX=y # CONFIG_WINCEPT is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set @@ -41,11 +41,13 @@ CONFIG_MATH_EMULATION=y # General setup # # CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y -CONFIG_SYSCTL=y +# CONFIG_SYSCTL is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_KCORE_ELF=y @@ -78,41 +80,43 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options # -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set -# CONFIG_NETLINK_DEV is not set +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y -CONFIG_IP_MULTICAST=y +# CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y +# CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -127,6 +131,7 @@ CONFIG_SYN_COOKIES=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -162,7 +167,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set # @@ -180,6 +184,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -187,8 +192,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -258,8 +264,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_UNIX98_PTYS is not set # # I2C support @@ -334,7 +339,7 @@ CONFIG_PROC_FS=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set @@ -395,7 +400,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SCC_ENET=y CONFIG_SCC1_ENET=y -CONFIG_FEC_ENET=y +# CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xxSMC2=y # CONFIG_8xx_ALTSMC2 is not set @@ -405,7 +410,7 @@ CONFIG_8xxSCC=y # Generic MPC8xx Options # CONFIG_8xx_COPYBACK=y -# CONFIG_8xx_CPU6 is not set +CONFIG_8xx_CPU6=y # # USB support diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig index 362c83689..f33966d35 100644 --- a/arch/ppc/configs/oak_defconfig +++ b/arch/ppc/configs/oak_defconfig @@ -1,6 +1,7 @@ # -# Default configuration for the IBM PowerPC 403 "Oak" evaluation boards. +# Automatically generated make config: don't edit # +# CONFIG_UID16 is not set # # Code maturity level options @@ -8,13 +9,21 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Platform support # CONFIG_PPC=y # CONFIG_6xx is not set CONFIG_4xx=y -# CONFIG_PPC64BRIDGE is not set -# CONFIG_82xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set # CONFIG_8xx is not set CONFIG_OAK=y # CONFIG_WALNUT is not set @@ -23,35 +32,33 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_MATH_EMULATION is not set # -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y - -# # General setup # +# CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set +# CONFIG_ISA is not set +# CONFIG_SBUS is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_FB is not set -# CONFIG_PMAC_PBOOK is not set -# CONFIG_MAC_FLOPPY is not set -# CONFIG_MAC_SERIAL is not set -# CONFIG_ADB is not set -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_TOTALMP is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_MOTOROLA_HOTSWAP is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set # # Plug and Play configuration @@ -63,22 +70,28 @@ CONFIG_KERNEL_ELF=y # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_IDE is not set - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_DEV_XD is not set -CONFIG_PARIDE_PARPORT=y -# CONFIG_PARIDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -94,17 +107,11 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -# CONFIG_SKB_LARGE is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -115,10 +122,11 @@ CONFIG_SYN_COOKIES=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -130,6 +138,13 @@ CONFIG_SYN_COOKIES=y # CONFIG_NET_SCHED is not set # +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# # SCSI support # # CONFIG_SCSI is not set @@ -144,7 +159,9 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set # CONFIG_DUMMY is not set +# CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -153,25 +170,26 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set +# CONFIG_GMAC is not set # CONFIG_NCR885E is not set CONFIG_OAKNET=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_RTL8139 is not set -# CONFIG_DM9102 is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set -# CONFIG_NET_EISA is not set +# CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -184,7 +202,7 @@ CONFIG_OAKNET=y # CONFIG_NET_RADIO is not set # -# Token Ring driver support +# Token Ring devices # # CONFIG_TR is not set # CONFIG_NET_FC is not set @@ -202,6 +220,11 @@ CONFIG_OAKNET=y # CONFIG_HAMRADIO is not set # +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# # ISDN subsystem # # CONFIG_ISDN is not set @@ -221,6 +244,15 @@ CONFIG_OAKNET=y # CONFIG_FB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# # Character devices # # CONFIG_VT is not set @@ -240,24 +272,24 @@ CONFIG_SERIAL_CONSOLE=y # # CONFIG_BUSMOUSE is not set # CONFIG_MOUSE is not set -# CONFIG_QIC02_TAPE is not set # -# Watchdog Cards +# Joysticks # -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set +# CONFIG_JOYSTICK is not set # -# Video For Linux +# Input core support is needed for joysticks # -# CONFIG_VIDEO_DEV is not set +# CONFIG_QIC02_TAPE is not set # -# Joystick support +# Watchdog Cards # -# CONFIG_JOYSTICK is not set +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -266,19 +298,22 @@ CONFIG_SERIAL_CONSOLE=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set +# CONFIG_AGP is not set # CONFIG_DRM is not set # -# Support for USB +# Multimedia devices # -# CONFIG_USB is not set +# CONFIG_VIDEO_DEV is not set # -# Filesystems +# File systems # # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set @@ -287,39 +322,60 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set -# CONFIG_UDF_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_SUN_PARTITION is not set +CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # @@ -328,6 +384,11 @@ CONFIG_LOCKD=y # CONFIG_SOUND is not set # +# USB support +# +# CONFIG_USB is not set + +# # Kernel hacking # # CONFIG_MAGIC_SYSRQ is not set diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig index 4dda3d93f..78ee82230 100644 --- a/arch/ppc/configs/rpxcllf_defconfig +++ b/arch/ppc/configs/rpxcllf_defconfig @@ -41,8 +41,10 @@ CONFIG_MATH_EMULATION=y # General setup # # CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -78,18 +80,25 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -127,6 +136,7 @@ CONFIG_SYN_COOKIES=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -180,6 +190,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -187,8 +198,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set diff --git a/arch/ppc/configs/rpxlite_defconfig b/arch/ppc/configs/rpxlite_defconfig index bacefe6f7..741d9265f 100644 --- a/arch/ppc/configs/rpxlite_defconfig +++ b/arch/ppc/configs/rpxlite_defconfig @@ -9,18 +9,27 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Platform support # CONFIG_PPC=y # CONFIG_6xx is not set # CONFIG_4xx is not set -# CONFIG_PPC64BRIDGE is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set # CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y CONFIG_RPXLITE=y # CONFIG_RPXCLASSIC is not set # CONFIG_BSEIP is not set +# CONFIG_TQM8xxL is not set +# CONFIG_TQM860L is not set +# CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set # CONFIG_ALL_PPC is not set @@ -29,15 +38,13 @@ CONFIG_MACH_SPECIFIC=y CONFIG_MATH_EMULATION=y # -# Loadable module support -# -# CONFIG_MODULES is not set - -# # General setup # +# CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -56,6 +63,11 @@ CONFIG_KERNEL_ELF=y # CONFIG_PARPORT is not set # +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# # Plug and Play configuration # # CONFIG_PNP is not set @@ -68,16 +80,25 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set -# CONFIG_RAID15_DANGEROUS is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_INITRD=y +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -96,17 +117,11 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -117,10 +132,11 @@ CONFIG_SKB_LARGE=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -155,6 +171,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -173,6 +190,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -180,8 +198,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -236,6 +255,15 @@ CONFIG_NET_ETHERNET=y # CONFIG_FB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# # Character devices # # CONFIG_VT is not set @@ -260,19 +288,19 @@ CONFIG_UNIX98_PTY_COUNT=256 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -281,9 +309,13 @@ CONFIG_UNIX98_PTY_COUNT=256 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -301,6 +333,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set @@ -360,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set # CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set @@ -375,6 +409,7 @@ CONFIG_SCC_ENET=y # CONFIG_SCC1_ENET is not set CONFIG_SCC2_ENET=y # CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set # CONFIG_8xxSMC2 is not set # CONFIG_8xxSCC is not set diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig index 73bc24eea..c3e95c6ac 100644 --- a/arch/ppc/configs/walnut_defconfig +++ b/arch/ppc/configs/walnut_defconfig @@ -1,6 +1,7 @@ # -# Default configuration for the IBM PowerPC 405GP "Walnut" evaluation board. +# Automatically generated make config: don't edit # +# CONFIG_UID16 is not set # # Code maturity level options @@ -8,13 +9,21 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Platform support # CONFIG_PPC=y # CONFIG_6xx is not set CONFIG_4xx=y -# CONFIG_PPC64BRIDGE is not set -# CONFIG_82xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set # CONFIG_8xx is not set # CONFIG_OAK is not set CONFIG_WALNUT=y @@ -23,35 +32,33 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_MATH_EMULATION is not set # -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y - -# # General setup # -CONFIG_PCI=y +# CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set +# CONFIG_ISA is not set +# CONFIG_SBUS is not set +# CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_FB is not set -# CONFIG_PMAC_PBOOK is not set -# CONFIG_MAC_FLOPPY is not set -# CONFIG_MAC_SERIAL is not set -# CONFIG_ADB is not set -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_TOTALMP is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_MOTOROLA_HOTSWAP is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set # # Plug and Play configuration @@ -63,22 +70,28 @@ CONFIG_KERNEL_ELF=y # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_IDE is not set - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_DEV_XD is not set -CONFIG_PARIDE_PARPORT=y -# CONFIG_PARIDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -94,17 +107,11 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -# CONFIG_SKB_LARGE is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -115,10 +122,11 @@ CONFIG_SYN_COOKIES=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -130,6 +138,13 @@ CONFIG_SYN_COOKIES=y # CONFIG_NET_SCHED is not set # +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# # SCSI support # # CONFIG_SCSI is not set @@ -144,7 +159,9 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set # CONFIG_DUMMY is not set +# CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -153,25 +170,26 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set +# CONFIG_GMAC is not set # CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_RTL8139 is not set -# CONFIG_DM9102 is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set -# CONFIG_NET_EISA is not set +# CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -184,7 +202,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_RADIO is not set # -# Token Ring driver support +# Token Ring devices # # CONFIG_TR is not set # CONFIG_NET_FC is not set @@ -202,6 +220,11 @@ CONFIG_NET_ETHERNET=y # CONFIG_HAMRADIO is not set # +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# # ISDN subsystem # # CONFIG_ISDN is not set @@ -221,6 +244,15 @@ CONFIG_NET_ETHERNET=y # CONFIG_FB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# # Character devices # # CONFIG_VT is not set @@ -234,30 +266,33 @@ CONFIG_SERIAL_CONSOLE=y # I2C support # CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set # # Mice # # CONFIG_BUSMOUSE is not set # CONFIG_MOUSE is not set -# CONFIG_QIC02_TAPE is not set # -# Watchdog Cards +# Joysticks # -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set +# CONFIG_JOYSTICK is not set # -# Video For Linux +# Input core support is needed for joysticks # -# CONFIG_VIDEO_DEV is not set +# CONFIG_QIC02_TAPE is not set # -# Joystick support +# Watchdog Cards # -# CONFIG_JOYSTICK is not set +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -266,19 +301,22 @@ CONFIG_I2C=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set +# CONFIG_AGP is not set # CONFIG_DRM is not set # -# Support for USB +# Multimedia devices # -# CONFIG_USB is not set +# CONFIG_VIDEO_DEV is not set # -# Filesystems +# File systems # # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set @@ -287,39 +325,60 @@ CONFIG_I2C=y # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set -# CONFIG_UDF_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_SUN_PARTITION is not set +CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # @@ -328,6 +387,11 @@ CONFIG_LOCKD=y # CONFIG_SOUND is not set # +# USB support +# +# CONFIG_USB is not set + +# # Kernel hacking # # CONFIG_MAGIC_SYSRQ is not set diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 9b3d88212..5574ecbdb 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -36,6 +36,7 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set +# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set CONFIG_PCI=y @@ -58,7 +59,6 @@ CONFIG_PCI_NAMES=y CONFIG_VGA_CONSOLE=y CONFIG_FB=y CONFIG_FB_COMPAT_XPMAC=y -CONFIG_PMAC_PBOOK=y CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y CONFIG_BOOTX_TEXT=y @@ -83,18 +83,25 @@ CONFIG_BOOTX_TEXT=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -130,6 +137,7 @@ CONFIG_ATALK=m # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -203,10 +211,11 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set # CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_OSB4 is not set # CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_VIA82CXXX_TUNING is not set CONFIG_BLK_DEV_SL82C105=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDEDMA_PMAC=y @@ -262,6 +271,7 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -273,8 +283,6 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set CONFIG_SCSI_SYM53C8XX=y @@ -293,6 +301,8 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -342,6 +352,7 @@ CONFIG_GMAC=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y @@ -358,26 +369,28 @@ CONFIG_DE4X5=y # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set # CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set -# CONFIG_ES3210 is not set -# CONFIG_EPIC100 is not set +# CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=y CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y CONFIG_PPP_ASYNC=y # CONFIG_PPP_SYNC_TTY is not set CONFIG_PPP_DEFLATE=y @@ -483,13 +496,15 @@ CONFIG_INPUT_EVDEV=y # # Macintosh device drivers # +CONFIG_ADB_CUDA=y +CONFIG_ADB_PMU=y +CONFIG_PMAC_PBOOK=y +CONFIG_PMAC_BACKLIGHT=y CONFIG_MAC_FLOPPY=y CONFIG_MAC_SERIAL=y # CONFIG_SERIAL_CONSOLE is not set CONFIG_ADB=y -CONFIG_ADB_CUDA=y CONFIG_ADB_MACIO=y -CONFIG_ADB_PMU=y CONFIG_INPUT_ADBHID=y CONFIG_MAC_HID=y CONFIG_MAC_ADBKEYCODES=y @@ -686,6 +701,7 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set @@ -715,7 +731,6 @@ CONFIG_SOUND_CS4232=m # CONFIG_SOUND_PAS is not set # CONFIG_PAS_JOYSTICK is not set # CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SOFTOSS is not set # CONFIG_SOUND_SB is not set # CONFIG_SOUND_AWE32_SYNTH is not set # CONFIG_SOUND_WAVEFRONT is not set @@ -768,6 +783,7 @@ CONFIG_USB_OHCI=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_NET1080 is not set # # USB Human Interface Devices (HID) @@ -776,11 +792,6 @@ CONFIG_USB_HID=y # CONFIG_USB_WACOM is not set # -# Mac-on-Linux (MOL) support -# -# CONFIG_MOL is not set - -# # Kernel hacking # CONFIG_MAGIC_SYSRQ=y diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 627cd7a2a..89922aaab 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -298,12 +298,10 @@ _GLOBAL(_switch) SYNC RFI -#ifdef CONFIG_SMP - .globl ret_from_smpfork -ret_from_smpfork: + .globl ret_from_fork +ret_from_fork: bl schedule_tail b ret_from_except -#endif .globl ret_from_intercept ret_from_intercept: diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S index 1129dd40e..06b7c6f1d 100644 --- a/arch/ppc/kernel/hashtable.S +++ b/arch/ppc/kernel/hashtable.S @@ -90,9 +90,14 @@ hash_page: REST_2GPRS(7, r21) #endif /* Get PTE (linux-style) and check access */ + lis r0,KERNELBASE@h /* check if kernel address */ + cmplw 0,r3,r0 mfspr r2,SPRG3 /* current task's THREAD (phys) */ lwz r5,PGDIR(r2) /* virt page-table root */ - tophys(r5,r5) /* convert to phys addr */ + blt+ 112f /* assume user more likely */ + lis r5,swapper_pg_dir@ha /* if kernel address, use */ + addi r5,r5,swapper_pg_dir@l /* kernel page table */ +112: tophys(r5,r5) /* convert to phys addr */ rlwimi r5,r3,12,20,29 /* insert top 10 bits of address */ lwz r5,0(r5) /* get pmd entry */ rlwinm. r5,r5,0,0,19 /* extract address of pte page */ @@ -152,11 +157,7 @@ hash_page: mfsrin r5,r3 /* get segment reg for segment */ rlwinm r5,r5,0,5,31 sldi r5,r5,12 - -#ifndef CONFIG_SMP /* do this later for SMP */ ori r5,r5,1 /* set V (valid) bit */ -#endif - rlwimi r5,r3,16,20,24 /* put in API (abbrev page index) */ /* Get the address of the primary PTE group in the hash table */ .globl hash_page_patch_A @@ -284,7 +285,9 @@ found_slot: */ found_empty: found_slot: - std r5,0(r3) /* clear V (valid) bit in PTE */ + li r0,1 + andc r5,r5,r0 /* clear V (valid) bit in PTE */ + std r5,0(r3) sync tlbsync sync @@ -299,11 +302,7 @@ found_slot: /* Construct the high word of the PPC-style PTE */ mfsrin r5,r3 /* get segment reg for segment */ rlwinm r5,r5,7,1,24 /* put VSID in 0x7fffff80 bits */ - -#ifndef CONFIG_SMP /* do this later for SMP */ oris r5,r5,0x8000 /* set V (valid) bit */ -#endif - rlwimi r5,r3,10,26,31 /* put in API (abbrev page index) */ /* Get the address of the primary PTE group in the hash table */ .globl hash_page_patch_A @@ -417,7 +416,8 @@ found_slot: */ found_empty: found_slot: - stw r5,0(r3) /* clear V (valid) bit in PTE */ + rlwinm r5,r5,0,1,31 /* clear V (valid) bit in PTE */ + stw r5,0(r3) sync tlbsync sync diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 5d26e2917..71b5a96c5 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -521,10 +521,15 @@ InstructionTLBMiss: */ mfctr r0 /* Get PTE (linux-style) and check access */ + mfspr r3,IMISS + lis r1,KERNELBASE@h /* check if kernel address */ + cmplw 0,r3,r1 mfspr r2,SPRG3 lwz r2,PGDIR(r2) - tophys(r2,r2) - mfspr r3,IMISS + blt+ 112f + lis r2,swapper_pg_dir@ha /* if kernel address, use */ + addi r2,r2,swapper_pg_dir@l /* kernel page table */ +112: tophys(r2,r2) rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ rlwinm. r2,r2,0,0,19 /* extract address of pte page */ @@ -588,10 +593,15 @@ DataLoadTLBMiss: */ mfctr r0 /* Get PTE (linux-style) and check access */ + mfspr r3,DMISS + lis r1,KERNELBASE@h /* check if kernel address */ + cmplw 0,r3,r1 mfspr r2,SPRG3 lwz r2,PGDIR(r2) - tophys(r2,r2) - mfspr r3,DMISS + blt+ 112f + lis r2,swapper_pg_dir@ha /* if kernel address, use */ + addi r2,r2,swapper_pg_dir@l /* kernel page table */ +112: tophys(r2,r2) rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ rlwinm. r2,r2,0,0,19 /* extract address of pte page */ @@ -654,10 +664,15 @@ DataStoreTLBMiss: */ mfctr r0 /* Get PTE (linux-style) and check access */ + mfspr r3,DMISS + lis r1,KERNELBASE@h /* check if kernel address */ + cmplw 0,r3,r1 mfspr r2,SPRG3 lwz r2,PGDIR(r2) - tophys(r2,r2) - mfspr r3,DMISS + blt+ 112f + lis r2,swapper_pg_dir@ha /* if kernel address, use */ + addi r2,r2,swapper_pg_dir@l /* kernel page table */ +112: tophys(r2,r2) rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ rlwinm. r2,r2,0,0,19 /* extract address of pte page */ diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index eef89f352..a0caa4a4c 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -343,6 +343,11 @@ int probe_irq_off (unsigned long irqs) return 0; } +unsigned int probe_irq_mask(unsigned long irqs) +{ + return 0; +} + void __init init_IRQ(void) { static int once = 0; diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index e3826293b..94e1cd277 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1219,11 +1219,7 @@ _GLOBAL(sys_call_table) .long sys_getresuid /* 165 */ .long sys_query_module .long sys_poll -#ifdef CONFIG_NFSD .long sys_nfsservctl -#else - .long sys_ni_syscall -#endif .long sys_setresgid .long sys_getresgid /* 170 */ .long sys_prctl diff --git a/arch/ppc/kernel/ppc8260_pic.c b/arch/ppc/kernel/ppc8260_pic.c index 21cfde0f7..5bd42a11f 100644 --- a/arch/ppc/kernel/ppc8260_pic.c +++ b/arch/ppc/kernel/ppc8260_pic.c @@ -79,7 +79,7 @@ static void m8260_mask_and_ack(unsigned int irq_nr) sipnr = &(immr->im_intctl.ic_sipnrh); ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); simr[word] = ppc_cached_irq_mask[word]; - sipnr[word] = 1 << bit; + sipnr[word] = 1 << (31 - bit); } struct hw_interrupt_type ppc8260_pic = { diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 9240431e6..827e37540 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -79,6 +79,7 @@ EXPORT_SYMBOL(do_lost_interrupts); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq_nosync); +EXPORT_SYMBOL(probe_irq_mask); #ifdef CONFIG_SMP EXPORT_SYMBOL(kernel_flag); #endif /* CONFIG_SMP */ @@ -222,6 +223,8 @@ EXPORT_SYMBOL(cuda_poll); #ifdef CONFIG_ADB_PMU EXPORT_SYMBOL(pmu_request); EXPORT_SYMBOL(pmu_poll); +EXPORT_SYMBOL(pmu_suspend); +EXPORT_SYMBOL(pmu_resume); #endif /* CONFIG_ADB_PMU */ #ifdef CONFIG_PMAC_PBOOK EXPORT_SYMBOL(pmu_register_sleep_notifier); @@ -298,6 +301,7 @@ EXPORT_SYMBOL(console_lock); EXPORT_SYMBOL(xmon); #endif EXPORT_SYMBOL(down_read_failed); +EXPORT_SYMBOL(down_write_failed); #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) extern void (*debugger)(struct pt_regs *regs); diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 27adc9958..a200b1c78 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -319,11 +319,8 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, { unsigned long msr; struct pt_regs * childregs, *kregs; -#ifdef CONFIG_SMP - extern void ret_from_smpfork(void); -#else - extern void ret_from_except(void); -#endif + extern void ret_from_fork(void); + /* Copy registers */ childregs = ((struct pt_regs *) ((unsigned long)p + sizeof(union task_union) @@ -336,11 +333,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, p->thread.ksp = (unsigned long) childregs - STACK_FRAME_OVERHEAD; p->thread.ksp -= sizeof(struct pt_regs ) + STACK_FRAME_OVERHEAD; kregs = (struct pt_regs *)(p->thread.ksp + STACK_FRAME_OVERHEAD); -#ifdef CONFIG_SMP - kregs->nip = (unsigned long)ret_from_smpfork; -#else - kregs->nip = (unsigned long)ret_from_except; -#endif + kregs->nip = (unsigned long)ret_from_fork; asm volatile("mfmsr %0" : "=r" (msr):); kregs->msr = msr; kregs->gpr[1] = (unsigned long)childregs - STACK_FRAME_OVERHEAD; diff --git a/arch/ppc/kernel/semaphore.c b/arch/ppc/kernel/semaphore.c index f17bc16ce..0ed7eaa4d 100644 --- a/arch/ppc/kernel/semaphore.c +++ b/arch/ppc/kernel/semaphore.c @@ -152,7 +152,7 @@ void down_read_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); do { - __set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); spin_unlock_irq(&sem->lock); schedule(); spin_lock_irq(&sem->lock); @@ -169,7 +169,7 @@ void down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); do { - __set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); spin_unlock_irq(&sem->lock); schedule(); spin_lock_irq(&sem->lock); diff --git a/arch/s390/config.in b/arch/s390/config.in index 894e40d5b..2f6096b3f 100644 --- a/arch/s390/config.in +++ b/arch/s390/config.in @@ -3,6 +3,8 @@ # see Documentation/kbuild/config-language.txt. # +define_bool CONFIG_ISA n +define_bool CONFIG_EISA n define_bool CONFIG_UID16 y mainmenu_name "Linux Kernel Configuration" diff --git a/arch/s390/kernel/semaphore.c b/arch/s390/kernel/semaphore.c index 86aef0185..a0a434581 100644 --- a/arch/s390/kernel/semaphore.c +++ b/arch/s390/kernel/semaphore.c @@ -55,7 +55,7 @@ void __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -75,7 +75,7 @@ void __down(struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -89,7 +89,7 @@ int __down_interruptible(struct semaphore * sem) int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); spin_lock_irq(&semaphore_lock); @@ -125,7 +125,7 @@ int __down_interruptible(struct semaphore * sem) spin_unlock_irq(&semaphore_lock); schedule(); - tsk->state = TASK_INTERRUPTIBLE|TASK_EXCLUSIVE; + tsk->state = TASK_INTERRUPTIBLE; spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); @@ -188,7 +188,7 @@ void down_write_failed_biased(struct rw_semaphore *sem) for (;;) { if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) break; - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!sem->write_bias_granted) schedule(); } @@ -240,7 +240,7 @@ void down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (atomic_read(&sem->count) < 0) { - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (atomic_read(&sem->count) >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); diff --git a/arch/sh/config.in b/arch/sh/config.in index f0a51f8d6..1aba71a62 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -66,6 +66,7 @@ mainmenu_option next_comment comment 'General setup' define_bool CONFIG_ISA n +define_bool CONFIG_EISA n define_bool CONFIG_SBUS n bool 'Networking support' CONFIG_NET diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c index 990960aa8..7cdda223c 100644 --- a/arch/sh/kernel/semaphore.c +++ b/arch/sh/kernel/semaphore.c @@ -195,7 +195,7 @@ struct rw_semaphore *down_write_failed_biased(struct rw_semaphore *sem) for (;;) { if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) break; - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!sem->write_bias_granted) schedule(); } @@ -251,7 +251,7 @@ struct rw_semaphore *down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (atomic_read(&sem->count) < 0) { - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (atomic_read(&sem->count) >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); diff --git a/arch/sparc/config.in b/arch/sparc/config.in index cb615fa0b..50b99ec22 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -31,6 +31,7 @@ bool 'Symmetric multi-processing support (does not work on sun4/sun4c)' CONFIG_S # Global things across all Sun machines. define_bool CONFIG_ISA n +define_bool CONFIG_EISA n define_bool CONFIG_PCMCIA n define_bool CONFIG_SBUS y define_bool CONFIG_SBUSCHAR y diff --git a/arch/sparc/kernel/semaphore.c b/arch/sparc/kernel/semaphore.c index 4359ec232..d6638be10 100644 --- a/arch/sparc/kernel/semaphore.c +++ b/arch/sparc/kernel/semaphore.c @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.3 2000/10/14 10:09:00 davem Exp $ +/* $Id: semaphore.c,v 1.4 2000/11/10 04:02:03 davem Exp $ * Generic semaphore code. Buyer beware. Do your own * specific changes in */ @@ -166,7 +166,7 @@ void down_write_failed_biased(struct rw_semaphore *sem) for (;;) { if (!ldstub(&sem->write_not_granted)) break; - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (sem->write_not_granted) schedule(); } @@ -216,7 +216,7 @@ void down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (sem->count < 0) { - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (sem->count >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index a754b796b..ea05d1388 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -29,6 +29,7 @@ bool 'Symmetric multi-processing support' CONFIG_SMP # Global things across all Sun machines. define_bool CONFIG_HAVE_DEC_LOCK y define_bool CONFIG_ISA n +define_bool CONFIG_EISA n define_bool CONFIG_PCMCIA n define_bool CONFIG_SBUS y define_bool CONFIG_SBUSCHAR y diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index 10e7ccc9c..a510c2aff 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.102 2000/11/08 05:13:30 davem Exp $ +/* $Id: ioctl32.c,v 1.103 2000/11/10 05:44:33 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -71,7 +71,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c index 8cb6e7211..1928d5a0d 100644 --- a/arch/sparc64/kernel/semaphore.c +++ b/arch/sparc64/kernel/semaphore.c @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.4 2000/10/14 10:09:00 davem Exp $ +/* $Id: semaphore.c,v 1.5 2000/11/10 04:02:03 davem Exp $ * Generic semaphore code. Buyer beware. Do your own * specific changes in */ @@ -223,7 +223,7 @@ void down_write_failed_biased(struct rw_semaphore *sem) for (;;) { if (test_and_clear_le_bit(1, &sem->granted)) break; - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!test_le_bit(1, &sem->granted)) schedule(); } @@ -273,7 +273,7 @@ void down_write_failed(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->wait, &wait); while (sem->count < 0) { - set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (sem->count >= 0) break; /* we must attempt to acquire or bias the lock */ schedule(); diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index d9d3f8622..7e01a75c5 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -496,7 +496,7 @@ static struct request *__get_request_wait(request_queue_t *q, int rw) add_wait_queue_exclusive(&q->wait_for_request, &wait); for (;;) { - __set_current_state(TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + __set_current_state(TASK_UNINTERRUPTIBLE); spin_lock_irq(&io_request_lock); rq = get_request(q, rw); spin_unlock_irq(&io_request_lock); diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 6a2352281..2d0b54648 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -100,7 +100,7 @@ static int rd_hardsec[NUM_RAMDISKS]; /* Size of real blocks in bytes */ static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */ static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */ static devfs_handle_t devfs_handle; -static struct inode *rd_inode[NUM_RAMDISKS]; /* Protected device inodes */ +static struct inode *rd_inode[NUM_RAMDISKS]; /* Protected device inodes */ /* * Parameters for the boot-loading of the RAM disk. These are set by @@ -108,7 +108,7 @@ static struct inode *rd_inode[NUM_RAMDISKS]; /* Protected device inodes */ * architecture-specific setup routine (from the stored boot sector * information). */ -int rd_size = 4096; /* Size of the RAM disks */ +int rd_size = CONFIG_BLK_DEV_RAM_SIZE; /* Size of the RAM disks */ /* * It would be very desiderable to have a soft-blocksize (that in the case * of the ramdisk driver is also the hardblocksize ;) of PAGE_SIZE because @@ -120,7 +120,7 @@ int rd_size = 4096; /* Size of the RAM disks */ * behaviour. The default is still BLOCK_SIZE (needed by rd_load_image that * supposes the filesystem in the image uses a BLOCK_SIZE blocksize). */ -int rd_blocksize = BLOCK_SIZE; /* Size of the RAM disks */ +int rd_blocksize = BLOCK_SIZE; /* blocksize of the RAM disks */ #ifndef MODULE diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 1ec7792a6..4e3066ba8 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -16,7 +16,7 @@ if [ "$CONFIG_SERIAL" = "y" ]; then tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL fi fi -dep_bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL +dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then bool ' Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS bool ' Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ diff --git a/drivers/char/console.c b/drivers/char/console.c index ea44cace4..0285eab79 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -2135,7 +2135,6 @@ void vt_console_print(struct console *co, const char * b, unsigned count) } } set_cursor(currcons); - poke_blanked_console(); quit: clear_bit(0, &printing); diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c index 84c7f0644..0d2b834b9 100644 --- a/drivers/char/drm/ffb_drv.c +++ b/drivers/char/drm/ffb_drv.c @@ -244,7 +244,7 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance) }; } -static int ffb_init_one(int prom_node, int instance) +static int __init ffb_init_one(int prom_node, int instance) { struct linux_prom64_registers regs[2*PROMREG_MAX]; drm_device_t *dev; @@ -305,7 +305,7 @@ static int ffb_init_one(int prom_node, int instance) return 0; } -static int ffb_init_dev_table(void) +static int __init ffb_init_dev_table(void) { int root, node; int total = 0; @@ -324,7 +324,7 @@ static int ffb_init_dev_table(void) return 0; } -int ffb_init(void) +int __init ffb_init(void) { int root, node, instance, ret; @@ -345,7 +345,7 @@ int ffb_init(void) return 0; } -void ffb_cleanup(void) +void __exit ffb_cleanup(void) { int instance; diff --git a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c index dba974c2b..a17bc1a9f 100644 --- a/drivers/char/drm/gamma_drv.c +++ b/drivers/char/drm/gamma_drv.c @@ -339,7 +339,7 @@ int gamma_find_devices(void) /* gamma_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int gamma_init(void) +static int __init gamma_init(void) { int retcode; drm_device_t *dev = &gamma_device; @@ -380,7 +380,7 @@ static int gamma_init(void) /* gamma_cleanup is called via cleanup_module at module unload time. */ -static void gamma_cleanup(void) +static void __exit gamma_cleanup(void) { drm_device_t *dev = &gamma_device; diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c index 42f9cbbc7..c02a93ee3 100644 --- a/drivers/char/drm/i810_drv.c +++ b/drivers/char/drm/i810_drv.c @@ -338,7 +338,7 @@ static int i810_takedown(drm_device_t *dev) /* i810_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int i810_init(void) +static int __init i810_init(void) { int retcode; drm_device_t *dev = &i810_device; @@ -397,7 +397,7 @@ static int i810_init(void) /* i810_cleanup is called via cleanup_module at module unload time. */ -static void i810_cleanup(void) +static void __exit i810_cleanup(void) { drm_device_t *dev = &i810_device; diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index f6a38d2ff..0f1b87b8b 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c @@ -338,7 +338,7 @@ static int mga_takedown(drm_device_t *dev) /* mga_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int mga_init(void) +static int __init mga_init(void) { int retcode; drm_device_t *dev = &mga_device; @@ -398,7 +398,7 @@ static int mga_init(void) /* mga_cleanup is called via cleanup_module at module unload time. */ -static void mga_cleanup(void) +static void __exit mga_cleanup(void) { drm_device_t *dev = &mga_device; diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index bbef428df..70d17f43d 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c @@ -323,7 +323,7 @@ static int r128_takedown(drm_device_t *dev) /* r128_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int r128_init(void) +static int __init r128_init(void) { int retcode; drm_device_t *dev = &r128_device; @@ -387,7 +387,7 @@ static int r128_init(void) /* r128_cleanup is called via cleanup_module at module unload time. */ -static void r128_cleanup(void) +static void __exit r128_cleanup(void) { drm_device_t *dev = &r128_device; diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c index 1a90610b7..26e0f6019 100644 --- a/drivers/char/drm/tdfx_drv.c +++ b/drivers/char/drm/tdfx_drv.c @@ -298,7 +298,7 @@ static int tdfx_takedown(drm_device_t *dev) /* tdfx_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int tdfx_init(void) +static int __init tdfx_init(void) { int retcode; drm_device_t *dev = &tdfx_device; @@ -346,7 +346,7 @@ static int tdfx_init(void) /* tdfx_cleanup is called via cleanup_module at module unload time. */ -static void tdfx_cleanup(void) +static void __exit tdfx_cleanup(void) { drm_device_t *dev = &tdfx_device; diff --git a/drivers/char/joystick/iforce.c b/drivers/char/joystick/iforce.c index acb0bfe5b..444d4e91c 100644 --- a/drivers/char/joystick/iforce.c +++ b/drivers/char/joystick/iforce.c @@ -54,6 +54,7 @@ MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver"); struct iforce { signed char data[IFORCE_MAX_LENGTH]; + struct usb_device *usbdev; struct input_dev dev; struct urb irq; int open; @@ -113,9 +114,11 @@ static int iforce_open(struct input_dev *dev) { struct iforce *iforce = dev->private; - if (dev->idbus == BUS_USB && !iforce->open++) + if (dev->idbus == BUS_USB && !iforce->open++) { + iforce->irq.dev = iforce->usbdev; if (usb_submit_urb(&iforce->irq)) return -EIO; + } return 0; } @@ -177,15 +180,12 @@ static void iforce_usb_irq(struct urb *urb) iforce_process_packet(&iforce->dev, iforce->data[0], 8, iforce->data + 1); } -static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum) +static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_endpoint_descriptor *endpoint; struct iforce *iforce; - if (dev->descriptor.idVendor != USB_VENDOR_ID_LOGITECH || - dev->descriptor.idProduct != USB_DEVICE_ID_LOGITECH_WMFORCE) - return NULL; - endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0; if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return NULL; @@ -216,10 +216,21 @@ static void iforce_usb_disconnect(struct usb_device *dev, void *ptr) kfree(iforce); } +static struct usb_device_id iforce_usb_ids [] = { + { + idVendor: USB_VENDOR_ID_LOGITECH, + idProduct: USB_DEVICE_ID_LOGITECH_WMFORCE + }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, iforce_usb_ids); + static struct usb_driver iforce_usb_driver = { name: "iforce", probe: iforce_usb_probe, disconnect: iforce_usb_disconnect, + id_table: iforce_usb_ids, }; #endif diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c index 2e9eb02df..87f98b029 100644 --- a/drivers/isdn/act2000/module.c +++ b/drivers/isdn/act2000/module.c @@ -1,4 +1,4 @@ -/* $Id: module.c,v 1.11 1999/10/30 09:48:04 keil Exp $ +/* $Id: module.c,v 1.12 2000/05/06 00:52:36 kai Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * @@ -20,6 +20,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: module.c,v $ + * Revision 1.12 2000/05/06 00:52:36 kai + * merged changes from kernel tree + * fixed timer and net_device->name breakage + * * Revision 1.11 1999/10/30 09:48:04 keil * miss one prefix act2000 * diff --git a/drivers/isdn/avmb1/avmcard.h b/drivers/isdn/avmb1/avmcard.h index 56fa0fba6..cf8287aa3 100644 --- a/drivers/isdn/avmb1/avmcard.h +++ b/drivers/isdn/avmb1/avmcard.h @@ -1,9 +1,12 @@ /* - * $Id: avmcard.h,v 1.7 2000/01/25 14:33:38 calle Exp $ + * $Id: avmcard.h,v 1.8 2000/10/10 17:44:19 kai Exp $ * * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: avmcard.h,v $ + * Revision 1.8 2000/10/10 17:44:19 kai + * changes from/for 2.2.18 + * * Revision 1.7 2000/01/25 14:33:38 calle * - Added Support AVM B1 PCI V4.0 (tested with prototype) * - splitted up t1pci.c into b1dma.c for common function with b1pciv4 @@ -347,13 +350,13 @@ static inline unsigned int b1_rd_reg(unsigned int base, static inline void b1_reset(unsigned int base) { b1outp(base, B1_RESET, 0); - udelay(55 * 2 * 1000); /* 2 TIC's */ + mdelay(55 * 2); /* 2 TIC's */ b1outp(base, B1_RESET, 1); - udelay(55 * 2 * 1000); /* 2 TIC's */ + mdelay(55 * 2); /* 2 TIC's */ b1outp(base, B1_RESET, 0); - udelay(55 * 2 * 1000); /* 2 TIC's */ + mdelay(55 * 2); /* 2 TIC's */ } static inline unsigned char b1_disable_irq(unsigned int base) diff --git a/drivers/isdn/avmb1/b1dma.c b/drivers/isdn/avmb1/b1dma.c index 94f493620..9da7a21ac 100644 --- a/drivers/isdn/avmb1/b1dma.c +++ b/drivers/isdn/avmb1/b1dma.c @@ -1,11 +1,19 @@ /* - * $Id: b1dma.c,v 1.7 2000/08/04 12:20:08 calle Exp $ + * $Id: b1dma.c,v 1.9 2000/11/01 14:05:02 calle Exp $ * * Common module for AVM B1 cards that support dma with AMCC * * (c) Copyright 2000 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: b1dma.c,v $ + * Revision 1.9 2000/11/01 14:05:02 calle + * - use module_init/module_exit from linux/init.h. + * - all static struct variables are initialized with "membername:" now. + * - avm_cs.c, let it work with newer pcmcia-cs. + * + * Revision 1.8 2000/10/10 17:44:19 kai + * changes from/for 2.2.18 + * * Revision 1.7 2000/08/04 12:20:08 calle * - Fix unsigned/signed warning in the right way ... * @@ -47,7 +55,7 @@ #include "capicmd.h" #include "capiutil.h" -static char *revision = "$Revision: 1.7 $"; +static char *revision = "$Revision: 1.9 $"; /* ------------------------------------------------------------- */ @@ -243,14 +251,14 @@ void b1dma_reset(avmcard *card) restore_flags(flags); b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); - udelay(10 * 1000); + mdelay(10); b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */ - udelay(10 * 1000); + mdelay(10); b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); if (card->cardtype == avm_t1pci) - udelay(42 * 1000); + mdelay(42); else - udelay(10 * 1000); + mdelay(10); } /* ------------------------------------------------------------- */ @@ -258,11 +266,11 @@ void b1dma_reset(avmcard *card) int b1dma_detect(avmcard *card) { b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); - udelay(10 * 1000); + mdelay(10); b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */ - udelay(10 * 1000); + mdelay(10); b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); - udelay(42 * 1000); + mdelay(42); b1dmaoutmeml(card->mbase+AMCC_RXLEN, 0); b1dmaoutmeml(card->mbase+AMCC_TXLEN, 0); diff --git a/drivers/isdn/avmb1/c4.c b/drivers/isdn/avmb1/c4.c index bbb5d5793..ae2c49261 100644 --- a/drivers/isdn/avmb1/c4.c +++ b/drivers/isdn/avmb1/c4.c @@ -1,11 +1,19 @@ /* - * $Id: c4.c,v 1.16 2000/08/20 07:30:13 keil Exp $ + * $Id: c4.c,v 1.18 2000/11/01 14:05:02 calle Exp $ * * Module for AVM C4 card. * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: c4.c,v $ + * Revision 1.18 2000/11/01 14:05:02 calle + * - use module_init/module_exit from linux/init.h. + * - all static struct variables are initialized with "membername:" now. + * - avm_cs.c, let it work with newer pcmcia-cs. + * + * Revision 1.17 2000/10/10 17:44:19 kai + * changes from/for 2.2.18 + * * Revision 1.16 2000/08/20 07:30:13 keil * changes for 2.4 * @@ -80,7 +88,7 @@ #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.16 $"; +static char *revision = "$Revision: 1.18 $"; #undef CONFIG_C4_DEBUG #undef CONFIG_C4_POLLDEBUG @@ -410,7 +418,7 @@ static int c4_detect(avmcard *card) return 8; if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, 0)) return 9; - udelay(1000); + mdelay(1); if (c4_peek(card, DC21285_DRAM_A0MR, &dummy)) return 10; if (c4_peek(card, DC21285_DRAM_A1MR, &dummy)) return 11; @@ -422,7 +430,7 @@ static int c4_detect(avmcard *card) if (c4_poke(card, DC21285_DRAM_A2MR+CAS_OFFSET, 0)) return 16; if (c4_poke(card, DC21285_DRAM_A3MR+CAS_OFFSET, 0)) return 17; - udelay(1000); + mdelay(1); if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, DRAM_TIMING_DEF)) return 18; @@ -927,7 +935,7 @@ static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) c4outmeml(card->mbase+MBOX_UP_LEN, 0); c4outmeml(card->mbase+MBOX_DOWN_LEN, 0); c4outmeml(card->mbase+DOORBELL, DBELL_INIT); - udelay(1000); + mdelay(1); c4outmeml(card->mbase+DOORBELL, DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST); diff --git a/drivers/isdn/avmb1/t1isa.c b/drivers/isdn/avmb1/t1isa.c index 2abd7ed4c..7a69f7b52 100644 --- a/drivers/isdn/avmb1/t1isa.c +++ b/drivers/isdn/avmb1/t1isa.c @@ -1,11 +1,19 @@ /* - * $Id: t1isa.c,v 1.13 2000/08/04 15:36:31 calle Exp $ + * $Id: t1isa.c,v 1.15 2000/11/01 14:05:02 calle Exp $ * * Module for AVM T1 HEMA-card. * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: t1isa.c,v $ + * Revision 1.15 2000/11/01 14:05:02 calle + * - use module_init/module_exit from linux/init.h. + * - all static struct variables are initialized with "membername:" now. + * - avm_cs.c, let it work with newer pcmcia-cs. + * + * Revision 1.14 2000/10/10 17:44:19 kai + * changes from/for 2.2.18 + * * Revision 1.13 2000/08/04 15:36:31 calle * copied wrong from file to file :-( * @@ -85,13 +93,14 @@ #include #include #include +#include #include #include "capicmd.h" #include "capiutil.h" #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.13 $"; +static char *revision = "$Revision: 1.15 $"; /* ------------------------------------------------------------- */ @@ -145,7 +154,7 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) cli(); /* board reset */ t1outp(base, T1_RESETBOARD, 0xf); - udelay(100 * 1000); + mdelay(100); dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */ /* write config */ @@ -157,18 +166,18 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) t1outp(base, ((base >> 4)) & 0x3, cregs[7]); restore_flags(flags); - udelay(100 * 1000); + mdelay(100); t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); - udelay(10 * 1000); + mdelay(10); t1outp(base, T1_FASTLINK+T1_RESETLINK, 1); t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1); - udelay(100 * 1000); + mdelay(100); t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); - udelay(10 * 1000); + mdelay(10); t1outp(base, T1_FASTLINK+T1_ANALYSE, 0); - udelay(5 * 1000); + mdelay(5); t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0); if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */ diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index 74905bba0..29245ddff 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -1,4 +1,4 @@ -/* $Id: icn.c,v 1.63 2000/05/06 00:52:39 kai Exp $ +/* $Id: icn.c,v 1.64 2000/10/02 17:33:43 keil Exp $ * ISDN low-level module for the ICN active ISDN-Card. * @@ -19,6 +19,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: icn.c,v $ + * Revision 1.64 2000/10/02 17:33:43 keil + * Fix NULL pointer error (thanks Luca Montecchia) + * * Revision 1.63 2000/05/06 00:52:39 kai * merged changes from kernel tree * fixed timer and net_device->name breakage @@ -251,7 +254,7 @@ #undef MAP_DEBUG static char -*revision = "$Revision: 1.63 $"; +*revision = "$Revision: 1.64 $"; static int icn_addcard(int, char *, char *); @@ -1873,7 +1876,7 @@ icn_setup(char *line) portbase = ints[1]; if (ints[0] > 1) membase = ints[2]; - if (strlen(str)) { + if (str && *str) { strcpy(sid, str); icn_id = sid; if ((p = strchr(sid, ','))) { diff --git a/drivers/isdn/isdn_cards.c b/drivers/isdn/isdn_cards.c index 63da26096..14413285f 100644 --- a/drivers/isdn/isdn_cards.c +++ b/drivers/isdn/isdn_cards.c @@ -1,4 +1,4 @@ -/* $Id: isdn_cards.c,v 1.11 2000/05/11 22:29:20 kai Exp $ +/* $Id: isdn_cards.c,v 1.13 2000/10/28 23:03:38 kai Exp $ * Linux ISDN subsystem, initialization for non-modularized drivers. * @@ -43,6 +43,9 @@ extern void kcapi_init(void); extern void capi_init(void); extern void capidrv_init(void); #endif +#if CONFIG_ISDN_DRV_ACT2000 +extern void act2000_init(void); +#endif void isdn_cards_init(void) diff --git a/drivers/isdn/isdn_common.c b/drivers/isdn/isdn_common.c index ba2c41eb5..dc117e886 100644 --- a/drivers/isdn/isdn_common.c +++ b/drivers/isdn/isdn_common.c @@ -1,4 +1,4 @@ -/* $Id: isdn_common.c,v 1.111 2000/08/20 07:40:14 keil Exp $ +/* $Id: isdn_common.c,v 1.113 2000/11/01 17:54:00 detabc Exp $ * Linux ISDN subsystem, common used functions (linklevel). * @@ -48,7 +48,7 @@ isdn_dev *dev; -static char *isdn_revision = "$Revision: 1.111 $"; +static char *isdn_revision = "$Revision: 1.113 $"; extern char *isdn_net_revision; extern char *isdn_tty_revision; diff --git a/drivers/isdn/isdn_net.c b/drivers/isdn/isdn_net.c index d33fb5135..b3b431443 100644 --- a/drivers/isdn/isdn_net.c +++ b/drivers/isdn/isdn_net.c @@ -1,4 +1,4 @@ -/* $Id: isdn_net.c,v 1.135 2000/08/10 22:52:46 kai Exp $ +/* $Id: isdn_net.c,v 1.140 2000/11/01 17:54:01 detabc Exp $ * Linux ISDN subsystem, network interfaces and related functions (linklevel). * @@ -181,7 +181,7 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp) int isdn_net_force_dial_lp(isdn_net_local *); static int isdn_net_start_xmit(struct sk_buff *, struct net_device *); -char *isdn_net_revision = "$Revision: 1.135 $"; +char *isdn_net_revision = "$Revision: 1.140 $"; /* * Code for raw-networking over ISDN @@ -190,7 +190,6 @@ char *isdn_net_revision = "$Revision: 1.135 $"; static void isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason) { - if(skb) { u_short proto = ntohs(skb->protocol); @@ -704,6 +703,7 @@ isdn_net_dial(void) i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel); if (i >= 0) { strcpy(dev->num[i], cmd.parm.setup.phone); + dev->usage[i] |= ISDN_USAGE_OUTGOING; isdn_info_update(); } printk(KERN_INFO "%s: dialing %d %s...\n", lp->name, @@ -1001,8 +1001,7 @@ void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb) /* * called from tq_immediate */ -static void -isdn_net_softint(void *private) +static void isdn_net_softint(void *private) { isdn_net_local *lp = private; struct sk_buff *skb; @@ -1086,9 +1085,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) return isdn_ppp_xmit(skb, ndev); } #endif - nd = ((isdn_net_local *) ndev->priv)->netdev; - lp = isdn_net_get_locked_lp(nd); if (!lp) { printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name); @@ -1218,6 +1215,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) buf = skb->data; isdn_dumppkt("S:", buf, skb->len, 40); #endif + if (!(lp->flags & ISDN_NET_CONNECTED)) { int chi; /* only do autodial if allowed by config */ @@ -1532,7 +1530,6 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) lp->stats.rx_packets++; lp->stats.rx_bytes += skb->len; } - skb->dev = ndev; skb->pkt_type = PACKET_HOST; skb->mac.raw = skb->data; @@ -1615,6 +1612,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) isdn_ppp_receive(lp->netdev, olp, skb); return; #endif + default: #ifdef CONFIG_ISDN_X25 /* try if there are generic sync_device receiver routines */ diff --git a/drivers/isdn/isdn_ppp.c b/drivers/isdn/isdn_ppp.c index 204995061..570ba04fa 100644 --- a/drivers/isdn/isdn_ppp.c +++ b/drivers/isdn/isdn_ppp.c @@ -1,4 +1,4 @@ -/* $Id: isdn_ppp.c,v 1.77 2000/06/12 16:46:34 keil Exp $ +/* $Id: isdn_ppp.c,v 1.82 2000/11/02 22:48:30 kai Exp $ * * Linux ISDN subsystem, functions for synchronous PPP (linklevel). * @@ -36,8 +36,6 @@ #define PPP_IPX 0x002b #endif -/* set this if you use dynamic addressing */ - /* Prototypes */ static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot); static int isdn_ppp_closewait(int slot); @@ -46,7 +44,7 @@ static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, static int isdn_ppp_if_get_unit(char *namebuf); static int isdn_ppp_set_compressor(struct ippp_struct *is,struct isdn_ppp_comp_data *); static struct sk_buff *isdn_ppp_decompress(struct sk_buff *, - struct ippp_struct *,struct ippp_struct *,int proto); + struct ippp_struct *,struct ippp_struct *,int *proto); static void isdn_ppp_receive_ccp(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb,int proto); static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto, @@ -85,7 +83,7 @@ static void isdn_ppp_mp_cleanup( isdn_net_local * lp ); static int isdn_ppp_bundle(struct ippp_struct *, int unit); #endif /* CONFIG_ISDN_MPP */ -char *isdn_ppp_revision = "$Revision: 1.77 $"; +char *isdn_ppp_revision = "$Revision: 1.82 $"; static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS]; @@ -849,15 +847,49 @@ isdn_ppp_cleanup(void) } /* + * check for address/control field and skip if allowed + * retval != 0 -> discard packet silently + */ +static int isdn_ppp_skip_ac(struct ippp_struct *is, struct sk_buff *skb) +{ + if (skb->len < 1) + return -1; + + if (skb->data[0] == 0xff) { + if (skb->len < 2) + return -1; + + if (skb->data[1] != 0x03) + return -1; + + // skip address/control (AC) field + skb_pull(skb, 2); + } else { + if (is->pppcfg & SC_REJ_COMP_AC) + // if AC compression was not negotiated, but used, discard packet + return -1; + } + return 0; +} + +/* * get the PPP protocol header and pull skb + * retval < 0 -> discard packet silently */ static int isdn_ppp_strip_proto(struct sk_buff *skb) { int proto; + + if (skb->len < 1) + return -1; + if (skb->data[0] & 0x1) { + // protocol field is compressed proto = skb->data[0]; - skb_pull(skb, 1); /* protocol ID is only 8 bit */ + skb_pull(skb, 1); } else { + if (skb->len < 2) + return -1; proto = ((int) skb->data[0] << 8) + skb->data[1]; skb_pull(skb, 2); } @@ -874,6 +906,9 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf int slot; int proto; + if (net_dev->local->master) + BUG(); // we're called with the master device always + slot = lp->ppp_slot; if (slot < 0 || slot > ISDN_MAX_CHANNELS) { printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot %d\n", lp->ppp_slot); @@ -887,54 +922,44 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf (long)is,(long)lp,lp->ppp_slot,is->unit,(int) skb->len); isdn_ppp_frame_log("receive", skb->data, skb->len, 32,is->unit,lp->ppp_slot); } - if (net_dev->local->master) { - printk(KERN_WARNING "isdn_ppp_receive: net_dev != master\n"); - net_dev = ((isdn_net_local *) net_dev->local->master->priv)->netdev; - } - if (skb->data[0] == 0xff && skb->data[1] == 0x03) - skb_pull(skb, 2); - else if (is->pppcfg & SC_REJ_COMP_AC) { - dev_kfree_skb(skb); - return; /* discard it silently */ - } - - proto = isdn_ppp_strip_proto(skb); + if (isdn_ppp_skip_ac(is, skb) < 0) { + kfree_skb(skb); + return; + } + proto = isdn_ppp_strip_proto(skb); + if (proto < 0) { + kfree_skb(skb); + return; + } + #ifdef CONFIG_ISDN_MPP - if (!(is->mpppcfg & SC_REJ_MP_PROT)) { - - if(is->compflags & SC_LINK_DECOMP_ON) { - if(proto == PPP_COMPFRAG) { - if(is->debug & 0x10) - printk(KERN_DEBUG "received single link compressed frame\n"); - skb = isdn_ppp_decompress(skb,is,NULL,proto); - if(!skb) - return; - proto = isdn_ppp_strip_proto(skb); - } - else - isdn_ppp_decompress(skb,is,NULL,proto); - } - - if (proto == PPP_MP) { - isdn_ppp_mp_receive(net_dev, lp, skb); - } - else - isdn_ppp_push_higher(net_dev, lp, skb, proto); - } else -#endif /* CONFIG_ISDN_MPP */ - isdn_ppp_push_higher(net_dev, lp, skb, proto); + if (is->compflags & SC_LINK_DECOMP_ON) { + skb = isdn_ppp_decompress(skb, is, NULL, &proto); + if (!skb) // decompression error + return; + } + + if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP + if (proto == PPP_MP) { + isdn_ppp_mp_receive(net_dev, lp, skb); + return; + } + } +#endif + isdn_ppp_push_higher(net_dev, lp, skb, proto); } /* - * push frame to higher layers + * we receive a reassembled frame, MPPP has been taken care of before. + * address/control and protocol have been stripped from the skb * note: net_dev has to be master net_dev */ static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto) { struct net_device *dev = &net_dev->dev; - struct ippp_struct *is; + struct ippp_struct *is, *mis; int slot; slot = lp->ppp_slot; @@ -944,35 +969,28 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff return; } is = ippp_table[slot]; + + if (lp->master) { // FIXME? + slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot; + if (slot < 0 || slot > ISDN_MAX_CHANNELS) { + printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot %d\n", lp->ppp_slot); + kfree_skb(skb); + return; + } + } + mis = ippp_table[slot]; + if (mis != is) { + printk(KERN_WARNING __FUNCTION__ ": BUG: is != mis %d %d %p %p\n", slot, lp->ppp_slot, mis, is); + } if (is->debug & 0x10) { printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto); isdn_ppp_frame_log("rpush", skb->data, skb->len, 32,is->unit,lp->ppp_slot); } - - if(proto == PPP_COMP) { - if(!lp->master) - skb = isdn_ppp_decompress(skb,is,is,proto); - else - skb = isdn_ppp_decompress(skb,is,ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot],proto); - - if(!skb) { - printk(KERN_DEBUG "ippp: compressed frame discarded!\n"); - return; - } - - proto = isdn_ppp_strip_proto(skb); - if (is->debug & 0x10) { - printk(KERN_DEBUG "RPostDecomp, skb %d %04x\n", (int) skb->len, proto); - isdn_ppp_frame_log("R-Decomp", skb->data, skb->len, 32,is->unit,lp->ppp_slot); - } - } - else if(is->compflags & SC_DECOMP_ON) { /* If decomp is ON */ - if(!lp->master) - isdn_ppp_decompress(skb,is,is,proto); - else - isdn_ppp_decompress(skb,is,ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot],proto); - } - + if (is->compflags & SC_DECOMP_ON) { + skb = isdn_ppp_decompress(skb, is, mis, &proto); + if (!skb) // decompression error + return; + } switch (proto) { case PPP_IPX: /* untested */ if (is->debug & 0x20) @@ -981,6 +999,13 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff skb->mac.raw = skb->data; skb->protocol = htons(ETH_P_IPX); break; + case PPP_IP: + if (is->debug & 0x20) + printk(KERN_DEBUG "isdn_ppp: IP\n"); + skb->dev = dev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IP); + break; #ifdef CONFIG_ISDN_PPP_VJ case PPP_VJC_UNCOMP: if (is->debug & 0x20) @@ -988,21 +1013,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) { printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n"); net_dev->local->stats.rx_dropped++; - dev_kfree_skb(skb); + kfree_skb(skb); return; } -#endif - case PPP_IP: - if (is->debug & 0x20) - printk(KERN_DEBUG "isdn_ppp: IP\n"); - skb->dev = dev; - skb->mac.raw = skb->data; - skb->protocol = htons(ETH_P_IP); - break; case PPP_VJC_COMP: if (is->debug & 0x20) printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n"); -#ifdef CONFIG_ISDN_PPP_VJ { struct sk_buff *skb_old = skb; int pkt_len; @@ -1011,7 +1027,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff if (!skb) { printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); net_dev->local->stats.rx_dropped++; - dev_kfree_skb(skb_old); + kfree_skb(skb_old); return; } skb->dev = dev; @@ -1020,22 +1036,17 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff skb->mac.raw = skb->data; pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb_old->len); - dev_kfree_skb(skb_old); + kfree_skb(skb_old); if (pkt_len < 0) { - dev_kfree_skb(skb); + kfree_skb(skb); lp->stats.rx_dropped++; return; } skb_trim(skb, pkt_len); skb->protocol = htons(ETH_P_IP); } -#else - printk(KERN_INFO "isdn: Ooopsa .. VJ-Compression support not compiled into isdn driver.\n"); - lp->stats.rx_dropped++; - dev_kfree_skb(skb); - return; -#endif break; +#endif case PPP_CCP: case PPP_CCPFRAG: isdn_ppp_receive_ccp(net_dev,lp,skb,proto); @@ -1061,7 +1072,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff /* * isdn_ppp_skb_push .. - * checks whether we have enough space at the beginning of the SKB + * checks whether we have enough space at the beginning of the skb * and allocs a new SKB if necessary */ static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len) @@ -1363,9 +1374,9 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) static u32 isdn_ppp_mp_get_seq( int short_seq, struct sk_buff * skb, u32 last_seq ); -struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, +static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, struct sk_buff * from, struct sk_buff * to ); -void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, +static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff * from, struct sk_buff * to ); static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); @@ -2256,8 +2267,20 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is, is->reset->lastid++; } +/* + * decompress packet + * + * if master = 0, we're trying to uncompress an per-link compressed packet, + * as opposed to an compressed reconstructed-from-MPPP packet. + * proto is updated to protocol field of uncompressed packet. + * + * retval: decompressed packet, + * same packet if uncompressed, + * NULL if decompression error + */ + static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struct *is,struct ippp_struct *master, - int proto) + int *proto) { void *stat = NULL; struct isdn_ppp_compressor *ipc = NULL; @@ -2268,84 +2291,69 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc unsigned char rsdata[IPPP_RESET_MAXDATABYTES]; if(!master) { - /* - * single link decompression - */ - if(!is->link_decompressor) { - printk(KERN_ERR "ippp: no link decompressor defined!\n"); - dev_kfree_skb(skb); - return NULL; - } - if(!is->link_decomp_stat) { - printk(KERN_DEBUG "ippp: no link decompressor data allocated\n"); - dev_kfree_skb(skb); - return NULL; - } + // per-link decompression stat = is->link_decomp_stat; ipc = is->link_decompressor; ri = is; - } - else { - /* - * 'normal' or bundle-compression - */ - if(!master->decompressor) { - printk(KERN_ERR "ippp: no decompressor defined!\n"); - dev_kfree_skb(skb); - return NULL; - } - if(!master->decomp_stat) { - printk(KERN_DEBUG "ippp: no decompressor data allocated\n"); - dev_kfree_skb(skb); - return NULL; - } + } else { stat = master->decomp_stat; ipc = master->decompressor; ri = master; } - /* - printk(KERN_DEBUG "ippp: Decompress valid!\n"); - */ + if (!ipc) { + // no decompressor -> we can't decompress. + printk(KERN_DEBUG "ippp: no decompressor defined!\n"); + return skb; + } + if (!stat) // if we have a compressor, stat has been set as well + BUG(); - if((master && proto == PPP_COMP) || (!master && proto == PPP_COMPFRAG) ) { - /* Set up reset params for the decompressor */ - memset(&rsparm, 0, sizeof(rsparm)); - rsparm.data = rsdata; - rsparm.maxdlen = IPPP_RESET_MAXDATABYTES; + if((master && *proto == PPP_COMP) || (!master && *proto == PPP_COMPFRAG) ) { + // compressed packets are compressed by their protocol type -/* !!!HACK,HACK,HACK!!! 2048 is only assumed */ - skb_out = dev_alloc_skb(2048); - len = ipc->decompress(stat,skb,skb_out, &rsparm); - dev_kfree_skb(skb); - if(len <= 0) { - /* Ok, some error */ - switch(len) { - case DECOMP_ERROR: - ri->pppcfg |= SC_DC_ERROR; - printk(KERN_INFO "ippp: decomp wants reset %s params\n", - rsparm.valid ? "with" : "without"); - - isdn_ppp_ccp_reset_trans(ri, &rsparm); - - break; - case DECOMP_FATALERROR: - ri->pppcfg |= SC_DC_FERROR; - /* Kick ipppd to recognize the error */ - isdn_ppp_ccp_kickup(ri); - break; - } - /* Did I see a leak here ? */ - dev_kfree_skb(skb_out); - return NULL; + // Set up reset params for the decompressor + memset(&rsparm, 0, sizeof(rsparm)); + rsparm.data = rsdata; + rsparm.maxdlen = IPPP_RESET_MAXDATABYTES; + + /* !!!HACK,HACK,HACK!!! 2048 is only assumed */ + skb_out = dev_alloc_skb(2048); + len = ipc->decompress(stat, skb, skb_out, &rsparm); + kfree_skb(skb); + if (len <= 0) { + switch(len) { + case DECOMP_ERROR: + ri->pppcfg |= SC_DC_ERROR; + printk(KERN_INFO "ippp: decomp wants reset %s params\n", + rsparm.valid ? "with" : "without"); + + isdn_ppp_ccp_reset_trans(ri, &rsparm); + break; + case DECOMP_FATALERROR: + ri->pppcfg |= SC_DC_FERROR; + /* Kick ipppd to recognize the error */ + isdn_ppp_ccp_kickup(ri); + break; + } + kfree_skb(skb_out); + return NULL; + } + + if (isdn_ppp_skip_ac(ri, skb) < 0) { + kfree_skb(skb); + return NULL; + } + *proto = isdn_ppp_strip_proto(skb); + if (*proto < 0) { + kfree_skb(skb); + return NULL; } return skb_out; - } - else { - /* - printk(KERN_DEBUG "isdn_ppp: [%d] Calling incomp with this frame!\n",is->unit); - */ - ipc->incomp(stat,skb,proto); + } else { + // uncompressed packets are fed through the decompressor to + // update the decompressor state + ipc->incomp(stat, skb, *proto); return skb; } } diff --git a/drivers/isdn/sc/debug.c b/drivers/isdn/sc/debug.c index 7d24ed731..d032508ac 100644 --- a/drivers/isdn/sc/debug.c +++ b/drivers/isdn/sc/debug.c @@ -1,5 +1,5 @@ /* - * $Id: debug.c,v 1.3 1997/10/01 09:22:20 fritz Exp $ + * $Id: debug.c,v 1.4 2000/10/28 23:03:40 kai Exp $ * Copyright (C) 1996 SpellCaster Telecommunications Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 9712ddbae..598e5d601 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -1296,6 +1296,33 @@ void pmu_blink(int n) * Put the powerbook to sleep. */ +static u32 save_via[8]; +static void save_via_state(void) +{ + save_via[0] = in_8(&via[ANH]); + save_via[1] = in_8(&via[DIRA]); + save_via[2] = in_8(&via[B]); + save_via[3] = in_8(&via[DIRB]); + save_via[4] = in_8(&via[PCR]); + save_via[5] = in_8(&via[ACR]); + save_via[6] = in_8(&via[T1CL]); + save_via[7] = in_8(&via[T1CH]); +} +static void restore_via_state(void) +{ + out_8(&via[ANH], save_via[0]); + out_8(&via[DIRA], save_via[1]); + out_8(&via[B], save_via[2]); + out_8(&via[DIRB], save_via[3]); + out_8(&via[PCR], save_via[4]); + out_8(&via[ACR], save_via[5]); + out_8(&via[T1CL], save_via[6]); + out_8(&via[T1CH], save_via[7]); + out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */ + out_8(&via[IFR], 0x7f); /* clear IFR */ + out_8(&via[IER], IER_SET | SR_INT | CB1_INT); +} + #define FEATURE_CTRL(base) ((unsigned int *)(base + 0x38)) #define GRACKLE_PM (1<<7) #define GRACKLE_DOZE (1<<5) @@ -1304,11 +1331,11 @@ void pmu_blink(int n) int __openfirmware powerbook_sleep_G3(void) { - int ret; unsigned long save_l2cr; unsigned long wait; unsigned short pmcr1; struct adb_request req; + int ret, timeout; /* Notify device drivers */ ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT); @@ -1333,24 +1360,54 @@ int __openfirmware powerbook_sleep_G3(void) } /* Give the disks a little time to actually finish writing */ - for (wait = jiffies + (HZ/4); time_before(jiffies, wait); ) + for (wait = jiffies + (HZ/2); time_before(jiffies, wait); ) mb(); + /* Wait for completion of async backlight requests */ + while (!bright_req_1.complete || !bright_req_2.complete || !bright_req_3.complete) + pmu_poll(); + + /* Turn off various things. Darwin does some retry tests here... */ + pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE); + while (!req.complete) + pmu_poll(); + pmu_request(&req, NULL, 2, PMU_POWER_CTRL, + PMU_POW_OFF|PMU_POW_BACKLIGHT|PMU_POW_IRLED|PMU_POW_MEDIABAY); + while (!req.complete) + pmu_poll(); + /* Disable all interrupts except pmu */ sleep_save_intrs(vias->intrs[0].line); + /* Make sure the PMU is idle */ + while (pmu_state != idle) + pmu_poll(); + /* Make sure the decrementer won't interrupt us */ asm volatile("mtdec %0" : : "r" (0x7fffffff)); - - feature_prepare_for_sleep(); + /* Make sure any pending DEC interrupt occuring while we did + * the above didn't re-enable the DEC */ + mb(); + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + + /* Giveup the FPU */ + if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0) + giveup_fpu(current); /* For 750, save backside cache setting and disable it */ save_l2cr = _get_L2CR(); /* (returns 0 if not 750) */ if (save_l2cr) _set_L2CR(0); - if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0) - giveup_fpu(current); + /* Ask the PMU to put us to sleep */ + pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); + while (!req.complete) + pmu_poll(); + + /* The VIA is supposed not to be restored correctly*/ + save_via_state(); + /* We shut down some HW */ + feature_prepare_for_sleep(); grackle_pcibios_read_config_word(0,0,0x70,&pmcr1); /* Apparently, MacOS uses NAP mode for Grackle ??? */ @@ -1358,15 +1415,6 @@ int __openfirmware powerbook_sleep_G3(void) pmcr1 |= GRACKLE_PM|GRACKLE_NAP; grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1); - /* Ask the PMU to put us to sleep */ - pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); - while (!req.complete) - pmu_poll(); - - cli(); - while (pmu_state != idle) - pmu_poll(); - /* Call low-level ASM sleep handler */ low_sleep_handler(); @@ -1374,33 +1422,54 @@ int __openfirmware powerbook_sleep_G3(void) grackle_pcibios_read_config_word(0, 0, 0x70, &pmcr1); pmcr1 &= ~(GRACKLE_PM|GRACKLE_DOZE|GRACKLE_SLEEP|GRACKLE_NAP); grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1); - - /* Make sure the PMU is idle */ - while (pmu_state != idle) - pmu_poll(); - - sti(); - + + /* Restore things */ feature_wake_up(); - - /* The PGD is only a placeholder until Dan finds a way to make - * this work properly on the 8xx processors. It is only used on - * 8xx processors, it is ignored here. - */ - set_context(current->mm->context, current->mm->pgd); - + restore_via_state(); + /* Restore L2 cache */ if (save_l2cr) - _set_L2CR(save_l2cr | 0x200000); /* set invalidate bit */ + _set_L2CR(save_l2cr); + + /* Restore userland MMU context */ + set_context(current->mm->context, current->mm->pgd); - /* reenable interrupts */ - sleep_restore_intrs(); + /* Re-enable DEC interrupts and kick DEC */ + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + sti(); + asm volatile("mtdec %0" : : "r" (0x10000000)); - /* Tell PMU we are ready */ - pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2); + /* Power things up */ + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc); while (!req.complete) pmu_poll(); - + pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, + PMU_POW0_ON|PMU_POW0_HARD_DRIVE); + while (!req.complete) + pmu_poll(); + pmu_request(&req, NULL, 2, PMU_POWER_CTRL, + PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY); + while (!req.complete) + pmu_poll(); + + /* ack all pending interrupts */ + timeout = 100000; + interrupt_data[0] = 1; + while (interrupt_data[0] || pmu_state != idle) { + if (--timeout < 0) + break; + if (pmu_state == idle) + adb_int_pending = 1; + via_pmu_interrupt(0, 0, 0); + udelay(10); + } + + /* reenable interrupt controller */ + sleep_restore_intrs(); + + /* Leave some time for HW to settle down */ + mdelay(100); + /* Notify drivers */ mdelay(10); broadcast_wake(); diff --git a/drivers/md/md.c b/drivers/md/md.c index a20e2d9d0..ad57901b7 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 79687ebba..e893ea978 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c @@ -432,11 +432,21 @@ static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try) ucpia->sbuf[1].urb = NULL; } + if (ucpia->sbuf[1].data) { + kfree(ucpia->sbuf[1].data); + ucpia->sbuf[1].data = NULL; + } + if (ucpia->sbuf[0].urb) { usb_unlink_urb(ucpia->sbuf[0].urb); usb_free_urb(ucpia->sbuf[0].urb); ucpia->sbuf[0].urb = NULL; } + + if (ucpia->sbuf[0].data) { + kfree(ucpia->sbuf[0].data); + ucpia->sbuf[0].data = NULL; + } } static int cpia_usb_close(void *privdata) @@ -461,7 +471,8 @@ int cpia_usb_init(void) /* Probing and initializing */ -static void *cpia_probe(struct usb_device *udev, unsigned int ifnum) +static void *cpia_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_interface_descriptor *interface; struct usb_cpia *ucpia; @@ -474,13 +485,6 @@ static void *cpia_probe(struct usb_device *udev, unsigned int ifnum) interface = &udev->actconfig->interface[ifnum].altsetting[0]; - /* Is it a CPiA? */ - if (udev->descriptor.idVendor != 0x0553) - return NULL; - if (udev->descriptor.idProduct != 0x0002) - return NULL; - - /* We found a CPiA */ printk(KERN_INFO "USB CPiA camera found\n"); ucpia = kmalloc(sizeof(*ucpia), GFP_KERNEL); @@ -552,11 +556,18 @@ fail_alloc_0: static void cpia_disconnect(struct usb_device *dev, void *ptr); +static struct usb_device_id cpia_id_table [] = { + { idVendor: 0x0553, idProduct: 0x0002 }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, cpia_id_table); + static struct usb_driver cpia_driver = { - "cpia", - cpia_probe, - cpia_disconnect, - { NULL, NULL } + name: "cpia", + probe: cpia_probe, + disconnect: cpia_disconnect, + id_table: cpia_id_table, }; /* don't use dev, it may be NULL! (see usb_cpia_cleanup) */ diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 76602ac54..ca71e1590 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -398,6 +398,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) static int el_open(struct net_device *dev) { + int retval; int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; @@ -407,9 +408,9 @@ static int el_open(struct net_device *dev) if (el_debug > 2) printk("%s: Doing el_open()...", dev->name); - if (request_irq(dev->irq, &el_interrupt, 0, "3c501", dev)) { + if ((retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev))) { MOD_DEC_USE_COUNT; - return -EAGAIN; + return retval; } spin_lock_irqsave(&lp->lock, flags); diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index bdc1c53da..7975d3c58 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -101,8 +101,6 @@ el2_probe(struct net_device *dev) break; if (base_bits != 1) continue; - if (check_region(netcard_portlist[i], EL2_IO_EXTENT)) - continue; if (el2_probe1(dev, netcard_portlist[i]) == 0) return 0; } @@ -126,13 +124,9 @@ el2_pio_probe(struct net_device *dev) else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; - for (i = 0; netcard_portlist[i]; i++) { - int ioaddr = netcard_portlist[i]; - if (check_region(ioaddr, EL2_IO_EXTENT)) - continue; - if (el2_probe1(dev, ioaddr) == 0) + for (i = 0; netcard_portlist[i]; i++) + if (el2_probe1(dev, netcard_portlist[i]) == 0) return 0; - } return -ENODEV; } @@ -143,14 +137,18 @@ el2_pio_probe(struct net_device *dev) int __init el2_probe1(struct net_device *dev, int ioaddr) { - int i, iobase_reg, membase_reg, saved_406, wordlength; - static unsigned version_printed = 0; + int i, iobase_reg, membase_reg, saved_406, wordlength, retval; + static unsigned version_printed; unsigned long vendor_id; + if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name)) + return -EBUSY; + /* Reset and/or avoid any lurking NE2000 */ if (inb(ioaddr + 0x408) == 0xff) { mdelay(1); - return -ENODEV; + retval = -ENODEV; + goto out; } /* We verify that it's a 3C503 board by checking the first three octets @@ -160,7 +158,8 @@ el2_probe1(struct net_device *dev, int ioaddr) /* ASIC location registers should be 0 or have only a single bit set. */ if ( (iobase_reg & (iobase_reg - 1)) || (membase_reg & (membase_reg - 1))) { - return -ENODEV; + retval = -ENODEV; + goto out; } saved_406 = inb_p(ioaddr + 0x406); outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */ @@ -172,7 +171,8 @@ el2_probe1(struct net_device *dev, int ioaddr) if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) { /* Restore the register we frobbed. */ outb(saved_406, ioaddr + 0x406); - return -ENODEV; + retval = -ENODEV; + goto out; } if (ei_debug && version_printed++ == 0) @@ -182,8 +182,9 @@ el2_probe1(struct net_device *dev, int ioaddr) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("3c503: unable to allocate memory for dev->priv.\n"); - return -ENOMEM; - } + retval = -ENOMEM; + goto out; + } printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr); @@ -282,8 +283,6 @@ el2_probe1(struct net_device *dev, int ioaddr) ei_status.block_input = &el2_block_input; ei_status.block_output = &el2_block_output; - request_region(ioaddr, EL2_IO_EXTENT, ei_status.name); - if (dev->irq == 2) dev->irq = 9; else if (dev->irq > 5 && dev->irq != 9) { @@ -310,6 +309,9 @@ el2_probe1(struct net_device *dev, int ioaddr) dev->name, ei_status.name, (wordlength+1)<<3); } return 0; +out: + release_region(ioaddr, EL2_IO_EXTENT); + return retval; } static int diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 22485f1d8..73318d229 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -854,6 +854,7 @@ static void elp_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) static int elp_open(struct net_device *dev) { elp_device *adapter; + int retval; adapter = dev->priv; @@ -893,16 +894,21 @@ static int elp_open(struct net_device *dev) /* * install our interrupt service routine */ - if (request_irq(dev->irq, &elp_interrupt, 0, "3c505", dev)) { - return -EAGAIN; + if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) { + printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq); + return retval; } - if (request_dma(dev->dma, "3c505")) { - printk("%s: could not allocate DMA channel\n", dev->name); - return -EAGAIN; + if ((retval = request_dma(dev->dma, dev->name))) { + free_irq(dev->irq, dev); + printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma); + return retval; } adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE); if (!adapter->dma_buffer) { - printk("Could not allocate DMA buffer\n"); + printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name); + free_dma(dev->dma); + free_irq(dev->irq, dev); + return -ENOMEM; } adapter->dmaing = 0; @@ -915,7 +921,7 @@ static int elp_open(struct net_device *dev) * configure adapter memory: we need 10 multicast addresses, default==0 */ if (elp_debug >= 3) - printk("%s: sending 3c505 memory configuration command\n", dev->name); + printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; adapter->tx_pcb.data.memconf.cmd_q = 10; adapter->tx_pcb.data.memconf.rcv_q = 20; @@ -1412,6 +1418,7 @@ int __init elplus_probe(struct net_device *dev) { elp_device *adapter; int i, tries, tries1, timeout, okay; + unsigned long cookie = 0; /* * setup adapter structure @@ -1479,21 +1486,21 @@ int __init elplus_probe(struct net_device *dev) */ adapter->tx_pcb.command = CMD_STATION_ADDRESS; adapter->tx_pcb.length = 0; - autoirq_setup(0); + cookie = probe_irq_on(); if (!send_pcb(dev, &adapter->tx_pcb)) { printk("%s: could not send first PCB\n", dev->name); - autoirq_report(0); + probe_irq_off(cookie); continue; } if (!receive_pcb(dev, &adapter->rx_pcb)) { printk("%s: could not read first PCB\n", dev->name); - autoirq_report(0); + probe_irq_off(cookie); continue; } if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) || (adapter->rx_pcb.length != 6)) { printk("%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length); - autoirq_report(0); + probe_irq_off(cookie); continue; } goto okay; @@ -1511,13 +1518,13 @@ int __init elplus_probe(struct net_device *dev) okay: if (dev->irq) { /* Is there a preset IRQ? */ - int rpt = autoirq_report(0); + int rpt = probe_irq_off(cookie); if (dev->irq != rpt) { printk("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt); } - /* if dev->irq == autoirq_report(0), all is well */ + /* if dev->irq == probe_irq_off(cookie), all is well */ } else /* No preset IRQ; just use what we can detect */ - dev->irq = autoirq_report(0); + dev->irq = probe_irq_off(cookie); switch (dev->irq) { /* Legal, sane? */ case 0: printk("%s: IRQ probe failed: check 3c505 jumpers.\n", @@ -1527,7 +1534,7 @@ int __init elplus_probe(struct net_device *dev) case 6: case 8: case 13: - printk("%s: Impossible IRQ %d reported by autoirq_report().\n", + printk("%s: Impossible IRQ %d reported by probe_irq_off().\n", dev->name, dev->irq); return -ENODEV; } @@ -1607,17 +1614,10 @@ int __init elplus_probe(struct net_device *dev) } #ifdef MODULE -static struct net_device dev_3c505[ELP_MAX_CARDS] = -{ - { "", /* device name is inserted by net_init.c */ - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, elplus_probe}, -}; - -static int io[ELP_MAX_CARDS] = { 0, }; -static int irq[ELP_MAX_CARDS] = { 0, }; -static int dma[ELP_MAX_CARDS] = { 0, }; +static struct net_device dev_3c505[ELP_MAX_CARDS]; +static int io[ELP_MAX_CARDS]; +static int irq[ELP_MAX_CARDS]; +static int dma[ELP_MAX_CARDS]; MODULE_PARM(io, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i"); MODULE_PARM(dma, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i"); @@ -1630,6 +1630,7 @@ int init_module(void) struct net_device *dev = &dev_3c505[this_dev]; dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; + dev->init = elplus_probe; if (dma[this_dev]) { dev->dma = dma[this_dev]; } else { diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 0b2e682de..c62338707 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -60,21 +60,21 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then fi bool ' 3COM cards' CONFIG_NET_VENDOR_3COM if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then - tristate ' 3c501 "EtherLink" support' CONFIG_EL1 - tristate ' 3c503 "EtherLink II" support' CONFIG_EL2 - tristate ' 3c505 "EtherLink Plus" support' CONFIG_ELPLUS - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate ' 3c507 "EtherLink 16" support (EXPERIMENTAL)' CONFIG_EL16 + dep_tristate ' 3c501 "EtherLink" support' CONFIG_EL1 $CONFIG_ISA + dep_tristate ' 3c503 "EtherLink II" support' CONFIG_EL2 $CONFIG_ISA + dep_tristate ' 3c505 "EtherLink Plus" support' CONFIG_ELPLUS $CONFIG_ISA + dep_tristate ' 3c507 "EtherLink 16" support (EXPERIMENTAL)' CONFIG_EL16 $CONFIG_ISA $CONFIG_EXPERIMENTAL + if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" -o "$CONFIG_MCA" = "y" ]; then + tristate ' 3c509/3c529 (MCA)/3c579 "EtherLink III" support' CONFIG_EL3 fi - tristate ' 3c509/3c529 (MCA)/3c579 "EtherLink III" support' CONFIG_EL3 - tristate ' 3c515 ISA "Fast EtherLink"' CONFIG_3C515 - if [ "$CONFIG_MCA" = "y" ]; then - tristate ' 3c523 "EtherLink/MC" support' CONFIG_ELMC - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate ' 3c527 "EtherLink/MC 32" support (EXPERIMENTAL)' CONFIG_ELMC_II - fi + if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" ]; then + tristate ' 3c515 ISA "Fast EtherLink"' CONFIG_3C515 + fi + dep_tristate ' 3c523 "EtherLink/MC" support' CONFIG_ELMC $CONFIG_MCA + dep_tristate ' 3c527 "EtherLink/MC 32" support (EXPERIMENTAL)' CONFIG_ELMC_II $CONFIG_MCA $CONFIG_EXPERIMENTAL + if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then + tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX fi - tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX fi tristate ' AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE bool ' Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC @@ -84,22 +84,22 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then tristate ' SMC Ultra MCA support' CONFIG_ULTRAMCA fi tristate ' SMC Ultra support' CONFIG_ULTRA - tristate ' SMC Ultra32 EISA support' CONFIG_ULTRA32 + dep_tristate ' SMC Ultra32 EISA support' CONFIG_ULTRA32 $CONFIG_EISA tristate ' SMC 9194 support' CONFIG_SMC9194 - fi - bool ' Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL - if [ "$CONFIG_NET_VENDOR_RACAL" = "y" ]; then - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate ' NI5010 support (EXPERIMENTAL)' CONFIG_NI5010 - fi - tristate ' NI5210 support' CONFIG_NI52 - tristate ' NI6510 support' CONFIG_NI65 - fi + fi + bool ' Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL + if [ "$CONFIG_NET_VENDOR_RACAL" = "y" ]; then + dep_tristate ' NI5010 support (EXPERIMENTAL)' CONFIG_NI5010 $CONFIG_EXPERIMENTAL + tristate ' NI5210 support' CONFIG_NI52 + tristate ' NI6510 support' CONFIG_NI65 + fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate ' AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700 fi tristate ' DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA - tristate ' HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 + if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" -o "$CONFIG_PCI" = "y" ]; then + tristate ' HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 + fi bool ' Other ISA cards' CONFIG_NET_ISA if [ "$CONFIG_NET_ISA" = "y" ]; then tristate ' Cabletron E21xx support' CONFIG_E2100 diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 511e1d3a3..f73af0828 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -56,12 +56,9 @@ #include #include -#undef ETHTOOL #undef INDEX_DEBUG -#ifdef ETHTOOL #include -#endif #include #include @@ -2427,7 +2424,6 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu) static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { -#ifdef ETHTOOL struct ace_private *ap = dev->priv; struct ace_regs *regs = ap->regs; struct ethtool_cmd ecmd; @@ -2453,7 +2449,7 @@ static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd))) return -EFAULT; - if (ecmd.cmd == ETH_GSET) { + if (ecmd.cmd == ETHTOOL_GSET) { ecmd.supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | @@ -2486,17 +2482,18 @@ static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) else ecmd.autoneg = AUTONEG_DISABLE; +#if 0 ecmd.trace = readl(®s->TuneTrace); - ecmd.txcoal = readl(®s->TuneTxCoalTicks); ecmd.rxcoal = readl(®s->TuneRxCoalTicks); +#endif ecmd.maxtxpkt = readl(®s->TuneMaxTxDesc); ecmd.maxrxpkt = readl(®s->TuneMaxRxDesc); if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd))) return -EFAULT; return 0; - } else if (ecmd.cmd == ETH_SSET) { + } else if (ecmd.cmd == ETHTOOL_SSET) { if(!capable(CAP_NET_ADMIN)) return -EPERM; @@ -2554,7 +2551,6 @@ static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } return 0; } -#endif return -EOPNOTSUPP; } diff --git a/drivers/net/bagetlance.c b/drivers/net/bagetlance.c index eeb6b77c5..1de818823 100644 --- a/drivers/net/bagetlance.c +++ b/drivers/net/bagetlance.c @@ -477,7 +477,7 @@ int __init bagetlance_probe( struct net_device *dev ) if (found) /* Assume there's only one board possible... That seems true, since * the Riebl/PAM board's address cannot be changed. */ - return( ENODEV ); + return( -ENODEV ); for( i = 0; i < N_LANCE_ADDR; ++i ) { if (lance_probe1( dev, &lance_addr_list[i] )) { @@ -486,7 +486,7 @@ int __init bagetlance_probe( struct net_device *dev ) } } - return( ENODEV ); + return( -ENODEV ); } diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 9efd94827..2b9b71d88 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1371,9 +1371,9 @@ static void __init bmac_probe1(struct device_node *bmac, int is_bmac_plus) return; err_out_irq1: - free_irq(bmac->intrs[1].line); + free_irq(bmac->intrs[1].line, dev); err_out_irq0: - free_irq(dev->irq); + free_irq(dev->irq, dev); err_out_iounmap_rx: iounmap((void *)bp->rx_dma); err_out_iounmap_tx: diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index d6e9759bf..c8cab2062 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -451,20 +451,14 @@ int __init eth16i_probe(struct net_device *dev) return -ENXIO; /* Seek card from the ISA io address space */ - for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++) { - if(check_region(ioaddr, ETH16I_IO_EXTENT)) - continue; + for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++) if(eth16i_probe1(dev, ioaddr) == 0) return 0; - } /* Seek card from the EISA io address space */ - for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) { - if(check_region(ioaddr, ETH16I_IO_EXTENT)) - continue; + for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) if(eth16i_probe1(dev, ioaddr) == 0) return 0; - } return -ENODEV; } @@ -472,10 +466,15 @@ int __init eth16i_probe(struct net_device *dev) static int __init eth16i_probe1(struct net_device *dev, int ioaddr) { struct eth16i_local *lp; - - static unsigned version_printed = 0; + static unsigned version_printed; + int retval; + boot = 1; /* To inform initilization that we are in boot probe */ + /* Let's grab the region */ + if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name)) + return -EBUSY; + /* The MB86985 chip has on register which holds information in which io address the chip lies. First read this register and compare @@ -485,14 +484,18 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) if(ioaddr < 0x1000) { if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] - != ioaddr) - return -ENODEV; + != ioaddr) { + retval = -ENODEV; + goto out; + } } /* Now we will go a bit deeper and try to find the chip's signature */ - if(eth16i_check_signature(ioaddr) != 0) - return -ENODEV; + if(eth16i_check_signature(ioaddr) != 0) { + retval = -ENODEV; + goto out; + } /* Now it seems that we have found a ethernet chip in this particular @@ -516,17 +519,15 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) /* Try to obtain interrupt vector */ - if (request_irq(dev->irq, (void *)ð16i_interrupt, 0, "eth16i", dev)) { + if ((retval = request_irq(dev->irq, (void *)ð16i_interrupt, 0, dev->name, dev))) { printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n", dev->name, cardname, ioaddr, dev->irq); - return -EAGAIN; + goto out; } printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ", dev->name, cardname, ioaddr, dev->irq); - /* Let's grab the region */ - request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i"); /* Now we will have to lock the chip's io address */ eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); @@ -540,8 +541,11 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) /* Initialize the device structure */ if(dev->priv == NULL) { dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL); - if(dev->priv == NULL) - return -ENOMEM; + if(dev->priv == NULL) { + free_irq(dev->irq, dev); + retval = -ENOMEM; + goto out; + } } memset(dev->priv, 0, sizeof(struct eth16i_local)); @@ -562,6 +566,9 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) boot = 0; return 0; +out: + release_region(ioaddr, ETH16I_IO_EXTENT); + return retval; } diff --git a/drivers/net/gmac.c b/drivers/net/gmac.c index 81a9408df..f4c526044 100644 --- a/drivers/net/gmac.c +++ b/drivers/net/gmac.c @@ -343,7 +343,7 @@ mii_lookup_and_reset(struct gmac *gm) mdelay(10); /* Find the PHY */ - for(i=31; i>0; --i) { + for(i=0; i<=31; i++) { mii_control = mii_read(gm, i, MII_CR); mii_status = mii_read(gm, i, MII_SR); if (mii_control != -1 && mii_status != -1 && @@ -351,7 +351,7 @@ mii_lookup_and_reset(struct gmac *gm) break; } gm->phy_addr = i; - if (gm->phy_addr < 0) + if (gm->phy_addr > 31) return 0; /* Reset it */ @@ -972,10 +972,11 @@ gmac_tx_timeout(struct net_device *dev) { struct gmac *gm = (struct gmac *) dev->priv; int i, timeout; - + unsigned long flags; + printk (KERN_ERR "%s: transmit timed out, resetting\n", dev->name); - spin_lock_irq(&gm->lock); + spin_lock_irqsave(&gm->lock, flags); /* Stop chip */ gmac_stop_dma(gm); @@ -1011,7 +1012,7 @@ gmac_tx_timeout(struct net_device *dev) /* Restart chip */ gmac_start_dma(gm); - spin_unlock_irq(&gm->lock); + spin_unlock_irqrestore(&gm->lock, flags); netif_wake_queue(dev); } @@ -1024,9 +1025,10 @@ gmac_xmit_start(struct sk_buff *skb, struct net_device *dev) { struct gmac *gm = (struct gmac *) dev->priv; volatile struct gmac_dma_desc *dp; + unsigned long flags; int i; - spin_lock_irq(&gm->lock); + spin_lock_irqsave(&gm->lock, flags); i = gm->next_tx; if (gm->tx_buff[i] != 0) { @@ -1036,7 +1038,7 @@ gmac_xmit_start(struct sk_buff *skb, struct net_device *dev) * Can this ever happen in 2.4 ? */ netif_stop_queue(dev); - spin_unlock_irq(&gm->lock); + spin_unlock_irqrestore(&gm->lock, flags); return 1; } gm->next_tx = (i + 1) & (NTX - 1); @@ -1058,7 +1060,7 @@ gmac_xmit_start(struct sk_buff *skb, struct net_device *dev) if (gm->tx_buff[gm->next_tx] != 0) netif_stop_queue(dev); - spin_unlock_irq(&gm->lock); + spin_unlock_irqrestore(&gm->lock, flags); dev->trans_start = jiffies; @@ -1078,9 +1080,12 @@ gmac_tx_cleanup(struct net_device *dev, int force_cleanup) int gone, i; i = gm->tx_gone; - gone = GM_IN(GM_TX_COMP); - - while (force_cleanup || i != gone) { + + /* Note: If i==gone, we empty the entire ring. This works because + * if the ring was empty, we wouldn't have received the interrupt + */ + do { + gone = GM_IN(GM_TX_COMP); skb = gm->tx_buff[i]; if (skb == NULL) break; @@ -1095,14 +1100,12 @@ gmac_tx_cleanup(struct net_device *dev, int force_cleanup) dev_kfree_skb_irq(skb); if (++i >= NTX) i = 0; - } + } while (force_cleanup || i != gone); gm->tx_gone = i; if (!force_cleanup && netif_queue_stopped(dev) && (gm->tx_buff[gm->next_tx] == 0)) netif_wake_queue(dev); - - spin_unlock(&gm->lock); } /* @@ -1373,6 +1376,8 @@ gmac_probe1(struct device_node *gmac) dev->irq = gmac->intrs[0].line; gm->dev = dev; gm->of_node = gmac; + + spin_lock_init(&gm->lock); if (pci_device_loc(gmac, &gm->pci_bus, &gm->pci_devfn)) { gm->pci_bus = gm->pci_devfn = 0xff; diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 48c01f0b3..68fb88261 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -141,10 +141,10 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) unsigned char checksum = 0; const char *name = "HP-PC-LAN+"; int mem_start; - static unsigned version_printed = 0; + static unsigned version_printed; - if (!request_region(ioaddr, HP_IO_EXTENT, "hp-plus")) - return -ENODEV; + if (!request_region(ioaddr, HP_IO_EXTENT, dev->name)) + return -EBUSY; /* Check for the HP+ signature, 50 48 0x 53. */ if (inw(ioaddr + HP_ID) != 0x4850 @@ -249,9 +249,10 @@ hpp_open(struct net_device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg; + int retval; - if (request_irq(dev->irq, ei_interrupt, 0, "hp-plus", dev)) { - return -EAGAIN; + if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) { + return retval; } /* Reset the 8390 and HP chip. */ diff --git a/drivers/net/hp.c b/drivers/net/hp.c index bd3ef30dd..26b92b8c6 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -101,9 +101,9 @@ int __init hp_probe1(struct net_device *dev, int ioaddr) { int i, retval, board_id, wordmode; const char *name; - static unsigned version_printed = 0; + static unsigned version_printed; - if (!request_region(ioaddr, HP_IO_EXTENT, "hp")) + if (!request_region(ioaddr, HP_IO_EXTENT, dev->name)) return -ENODEV; /* Check for the HP physical address, 08 00 09 xx xx xx. */ @@ -155,7 +155,7 @@ int __init hp_probe1(struct net_device *dev, int ioaddr) outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE); outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE); if (irq == probe_irq_off(cookie) /* It's a good IRQ line! */ - && request_irq (irq, ei_interrupt, 0, "hp", dev) == 0) { + && request_irq (irq, ei_interrupt, 0, dev->name, dev) == 0) { printk(" selecting IRQ %d.\n", irq); dev->irq = *irqp; break; @@ -170,9 +170,8 @@ int __init hp_probe1(struct net_device *dev, int ioaddr) } else { if (dev->irq == 2) dev->irq = 9; - if (request_irq(dev->irq, ei_interrupt, 0, "hp", dev)) { + if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) { printk (" unable to get IRQ %d.\n", dev->irq); - retval = -EBUSY; goto out1; } } diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 776169ae9..8f05bb5a0 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -857,7 +857,7 @@ static int ibmlana_open(struct IBMLANA_NETDEV *dev) result = request_irq(priv->realirq, irq_handler, - SA_SHIRQ | SA_SAMPLE_RANDOM, "ibm_lana", dev); + SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); if (result != 0) { printk("%s: failed to register irq %d\n", dev->name, dev->irq); @@ -1046,7 +1046,7 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev) /* can't work without an MCA bus ;-) */ if (MCA_bus == 0) - return ENODEV; + return -ENODEV; /* start address of 1 --> forced detection */ @@ -1101,19 +1101,18 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev) /* nothing found ? */ if (slot == -1) - return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV; + return ((base != 0) || (irq != 0)) ? -ENXIO : -ENODEV; /* announce success */ printk("%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1); /* try to obtain I/O range */ - if (check_region(iobase, IBM_LANA_IORANGE) < 0) { - printk("cannot allocate I/O range at %#x!\n", iobase); + if (!request_region(iobase, IBM_LANA_IORANGE, dev->name)) { + printk("%s: cannot allocate I/O range at %#x!\n", dev->name, iobase); startslot = slot + 1; - return 0; + return -EBUSY; } - request_region(iobase, IBM_LANA_IORANGE, "ibm_lana"); /* make procfs entries */ @@ -1128,6 +1127,10 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev) priv = dev->priv = (ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL); + if (!priv) { + release_region(iobase, IBM_LANA_IORANGE); + return -ENOMEM; + } priv->slot = slot; priv->realirq = irq; priv->medium = medium; @@ -1189,24 +1192,11 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev) #define DEVMAX 5 -#if (LINUX_VERSION_CODE >= 0x020363) -static struct IBMLANA_NETDEV moddevs[DEVMAX] = - { {" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe} +static struct IBMLANA_NETDEV moddevs[DEVMAX] = { + { init: ibmlana_probe }, { init: ibmlana_probe }, + { init: ibmlana_probe }, { init: ibmlana_probe }, + { init: ibmlana_probe } }; -#else -static char NameSpace[8 * DEVMAX]; -static struct IBMLANA_NETDEV moddevs[DEVMAX] = - { {NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{NameSpace + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe}, -{NameSpace + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ibmlana_probe} -}; -#endif int irq = 0; int io = 0; diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 03944f066..70080e005 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -629,8 +629,16 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* Check if we need to change the speed */ - if ((speed = irda_get_speed(skb)) != self->io.speed) - self->new_speed = speed; + if ((speed = irda_get_speed(skb)) != self->io.speed) { + /* Check for empty frame */ + if (!skb->len) { + irda_task_execute(self, __irport_change_speed, + irport_change_speed_complete, + NULL, (void *) speed); + return 0; + } else + self->new_speed = speed; + } spin_lock_irqsave(&self->lock, flags); @@ -999,7 +1007,9 @@ static struct net_device_stats *irport_net_get_stats(struct net_device *dev) #ifdef MODULE MODULE_PARM(io, "1-4i"); +MODULE_PARM_DESC(io, "Base I/O adresses"); MODULE_PARM(irq, "1-4i"); +MODULE_PARM_DESC(irq, "IRQ lines"); MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode"); diff --git a/drivers/net/irda/irtty.c b/drivers/net/irda/irtty.c index 1fd3acda9..614c5e200 100644 --- a/drivers/net/irda/irtty.c +++ b/drivers/net/irda/irtty.c @@ -176,7 +176,7 @@ static int irtty_open(struct tty_struct *tty) MINOR(tty->device) - tty->driver.minor_start + tty->driver.name_base); - hashbin_insert(irtty, (queue_t *) self, (int) self, NULL); + hashbin_insert(irtty, (irda_queue_t *) self, (int) self, NULL); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); @@ -233,8 +233,6 @@ static int irtty_open(struct tty_struct *tty) ERROR(__FUNCTION__ "(), dev_alloc() failed!\n"); return -ENOMEM; } - /* dev_alloc doesn't clear the struct */ - memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*)); dev->priv = (void *) self; self->netdev = dev; @@ -640,8 +638,16 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* Check if we need to change the speed */ - if ((speed = irda_get_speed(skb)) != self->io.speed) - self->new_speed = speed; + if ((speed = irda_get_speed(skb)) != self->io.speed) { + /* Check for empty frame */ + if (!skb->len) { + irda_task_execute(self, irtty_change_speed, + irtty_change_speed_complete, + NULL, (void *) speed); + return 0; + } else + self->new_speed = speed; + } /* Init tx buffer*/ self->tx_buff.data = self->tx_buff.head; @@ -1029,6 +1035,7 @@ MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("IrDA TTY device driver"); MODULE_PARM(qos_mtt_bits, "i"); +MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); /* * Function init_module (void) diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 834300c28..ba79f94ba 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -1076,9 +1076,15 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* Check if we need to change the speed */ - if ((speed = irda_get_speed(skb)) != self->io.speed) - self->new_speed = speed; - + if ((speed = irda_get_speed(skb)) != self->io.speed) { + /* Check for empty frame */ + if (!skb->len) { + nsc_ircc_change_speed(self, speed); + return 0; + } else + self->new_speed = speed; + } + spin_lock_irqsave(&self->lock, flags); /* Save current bank */ @@ -1120,8 +1126,14 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* Check if we need to change the speed */ - if ((speed = irda_get_speed(skb)) != self->io.speed) - self->new_speed = speed; + if ((speed = irda_get_speed(skb)) != self->io.speed) { + /* Check for empty frame */ + if (!skb->len) { + nsc_ircc_change_speed_complete(self, speed); + return 0; + } else + self->new_speed = speed; + } spin_lock_irqsave(&self->lock, flags); @@ -2029,10 +2041,15 @@ MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("NSC IrDA Device Driver"); MODULE_PARM(qos_mtt_bits, "i"); +MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); MODULE_PARM(io, "1-4i"); +MODULE_PARM_DESC(io, "Base I/O addresses"); MODULE_PARM(irq, "1-4i"); +MODULE_PARM_DESC(irq, "IRQ lines"); MODULE_PARM(dma, "1-4i"); +MODULE_PARM_DESC(dma, "DMA channels"); MODULE_PARM(dongle_id, "i"); +MODULE_PARM_DESC(dongle_id, "Type-id of used dongle"); int init_module(void) { diff --git a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c index 470d6dd4d..45e85b08c 100644 --- a/drivers/net/irda/smc-ircc.c +++ b/drivers/net/irda/smc-ircc.c @@ -589,6 +589,8 @@ static void ircc_change_speed(void *priv, __u32 speed) register_bank(iobase, 0); outb(fast, iobase+IRCC_LCR_A); + + netif_start_queue(dev); } /* @@ -612,13 +614,19 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) iobase = self->io.fir_base; - spin_lock_irqsave(&self->lock, flags); + netif_stop_queue(dev); /* Check if we need to change the speed after this frame */ - if ((speed = irda_get_speed(skb)) != self->io.speed) - self->new_speed = speed; + if ((speed = irda_get_speed(skb)) != self->io.speed) { + /* Check for empty frame */ + if (!skb->len) { + smc_ircc_change_speed(self, speed); + return 0; + } else + self->new_speed = speed; + } - netif_stop_queue(dev); + spin_lock_irqsave(&self->lock, flags); memcpy(self->tx_buff.head, skb->data, skb->len); @@ -814,7 +822,7 @@ static void ircc_dma_receive_complete(struct ircc_cb *self, int iobase) else len -= 4; - if ((len < 2) && (len > 2050)) { + if ((len < 2) || (len > 2050)) { WARNING(__FUNCTION__ "(), bogus len=%d\n", len); return; } @@ -1039,7 +1047,9 @@ static int ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data) MODULE_AUTHOR("Thomas Davis "); MODULE_DESCRIPTION("SMC IrCC controller driver"); MODULE_PARM(ircc_dma, "1i"); +MODULE_PARM_DESC(ircc_dma, "DMA channel"); MODULE_PARM(ircc_irq, "1i"); +MODULE_PARM_DESC(ircc_irq, "IRQ line"); int init_module(void) { diff --git a/drivers/net/irda/toshoboe.c b/drivers/net/irda/toshoboe.c index 65ccfee2b..39a130436 100644 --- a/drivers/net/irda/toshoboe.c +++ b/drivers/net/irda/toshoboe.c @@ -272,8 +272,14 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) ); /* Check if we need to change the speed */ - if ((speed = irda_get_speed(skb)) != self->io.speed) - self->new_speed = speed; + if ((speed = irda_get_speed(skb)) != self->io.speed) { + /* Check for empty frame */ + if (!skb->len) { + toshoboe_change_speed(self, speed); + return 0; + } else + self->new_speed = speed; + } netif_stop_queue(dev); @@ -628,7 +634,10 @@ static int toshoboe_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #ifdef MODULE +MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver"); +MODULE_AUTHOR("James McKenzie "); MODULE_PARM (max_baud, "i"); +MODULE_PARM_DESC(max_baus, "Maximum baud rate"); static int toshoboe_close (struct toshoboe_cb *self) diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 2456e012d..91e81df66 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -255,13 +255,12 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq, dev->get_stats = w83977af_net_get_stats; rtnl_lock(); - err = register_netdev(dev); + err = register_netdevice(dev); rtnl_unlock(); if (err) { - ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + ERROR(__FUNCTION__ "(), register_netdevice() failed!\n"); return -1; } - MESSAGE("IrDA: Registered device %s\n", dev->name); return 0; @@ -514,8 +513,14 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* Check if we need to change the speed */ - if ((speed = irda_get_speed(skb)) != self->io.speed) - self->new_speed = speed; + if ((speed = irda_get_speed(skb)) != self->io.speed) { + /* Check for empty frame */ + if (!skb->len) { + w83977af_change_speed(self, speed); + return 0; + } else + self->new_speed = speed; + } /* Save current set */ set = inb(iobase+SSR); @@ -1366,9 +1371,11 @@ MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver"); MODULE_PARM(qos_mtt_bits, "i"); +MODULE_PARM_DESC(qos_mtt_bits, "Mimimum Turn Time"); MODULE_PARM(io, "1-4i"); -MODULE_PARM(io2, "1-4i"); +MODULE_PARM_DESC(io, "Base I/O addresses"); MODULE_PARM(irq, "1-4i"); +MODULE_PARM_DESC(irq, "IRQ lines"); /* * Function init_module (void) diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index 2a558e20e..3ff0ef141 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -200,12 +200,12 @@ static int ne2_procinfo(char *buf, int slot, struct net_device *dev) static int __init ne2_probe1(struct net_device *dev, int slot) { - int i, base_addr, irq; + int i, base_addr, irq, retval; unsigned char POS; unsigned char SA_prom[32]; const char *name = "NE/2"; int start_page, stop_page; - static unsigned version_printed = 0; + static unsigned version_printed; if (ei_debug && version_printed++ == 0) printk(version); @@ -226,6 +226,9 @@ static int __init ne2_probe1(struct net_device *dev, int slot) base_addr = addresses[i - 1]; irq = irqs[(POS & 0x60)>>5]; + if (!request_region(base_addr, NE_IO_EXTENT, dev->name)) + return -EBUSY; + #ifdef DEBUG printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS, base_addr, irq); @@ -239,7 +242,8 @@ static int __init ne2_probe1(struct net_device *dev, int slot) outb(0x21, base_addr + NE_CMD); if (inb(base_addr + NE_CMD) != 0x21) { printk("NE/2 adapter not responding\n"); - return -ENODEV; + retval = -ENODEV; + goto out; } /* In the crynwr sources they do a RAM-test here. I skip it. I suppose @@ -260,7 +264,8 @@ static int __init ne2_probe1(struct net_device *dev, int slot) while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0) if (jiffies - reset_start_time > 2*HZ/100) { printk(" not found (no reset ack).\n"); - return -ENODEV; + retval = -ENODEV; + goto out; } outb_p(0xff, base_addr + EN0_ISR); /* Ack all intr. */ @@ -309,14 +314,11 @@ static int __init ne2_probe1(struct net_device *dev, int slot) /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ - { - int irqval = request_irq(dev->irq, ei_interrupt, - 0, name, dev); - if (irqval) { - printk (" unable to get IRQ %d (irqval=%d).\n", - dev->irq, +irqval); - return -EAGAIN; - } + retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); + if (retval) { + printk (" unable to get IRQ %d (irqval=%d).\n", + dev->irq, retval); + goto out; } dev->base_addr = base_addr; @@ -325,11 +327,10 @@ static int __init ne2_probe1(struct net_device *dev, int slot) if (ethdev_init(dev)) { printk (" unable to get memory for dev->priv.\n"); free_irq(dev->irq, dev); - return -ENOMEM; + retval = -ENOMEM; + goto out; } - request_region(base_addr, NE_IO_EXTENT, name); - for(i = 0; i < ETHER_ADDR_LEN; i++) { printk(" %2.2x", SA_prom[i]); dev->dev_addr[i] = SA_prom[i]; @@ -362,6 +363,9 @@ static int __init ne2_probe1(struct net_device *dev, int slot) dev->stop = &ne_close; NS8390_init(dev, 0); return 0; +out: + release_region(base_addr, NE_IO_EXTENT); + return retval; } static int ne_open(struct net_device *dev) diff --git a/drivers/net/pcmcia/Config.in b/drivers/net/pcmcia/Config.in index 4ad968390..0f116b23d 100644 --- a/drivers/net/pcmcia/Config.in +++ b/drivers/net/pcmcia/Config.in @@ -36,7 +36,8 @@ if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \ "$CONFIG_PCMCIA_FMVJ18X" = "y" -o "$CONFIG_PCMCIA_PCNET" = "y" -o \ "$CONFIG_PCMCIA_NMCLAN" = "y" -o "$CONFIG_PCMCIA_SMC91C92" = "y" -o \ "$CONFIG_PCMCIA_XIRC2PS" = "y" -o "$CONFIG_PCMCIA_RAYCS" = "y" -o \ - "$CONFIG_PCMCIA_NETWAVE" = "y" -o "$CONFIG_PCMCIA_WAVELAN" = "y" ]; then + "$CONFIG_PCMCIA_NETWAVE" = "y" -o "$CONFIG_PCMCIA_WAVELAN" = "y" -o \ + "$CONFIG_PCMCIA_XIRTULIP" = "y" ]; then define_bool CONFIG_PCMCIA_NETCARD y fi diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index e705868d6..6e69b12b2 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -1550,36 +1550,29 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) rrpriv = (struct rr_private *)dev->priv; - switch(cmd){ case SIOCRRGFW: - if (!capable(CAP_SYS_RAWIO)){ - error = -EPERM; - goto out; - } + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); if (!image){ printk(KERN_ERR "%s: Unable to allocate memory " "for EEPROM image\n", dev->name); - error = -ENOMEM; - goto out; + return -ENOMEM; } spin_lock(&rrpriv->lock); if (rrpriv->fw_running){ printk("%s: Firmware already running\n", dev->name); - kfree(image); error = -EPERM; goto out_spin; } i = rr_read_eeprom(rrpriv, 0, image, EEPROM_BYTES); if (i != EEPROM_BYTES){ - kfree(image); - printk(KERN_ERR "%s: Error reading EEPROM\n", - dev->name); + printk(KERN_ERR "%s: Error reading EEPROM\n", dev->name); error = -EFAULT; goto out_spin; } @@ -1591,9 +1584,8 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return error; case SIOCRRPFW: - if (!capable(CAP_SYS_RAWIO)){ + if (!capable(CAP_SYS_RAWIO)) return -EPERM; - } image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); if (!image){ @@ -1604,18 +1596,21 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) oldimage = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); if (!oldimage){ + kfree(image); printk(KERN_ERR "%s: Unable to allocate memory " "for old EEPROM image\n", dev->name); return -ENOMEM; } error = copy_from_user(image, rq->ifr_data, EEPROM_BYTES); - if (error) - error = -EFAULT; + if (error) { + kfree(image); + kfree(oldimage); + return -EFAULT; + } spin_lock(&rrpriv->lock); if (rrpriv->fw_running){ - kfree(image); kfree(oldimage); printk("%s: Firmware already running\n", dev->name); error = -EPERM; @@ -1652,6 +1647,7 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } out_spin: + kfree(image); spin_unlock(&rrpriv->lock); return error; } diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index e60c41f74..26ba670b5 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -116,13 +116,9 @@ seeq8005_probe(struct net_device *dev) else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; - for (i = 0; seeq8005_portlist[i]; i++) { - int ioaddr = seeq8005_portlist[i]; - if (check_region(ioaddr, SEEQ8005_IO_EXTENT)) - continue; - if (seeq8005_probe1(dev, ioaddr) == 0) + for (i = 0; seeq8005_portlist[i]; i++) + if (seeq8005_probe1(dev, seeq8005_portlist[i]) == 0) return 0; - } return -ENODEV; } @@ -133,7 +129,7 @@ seeq8005_probe(struct net_device *dev) static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) { - static unsigned version_printed = 0; + static unsigned version_printed; int i,j; unsigned char SA_prom[32]; int old_cfg1; @@ -141,33 +137,42 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) int old_stat; int old_dmaar; int old_rear; + int retval; + + if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005")) + return -ENODEV; if (net_debug>1) printk("seeq8005: probing at 0x%x\n",ioaddr); old_stat = inw(SEEQ_STATUS); /* read status register */ - if (old_stat == 0xffff) - return -ENODEV; /* assume that 0xffff == no device */ + if (old_stat == 0xffff) { + retval = -ENODEV; + goto out; /* assume that 0xffff == no device */ + } if ( (old_stat & 0x1800) != 0x1800 ) { /* assume that unused bits are 1, as my manual says */ if (net_debug>1) { printk("seeq8005: reserved stat bits != 0x1800\n"); printk(" == 0x%04x\n",old_stat); } - return -ENODEV; + retval = -ENODEV; + goto out; } old_rear = inw(SEEQ_REA); if (old_rear == 0xffff) { outw(0,SEEQ_REA); if (inw(SEEQ_REA) == 0xffff) { /* assume that 0xffff == no device */ - return -ENODEV; + retval = -ENODEV; + goto out; } } else if ((old_rear & 0xff00) != 0xff00) { /* assume that unused bits are 1 */ if (net_debug>1) { printk("seeq8005: unused rear bits != 0xff00\n"); printk(" == 0x%04x\n",old_rear); } - return -ENODEV; + retval = -ENODEV; + goto out; } old_cfg2 = inw(SEEQ_CFG2); /* read CFG2 register */ @@ -185,8 +190,8 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); /* setup for reading PROM */ outw( 0, SEEQ_DMAAR); /* set starting PROM address */ outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1); /* set buffer to look at PROM */ - - + + j=0; for(i=0; i <32; i++) { j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff; @@ -201,7 +206,8 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) outw( old_stat, SEEQ_STATUS); outw( old_dmaar, SEEQ_DMAAR); outw( old_cfg1, SEEQ_CFG1); - return -ENODEV; + retval = -ENODEV; + goto out; } #endif @@ -299,14 +305,12 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) if (irqval) { printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, irqval); - return -EAGAIN; + retval = -EAGAIN; + goto out; } } #endif - /* Grab the region so we can find another board if autoIRQ fails. */ - request_region(ioaddr, SEEQ8005_IO_EXTENT,"seeq8005"); - /* Initialize the device structure. */ dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); if (dev->priv == NULL) @@ -327,6 +331,9 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) dev->flags &= ~IFF_MULTICAST; return 0; +out: + release_region(ioaddr, SEEQ8005_IO_EXTENT); + return retval; } diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 3fc785761..cc0eae214 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -140,7 +140,6 @@ struct sis900_private { BufferDesc rx_ring[NUM_RX_DESC]; unsigned int tx_full; /* The Tx queue is full. */ - int LinkOn; }; MODULE_AUTHOR("Jim Huang , Ollie Lho "); @@ -374,9 +373,9 @@ static int __init sis900_mii_probe (struct net_device * net_dev) } if (sis_priv->mii->status & MII_STAT_LINK) - sis_priv->LinkOn = TRUE; + netif_carrier_on(net_dev); else - sis_priv->LinkOn = FALSE; + netif_carrier_off(net_dev); return 1; } @@ -709,7 +708,7 @@ static void sis630e_set_eq(struct net_device *net_dev) u16 reg14h, eq_value, max_value=0, min_value=0; int i, maxcount=10; - if (sis_priv->LinkOn == TRUE) { + if (netif_carrier_ok(net_dev)) { reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV); mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF); for (i=0; i < maxcount; i++) { @@ -753,10 +752,10 @@ static void sis900_timer(unsigned long data) /* current mii phy is failed to link, try another one */ while (!(status & MII_STAT_LINK)) { if (mii_phy->next == NULL) { - if (sis_priv->LinkOn) { + if (netif_carrier_ok(net_dev)) { /* link stat change from ON to OFF */ next_tick = HZ; - sis_priv->LinkOn = FALSE; + netif_carrier_off(net_dev); /* Equalizer workaroung Rule */ pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision); @@ -774,9 +773,9 @@ static void sis900_timer(unsigned long data) status = mdio_read(net_dev, mii_phy->phy_addr, MII_STATUS); } - if (!sis_priv->LinkOn) { + if (!netif_carrier_ok(net_dev)) { /* link stat change forn OFF to ON, read and report link mode */ - sis_priv->LinkOn = TRUE; + netif_carrier_on(net_dev); next_tick = 5*HZ; /* Equalizer workaroung Rule */ @@ -1340,7 +1339,7 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map) be temporary down and we need to reflect that here. When the Link comes up again, it will be sensed by the sis_timer procedure, which also does all the rest for us */ - sis_priv->LinkOn=FALSE; + netif_carrier_off(dev); /* read current state */ status = mdio_read(dev, mii_phy->phy_addr, MII_CONTROL); @@ -1360,7 +1359,7 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map) be temporary down and we need to reflect that here. When the Link comes up again, it will be sensed by the sis_timer procedure, which also does all the rest for us */ - sis_priv->LinkOn=FALSE; + netif_carrier_off(dev); /* set Speed to 10Mbps */ /* read current state */ @@ -1379,7 +1378,7 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map) be temporary down and we need to reflect that here. When the Link comes up again, it will be sensed by the sis_timer procedure, which also does all the rest for us */ - sis_priv->LinkOn=FALSE; + netif_carrier_off(dev); /* set Speed to 100Mbps */ /* disable auto negotiation and enable 100MBit Mode */ diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h index 740b72dc8..561a40444 100644 --- a/drivers/net/sis900.h +++ b/drivers/net/sis900.h @@ -255,9 +255,6 @@ enum sis630_revision_id { #define NUM_TX_DESC 16 /* Number of Tx descriptor registers. */ #define NUM_RX_DESC 16 /* Number of Rx descriptor registers. */ -#define TRUE 1 -#define FALSE 0 - /* PCI stuff, should be move to pic.h */ #define PCI_DEVICE_ID_SI_900 0x900 #define PCI_DEVICE_ID_SI_7016 0x7016 diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index c36f2f379..af2050833 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -194,7 +194,7 @@ int __init ultramca_probe(struct net_device *dev) } if(!adapter_found) { - return ((base_addr || irq) ? ENXIO : ENODEV); + return ((base_addr || irq) ? -ENXIO : -ENODEV); } /* Adapter found. */ @@ -249,6 +249,9 @@ int __init ultramca_probe(struct net_device *dev) if (dev->mem_start == 0) /* sanity check, shouldn't happen */ return -ENODEV; + if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) + return -EBUSY; + reg4 = inb(ioaddr + 4) & 0x7f; outb(reg4, ioaddr + 4); @@ -279,14 +282,10 @@ int __init ultramca_probe(struct net_device *dev) if (ethdev_init(dev)) { printk (KERN_INFO ", no memory for dev->priv.\n"); + release_region(ioaddr, ULTRA_IO_EXTENT); return -ENOMEM; } - /* OK, we are certain this is going to work. Setup the device. - */ - - request_region(ioaddr, ULTRA_IO_EXTENT, "smc-mca"); - /* The 8390 isn't at the base address, so fake the offset */ @@ -322,9 +321,10 @@ int __init ultramca_probe(struct net_device *dev) static int ultramca_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ + int retval; - if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev)) - return -EAGAIN; + if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) + return retval; outb(ULTRA_MEMENB, ioaddr); /* Enable memory */ outb(0x80, ioaddr + 5); /* ??? */ diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index e5632db93..5e7c7aeae 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -112,41 +112,44 @@ int __init ultra_probe(struct net_device *dev) else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; - for (i = 0; ultra_portlist[i]; i++) { - int ioaddr = ultra_portlist[i]; - if (check_region(ioaddr, ULTRA_IO_EXTENT)) - continue; - if (ultra_probe1(dev, ioaddr) == 0) + for (i = 0; ultra_portlist[i]; i++) + if (ultra_probe1(dev, ultra_portlist[i]) == 0) return 0; - } return -ENODEV; } static int __init ultra_probe1(struct net_device *dev, int ioaddr) { - int i; + int i, retval; int checksum = 0; const char *model_name; unsigned char eeprom_irq = 0; - static unsigned version_printed = 0; + static unsigned version_printed; /* Values from various config regs. */ unsigned char num_pages, irqreg, addr, piomode; unsigned char idreg = inb(ioaddr + 7); unsigned char reg4 = inb(ioaddr + 4) & 0x7f; + if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) + return -EBUSY; + /* Check the ID nibble. */ if ((idreg & 0xF0) != 0x20 /* SMC Ultra */ - && (idreg & 0xF0) != 0x40) /* SMC EtherEZ */ - return -ENODEV; + && (idreg & 0xF0) != 0x40) { /* SMC EtherEZ */ + retval = -ENODEV; + goto out; + } /* Select the station address register set. */ outb(reg4, ioaddr + 4); for (i = 0; i < 8; i++) checksum += inb(ioaddr + 8 + i); - if ((checksum & 0xff) != 0xFF) - return -ENODEV; + if ((checksum & 0xff) != 0xFF) { + retval = -ENODEV; + goto out; + } if (ei_debug && version_printed++ == 0) printk(version); @@ -181,7 +184,8 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr) if (irq == 0) { printk(", failed to detect IRQ line.\n"); - return -EAGAIN; + retval = -EAGAIN; + goto out; } dev->irq = irq; eeprom_irq = 1; @@ -190,12 +194,10 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (", no memory for dev->priv.\n"); - return -ENOMEM; + retval = -ENOMEM; + goto out; } - /* OK, we are certain this is going to work. Setup the device. */ - request_region(ioaddr, ULTRA_IO_EXTENT, model_name); - /* The 8390 isn't at the base address, so fake the offset */ dev->base_addr = ioaddr+ULTRA_NIC_OFFSET; @@ -236,17 +238,22 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr) NS8390_init(dev, 0); return 0; +out: + release_region(ioaddr, ULTRA_IO_EXTENT); + return retval; } static int ultra_open(struct net_device *dev) { + int retval; int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40, - 0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, }; + 0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, }; - if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev)) - return -EAGAIN; + retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); + if (retval) + return retval; outb(0x00, ioaddr); /* Disable shared memory for safety. */ outb(0x80, ioaddr + 5); diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index fba1949a8..201b259f7 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -200,13 +200,6 @@ static int smc_open(struct net_device *dev); static void smc_timeout(struct net_device *dev); /* - . This is called by the kernel to send a packet out into the net. it's - . responsible for doing a best-effort send, but if it's simply not possible - . to send it, the packet gets dropped. -*/ -static int smc_send_packet(struct sk_buff *skb, struct net_device *dev); - -/* . This is called by the kernel in response to 'ifconfig ethX down'. It . is responsible for cleaning up everything that the open routine . does, and maybe putting the card into a powerdown state. @@ -512,6 +505,10 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de unsigned short numPages; word time_out; + netif_stop_queue(dev); + /* Well, I want to send the packet.. but I don't know + if I can send it right now... */ + if ( lp->saved_skb) { /* THIS SHOULD NEVER HAPPEN. */ lp->stats.tx_aborted_errors++; @@ -626,7 +623,7 @@ static void smc_hardware_send_packet( struct net_device * dev ) if ( packet_no & 0x80 ) { /* or isn't there? BAD CHIP! */ printk(KERN_DEBUG CARDNAME": Memory allocation failed. \n"); - kfree_skb(skb); + dev_kfree_skb(skb); lp->saved_skb = NULL; netif_wake_queue(dev); return; @@ -761,6 +758,7 @@ int __init smc_init(struct net_device *dev) int __init smc_findirq( int ioaddr ) { int timeout = 20; + unsigned long cookie; /* I have to do a STI() here, because this is called from @@ -768,7 +766,7 @@ int __init smc_findirq( int ioaddr ) rather difficult to get interrupts for auto detection */ sti(); - autoirq_setup( 0 ); + cookie = probe_irq_on(); /* * What I try to do here is trigger an ALLOC_INT. This is done @@ -821,7 +819,7 @@ int __init smc_findirq( int ioaddr ) cli(); /* and return what I found */ - return autoirq_report( 0 ); + return probe_irq_off(cookie); } /*---------------------------------------------------------------------- @@ -922,13 +920,6 @@ static int __init smc_initcard(struct net_device *dev, int ioaddr) int irqval; - /* see if I need to initialize the ethernet card structure */ - if (dev == NULL) { - dev = init_etherdev(0, 0); - if (dev == NULL) - return -ENOMEM; - } - if (version_printed++ == 0) printk("%s", version); @@ -1060,7 +1051,7 @@ static int __init smc_initcard(struct net_device *dev, int ioaddr) dev->open = smc_open; dev->stop = smc_close; - dev->hard_start_xmit = smc_send_packet; + dev->hard_start_xmit = smc_wait_to_send_packet; dev->tx_timeout = smc_timeout; dev->watchdog_timeo = HZ/20; dev->get_stats = smc_query_statistics; @@ -1181,14 +1172,6 @@ static void smc_timeout(struct net_device *dev) netif_wake_queue(dev); } -static int smc_send_packet(struct sk_buff *skb, struct net_device *dev) -{ - netif_stop_queue(dev); - /* Well, I want to send the packet.. but I don't know - if I can send it right now... */ - return smc_wait_to_send_packet( skb, dev ); -} - /*-------------------------------------------------------------------- . . This is the main routine of the driver, to handle the device when @@ -1594,15 +1577,11 @@ static void smc_set_multicast_list(struct net_device *dev) #ifdef MODULE -static struct net_device devSMC9194 = { - "", /* device name is inserted by linux/drivers/net/net_init.c */ - 0, 0, 0, 0, - 0, 0, /* I/O address, IRQ */ - 0, 0, 0, NULL, smc_init }; +static struct net_device devSMC9194 = { init: smc_init }; -int io = 0; -int irq = 0; -int ifport = 0; +static int io; +static int irq; +static int ifport; MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 2f0f46d95..e4d598796 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1,4 +1,4 @@ -/* $Id: sunhme.c,v 1.98 2000/10/22 16:08:38 davem Exp $ +/* $Id: sunhme.c,v 1.99 2000/11/10 05:44:33 davem Exp $ * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, * auto carrier detecting ethernet driver. Also known as the * "Happy Meal Ethernet" found on SunSwift SBUS cards. @@ -24,6 +24,7 @@ static char *version = #include #include #include +#include #include #include #include @@ -41,7 +42,6 @@ static char *version = #ifndef __sparc_v9__ #include #endif -#include #include #include diff --git a/drivers/net/wan/comx-proto-lapb.c b/drivers/net/wan/comx-proto-lapb.c index 0e2737ac3..acbb7f112 100644 --- a/drivers/net/wan/comx-proto-lapb.c +++ b/drivers/net/wan/comx-proto-lapb.c @@ -15,6 +15,9 @@ * Version 0.80 (99/06/14): * - cleaned up the source code a bit * - ported back to kernel, now works as non-module + * + * Changed (00/10/29, Henner Eisen): + * - comx_rx() / comxlapb_data_indication() return status. * */ @@ -359,7 +362,7 @@ static void comxlapb_disconnected(void *token, int reason) comx_status(ch->dev, ch->line_status); } -static void comxlapb_data_indication(void *token, struct sk_buff *skb) +static int comxlapb_data_indication(void *token, struct sk_buff *skb) { struct comx_channel *ch = token; @@ -373,7 +376,7 @@ static void comxlapb_data_indication(void *token, struct sk_buff *skb) skb->dev = ch->dev; skb->mac.raw = skb->data; - comx_rx(ch->dev, skb); + return comx_rx(ch->dev, skb); } static void comxlapb_data_transmit(void *token, struct sk_buff *skb) diff --git a/drivers/net/wan/comx.c b/drivers/net/wan/comx.c index f1e1ffdcb..515807e07 100644 --- a/drivers/net/wan/comx.c +++ b/drivers/net/wan/comx.c @@ -46,6 +46,9 @@ * Version 0.85 (00/08/15): * - resource release on failure in comx_mkdir * - fix return value on failure at comx_write_proc + * + * Changed (00/10/29, Henner Eisen): + * - comx_rx() / comxlapb_data_indication() return status. */ #define VERSION "0.85" diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 826fb02c6..f101e25f7 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -16,6 +16,7 @@ * * History * LAPBETH 001 Jonathan Naylor Cloned from bpqether.c + * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ #include @@ -185,7 +186,7 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe return 0; } -static void lapbeth_data_indication(void *token, struct sk_buff *skb) +static int lapbeth_data_indication(void *token, struct sk_buff *skb) { struct lapbethdev *lapbeth = (struct lapbethdev *)token; unsigned char *ptr; @@ -198,7 +199,7 @@ static void lapbeth_data_indication(void *token, struct sk_buff *skb) skb->mac.raw = skb->data; skb->pkt_type = PACKET_HOST; - netif_rx(skb); + return netif_rx(skb); } /* diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 5651ddeb2..1d8b6b1d8 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -9,6 +9,9 @@ * recommendations. Its primarily for testing purposes. If you wanted * to do CCITT then in theory all you need is to nick the HDLC async * checksum routines from ppp.c + * Changes: + * + * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ #include @@ -390,9 +393,9 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev) * at the net layer. */ -static void x25_asy_data_indication(void *token, struct sk_buff *skb) +static int x25_asy_data_indication(void *token, struct sk_buff *skb) { - netif_rx(skb); + return netif_rx(skb); } /* diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index 7caa27312..2ee80ae09 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c @@ -1125,6 +1125,7 @@ ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0, schedule_size = 0, ok = 0; void *tmp; + unsigned long page; switch (chip) { case 710: @@ -1191,6 +1192,12 @@ ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, */ (sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size; + page = __get_free_pages(GFP_ATOMIC,1); + if(page==0) + { + printk(KERN_ERR "53c7xx: out of memory.\n"); + return -ENOMEM; + } #ifdef FORCE_DSA_ALIGNMENT /* * 53c710 rev.0 doesn't have an add-with-carry instruction. @@ -1203,10 +1210,11 @@ ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, panic("53c7xx: hostdata > 8K"); instance = scsi_register (tpnt, 4); if (!instance) + { + free_page(page); return -1; - instance->hostdata[0] = __get_free_pages(GFP_ATOMIC, 1); - if (instance->hostdata[0] == 0) - panic ("53c7xx: Couldn't get hostdata memory"); + } + instance->hostdata[0] = page; memset((void *)instance->hostdata[0], 0, 8192); cache_push(virt_to_phys((void *)(instance->hostdata[0])), 8192); cache_clear(virt_to_phys((void *)(instance->hostdata[0])), 8192); @@ -3087,7 +3095,7 @@ allocate_cmd (Scsi_Cmnd *cmd) { panic ("53c7xx: allocate_cmd size > 4K"); real = get_free_page(GFP_ATOMIC); if (real == 0) - panic ("53c7xx: Couldn't get memory for allocate_cmd"); + return NULL; memset((void *)real, 0, 4096); cache_push(virt_to_phys((void *)real), 4096); cache_clear(virt_to_phys((void *)real), 4096); diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 1abc1a8c7..83512a854 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -2793,6 +2793,11 @@ int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) Register the SCSI Host structure. */ Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T)); + if(Host==NULL) + { + release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + continue; + } HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata; memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T)); HostAdapter->SCSI_Host = Host; diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 98ceaf3e9..c9e6c1d40 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -207,6 +207,8 @@ int __init a2091_detect(Scsi_Host_Template *tpnt) continue; instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); + if(instance == NULL) + continue; instance->base = ZTWO_VADDR(address); instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = z->slotaddr; diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 422536d77..c9a4253f0 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -175,6 +175,8 @@ int __init a3000_detect(Scsi_Host_Template *tpnt) tpnt->proc_info = &wd33c93_proc_info; a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); + if(a3000_host == NULL) + return 0; a3000_host->base = ZTWO_VADDR(0xDD0000); a3000_host->irq = IRQ_AMIGA_PORTS; DMA(a3000_host)->DAWR = DAWR_A3000; diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index bf89438ee..69fec6b14 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -4774,6 +4774,9 @@ advansys_detect(Scsi_Host_Template *tpnt) */ ASC_DBG(2, "advansys_detect: scsi_register()\n"); shp = scsi_register(tpnt, sizeof(asc_board_t)); + + if(shp==NULL) + continue; /* Save a pointer to the Scsi_host of each board found. */ asc_host[asc_board_count++] = shp; diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 7ed3170c9..9d3584a25 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -1154,6 +1154,8 @@ int aha1542_detect(Scsi_Host_Template * tpnt) shpnt = scsi_register(tpnt, sizeof(struct aha1542_hostdata)); + if(shpnt==NULL) + continue; /* For now we do this - until kmalloc is more intelligent we are resigned to stupid hacks like this */ if (SCSI_PA(shpnt) >= ISA_DMA_THRESHOLD) { diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index c3a25c121..8e8c901bb 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -541,6 +541,11 @@ int aha1740_detect(Scsi_Host_Template * tpnt) continue; } shpnt = scsi_register(tpnt, sizeof(struct aha1740_hostdata)); + if(shpnt == NULL) + { + free_irq(irq_level, NULL); + continue; + } request_region(slotbase, SLOTSIZE, "aha1740"); shpnt->base = 0; shpnt->io_port = slotbase; diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 118f09f05..77feb1cbc 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -667,6 +667,12 @@ int atari_scsi_detect (Scsi_Host_Template *host) } #endif instance = scsi_register (host, sizeof (struct NCR5380_hostdata)); + if(instance == NULL) + { + atari_stram_free(atari_dma_buffer); + atari_dma_buffer = 0; + return 0; + } atari_scsi_host = instance; /* Set irq to 0, to avoid that the mid-level code disables our interrupt * during queue_command calls. This is completely unnecessary, and even diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index b0722e20f..890d44426 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1734,6 +1734,8 @@ int atp870u_detect(Scsi_Host_Template * tpnt) dev->ultra_map = 0xffff; } shpnt = scsi_register(tpnt, 4); + if(shpnt==NULL) + return count; save_flags(flags); cli(); diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c index b51b515a6..dac695423 100644 --- a/drivers/scsi/cpqfcTSinit.c +++ b/drivers/scsi/cpqfcTSinit.c @@ -290,6 +290,9 @@ int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate) (ULONG)sizeof(CPQFCHBA)); HostAdapter = scsi_register( ScsiHostTemplate, sizeof( CPQFCHBA ) ); + + if(HostAdapter == NULL) + continue; DEBUG_PCI( printk(" HBA found!\n")); DEBUG_PCI( printk(" HostAdapter->PciDev->irq = %u\n", PciDev->irq) ); DEBUG_PCI(printk(" PciDev->baseaddress[]= %lx\n", PciDev->base_address[0])); diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index 327743bf8..b369c0618 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -82,6 +82,11 @@ int __init dmx3191d_detect(Scsi_Host_Template *tmpl) { request_region(port, DMX3191D_REGION, DMX3191D_DRIVER_NAME); instance = scsi_register(tmpl, sizeof(struct NCR5380_hostdata)); + if(instance == NULL) + { + release_region(port, DMX3191D_REGION); + continue; + } instance->io_port = port; instance->irq = pdev->irq; NCR5380_init(instance, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 5e2635cba..845174d27 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -241,6 +241,9 @@ int __init dtc_detect(Scsi_Host_Template * tpnt){ break; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + if(instance == NULL) + break; + instance->base = base; NCR5380_init(instance, 0); diff --git a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c index 09b6929b2..9559c716c 100644 --- a/drivers/scsi/eata_dma.c +++ b/drivers/scsi/eata_dma.c @@ -554,7 +554,17 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) GFP_ATOMIC | GFP_DMA); } if (ccb->sg_list == NULL) - panic("eata_dma: Run out of DMA memory for SG lists !\n"); + { + /* + * Claim the bus was busy. Actually we are the problem but this + * will do a deferred retry for us ;) + */ + printk(KERN_ERR "eata_dma: Run out of DMA memory for SG lists !\n"); + cmd->result = DID_BUS_BUSY << 16; + ccb->status = FREE; + done(cmd); + return(0); + } ccb->cp_dataDMA = htonl(virt_to_bus(ccb->sg_list)); ccb->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list)); @@ -909,8 +919,17 @@ char * get_board_data(u32 base, u32 irq, u32 id) cp = (struct eata_ccb *) kmalloc(sizeof(struct eata_ccb), GFP_ATOMIC | GFP_DMA); + + if(cp==NULL) + return NULL; + sp = (struct eata_sp *) kmalloc(sizeof(struct eata_sp), GFP_ATOMIC | GFP_DMA); + if(sp==NULL) + { + kfree(cp); + return NULL; + } buff = dma_scratch; @@ -1463,6 +1482,10 @@ int eata_detect(Scsi_Host_Template * tpnt) if(status == NULL || dma_scratch == NULL) { printk("eata_dma: can't allocate enough memory to probe for hosts !\n"); + if(status) + kfree(status); + if(dma_scratch) + kfree(dma_scratch); return(0); } diff --git a/drivers/scsi/eata_dma_proc.c b/drivers/scsi/eata_dma_proc.c index 7961483e1..3ee72657c 100644 --- a/drivers/scsi/eata_dma_proc.c +++ b/drivers/scsi/eata_dma_proc.c @@ -153,7 +153,18 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, } else { SDev = scsi_get_host_dev(HBA_ptr); + + if(SDev == NULL) + return -ENOMEM; + scmd = scsi_allocate_request(SDev); + + if(scmd == NULL) + { + scsi_free_host_dev(SDev); + return -ENOMEM; + } + cmnd[0] = LOG_SENSE; cmnd[1] = 0; diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index ef4561fdc..0d890817c 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -728,6 +728,12 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt) size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz)); sh = scsi_register(tpnt, size); + if(sh == NULL) + { + release_region(base, 8); + return FALSE; + } + hd = SD(sh); memset(hd->ccb, 0, (sizeof(struct eata_ccb) * ntohs(gc->queuesiz))); diff --git a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c index 05ff2f7d9..4ffef8561 100644 --- a/drivers/scsi/fcal.c +++ b/drivers/scsi/fcal.c @@ -128,7 +128,11 @@ int __init fcal_detect(Scsi_Host_Template *tpnt) if (!ages) continue; host = scsi_register (tpnt, sizeof (struct fcal)); - if (!host) panic ("Cannot register FCAL host\n"); + if (!host) + { + kfree(ages); + continue; + } nfcals++; diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index d6ac51931..884a2ea25 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -965,6 +965,8 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) get resources. */ shpnt = scsi_register( tpnt, 0 ); + if(shpnt == NULL) + return 0; shpnt->irq = interrupt_level; shpnt->io_port = port_base; shpnt->n_io_port = 0x10; diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index c582c8e72..492de3866 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -390,6 +390,17 @@ int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt){ NCR5380_region_size, "ncr5380"); #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + if(instance == NULL) + { +#ifdef CONFIG_SCSI_G_NCR5380_PORT + release_region(overrides[current_override].NCR5380_map_name, + NCR5380_region_size); +#else + release_mem_region(overrides[current_override].NCR5380_map_name, + NCR5380_region_size); +#endif + } + instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name; NCR5380_init(instance, flags); @@ -902,3 +913,4 @@ MODULE_PARM(ncr_53c400a, "i"); MODULE_PARM(dtc_3181e, "i"); #endif + diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index dd26cda1e..b28cba5a6 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -3125,6 +3125,8 @@ int __init gdth_detect(Scsi_Host_Template *shtp) break; if (gdth_search_isa(isa_bios)) { /* controller found */ shp = scsi_register(shtp,sizeof(gdth_ext_str)); + if(shp == NULL) + continue; ha = HADATA(shp); if (!gdth_init_isa(isa_bios,ha)) { scsi_unregister(shp); @@ -3197,6 +3199,8 @@ int __init gdth_detect(Scsi_Host_Template *shtp) break; if (gdth_search_eisa(eisa_slot)) { /* controller found */ shp = scsi_register(shtp,sizeof(gdth_ext_str)); + if(shp == NULL) + continue; ha = HADATA(shp); if (!gdth_init_eisa(eisa_slot,ha)) { scsi_unregister(shp); @@ -3268,6 +3272,8 @@ int __init gdth_detect(Scsi_Host_Template *shtp) if (gdth_ctr_count >= MAXHA) break; shp = scsi_register(shtp,sizeof(gdth_ext_str)); + if(shp == NULL) + continue; ha = HADATA(shp); if (!gdth_init_pci(&pcistr[ctr],ha)) { scsi_unregister(shp); @@ -3571,25 +3577,31 @@ static void gdth_flush(int hanum) ha = HADATA(gdth_ctr_tab[hanum]); sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - scp = scsi_allocate_device(sdev, 1, FALSE); - - scp->cmd_len = 12; - scp->use_sg = 0; + if(sdev) + scp = scsi_allocate_device(sdev, 1, FALSE); + + if(sdev!= NULL && scp != NULL) + { + scp->cmd_len = 12; + scp->use_sg = 0; - for (i = 0; i < MAX_HDRIVES; ++i) { - if (ha->hdr[i].present) { - gdtcmd.BoardNode = LOCALBOARD; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_FLUSH; - gdtcmd.u.cache.DeviceNo = i; - gdtcmd.u.cache.BlockNo = 1; - gdtcmd.u.cache.sg_canz = 0; - TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); - gdth_do_cmd(scp, &gdtcmd, 30); + for (i = 0; i < MAX_HDRIVES; ++i) { + if (ha->hdr[i].present) { + gdtcmd.BoardNode = LOCALBOARD; + gdtcmd.Service = CACHESERVICE; + gdtcmd.OpCode = GDT_FLUSH; + gdtcmd.u.cache.DeviceNo = i; + gdtcmd.u.cache.BlockNo = 1; + gdtcmd.u.cache.sg_canz = 0; + TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); + gdth_do_cmd(scp, &gdtcmd, 30); + } } } - scsi_release_command(scp); - scsi_free_host_dev(sdev); + if(scp!=NULL) + scsi_release_command(scp); + if(sdev!=NULL) + scsi_free_host_dev(sdev); } /* shutdown routine */ diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index 13d7dc398..e37175af2 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -39,7 +39,17 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum) piowr = (gdth_iowr_str *)buffer; sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]); + + if(sdev==NULL) + return -ENOMEM; + scp = scsi_allocate_device(sdev, 1, FALSE); + + if(scp==NULL) + { + scsi_free_host_dev(sdev); + return -ENOMEM; + } scp->cmd_len = 12; scp->use_sg = 0; diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index cd64662ee..e6d5b2942 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -304,6 +304,8 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt) #endif instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); + if(instance == NULL) + goto release; instance->base = ZTWO_VADDR(address); instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = z->slotaddr; diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 6d312168c..61298e9c0 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -198,6 +198,8 @@ int imm_detect(Scsi_Host_Template * host) host->can_queue = IMM_CAN_QUEUE; host->sg_tablesize = imm_sg; hreg = scsi_register(host, 0); + if(hreg == NULL) + continue; hreg->io_port = pb->base; hreg->n_io_port = ports; hreg->dma_channel = -1; diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index 4453fdab7..b47b7a0e1 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -2024,8 +2024,10 @@ char buf[32]; */ tpnt->proc_name = "in2000"; - detect_count++; instance = scsi_register(tpnt, sizeof(struct IN2000_hostdata)); + if(instance == NULL) + continue; + detect_count++; if (!instance_list) instance_list = instance; hostdata = (struct IN2000_hostdata *)instance->hostdata; diff --git a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c index fa03acae8..4dc0717c7 100644 --- a/drivers/scsi/ini9100u.c +++ b/drivers/scsi/ini9100u.c @@ -389,6 +389,11 @@ int i91u_detect(Scsi_Host_Template * tpnt) pHCB->HCS_Index = i; /* 7/29/98 */ hreg = scsi_register(tpnt, sizeof(HCS)); + if(hreg == NULL) + { + release_region(pHCB->HCS_Base, 256); + return 0; + } hreg->io_port = pHCB->HCS_Base; hreg->n_io_port = 0xff; hreg->can_queue = tul_num_scb; /* 03/05/98 */ diff --git a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c index 5d0efa845..3adcc43ce 100644 --- a/drivers/scsi/inia100.c +++ b/drivers/scsi/inia100.c @@ -363,6 +363,7 @@ int inia100_detect(Scsi_Host_Template * tpnt) sz = orc_num_scb * sizeof(ESCB); if ((pHCB->HCS_virEscbArray = (PVOID) kmalloc(sz, GFP_ATOMIC | GFP_DMA)) == NULL) { printk("inia100: ESCB memory allocation error\n"); + /* ?? does pHCB->HCS_virtScbArray leak ??*/ return (0); } memset((unsigned char *) pHCB->HCS_virEscbArray, 0, sz); @@ -383,7 +384,8 @@ int inia100_detect(Scsi_Host_Template * tpnt) hreg = scsi_register(tpnt, sizeof(ORC_HCS)); if (hreg == NULL) { - printk("Invalid scsi_register pointer.\n"); + release_region(pHCB->HCS_Base, 256); /* Register */ + return 0; } hreg->io_port = pHCB->HCS_Base; hreg->n_io_port = 0xff; diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 87b46476b..ba29e33d8 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -78,8 +78,8 @@ mac53c94_detect(Scsi_Host_Template *tp) panic("53c94: expected 2 addrs and intrs (got %d/%d)", node->n_addrs, node->n_intrs); host = scsi_register(tp, sizeof(struct fsc_state)); - if (host == 0) - panic("couldn't register 53c94 host"); + if (host == NULL) + break; host->unique_id = nfscs; #ifndef MODULE note_scsi_host(node, host); diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 54f3f7c39..cbc805e4d 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -258,6 +258,8 @@ int macscsi_detect(Scsi_Host_Template * tpnt) for (count = 0; count < mac_num_scsi; count++) { #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + if(instance == NULL) + continue; default_instance = instance; if (macintosh_config->ident == MAC_MODEL_IIFX) { diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index d44ce6a18..03e941fd9 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -440,6 +440,9 @@ int __init pas16_detect(Scsi_Host_Template * tpnt) break; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + if(instance == NULL) + break; + instance->io_port = io_port; NCR5380_init(instance, 0); diff --git a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c index 425932efc..3b9b0e227 100644 --- a/drivers/scsi/pci2000.c +++ b/drivers/scsi/pci2000.c @@ -682,6 +682,8 @@ int Pci2000_Detect (Scsi_Host_Template *tpnt) if (pci_enable_device(pdev)) continue; pshost = scsi_register (tpnt, sizeof(ADAPTER2000)); + if(pshost == NULL) + continue; padapter = HOSTDATA(pshost); padapter->basePort = pci_resource_start (pdev, 1); diff --git a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c index 1869be7c0..6b767a1c8 100644 --- a/drivers/scsi/pci2220i.c +++ b/drivers/scsi/pci2220i.c @@ -2545,6 +2545,9 @@ int Pci2220i_Detect (Scsi_Host_Template *tpnt) if (pci_enable_device(pcidev)) continue; pshost = scsi_register (tpnt, sizeof(ADAPTER2220I)); + if(pshost==NULL) + continue; + padapter = HOSTDATA(pshost); if ( GetRegs (pshost, FALSE, pcidev) ) diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index 73dfaf299..a0ca91c60 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c @@ -221,7 +221,11 @@ int __init pluto_detect(Scsi_Host_Template *tpnt) if (!ages) continue; host = scsi_register (tpnt, sizeof (struct pluto)); - if (!host) panic ("Cannot register PLUTO host\n"); + if(!host) + { + kfree(ages); + continue; + } nplutos++; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 96b3c8400..661316cac 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -194,6 +194,8 @@ int ppa_detect(Scsi_Host_Template * host) host->can_queue = PPA_CAN_QUEUE; host->sg_tablesize = ppa_sg; hreg = scsi_register(host, 0); + if(hreg == NULL) + continue; hreg->io_port = pb->base; hreg->n_io_port = ports; hreg->dma_channel = -1; diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index ccd233120..d3987e52a 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -597,6 +597,8 @@ int Psi240i_Detect (Scsi_Host_Template *tpnt) continue; pshost = scsi_register (tpnt, sizeof(ADAPTER240I)); + if(pshost == NULL) + continue; save_flags (flags); cli (); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index c52465a8c..8a9a6d92e 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -554,9 +554,21 @@ static void scsi_debug_send_self_command(struct Scsi_Host * shpnt) printk("Allocating host dev\n"); sdev = scsi_get_host_dev(shpnt); + if(sdev==NULL) + { + printk("Out of memory.\n"); + return; + } + printk("Got %p. Allocating command block\n", sdev); scp = scsi_allocate_request(sdev); printk("Got %p\n", scp); + + if(scp==NULL) + { + printk("Out of memory.\n"); + goto bail; + } scp->sr_cmd_len = 6; scp->sr_use_sg = 0; @@ -567,7 +579,8 @@ static void scsi_debug_send_self_command(struct Scsi_Host * shpnt) printk("Releasing command\n"); scsi_release_request(scp); - printk("Freeing device\n"); +bail: + printk("Freeing device\n"); scsi_free_host_dev(sdev); } @@ -762,6 +775,8 @@ void *scsi_debug_get_handle(void) static Scsi_Host_Template driver_copy = SCSI_DEBUG; void *rtn; rtn = kmalloc(sizeof(driver_copy), GFP_ATOMIC); + if(rtn==NULL) + return NULL; memcpy(rtn, (void *) &driver_copy, sizeof(driver_copy)); return rtn; } diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 1ee407d14..ebd5eff75 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -488,6 +488,9 @@ int __init seagate_st0x_detect (Scsi_Host_Template * tpnt) * loose our first interrupt. */ instance = scsi_register (tpnt, 0); + if(instance == NULL) + return 0; + hostno = instance->host_no; if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT, (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) { diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index cd92b715e..50a7bb34d 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -275,6 +275,8 @@ int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) SGIblows->proc_name = "SGIWD93"; sgiwd93_host = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); + if(sgiwd93_host == NULL) + return 0; sgiwd93_host->base = (unsigned long) hregs; sgiwd93_host->irq = SGI_WD93_0_IRQ; @@ -294,22 +296,25 @@ int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) /* set up second controller on the Indigo2 */ if(!sgi_guiness) { sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); - sgiwd93_host1->base = (unsigned long) hregs1; - sgiwd93_host1->irq = SGI_WD93_1_IRQ; - - buf = (uchar *) get_free_page(GFP_KERNEL); - init_hpc_chain(buf); - dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); - /* HPC_SCSI_REG1 | 0x03 | KSEG1 */ - wd33c93_init(sgiwd93_host1, (wd33c93_regs *) 0xbfbc8003, - dma_setup, dma_stop, WD33C93_FS_16_20); - - hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata; - hdata1->no_sync = 0; - hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf)); - dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); - - request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1); + if(sgiwd93_host1 != NULL) + { + sgiwd93_host1->base = (unsigned long) hregs1; + sgiwd93_host1->irq = SGI_WD93_1_IRQ; + + buf = (uchar *) get_free_page(GFP_KERNEL); + init_hpc_chain(buf); + dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); + /* HPC_SCSI_REG1 | 0x03 | KSEG1 */ + wd33c93_init(sgiwd93_host1, (wd33c93_regs *) 0xbfbc8003, + dma_setup, dma_stop, WD33C93_FS_16_20); + + hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata; + hdata1->no_sync = 0; + hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf)); + dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); + + request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1); + } } called = 1; diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 29084c39d..6769009d5 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -250,6 +250,9 @@ int sun3scsi_detect(Scsi_Host_Template * tpnt) #endif instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + if(instance == NULL) + return 0; + default_instance = instance; instance->io_port = (unsigned long) ioaddr; diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c index 3ea1adac1..733abc939 100644 --- a/drivers/scsi/sym53c416.c +++ b/drivers/scsi/sym53c416.c @@ -677,6 +677,8 @@ int sym53c416_detect(Scsi_Host_Template *tpnt) if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE)) { shpnt = scsi_register(tpnt, 0); + if(shpnt==NULL) + continue; save_flags(flags); cli(); /* Request for specified IRQ */ diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index f152035b9..3abd78cd2 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -234,6 +234,9 @@ int __init t128_detect(Scsi_Host_Template * tpnt){ break; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + if(instance == NULL) + break; + instance->base = base; NCR5380_init(instance, 0); diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 5d943c645..e7af1328b 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -1626,6 +1626,8 @@ int wd7000_detect (Scsi_Host_Template *tpnt) * array hostdata. */ sh = scsi_register (tpnt, sizeof (Adapter)); + if(sh==NULL) + continue; host = (Adapter *) sh->hostdata; #ifdef WD7000_DEBUG diff --git a/drivers/sound/724hwmcode.h b/drivers/sound/724hwmcode.h index 756583529..6f44377f1 100644 --- a/drivers/sound/724hwmcode.h +++ b/drivers/sound/724hwmcode.h @@ -9,7 +9,7 @@ #ifndef _HWMCODE_ #define _HWMCODE_ -static unsigned long int DspInst[] = { +static unsigned long int DspInst[] __initdata = { 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, @@ -20,7 +20,7 @@ static unsigned long int DspInst[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; -static unsigned long int CntrlInst[] = { +static unsigned long int CntrlInst[] __initdata = { 0x000007, 0x240007, 0x0C0007, 0x1C0007, 0x060007, 0x700002, 0x000020, 0x030040, 0x007104, 0x004286, 0x030040, 0x000F0D, @@ -799,7 +799,7 @@ static unsigned long int CntrlInst[] = { // 04/09?@creat // 04/12 stop nise fix // 06/21?@WorkingOff timming -static unsigned long int CntrlInst1E[] = { +static unsigned long int CntrlInst1E[] __initdata = { 0x000007, 0x240007, 0x0C0007, 0x1C0007, 0x060007, 0x700002, 0x000020, 0x030040, 0x007104, 0x004286, 0x030040, 0x000F0D, diff --git a/drivers/sound/cs4232.c b/drivers/sound/cs4232.c index 8891124cb..f32f295c3 100644 --- a/drivers/sound/cs4232.c +++ b/drivers/sound/cs4232.c @@ -40,6 +40,8 @@ * Christoph Hellwig Adapted to module_init/module_exit, * simple cleanups * Arnaldo C. de Melo got rid of attach_uart401 + * Bartlomiej Zolnierkiewicz + * Added some __init/__initdata/__exit */ #include @@ -67,7 +69,7 @@ static int mpu_base = 0, mpu_irq = 0; static int synth_base = 0, synth_irq = 0; static int mpu_detected = 0; -int probe_cs4232_mpu(struct address_info *hw_config) +int __init probe_cs4232_mpu(struct address_info *hw_config) { /* * Just write down the config values. @@ -79,7 +81,7 @@ int probe_cs4232_mpu(struct address_info *hw_config) return 1; } -static unsigned char crystal_key[] = /* A 32 byte magic key sequence */ +static unsigned char crystal_key[] __initdata = /* A 32 byte magic key sequence */ { 0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc, 0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2, @@ -93,7 +95,7 @@ static void sleep(unsigned howlong) schedule_timeout(howlong); } -int probe_cs4232(struct address_info *hw_config) +int __init probe_cs4232(struct address_info *hw_config) { int i, n; int base = hw_config->io_base, irq = hw_config->irq; @@ -209,7 +211,7 @@ int probe_cs4232(struct address_info *hw_config) return 0; } -void attach_cs4232(struct address_info *hw_config) +void __init attach_cs4232(struct address_info *hw_config) { int base = hw_config->io_base, irq = hw_config->irq, @@ -268,7 +270,7 @@ void attach_cs4232(struct address_info *hw_config) } } -void unload_cs4232(struct address_info *hw_config) +void __exit unload_cs4232(struct address_info *hw_config) { int base = hw_config->io_base, irq = hw_config->irq; int dma1 = hw_config->dma, dma2 = hw_config->dma2; diff --git a/drivers/sound/cs4281.c b/drivers/sound/cs4281.c index 5d2810129..a3005f6bc 100644 --- a/drivers/sound/cs4281.c +++ b/drivers/sound/cs4281.c @@ -40,6 +40,7 @@ // libOSSm.so) // 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal) // 11/03/00 trw - fixed interrupt loss/stutter, added debug. +// 11/10/00 bkz - added __devinit to cs4281_hw_init() // // ***************************************************************************** @@ -655,7 +656,7 @@ static int cs4281_write_ac97(struct cs4281_state *card, u32 offset, //****************************************************************************** // "Init4281()" -- Bring up the part. //****************************************************************************** -static int cs4281_hw_init(struct cs4281_state *card) +static int __devinit cs4281_hw_init(struct cs4281_state *card) { u32 ac97_slotid; u32 temp1, temp2; diff --git a/drivers/sound/cs461x_image.h b/drivers/sound/cs461x_image.h index 6826aa9a6..36d3ed18f 100644 --- a/drivers/sound/cs461x_image.h +++ b/drivers/sound/cs461x_image.h @@ -1,4 +1,4 @@ -struct BA1struct BA1Struct = { +struct BA1struct BA1Struct __initdata = { {{ 0x00000000, 0x00003000 },{ 0x00010000, 0x00003800 },{ 0x00020000, 0x00007000 }}, {0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000, diff --git a/drivers/sound/cs46xx.c b/drivers/sound/cs46xx.c index 765c1a643..a10f9d2c2 100644 --- a/drivers/sound/cs46xx.c +++ b/drivers/sound/cs46xx.c @@ -25,7 +25,9 @@ * Changes: * 20000815 Updated driver to kernel 2.4, some cleanups/fixes * Nils Faerber - * + * 20001110 Added __initdata to BA1Struct in cs461x_image.h + * and three more __init here + * Bartlomiej Zolnierkiewicz */ #include @@ -1999,7 +2001,7 @@ static int __init cs_ac97_init(struct cs_card *card) /* Boot the card */ -static void cs461x_download(struct cs_card *card, u32 *src, unsigned long offset, unsigned long len) +static void __init cs461x_download(struct cs_card *card, u32 *src, unsigned long offset, unsigned long len) { unsigned long counter; void *dst; @@ -2024,7 +2026,7 @@ struct BA1struct { #include "cs461x_image.h" -static void cs461x_download_image(struct cs_card *card) +static void __init cs461x_download_image(struct cs_card *card) { int idx; unsigned long offset = 0; @@ -2240,7 +2242,7 @@ static void cs461x_proc_stop(struct cs_card *card) -static int cs_hardware_init(struct cs_card *card) +static int __init cs_hardware_init(struct cs_card *card) { unsigned long end_time; unsigned int tmp; diff --git a/drivers/sound/dmasound/dmasound_core.c b/drivers/sound/dmasound/dmasound_core.c index 21f54bdb1..5550ee2c9 100644 --- a/drivers/sound/dmasound/dmasound_core.c +++ b/drivers/sound/dmasound/dmasound_core.c @@ -936,6 +936,7 @@ static int sq_release(struct inode *inode, struct file *file) static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { + int val; u_long fmt; int data; int size, nbufs; @@ -1013,7 +1014,7 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, } else size = write_sq.bufSize; sq_setup(&write_sq, write_sq.numBufs, nbufs, size); - return 0; + return IOCTL_OUT(arg,write_sq.bufSize | write_sq.numBufs << 16); case SNDCTL_DSP_GETOSPACE: info.fragments = write_sq.max_active - write_sq.count; info.fragstotal = write_sq.max_active; @@ -1022,6 +1023,9 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, if (copy_to_user((void *)arg, &info, sizeof(info))) return -EFAULT; return 0; + case SNDCTL_DSP_GETCAPS: + val = 1; /* Revision level of this ioctl() */ + return IOCTL_OUT(arg,val); default: return mixer_ioctl(inode, file, cmd, arg); diff --git a/drivers/sound/gus_midi.c b/drivers/sound/gus_midi.c index 1705d0df2..f9fd75161 100644 --- a/drivers/sound/gus_midi.c +++ b/drivers/sound/gus_midi.c @@ -9,6 +9,10 @@ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. + * + * Changes: + * 11-10-2000 Bartlomiej Zolnierkiewicz + * Added __init to gus_midi_init() */ #include "sound_config.h" @@ -199,7 +203,7 @@ static struct midi_operations gus_midi_operations = buffer_status: gus_midi_buffer_status, }; -void gus_midi_init(struct address_info *hw_config) +void __init gus_midi_init(struct address_info *hw_config) { int dev = sound_alloc_mididev(); diff --git a/drivers/sound/gus_wave.c b/drivers/sound/gus_wave.c index 26853486e..add5de9c2 100644 --- a/drivers/sound/gus_wave.c +++ b/drivers/sound/gus_wave.c @@ -14,6 +14,7 @@ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious * usage of CS4231A codec, GUS wave and MIDI for GUS MAX. + * Bartlomiej Zolnierkiewicz : added some __init/__exit */ @@ -853,7 +854,7 @@ static void gus_initialize(void) } -static void pnp_mem_init(void) +static void __init pnp_mem_init(void) { #include "iwmem.h" #define CHUNK_SIZE (256*1024) @@ -1022,7 +1023,7 @@ static void pnp_mem_init(void) gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02); } -int gus_wave_detect(int baseaddr) +int __init gus_wave_detect(int baseaddr) { unsigned long i, max_mem = 1024L; unsigned long loc; @@ -2901,7 +2902,7 @@ static struct mixer_operations gus_mixer_operations = ioctl: gus_default_mixer_ioctl }; -static int gus_default_mixer_init(void) +static int __init gus_default_mixer_init(void) { int n; @@ -2926,7 +2927,7 @@ static int gus_default_mixer_init(void) return n; } -void gus_wave_init(struct address_info *hw_config) +void __init gus_wave_init(struct address_info *hw_config) { unsigned long flags; unsigned char val; @@ -3167,7 +3168,7 @@ void gus_wave_init(struct address_info *hw_config) } } -void gus_wave_unload(struct address_info *hw_config) +void __exit gus_wave_unload(struct address_info *hw_config) { #ifdef CONFIG_SOUND_GUSMAX if (have_gus_max) diff --git a/drivers/sound/ics2101.c b/drivers/sound/ics2101.c index 84ca968df..5c388ae8a 100644 --- a/drivers/sound/ics2101.c +++ b/drivers/sound/ics2101.c @@ -12,6 +12,7 @@ * * * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) + * Bartlomiej Zolnierkiewicz : added __init to ics2101_mixer_init() */ #include "sound_config.h" @@ -212,8 +213,7 @@ static struct mixer_operations ics2101_mixer_operations = ioctl: ics2101_mixer_ioctl }; -int -ics2101_mixer_init(void) +int __init ics2101_mixer_init(void) { int i; int n; diff --git a/drivers/sound/iwmem.h b/drivers/sound/iwmem.h index b96d5ed1b..84745fbca 100644 --- a/drivers/sound/iwmem.h +++ b/drivers/sound/iwmem.h @@ -1,5 +1,5 @@ /* - * sound/iwmem.c + * sound/iwmem.h * * DRAM size encoding table for AMD Interwave chip. */ @@ -9,12 +9,15 @@ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. + * + * Changes: + * Bartlomiej Zolnierkiewicz : added __initdata to mem_decode */ #define K 1024 #define M (1024*K) -static int mem_decode[][4] = +static int mem_decode[][4] __initdata = { /* Bank0 Bank1 Bank2 Bank3 Encoding bits */ {256*K, 0, 0, 0}, /* 0 */ diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c index c2cb30457..ca96b7f99 100644 --- a/drivers/sound/maestro.c +++ b/drivers/sound/maestro.c @@ -115,6 +115,8 @@ * themselves, but we'll see. * * History + * (still v0.14) Nov 10 2000 - Bartlomiej Zolnierkiewicz + * add __init to maestro_ac97_init() and maestro_install() * (still based on v0.14) Mar 29 2000 - Zach Brown * move to 2.3 power management interface, which * required hacking some suspend/resume/check paths @@ -812,7 +814,7 @@ ac97_recmask_io(struct ess_card *card, int read, int mask) * The PT101 setup is untested. */ -static u16 maestro_ac97_init(struct ess_card *card) +static u16 __init maestro_ac97_init(struct ess_card *card) { u16 vend1, vend2, caps; @@ -3290,7 +3292,7 @@ parse_power(struct ess_card *card, struct pci_dev *pcidev) return card->power_regs ? 1 : 0; } -static int +static int __init maestro_install(struct pci_dev *pcidev, int card_type) { u32 n; diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c index d9226d406..54927b719 100644 --- a/drivers/sound/maui.c +++ b/drivers/sound/maui.c @@ -14,6 +14,8 @@ * Alan Cox General clean up, use kernel IRQ * system * Christoph Hellwig Adapted to module_init/module_exit + * Bartlomiej Zolnierkiewicz + * Added __init to download_code() * * Status: * Andrew J. Kroll Tested 06/01/1999 with: @@ -104,7 +106,7 @@ static void mauiintr(int irq, void *dev_id, struct pt_regs *dummy) irq_ok = 1; } -static int download_code(void) +static int __init download_code(void) { int i, lines = 0; int eol_seen = 0, done = 0; diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c index de587668a..e6bb002e0 100644 --- a/drivers/sound/mpu401.c +++ b/drivers/sound/mpu401.c @@ -13,6 +13,7 @@ * * Thomas Sailer ioctl code reworked (vmalloc/vfree removed) * Alan Cox modularisation, use normal request_irq, use dev_id + * Bartlomiej Zolnierkiewicz removed some __init to allow using many drivers */ #include @@ -908,7 +909,7 @@ static struct midi_operations mpu401_midi_proto = static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV]; -static void __init mpu401_chk_version(int n, struct mpu_config *devc) +static void mpu401_chk_version(int n, struct mpu_config *devc) { int tmp; unsigned long flags; @@ -939,7 +940,7 @@ static void __init mpu401_chk_version(int n, struct mpu_config *devc) restore_flags(flags); } -void __init attach_mpu401(struct address_info *hw_config, struct module *owner) +void attach_mpu401(struct address_info *hw_config, struct module *owner) { unsigned long flags; char revision_char; @@ -1166,7 +1167,7 @@ static void set_uart_mode(int dev, struct mpu_config *devc, int arg) } -int __init probe_mpu401(struct address_info *hw_config) +int probe_mpu401(struct address_info *hw_config) { int ok = 0; struct mpu_config tmp_devc; @@ -1662,7 +1663,7 @@ static void timer_ext_event(struct mpu_config *devc, int event, int parm) } } -static int __init mpu_timer_init(int midi_dev) +static int mpu_timer_init(int midi_dev) { struct mpu_config *devc; int n; @@ -1724,7 +1725,7 @@ static int __initdata irq = -1; MODULE_PARM(irq, "i"); MODULE_PARM(io, "i"); -int init_mpu401(void) +int __init init_mpu401(void) { /* Can be loaded either for module use or to provide functions to others */ @@ -1739,7 +1740,7 @@ int init_mpu401(void) return 0; } -void cleanup_mpu401(void) +void __exit cleanup_mpu401(void) { if (io != -1 && irq != -1) { /* Check for use by, for example, sscape driver */ diff --git a/drivers/sound/msnd.c b/drivers/sound/msnd.c index 43b42d0a5..2fd11df4b 100644 --- a/drivers/sound/msnd.c +++ b/drivers/sound/msnd.c @@ -57,7 +57,7 @@ static multisound_dev_t *devs[MSND_MAX_DEVS]; static int num_devs; -int msnd_register(multisound_dev_t *dev) +int __init msnd_register(multisound_dev_t *dev) { int i; diff --git a/drivers/sound/msnd_pinnacle.c b/drivers/sound/msnd_pinnacle.c index 7b9b1cc29..305969ff0 100644 --- a/drivers/sound/msnd_pinnacle.c +++ b/drivers/sound/msnd_pinnacle.c @@ -1404,7 +1404,7 @@ static int __init attach_multisound(void) } #ifdef MODULE -static void unload_multisound(void) +static void __exit unload_multisound(void) { release_region(dev.io, dev.numio); free_irq(dev.irq, &dev); diff --git a/drivers/sound/nm256_audio.c b/drivers/sound/nm256_audio.c index 27f432e17..3aaca0c1b 100644 --- a/drivers/sound/nm256_audio.c +++ b/drivers/sound/nm256_audio.c @@ -11,6 +11,10 @@ * This driver was written by someone who wishes to remain anonymous. * It is in the public domain, so share and enjoy. Try to make a profit * off of it; go on, I dare you. + * + * Changes: + * 11-10-2000 Bartlomiej Zolnierkiewicz + * Added some __init */ #define __NO_VERSION__ @@ -945,7 +949,7 @@ static struct ac97_mixer_value_list mixer_defaults[] = { /* Installs the AC97 mixer into CARD. */ -static int +static int __init nm256_install_mixer (struct nm256_info *card) { int mixer; @@ -989,7 +993,7 @@ nm256_full_reset (struct nm256_info *card) * RAM. */ -static void +static void __init nm256_peek_for_sig (struct nm256_info *card) { u32 port1offset @@ -1031,7 +1035,7 @@ nm256_peek_for_sig (struct nm256_info *card) * VERSTR is a human-readable version string. */ -static int +static int __init nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) { struct nm256_info *card; @@ -1252,7 +1256,7 @@ handle_pm_event (struct pm_dev *dev, pm_request_t rqst, void *data) * the sound cards are. */ -int +int __init init_nm256(void) { struct pci_dev *pcidev = NULL; diff --git a/drivers/sound/pas2_midi.c b/drivers/sound/pas2_midi.c index 979e2a8ec..93ee7da26 100644 --- a/drivers/sound/pas2_midi.c +++ b/drivers/sound/pas2_midi.c @@ -9,6 +9,8 @@ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. + * + * Bartlomiej Zolnierkiewicz : Added __init to pas_init_mixer() */ #include "sound_config.h" @@ -204,7 +206,7 @@ static struct midi_operations pas_midi_operations = buffer_status: pas_buffer_status, }; -void pas_midi_init(void) +void __init pas_midi_init(void) { int dev = sound_alloc_mididev(); diff --git a/drivers/sound/pas2_mixer.c b/drivers/sound/pas2_mixer.c index 00cadcc93..92a918a2c 100644 --- a/drivers/sound/pas2_mixer.c +++ b/drivers/sound/pas2_mixer.c @@ -14,6 +14,7 @@ */ /* * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) + * Bartlomiej Zolnierkiewicz : added __init to pas_init_mixer() */ #include "sound_config.h" @@ -315,7 +316,7 @@ static struct mixer_operations pas_mixer_operations = ioctl: pas_mixer_ioctl }; -int +int __init pas_init_mixer(void) { int d; diff --git a/drivers/sound/pas2_pcm.c b/drivers/sound/pas2_pcm.c index 90d461ed0..f3be2c052 100644 --- a/drivers/sound/pas2_pcm.c +++ b/drivers/sound/pas2_pcm.c @@ -12,6 +12,7 @@ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) * Alan Cox : Swatted a double allocation of device bug. Made a few * more things module options. + * Bartlomiej Zolnierkiewicz : Added __init to pas_pcm_init() */ #include "sound_config.h" @@ -385,7 +386,7 @@ static struct audio_driver pas_audio_driver = trigger: pas_audio_trigger }; -void pas_pcm_init(struct address_info *hw_config) +void __init pas_pcm_init(struct address_info *hw_config) { DEB(printk("pas2_pcm.c: long pas_pcm_init()\n")); diff --git a/drivers/sound/pss.c b/drivers/sound/pss.c index cf30d7374..728fe8165 100644 --- a/drivers/sound/pss.c +++ b/drivers/sound/pss.c @@ -50,6 +50,8 @@ * setting is the previous hardcoded setting "/etc/sound/pss_synth". * 00-03-03: Christoph Hellwig * Adapted to module_init/module_exit + * 11-10-2000: Bartlomiej Zolnierkiewicz + * Added __init to probe_pss(), attach_pss() and probe_pss_mpu() */ @@ -168,7 +170,7 @@ static void pss_write(pss_confdata *devc, int data) printk(KERN_WARNING "PSS: DSP Command (%04x) Timeout.\n", data); } -int probe_pss(struct address_info *hw_config) +int __init probe_pss(struct address_info *hw_config) { unsigned short id; int irq, dma; @@ -644,7 +646,7 @@ void configure_nonsound_components(void) } } -void attach_pss(struct address_info *hw_config) +void __init attach_pss(struct address_info *hw_config) { unsigned short id; char tmp[100]; @@ -693,7 +695,7 @@ void attach_pss(struct address_info *hw_config) conf_printf(tmp, hw_config); } -int probe_pss_mpu(struct address_info *hw_config) +int __init probe_pss_mpu(struct address_info *hw_config) { int timeout; diff --git a/drivers/sound/sgalaxy.c b/drivers/sound/sgalaxy.c index ef0e4199c..9d16bbe9f 100644 --- a/drivers/sound/sgalaxy.c +++ b/drivers/sound/sgalaxy.c @@ -16,6 +16,10 @@ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. + * + * Changes: + * 11-10-2000 Bartlomiej Zolnierkiewicz + * Added __init to sb_rst() and sb_cmd() */ #include @@ -40,7 +44,7 @@ static void sleep( unsigned howlong ) #define SBDSP_STATUS SBDSP_COMMAND #define SBDSP_DATA_AVAIL 0xE -static int sb_rst(int base) +static int __init sb_rst(int base) { int i; @@ -62,7 +66,7 @@ static int sb_rst(int base) return 1; } -static int sb_cmd( int base, unsigned char val ) +static int __init sb_cmd( int base, unsigned char val ) { int i; diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c index 1c399bd5c..85e523cbd 100644 --- a/drivers/sound/sscape.c +++ b/drivers/sound/sscape.c @@ -14,6 +14,7 @@ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) * Sergey Smitienko : ensoniq p'n'p support * Christoph Hellwig : adapted to module_init/module_exit + * Bartlomiej Zolnierkiewicz : added __init to attach_sscape() */ #include @@ -609,7 +610,7 @@ static coproc_operations sscape_coproc_operations = static int sscape_detected = 0; static int sscape_is_pnp = 0; -void attach_sscape(struct address_info *hw_config) +void __init attach_sscape(struct address_info *hw_config) { #ifndef SSCAPE_REGS /* diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c index b6e870d32..9e32811ac 100644 --- a/drivers/sound/trident.c +++ b/drivers/sound/trident.c @@ -145,7 +145,7 @@ /* minor number of /dev/swmodem (temporary, experimental) */ #define SND_DEV_SWMODEM 7 -static const unsigned ali_multi_channels_5_1[] = { ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL,ALI_CENTER_CHANNEL, ALI_LEF_CHANNEL/*, ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL*/}; +static const unsigned ali_multi_channels_5_1[] = { ALI_CENTER_CHANNEL, ALI_LEF_CHANNEL, ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL}; static const unsigned sample_size[] = { 1, 2, 2, 4 }; static const unsigned sample_shift[] = { 0, 1, 1, 2 }; diff --git a/drivers/sound/vwsnd.c b/drivers/sound/vwsnd.c index be2cdf678..3143d7b64 100644 --- a/drivers/sound/vwsnd.c +++ b/drivers/sound/vwsnd.c @@ -135,6 +135,10 @@ * For AFMT_S8, AFMT_MU_LAW and AFMT_A_LAW output, we have to XOR * the 0x80 bit in software to compensate for Lithium's XOR. * This happens in pcm_copy_{in,out}(). + * + * Changes: + * 11-10-2000 Bartlomiej Zolnierkiewicz + * Added some __init/__exit */ #include @@ -1330,7 +1334,7 @@ static void ad1843_shutdown_adc(lithium_t *lith) * * return 0 on success, -errno on failure. */ -static int ad1843_init(lithium_t *lith) +static int __init ad1843_init(lithium_t *lith) { unsigned long later; int err; @@ -3239,7 +3243,7 @@ static struct file_operations vwsnd_mixer_fops = { /* driver probe routine. Return nonzero if hardware is found. */ -static int probe_vwsnd(struct address_info *hw_config) +static int __init probe_vwsnd(struct address_info *hw_config) { lithium_t lith; int w; @@ -3291,7 +3295,7 @@ static int probe_vwsnd(struct address_info *hw_config) * Return +minor_dev on success, -errno on failure. */ -static int attach_vwsnd(struct address_info *hw_config) +static int __init attach_vwsnd(struct address_info *hw_config) { vwsnd_dev_t *devc = NULL; int err = -ENOMEM; @@ -3417,7 +3421,7 @@ static int attach_vwsnd(struct address_info *hw_config) return err; } -static int unload_vwsnd(struct address_info *hw_config) +static int __exit unload_vwsnd(struct address_info *hw_config) { vwsnd_dev_t *devc, **devcp; @@ -3481,10 +3485,3 @@ static void __exit cleanup_vwsnd(void) module_init(init_vwsnd); module_exit(cleanup_vwsnd); - -/* - * Local variables: - * compile-command: "cd ../..; make modules SUBDIRS=drivers/sound" - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/sound/waveartist.c b/drivers/sound/waveartist.c index 5e4f6c34d..be7b9afbc 100644 --- a/drivers/sound/waveartist.c +++ b/drivers/sound/waveartist.c @@ -17,6 +17,10 @@ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. + * + * Changes: + * 11-10-2000 Bartlomiej Zolnierkiewicz + * Added __init to waveartist_init() */ /* Debugging */ @@ -1190,8 +1194,7 @@ static struct mixer_operations waveartist_mixer_operations = ioctl: waveartist_mixer_ioctl }; -static int -waveartist_init(wavnc_info *devc) +static int __init waveartist_init(wavnc_info *devc) { wavnc_port_info *portc; char rev[3], dev_name[64]; diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c index 5a1a161d9..521f2045a 100644 --- a/drivers/sound/wavfront.c +++ b/drivers/sound/wavfront.c @@ -60,7 +60,12 @@ * * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software - * for more info. */ + * for more info. + * + * Changes: + * 11-10-2000 Bartlomiej Zolnierkiewicz + * Added some __init and __initdata to entries in yss225.c + */ #include @@ -2247,9 +2252,7 @@ wavefront_should_cause_interrupt (int val, int port, int timeout) restore_flags (flags); } -static int -wavefront_hw_reset (void) - +static int __init wavefront_hw_reset (void) { int bits; int hwv[2]; @@ -2703,8 +2706,7 @@ static int __init wavefront_config_midi (void) return 0; } -static int -wavefront_do_reset (int atboot) +static int __init wavefront_do_reset (int atboot) { char voices[1]; @@ -3076,7 +3078,7 @@ wffx_ioctl (wavefront_fx_info *r) a somewhat "algorithmic" approach. */ -static int wffx_init (void) +static int __init wffx_init (void) { int i; int j; diff --git a/drivers/sound/ymf_sb.c b/drivers/sound/ymf_sb.c index 6020b85b6..26a062a8f 100644 --- a/drivers/sound/ymf_sb.c +++ b/drivers/sound/ymf_sb.c @@ -43,6 +43,10 @@ Thu Sep 21 05:32:51 BRT 2000 0.0.5 * got rid of attach_uart401 and attach_sbmpu Arnaldo Carvalho de Melo + + Fri Nov 10 21:24:11 CET 2000 0.0.6 + * added some __init and __initdata to entries in 724hwmcode.h + Bartlomiej Zolnierkiewicz */ #include @@ -220,7 +224,7 @@ #define PFX "ymf_sb: " -#define YMFSB_VERSION "0.0.5" +#define YMFSB_VERSION "0.0.6" #define YMFSB_CARD_NAME "YMF7xx Legacy Audio driver " YMFSB_VERSION #ifdef SUPPORT_UART401_MIDI @@ -338,7 +342,7 @@ static int writeAc97( int adr, unsigned short val ) return 0; } -static int checkCodec( struct pci_dev *pcidev ) +static int __init checkCodec( struct pci_dev *pcidev ) { u8 tmp8; @@ -357,7 +361,7 @@ static int checkCodec( struct pci_dev *pcidev ) return 0; } -static int setupLegacyIO( struct pci_dev *pcidev ) +static int __init setupLegacyIO( struct pci_dev *pcidev ) { int v; int sbio=0,mpuio=0,oplio=0,dma=0; @@ -500,7 +504,7 @@ static void disableDSP( void ) return; } -static int setupInstruction( struct pci_dev *pcidev ) +static int __init setupInstruction( struct pci_dev *pcidev ) { int i; int val; diff --git a/drivers/sound/yss225.c b/drivers/sound/yss225.c index e5d7ec098..78f946efe 100644 --- a/drivers/sound/yss225.c +++ b/drivers/sound/yss225.c @@ -1,4 +1,4 @@ -unsigned char page_zero[] = { +unsigned char page_zero[] __initdata = { 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, @@ -25,7 +25,7 @@ unsigned char page_zero[] = { 0x1d, 0x02, 0xdf }; -unsigned char page_one[] = { +unsigned char page_one[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, 0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, @@ -52,7 +52,7 @@ unsigned char page_one[] = { 0x60, 0x00, 0x1b }; -unsigned char page_two[] = { +unsigned char page_two[] __initdata = { 0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, 0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -67,7 +67,7 @@ unsigned char page_two[] = { 0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 }; -unsigned char page_three[] = { +unsigned char page_three[] __initdata = { 0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -82,7 +82,7 @@ unsigned char page_three[] = { 0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 }; -unsigned char page_four[] = { +unsigned char page_four[] __initdata = { 0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -97,7 +97,7 @@ unsigned char page_four[] = { 0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 }; -unsigned char page_six[] = { +unsigned char page_six[] __initdata = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, @@ -118,7 +118,7 @@ unsigned char page_six[] = { 0x80, 0x00, 0x7e, 0x80, 0x80 }; -unsigned char page_seven[] = { +unsigned char page_seven[] __initdata = { 0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, @@ -145,7 +145,7 @@ unsigned char page_seven[] = { 0x00, 0x02, 0x00 }; -unsigned char page_zero_v2[] = { +unsigned char page_zero_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -157,7 +157,7 @@ unsigned char page_zero_v2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned char page_one_v2[] = { +unsigned char page_one_v2[] __initdata = { 0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -169,21 +169,21 @@ unsigned char page_one_v2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned char page_two_v2[] = { +unsigned char page_two_v2[] __initdata = { 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned char page_three_v2[] = { +unsigned char page_three_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned char page_four_v2[] = { +unsigned char page_four_v2[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -191,7 +191,7 @@ unsigned char page_four_v2[] = { 0x00, 0x00, 0x00, 0x00 }; -unsigned char page_seven_v2[] = { +unsigned char page_seven_v2[] __initdata = { 0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -202,7 +202,7 @@ unsigned char page_seven_v2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned char mod_v2[] = { +unsigned char mod_v2[] __initdata = { 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, @@ -232,7 +232,7 @@ unsigned char mod_v2[] = { 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, 0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 }; -unsigned char coefficients[] = { +unsigned char coefficients[] __initdata = { 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, 0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, @@ -268,14 +268,14 @@ unsigned char coefficients[] = { 0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, 0xba }; -unsigned char coefficients2[] = { +unsigned char coefficients2[] __initdata = { 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, 0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, 0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 }; -unsigned char coefficients3[] = { +unsigned char coefficients3[] __initdata = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, 0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in index 9e510e087..d4feefa21 100644 --- a/drivers/usb/Config.in +++ b/drivers/usb/Config.in @@ -37,6 +37,7 @@ comment 'USB Devices' if [ "$CONFIG_USB_SERIAL" != "n" ]; then bool ' USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC dep_tristate ' USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL + dep_tristate ' USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then dep_tristate ' USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL dep_tristate ' USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL @@ -49,8 +50,8 @@ comment 'USB Devices' bool ' USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X bool ' USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W fi - dep_tristate ' USB Digi International AccelePort USB Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL dep_tristate ' USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL + dep_tristate ' USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL fi bool ' USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG fi diff --git a/drivers/usb/acm.c b/drivers/usb/acm.c index 65a1bbbb0..1736c503b 100644 --- a/drivers/usb/acm.c +++ b/drivers/usb/acm.c @@ -477,114 +477,113 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_ * USB probe and disconnect routines. */ -static void *acm_probe(struct usb_device *dev, unsigned int ifnum) +static void *acm_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct acm *acm; struct usb_config_descriptor *cfacm; struct usb_interface_descriptor *ifcom, *ifdata; struct usb_endpoint_descriptor *epctrl, *epread, *epwrite; - int readsize, ctrlsize, minor, i; + int readsize, ctrlsize, minor; unsigned char *buf; - if (dev->descriptor.bDeviceClass != 2 || dev->descriptor.bDeviceSubClass != 0 + /* Since 0 is treated as a wildcard by the USB pattern matching, + we explicitly check bDeviceSubClass and bDeviceProtocol + here. */ + if (dev->descriptor.bDeviceSubClass != 0 || dev->descriptor.bDeviceProtocol != 0) return NULL; - for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { + cfacm = dev->actconfig; - cfacm = dev->config + i; + dbg("probing config %d", cfacm->bConfigurationValue); - dbg("probing config %d", cfacm->bConfigurationValue); + if (cfacm->bNumInterfaces != 2 || + usb_interface_claimed(cfacm->interface + 0) || + usb_interface_claimed(cfacm->interface + 1)) + return NULL; - if (cfacm->bNumInterfaces != 2 || - usb_interface_claimed(cfacm->interface + 0) || - usb_interface_claimed(cfacm->interface + 1)) - continue; + ifcom = cfacm->interface[0].altsetting + 0; + ifdata = cfacm->interface[1].altsetting + 0; - ifcom = cfacm->interface[0].altsetting + 0; - ifdata = cfacm->interface[1].altsetting + 0; - - if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints != 2) { - ifcom = cfacm->interface[1].altsetting + 0; - ifdata = cfacm->interface[0].altsetting + 0; - if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints != 2) - continue; - } + if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints != 2) { + ifcom = cfacm->interface[1].altsetting + 0; + ifdata = cfacm->interface[0].altsetting + 0; + if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints !=2) + return NULL; + } - if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 || - ifcom->bInterfaceProtocol != 1 || ifcom->bNumEndpoints < 1) - continue; + if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 || + ifcom->bInterfaceProtocol != 1 || ifcom->bNumEndpoints != 1) + return NULL; - epctrl = ifcom->endpoint + 0; - epread = ifdata->endpoint + 0; - epwrite = ifdata->endpoint + 1; + epctrl = ifcom->endpoint + 0; + epread = ifdata->endpoint + 0; + epwrite = ifdata->endpoint + 1; - if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 || - (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 || - ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80) - continue; + if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 || + (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 || + ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80) + return NULL; - if ((epread->bEndpointAddress & 0x80) != 0x80) { - epread = ifdata->endpoint + 1; - epwrite = ifdata->endpoint + 0; - } + if ((epread->bEndpointAddress & 0x80) != 0x80) { + epread = ifdata->endpoint + 1; + epwrite = ifdata->endpoint + 0; + } - usb_set_configuration(dev, cfacm->bConfigurationValue); + usb_set_configuration(dev, cfacm->bConfigurationValue); - for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); - if (acm_table[minor]) { - err("no more free acm devices"); - return NULL; - } + for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); + if (acm_table[minor]) { + err("no more free acm devices"); + return NULL; + } - if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) { - err("out of memory"); - return NULL; - } - memset(acm, 0, sizeof(struct acm)); + if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) { + err("out of memory"); + return NULL; + } + memset(acm, 0, sizeof(struct acm)); - ctrlsize = epctrl->wMaxPacketSize; - readsize = epread->wMaxPacketSize; - acm->writesize = epwrite->wMaxPacketSize; - acm->iface = cfacm->interface; - acm->minor = minor; - acm->dev = dev; + ctrlsize = epctrl->wMaxPacketSize; + readsize = epread->wMaxPacketSize; + acm->writesize = epwrite->wMaxPacketSize; + acm->iface = cfacm->interface; + acm->minor = minor; + acm->dev = dev; - acm->tqueue.routine = acm_softint; - acm->tqueue.data = acm; + acm->tqueue.routine = acm_softint; + acm->tqueue.data = acm; - if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) { - err("out of memory"); - kfree(acm); - return NULL; - } + if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) { + err("out of memory"); + kfree(acm); + return NULL; + } - FILL_INT_URB(&acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress), - buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); + FILL_INT_URB(&acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress), + buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); - FILL_BULK_URB(&acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress), - buf += ctrlsize, readsize, acm_read_bulk, acm); - acm->readurb.transfer_flags |= USB_NO_FSBR; + FILL_BULK_URB(&acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress), + buf += ctrlsize, readsize, acm_read_bulk, acm); + acm->readurb.transfer_flags |= USB_NO_FSBR; - FILL_BULK_URB(&acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress), - buf += readsize, acm->writesize, acm_write_bulk, acm); - acm->writeurb.transfer_flags |= USB_NO_FSBR; - - printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor); + FILL_BULK_URB(&acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress), + buf += readsize, acm->writesize, acm_write_bulk, acm); + acm->writeurb.transfer_flags |= USB_NO_FSBR; - acm_set_control(acm, acm->ctrlout); + printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor); - acm->line.speed = cpu_to_le32(9600); - acm->line.databits = 8; - acm_set_line(acm, &acm->line); + acm_set_control(acm, acm->ctrlout); - usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm); - usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm); + acm->line.speed = cpu_to_le32(9600); + acm->line.databits = 8; + acm_set_line(acm, &acm->line); - tty_register_devfs(&acm_tty_driver, 0, minor); - return acm_table[minor] = acm; - } + usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm); + usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm); - return NULL; + tty_register_devfs(&acm_tty_driver, 0, minor); + return acm_table[minor] = acm; } static void acm_disconnect(struct usb_device *dev, void *ptr) @@ -622,10 +621,19 @@ static void acm_disconnect(struct usb_device *dev, void *ptr) * USB driver structure. */ +static struct usb_device_id acm_ids [] = { + { bDeviceClass: 2}, + { bInterfaceClass: 2, bInterfaceSubClass: 2, bInterfaceProtocol: 1}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, acm_ids); + static struct usb_driver acm_driver = { name: "acm", probe: acm_probe, - disconnect: acm_disconnect + disconnect: acm_disconnect, + id_table: acm_ids, }; /* diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c index 1db828b24..065d31942 100644 --- a/drivers/usb/audio.c +++ b/drivers/usb/audio.c @@ -2691,16 +2691,23 @@ static /*const*/ struct file_operations usb_audio_fops = { /* --------------------------------------------------------------------- */ -static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum); +static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); static void usb_audio_disconnect(struct usb_device *dev, void *ptr); +static struct usb_device_id usb_audio_ids [] = { + { bInterfaceClass: USB_CLASS_AUDIO, bInterfaceSubClass: 1}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usb_audio_ids); + static struct usb_driver usb_audio_driver = { - "audio", - usb_audio_probe, - usb_audio_disconnect, - LIST_HEAD_INIT(usb_audio_driver.driver_list), - NULL, - 0 + name: "audio", + probe: usb_audio_probe, + disconnect: usb_audio_disconnect, + driver_list: LIST_HEAD_INIT(usb_audio_driver.driver_list), + id_table: usb_audio_ids, }; static void *find_descriptor(void *descstart, unsigned int desclen, void *after, @@ -3640,7 +3647,8 @@ ret: /* we only care for the currently active configuration */ -static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum) +static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_config_descriptor *config = dev->actconfig; unsigned char *buffer; @@ -3653,25 +3661,13 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum) config->interface[ifnum].altsetting[0].bInterfaceClass, config->interface[ifnum].altsetting[0].bInterfaceSubClass); #endif - if (config->interface[ifnum].altsetting[0].bInterfaceClass != USB_CLASS_AUDIO || - config->interface[ifnum].altsetting[0].bInterfaceSubClass != 1) { -#if 0 - printk(KERN_DEBUG "usbaudio: vendor id 0x%04x, product id 0x%04x contains no AudioControl interface\n", - dev->descriptor.idVendor, dev->descriptor.idProduct); -#endif - return NULL; - } + /* * audiocontrol interface found * find which configuration number is active */ - for (i = 0; i < dev->descriptor.bNumConfigurations; i++) - if (dev->config+i == config) - goto configfound; - printk(KERN_ERR "usbaudio: cannot find active configuration number of device %d\n", dev->devnum); - return NULL; + i = dev->actconfig - config; - configfound: if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { printk(KERN_ERR "usbaudio: set_configuration failed (ConfigValue 0x%x)\n", config->bConfigurationValue); return NULL; diff --git a/drivers/usb/bluetooth.c b/drivers/usb/bluetooth.c index c543b249e..0509f2347 100644 --- a/drivers/usb/bluetooth.c +++ b/drivers/usb/bluetooth.c @@ -183,14 +183,27 @@ static void bluetooth_ctrl_callback (struct urb *urb); static void bluetooth_read_bulk_callback (struct urb *urb); static void bluetooth_write_bulk_callback (struct urb *urb); -static void * usb_bluetooth_probe (struct usb_device *dev, unsigned int ifnum); +static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); static void usb_bluetooth_disconnect (struct usb_device *dev, void *ptr); +static struct usb_device_id usb_bluetooth_ids [] = { + { + bDeviceClass: WIRELESS_CLASS_CODE, + bDeviceSubClass: RF_SUBCLASS_CODE, + bDeviceProtocol: BLUETOOTH_PROGRAMMING_PROTOCOL_CODE + }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids); + static struct usb_driver usb_bluetooth_driver = { name: "bluetooth", probe: usb_bluetooth_probe, disconnect: usb_bluetooth_disconnect, + id_table: usb_bluetooth_ids, }; static int bluetooth_refcount; @@ -950,7 +963,8 @@ static void bluetooth_softint(void *private) } -static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum) +static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_bluetooth *bluetooth = NULL; struct usb_interface_descriptor *interface; @@ -967,16 +981,6 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum) int num_bulk_in = 0; int num_bulk_out = 0; - /* see if this device has the proper class signature */ - if ((dev->descriptor.bDeviceClass != WIRELESS_CLASS_CODE) || - (dev->descriptor.bDeviceSubClass != RF_SUBCLASS_CODE) || - (dev->descriptor.bDeviceProtocol != BLUETOOTH_PROGRAMMING_PROTOCOL_CODE)) { - dbg (__FUNCTION__ " - class signature %d, %d, %d did not match", - dev->descriptor.bDeviceClass, dev->descriptor.bDeviceSubClass, - dev->descriptor.bDeviceProtocol); - return NULL; - } - interface = &dev->actconfig->interface[ifnum].altsetting[0]; control_out_endpoint = interface->bInterfaceNumber; diff --git a/drivers/usb/dabusb.c b/drivers/usb/dabusb.c index d14e8e97b..154ed17cb 100644 --- a/drivers/usb/dabusb.c +++ b/drivers/usb/dabusb.c @@ -718,7 +718,8 @@ static int dabusb_find_struct (void) } /* --------------------------------------------------------------------- */ -static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum) +static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum, + const struct usb_device_id *id) { int devnum; pdabusb_t s; @@ -726,11 +727,6 @@ static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum) dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum); - /* the 1234:5678 is just a self assigned test ID */ - if ((usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x2131) && - (usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x9999)) - return NULL; - /* We don't handle multiple configurations */ if (usbdev->descriptor.bNumConfigurations != 1) return NULL; @@ -790,14 +786,22 @@ static void dabusb_disconnect (struct usb_device *usbdev, void *ptr) MOD_DEC_USE_COUNT; } +static struct usb_device_id dabusb_ids [] = { + { idVendor: 0x0547, idProduct: 0x2131 }, + { idVendor: 0x0547, idProduct: 0x9999 }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, dabusb_ids); + static struct usb_driver dabusb_driver = { - "dabusb", - dabusb_probe, - dabusb_disconnect, - {NULL, NULL}, - &dabusb_fops, - DABUSB_MINOR + name: "dabusb", + probe: dabusb_probe, + disconnect: dabusb_disconnect, + fops: &dabusb_fops, + minor: DABUSB_MINOR, + id_table: dabusb_ids, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/usb/dc2xx.c b/drivers/usb/dc2xx.c index 6760e797b..11afdcfa2 100644 --- a/drivers/usb/dc2xx.c +++ b/drivers/usb/dc2xx.c @@ -44,6 +44,8 @@ * 03 Nov, 1999 -- update for 2.3.25 kernel API changes. * 08 Jan, 2000 .. multiple camera support * 12 Aug, 2000 .. add some real locking, remove an Oops + * 10 Oct, 2000 .. usb_device_id table created. + * 01 Nov, 2000 .. usb_device_id support added by Adam J. Richter * * Thanks to: the folk who've provided USB product IDs, sent in * patches, and shared their sucesses! @@ -59,7 +61,12 @@ #include #include #include -#undef DEBUG + +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif #include @@ -82,7 +89,7 @@ /* table of cameras that work through this driver */ -static __devinitdata struct usb_device_id camera_table [] = { +static struct usb_device_id camera_table [] = { /* These have the same application level protocol */ { idVendor: 0x040a, idProduct: 0x0120 }, // Kodak DC-240 @@ -105,7 +112,7 @@ static __devinitdata struct usb_device_id camera_table [] = { * means, among other things, no iso or interrupt endpoints. */ - { } // TERMINATING ENTRY + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, camera_table); @@ -346,7 +353,7 @@ static /* const */ struct file_operations usb_camera_fops = { static void * __devinit -camera_bind (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *camera_info) +camera_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *camera_info) { int i; struct usb_interface_descriptor *interface; @@ -471,7 +478,7 @@ static /* const */ struct usb_driver camera_driver = { name: "dc2xx", id_table: camera_table, - bind: camera_bind, + probe: camera_probe, disconnect: camera_disconnect, fops: &usb_camera_fops, diff --git a/drivers/usb/devio.c b/drivers/usb/devio.c index 2a1e12aad..47c33826f 100644 --- a/drivers/usb/devio.c +++ b/drivers/usb/devio.c @@ -292,7 +292,8 @@ static void destroy_all_async(struct dev_state *ps) * interface claiming */ -static void *driver_probe(struct usb_device *dev, unsigned int intf) +static void *driver_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id) { return NULL; } @@ -541,13 +542,17 @@ static int proc_control(struct dev_state *ps, void *arg) i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.request, ctrl.requesttype, ctrl.value, ctrl.index, tbuf, ctrl.length, tmo); if ((i > 0) && ctrl.length) { - if (copy_to_user(ctrl.data, tbuf, ctrl.length)) + if (copy_to_user(ctrl.data, tbuf, ctrl.length)) { + free_page((unsigned long)tbuf); return -EFAULT; + } } } else { if (ctrl.length) { - if (copy_from_user(tbuf, ctrl.data, ctrl.length)) + if (copy_from_user(tbuf, ctrl.data, ctrl.length)) { + free_page((unsigned long)tbuf); return -EFAULT; + } } i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.request, ctrl.requesttype, ctrl.value, ctrl.index, tbuf, ctrl.length, tmo); @@ -594,13 +599,17 @@ static int proc_bulk(struct dev_state *ps, void *arg) } i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); if (!i && len2) { - if (copy_to_user(bulk.data, tbuf, len2)) + if (copy_to_user(bulk.data, tbuf, len2)) { + free_page((unsigned long)tbuf); return -EFAULT; + } } } else { if (len1) { - if (copy_from_user(tbuf, bulk.data, len1)) + if (copy_from_user(tbuf, bulk.data, len1)) { + free_page((unsigned long)tbuf); return -EFAULT; + } } i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); } @@ -697,9 +706,11 @@ static int proc_resetdevice(struct dev_state *ps) continue; if (intf->driver) { + const struct usb_device_id *id; down(&intf->driver->serialize); intf->driver->disconnect(ps->dev, intf->private_data); - intf->driver->probe(ps->dev, i); + id = usb_match_id(ps->dev,intf,intf->driver->id_table); + intf->driver->probe(ps->dev, i, id); up(&intf->driver->serialize); } } diff --git a/drivers/usb/dsbr100.c b/drivers/usb/dsbr100.c index aa6372b91..373d8ef07 100644 --- a/drivers/usb/dsbr100.c +++ b/drivers/usb/dsbr100.c @@ -70,7 +70,8 @@ #define TB_LEN 16 -static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum); +static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); static void usb_dsbr100_disconnect(struct usb_device *dev, void *ptr); static int usb_dsbr100_ioctl(struct video_device *dev, unsigned int cmd, void *arg); @@ -105,13 +106,20 @@ static struct video_device usb_dsbr100_radio= static int users = 0; +static struct usb_device_id usb_dsbr100_table [] = { + { idVendor: DSB100_VENDOR, idProduct: DSB100_PRODUCT }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usb_dsbr100_table); + static struct usb_driver usb_dsbr100_driver = { name: "dsbr100", probe: usb_dsbr100_probe, disconnect: usb_dsbr100_disconnect, - driver_list: {NULL,NULL}, - fops: NULL, - minor: 0 + fops: NULL, + minor: 0, + id_table: usb_dsbr100_table, }; @@ -164,13 +172,11 @@ static void dsbr100_getstat(usb_dsbr100 *radio) } -static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum) +static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { usb_dsbr100 *radio; - if (dev->descriptor.idVendor!=DSB100_VENDOR || - dev->descriptor.idProduct!=DSB100_PRODUCT) - return NULL; if (!(radio = kmalloc(sizeof(usb_dsbr100),GFP_KERNEL))) return NULL; usb_dsbr100_radio.priv = radio; diff --git a/drivers/usb/hid.c b/drivers/usb/hid.c index db4df7931..5acdded23 100644 --- a/drivers/usb/hid.c +++ b/drivers/usb/hid.c @@ -1373,9 +1373,6 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum, c if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) && (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL; - if (interface->bInterfaceClass != USB_INTERFACE_CLASS_HID) - return NULL; - if (usb_get_extra_descriptor(interface, USB_DT_HID, &hdesc) && usb_get_extra_descriptor(&interface->endpoint[0], USB_DT_HID, &hdesc)) { dbg("class descriptor not present\n"); @@ -1471,7 +1468,8 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum, c return hid; } -static void* hid_probe(struct usb_device *dev, unsigned int ifnum) +static void* hid_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct hid_device *hid; char name[128]; @@ -1527,10 +1525,18 @@ static void hid_disconnect(struct usb_device *dev, void *ptr) hid_free_device(hid); } +static struct usb_device_id hid_usb_ids [] = { + { bInterfaceClass: USB_INTERFACE_CLASS_HID}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, hid_usb_ids); + static struct usb_driver hid_driver = { name: "hid", probe: hid_probe, - disconnect: hid_disconnect + disconnect: hid_disconnect, + id_table: hid_usb_ids, }; static int __init hid_init(void) diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c index 144cea36c..dc6621823 100644 --- a/drivers/usb/hub.c +++ b/drivers/usb/hub.c @@ -235,7 +235,9 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor return 0; } -static void *hub_probe(struct usb_device *dev, unsigned int i) +static void *hub_probe(struct usb_device *dev, unsigned int i, + const struct usb_device_id *id) + { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; @@ -244,10 +246,6 @@ static void *hub_probe(struct usb_device *dev, unsigned int i) interface = &dev->actconfig->interface[i].altsetting[0]; - /* Is it a hub? */ - if (interface->bInterfaceClass != USB_CLASS_HUB) - return NULL; - /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ if ((interface->bInterfaceSubClass != 0) && @@ -769,11 +767,19 @@ static int usb_hub_thread(void *__hub) return 0; } +static struct usb_device_id hub_id_table [] = { + { bInterfaceClass: USB_CLASS_HUB}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, hub_id_table); + static struct usb_driver hub_driver = { name: "hub", probe: hub_probe, ioctl: hub_ioctl, - disconnect: hub_disconnect + disconnect: hub_disconnect, + id_table: hub_id_table, }; /* diff --git a/drivers/usb/ibmcam.c b/drivers/usb/ibmcam.c index 590bcd4bd..0364b33c6 100644 --- a/drivers/usb/ibmcam.c +++ b/drivers/usb/ibmcam.c @@ -2953,7 +2953,8 @@ static int ibmcam_find_struct(void) * 5/24/00 Corrected to prevent race condition (MOD_xxx_USE_COUNT). * 7/3/00 Fixed endianness bug. */ -static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum) +static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_ibmcam *ibmcam = NULL; const struct usb_interface_descriptor *interface; @@ -2967,11 +2968,6 @@ static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum) if (dev->descriptor.bNumConfigurations != 1) return NULL; - /* Is it an IBM camera? */ - if ((dev->descriptor.idVendor != 0x0545) || - (dev->descriptor.idProduct != 0x8080)) - return NULL; - /* Check the version/revision */ switch (dev->descriptor.bcdDevice) { case 0x0002: @@ -2988,10 +2984,9 @@ static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum) dev->descriptor.bcdDevice); model = IBMCAM_MODEL_2; break; - default: - printk(KERN_ERR "IBM camera with revision 0x%04x is not supported.\n", - dev->descriptor.bcdDevice); - return NULL; + + /* ibmcam_table contents prevents any other values from ever + being passed to us, so no need for "default" case. */ } /* Validate found interface: must have one ISO endpoint */ @@ -3124,11 +3119,29 @@ static void usb_ibmcam_disconnect(struct usb_device *dev, void *ptr) MOD_DEC_USE_COUNT; } +static struct usb_device_id ibmcam_table [] = { + { + idVendor: 0x0545, + idProduct: 0x8080, + bcdDevice_lo: 0x0002, + bcdDevice_hi: 0x0002 + }, + { + idVendor: 0x0545, + idProduct: 0x8080, + bcdDevice_lo: 0X030a, + bcdDevice_hi: 0x030a + }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, ibmcam_table); + static struct usb_driver ibmcam_driver = { - "ibmcam", - usb_ibmcam_probe, - usb_ibmcam_disconnect, - { NULL, NULL } + name: "ibmcam", + probe: usb_ibmcam_probe, + disconnect: usb_ibmcam_disconnect, + id_table: ibmcam_table, }; /* diff --git a/drivers/usb/mdc800.c b/drivers/usb/mdc800.c index e4fc25d39..131681c8e 100644 --- a/drivers/usb/mdc800.c +++ b/drivers/usb/mdc800.c @@ -370,7 +370,8 @@ static struct usb_driver mdc800_usb_driver; /* * Callback to search the Mustek MDC800 on the USB Bus */ -static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum ) +static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, + const struct usb_device_id *id) { int i,j; struct usb_interface_descriptor *intf_desc; @@ -379,11 +380,6 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum ) dbg ("(mdc800_usb_probe) called."); - if (dev->descriptor.idVendor != MDC800_VENDOR_ID) - return 0; - if (dev->descriptor.idProduct != MDC800_PRODUCT_ID) - return 0; - if (mdc800->dev != 0) { warn ("only one Mustek MDC800 is supported."); @@ -873,17 +869,23 @@ static struct file_operations mdc800_device_ops = +static struct usb_device_id mdc800_table [] = { + { idVendor: MDC800_VENDOR_ID, idProduct: MDC800_PRODUCT_ID }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, mdc800_table); /* * USB Driver Struct for this device */ static struct usb_driver mdc800_usb_driver = { - "mdc800", - mdc800_usb_probe, - mdc800_usb_disconnect, - { 0,0 }, - &mdc800_device_ops, - MDC800_DEVICE_MINOR_BASE + name: "mdc800", + probe: mdc800_usb_probe, + disconnect: mdc800_usb_disconnect, + fops: &mdc800_device_ops, + minor: MDC800_DEVICE_MINOR_BASE, + id_table: mdc800_table }; diff --git a/drivers/usb/microtek.c b/drivers/usb/microtek.c index d7ecc441f..daa18c88f 100644 --- a/drivers/usb/microtek.c +++ b/drivers/usb/microtek.c @@ -140,14 +140,17 @@ /* USB layer driver interface */ -static void *mts_usb_probe(struct usb_device *dev, unsigned int interface); +static void *mts_usb_probe(struct usb_device *dev, unsigned int interface, + const struct usb_device_id *id); static void mts_usb_disconnect(struct usb_device *dev, void *ptr); +static struct usb_device_id mts_usb_ids []; + static struct usb_driver mts_usb_driver = { - "microtek", - mts_usb_probe, - mts_usb_disconnect, - { NULL, NULL } /* we need no fops. let gcc fill it */ + name: "microtek", + probe: mts_usb_probe, + disconnect: mts_usb_disconnect, + id_table: mts_usb_ids, }; @@ -792,8 +795,6 @@ static void mts_usb_disconnect (struct usb_device *dev, void *ptr) struct vendor_product { - u16 idVendor; - u16 idProduct; char* name; enum { @@ -808,37 +809,37 @@ struct vendor_product /* These are taken from the msmUSB.inf file on the Windows driver CD */ const static struct vendor_product mts_supported_products[] = { - { - 0x4ce, 0x300,"Phantom 336CX",mts_sup_unknown - }, - { - 0x5da, 0x94,"Phantom 336CX",mts_sup_unknown - }, - { - 0x5da, 0x99,"Scanmaker X6",mts_sup_alpha - }, - { - 0x5da, 0x9a,"Phantom C6",mts_sup_unknown - }, - { - 0x5da, 0xa0,"Phantom 336CX",mts_sup_unknown - }, - { - 0x5da, 0xa3,"ScanMaker V6USL",mts_sup_unknown - }, - { - 0x5da, 0x80a3,"ScanMaker V6USL",mts_sup_unknown - }, - { - 0x5da, 0x80ac,"Scanmaker V6UL",mts_sup_unknown - } -} -; -const static struct vendor_product* mts_last_product = &mts_supported_products[ sizeof(mts_supported_products) / sizeof(struct vendor_product) ]; - /* Must never be derefed, points to one after last entry */ + { "Phantom 336CX", mts_sup_unknown}, + { "Phantom 336CX", mts_sup_unknown}, + { "Scanmaker X6", mts_sup_alpha}, + { "Phantom C6", mts_sup_unknown}, + { "Phantom 336CX", mts_sup_unknown}, + { "ScanMaker V6USL", mts_sup_unknown}, + { "ScanMaker V6USL", mts_sup_unknown}, + { "Scanmaker V6UL", mts_sup_unknown}, +}; + +/* The entries of microtek_table must correspond, line-by-line to + the entries of mts_supported_products[]. */ + +static struct usb_device_id mts_usb_ids [] = +{ + {idVendor: 0x4ce, idProduct: 0x0300}, + {idVendor: 0x5da, idProduct: 0x0094}, + {idVendor: 0x5da, idProduct: 0x0099}, + {idVendor: 0x5da, idProduct: 0x009a}, + {idVendor: 0x5da, idProduct: 0x00a0}, + {idVendor: 0x5da, idProduct: 0x00a3}, + {idVendor: 0x5da, idProduct: 0x80a3}, + {idVendor: 0x5da, idProduct: 0x80ac}, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, mts_usb_ids); -static void * mts_usb_probe (struct usb_device *dev, unsigned int interface) + +static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, + const struct usb_device_id *id) { int i; int result; @@ -861,20 +862,8 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface) (int)dev->descriptor.idVendor ); MTS_DEBUG_GOT_HERE(); - - /* checking IDs */ - for( p = mts_supported_products; p != mts_last_product; p++ ) - if ( dev->descriptor.idVendor == p->idVendor && - dev->descriptor.idProduct == p->idProduct ) - goto is_supported; - else - MTS_DEBUG( "doesn't appear to be model %s\n", p->name ); - - MTS_DEBUG( "returning NULL: unsupported\n" ); - - return NULL; - - is_supported: + + p = &mts_supported_products[id - mts_usb_ids]; MTS_DEBUG_GOT_HERE(); diff --git a/drivers/usb/net1080.c b/drivers/usb/net1080.c index bdfe71eb4..2ce91d059 100644 --- a/drivers/usb/net1080.c +++ b/drivers/usb/net1080.c @@ -11,7 +11,9 @@ * The IP-over-USB protocol here may be of interest. Embedded devices * could implement it at the cost of two bulk endpoints, and whatever * other system resources the desired IP-based applications need. - * Some Linux palmtops could support that today. + * Some Linux palmtops could support that today. (Devices that don't + * support the TTL-driven data mangling of the net1080 chip won't need + * the header/trailer support though.) * * STATUS: * @@ -22,6 +24,15 @@ * should handle static and dynamic ("pump") setups. * * RX/TX queue sizes currently fixed at one due to URB unlink problems. + * + * 10-oct-2000 + * usb_device_id table created. + * + * 28-oct-2000 + * misc fixes; mostly, discard more TTL-mangled rx packets. + * + * 01-nov-2000 + * usb_device_id table support added by Adam J. Richter . * *-------------------------------------------------------------------------*/ @@ -989,7 +1000,7 @@ static void net1080_disconnect (struct usb_device *udev, void *ptr) // precondition: never called in_interrupt static void * -net1080_bind (struct usb_device *udev, unsigned ifnum, const struct usb_device_id *prod) +net1080_probe (struct usb_device *udev, unsigned ifnum, const struct usb_device_id *prod) { struct net1080 *dev; struct net_device *net; @@ -1073,7 +1084,7 @@ net1080_bind (struct usb_device *udev, unsigned ifnum, const struct usb_device_i static struct usb_driver net1080_driver = { name: "net1080", id_table: products, - bind: net1080_bind, + probe: net1080_probe, disconnect: net1080_disconnect, }; diff --git a/drivers/usb/ov511.c b/drivers/usb/ov511.c index 275ff05b7..e66f2e57a 100644 --- a/drivers/usb/ov511.c +++ b/drivers/usb/ov511.c @@ -53,6 +53,21 @@ static const char version[] = "1.25"; #undef OV511_GBR422 /* Experimental -- sets the 7610 to GBR422 */ +static struct usb_device_id ov511_table [] = { + + { idVendor: 0x05a9, idProduct: 0x0511, bInterfaceClass: 0xFF }, + { idVendor: 0x05a9, idProduct: 0xA511, bInterfaceClass: 0xFF }, + { idVendor: 0x05a9, idProduct: 0x0002, bInterfaceClass: 0xFF }, + + { idVendor: 0x0813, idProduct: 0x0511, bInterfaceClass: 0xFF }, + { idVendor: 0x0813, idProduct: 0xA511, bInterfaceClass: 0xFF }, + + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, ov511_table); + + #define OV511_I2C_RETRIES 3 /* Video Size 640 x 480 x 3 bytes for RGB */ @@ -3144,7 +3159,8 @@ error: * ***************************************************************************/ -static void* ov511_probe(struct usb_device *dev, unsigned int ifnum) +static void* ov511_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_interface_descriptor *interface; struct usb_ov511 *ov511; @@ -3158,18 +3174,9 @@ static void* ov511_probe(struct usb_device *dev, unsigned int ifnum) interface = &dev->actconfig->interface[ifnum].altsetting[0]; - /* Is it an OV511/OV511+? */ - if (dev->descriptor.idVendor != 0x05a9 - && dev->descriptor.idVendor != 0x0813) - return NULL; - if (dev->descriptor.idProduct != 0x0511 - && dev->descriptor.idProduct != 0xA511 - && dev->descriptor.idProduct != 0x0002) - return NULL; - - /* Checking vendor/product should be enough, but what the hell */ - if (interface->bInterfaceClass != 0xFF) - return NULL; + /* Checking vendor/product should be enough, but what the hell. + USB ID matching cannot check for a bInterfaceSubclass value + of 0, so we check it here. */ if (interface->bInterfaceSubClass != 0x00) return NULL; @@ -3196,14 +3203,9 @@ static void* ov511_probe(struct usb_device *dev, unsigned int ifnum) ov511->bridge = BRG_OV511PLUS; break; case 0x0002: - if (dev->descriptor.idVendor != 0x0813) - goto error; info("Intel Play Me2Cam (OV511+) found"); ov511->bridge = BRG_OV511PLUS; break; - default: - err("Unknown product ID"); - goto error; } ov511->customid = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID); @@ -3321,10 +3323,10 @@ static void ov511_disconnect(struct usb_device *dev, void *ptr) } static struct usb_driver ov511_driver = { - "ov511", - ov511_probe, - ov511_disconnect, - { NULL, NULL } + name: "ov511", + probe: ov511_probe, + disconnect: ov511_disconnect, + id_table: ov511_table, }; diff --git a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c index 2c9fd8b82..e78d5ede9 100644 --- a/drivers/usb/pegasus.c +++ b/drivers/usb/pegasus.c @@ -157,8 +157,6 @@ typedef struct pegasus { struct usb_eth_dev { char *name; - __u16 vendor; - __u16 device; __u32 private; /* LSB is gpio reset value */ }; @@ -176,57 +174,33 @@ MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0) - default = MII mode = 0"); +#define PEGASUS_DEV(product_name, vendor_id, product_id, flags) \ + {name: product_name, private: flags}, + static struct usb_eth_dev usb_dev_id[] = { - {"Billionton USB-100", 0x08dd, 0x0986, - DEFAULT_GPIO_RESET}, - {"Billionton USBLP-100", 0x08dd, 0x0987, - DEFAULT_GPIO_RESET | HAS_HOME_PNA}, - {"Billionton USBEL-100", 0x08dd, 0x0988, - DEFAULT_GPIO_RESET}, - {"Billionton USBE-100", 0x08dd, 0x8511, - DEFAULT_GPIO_RESET | PEGASUS_II}, - {"Corega FEter USB-TX", 0x7aa, 0x0004, - DEFAULT_GPIO_RESET}, - {"MELCO/BUFFALO LUA-TX", 0x0411, 0x0001, - DEFAULT_GPIO_RESET}, - {"D-Link DSB-650TX", 0x2001, 0x4001, - LINKSYS_GPIO_RESET}, - {"D-Link DSB-650TX", 0x2001, 0x4002, - LINKSYS_GPIO_RESET}, - {"D-Link DSB-650TX(PNA)", 0x2001, 0x4003, - DEFAULT_GPIO_RESET | HAS_HOME_PNA}, - {"D-Link DSB-650", 0x2001, 0xabc1, - DEFAULT_GPIO_RESET}, - {"D-Link DU-E10", 0x07b8, 0xabc1, - DEFAULT_GPIO_RESET}, - {"D-Link DU-E100", 0x07b8, 0x4002, - DEFAULT_GPIO_RESET}, - {"Linksys USB10TX", 0x066b, 0x2202, - LINKSYS_GPIO_RESET}, - {"Linksys USB100TX", 0x066b, 0x2203, - LINKSYS_GPIO_RESET}, - {"Linksys USB100TX", 0x066b, 0x2204, - LINKSYS_GPIO_RESET | HAS_HOME_PNA}, - {"Linksys USB Ethernet Adapter", 0x066b, 0x2206, - LINKSYS_GPIO_RESET}, - {"SMC 202 USB Ethernet", 0x0707, 0x0200, - DEFAULT_GPIO_RESET}, - {"ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)", 0x07a6, 0x0986, - DEFAULT_GPIO_RESET | HAS_HOME_PNA}, - {"Accton USB 10/100 Ethernet Adapter", 0x083a, 0x1046, - DEFAULT_GPIO_RESET}, - {"IO DATA USB ET/TX", 0x04bb, 0x0904, - DEFAULT_GPIO_RESET}, - {"LANEED USB Ethernet LD-USB/TX", 0x056e, 0x4002, - DEFAULT_GPIO_RESET}, - {"SOHOware NUB100 Ethernet", 0x15e8, 0x9100, - DEFAULT_GPIO_RESET}, - {"ADMtek ADM8511 \"Pegasus II\" USB Ethernet", 0x07a6, 0x8511, - DEFAULT_GPIO_RESET | PEGASUS_II}, - {NULL, 0, 0, 0} + +# define PEGASUS_DEV(product_name, vendor_id, product_id, flags) \ + {name: product_name, private: flags}, +# include "pegasus_devs.h" +# undef PEGASUS_DEV + + {NULL, 0 } }; +/* The entries in this table MUST CORRESPOND LINE-BY-LINE to the + entries of usb_dev_id[]. */ +static struct usb_device_id pegasus_ids [] = { +# define PEGASUS_DEV(product_name, vendor_id, product_id, flags) \ + {idVendor: vendor_id, idProduct: product_id }, +# include "pegasus_devs.h" +# undef PEGASUS_DEV + + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, pegasus_ids); + static int update_eth_regs_async( pegasus_t * ); /* Aargh!!! I _really_ hate such tweaks */ static void ctrl_callback( urb_t *urb ) @@ -858,20 +832,6 @@ static void pegasus_set_multicast( struct net_device *net ) } -static int check_device_ids( __u16 vendor, __u16 product ) -{ - int i=0; - - while ( usb_dev_id[i].name ) { - if ( (usb_dev_id[i].vendor == vendor) && - (usb_dev_id[i].device == product) ) - return i; - i++; - } - return -1; -} - - static __u8 mii_phy_probe( pegasus_t *pegasus ) { int i; @@ -900,15 +860,12 @@ static inline void setup_pegasus_II( pegasus_t *pegasus ) } -static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum ) +static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct net_device *net; pegasus_t *pegasus; - int dev_indx; - - if ( (dev_indx = check_device_ids(dev->descriptor.idVendor, dev->descriptor.idProduct)) == -1 ) { - return NULL; - } + const int dev_indx = id - pegasus_ids; if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { err("usb_set_configuration() failed"); @@ -995,6 +952,7 @@ static struct usb_driver pegasus_driver = { name: "pegasus", probe: pegasus_probe, disconnect: pegasus_disconnect, + id_table: pegasus_ids, }; int __init pegasus_init(void) diff --git a/drivers/usb/pegasus_devs.h b/drivers/usb/pegasus_devs.h new file mode 100644 index 000000000..8b6e77def --- /dev/null +++ b/drivers/usb/pegasus_devs.h @@ -0,0 +1,89 @@ +/* This file is derived from pegasus.c. + * Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* This file should be included after defining the macro PEGASUS_DEV. */ + +PEGASUS_DEV( "Billionton USB-100", 0x08dd, 0x0986, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "Billionton USBLP-100", 0x08dd, 0x0987, + DEFAULT_GPIO_RESET | HAS_HOME_PNA ) + +PEGASUS_DEV( "Billionton USBEL-100", 0x08dd, 0x0988, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "Billionton USBE-100", 0x08dd, 0x8511, + DEFAULT_GPIO_RESET | PEGASUS_II ) + +PEGASUS_DEV( "Corega FEter USB-TX", 0x7aa, 0x0004, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", 0x0411, 0x0001, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "D-Link DSB-650TX", 0x2001, 0x4001, + LINKSYS_GPIO_RESET ) + +PEGASUS_DEV( "D-Link DSB-650TX", 0x2001, 0x4002, + LINKSYS_GPIO_RESET ) + +PEGASUS_DEV( "D-Link DSB-650TX(PNA)", 0x2001, 0x4003, + DEFAULT_GPIO_RESET | HAS_HOME_PNA ) + +PEGASUS_DEV( "D-Link DSB-650", 0x2001, 0xabc1, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "D-Link DU-E10", 0x07b8, 0xabc1, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "D-Link DU-E100", 0x07b8, 0x4002, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "Linksys USB10TX", 0x066b, 0x2202, + LINKSYS_GPIO_RESET ) + +PEGASUS_DEV( "Linksys USB100TX", 0x066b, 0x2203, + LINKSYS_GPIO_RESET ) + +PEGASUS_DEV( "Linksys USB100TX", 0x066b, 0x2204, + LINKSYS_GPIO_RESET | HAS_HOME_PNA ) + +PEGASUS_DEV( "Linksys USB Ethernet Adapter", 0x066b, 0x2206, + LINKSYS_GPIO_RESET ) + +PEGASUS_DEV( "SMC 202 USB Ethernet", 0x0707, 0x0200, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)", 0x07a6, 0x0986, + DEFAULT_GPIO_RESET | HAS_HOME_PNA ) + +PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", 0x083a, 0x1046, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "IO DATA USB ET/TX", 0x04bb, 0x0904, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", 0x056e, 0x4002, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "SOHOware NUB100 Ethernet", 0x15e8, 0x9100, + DEFAULT_GPIO_RESET ) + +PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", 0x07a6, 0x8511, + DEFAULT_GPIO_RESET | PEGASUS_II ) diff --git a/drivers/usb/printer.c b/drivers/usb/printer.c index 7614373cf..b7dfc3503 100644 --- a/drivers/usb/printer.c +++ b/drivers/usb/printer.c @@ -393,15 +393,18 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t return count; } -static void *usblp_probe(struct usb_device *dev, unsigned int ifnum) +static void *usblp_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *epread, *epwrite; struct usblp *usblp; - int minor, i, alts = -1, bidir = 0; + int minor, i, bidir = 0; + int alts = dev->actconfig->interface[ifnum].act_altsetting; int length, err; char *buf; + /* If a bidirectional interface exists, use it. */ for (i = 0; i < dev->actconfig->interface[ifnum].num_altsetting; i++) { interface = &dev->actconfig->interface[ifnum].altsetting[i]; @@ -411,18 +414,13 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum) (interface->bInterfaceProtocol > 1 && interface->bNumEndpoints < 2)) continue; - if (alts == -1) - alts = i; - - if (!bidir && interface->bInterfaceProtocol > 1) { + if (interface->bInterfaceProtocol > 1) { bidir = 1; alts = i; + break; } } - if (alts == -1) - return NULL; - interface = &dev->actconfig->interface[ifnum].altsetting[alts]; if (usb_set_interface(dev, ifnum, alts)) err("can't set desired altsetting %d on interface %d", alts, ifnum); @@ -544,12 +542,22 @@ static struct file_operations usblp_fops = { release: usblp_release, }; +static struct usb_device_id usblp_ids [] = { + { bInterfaceClass: 7, bInterfaceSubClass: 1, bInterfaceProtocol: 1}, + { bInterfaceClass: 7, bInterfaceSubClass: 1, bInterfaceProtocol: 2}, + { bInterfaceClass: 7, bInterfaceSubClass: 1, bInterfaceProtocol: 3}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usblp_ids); + static struct usb_driver usblp_driver = { name: "usblp", probe: usblp_probe, disconnect: usblp_disconnect, fops: &usblp_fops, - minor: USBLP_MINOR_BASE + minor: USBLP_MINOR_BASE, + id_table: usblp_ids, }; static int __init usblp_init(void) diff --git a/drivers/usb/rio500.c b/drivers/usb/rio500.c index e40e6c30f..e54ed66a2 100644 --- a/drivers/usb/rio500.c +++ b/drivers/usb/rio500.c @@ -407,19 +407,11 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos) return read_count; } -static void *probe_rio(struct usb_device *dev, unsigned int ifnum) +static void *probe_rio(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct rio_usb_data *rio = &rio_instance; - if (dev->descriptor.idVendor != 0x841) { - return NULL; - } - - if (dev->descriptor.idProduct != 0x1 /* RIO 500 */ ) { - warn(KERN_INFO "Rio player model not supported/tested."); - return NULL; - } - info("USB Rio found at address %d", dev->devnum); rio->present = 1; @@ -470,14 +462,20 @@ file_operations usb_rio_fops = { release: close_rio, }; -static struct -usb_driver rio_driver = { - "rio500", - probe_rio, - disconnect_rio, - {NULL, NULL}, - &usb_rio_fops, - RIO_MINOR +static struct usb_device_id rio_table [] = { + { idVendor: 0x0841, idProduct: 1 }, /* Rio 500 */ + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, rio_table); + +static struct usb_driver rio_driver = { + name: "rio500", + probe: probe_rio, + disconnect: disconnect_rio, + fops: &usb_rio_fops, + minor: RIO_MINOR, + id_table: rio_table, }; int usb_rio_init(void) diff --git a/drivers/usb/scanner.c b/drivers/usb/scanner.c index 67ea8c8d8..2ee4ba127 100644 --- a/drivers/usb/scanner.c +++ b/drivers/usb/scanner.c @@ -244,6 +244,82 @@ */ #include "scanner.h" +/* Table of scanners that may work with this driver */ +static struct usb_device_id scanner_device_ids [] = { + /* Acer */ + { idVendor: 0x04a5, idProduct: 0x2060 },/* Prisa Acerscan 620U & 640U (!)*/ + { idVendor: 0x04a5, idProduct: 0x2040 },/* Prisa AcerScan 620U (!) */ + { idVendor: 0x04a5, idProduct: 0x2022 },/* Vuego Scan Brisa 340U */ + /* Agfa */ + { idVendor: 0x06bd, idProduct: 0x0001 }, /* SnapScan 1212U */ + { idVendor: 0x06bd, idProduct: 0x2061 }, /* Another SnapScan 1212U (?)*/ + { idVendor: 0x06bd, idProduct: 0x0100 }, /* SnapScan Touch */ + /* Colorado -- See Primax/Colorado below */ + /* Epson -- See Seiko/Epson below */ + /* Genius */ + { idVendor: 0x0458, idProduct: 0x2001 }, /* ColorPage-Vivid Pro */ + /* Hewlett Packard */ + { idVendor: 0x03f0, idProduct: 0x0205 }, /* 3300C */ + { idVendor: 0x03f0, idProduct: 0x0101 }, /* 4100C */ + { idVendor: 0x03f0, idProduct: 0x0105 }, /* 4200C */ + { idVendor: 0x03f0, idProduct: 0x0102 }, /* PhotoSmart S20 */ + { idVendor: 0x03f0, idProduct: 0x0401 }, /* 5200C */ + { idVendor: 0x03f0, idProduct: 0x0701 }, /* 5300C */ + { idVendor: 0x03f0, idProduct: 0x0201 }, /* 6200C */ + { idVendor: 0x03f0, idProduct: 0x0601 }, /* 6300C */ + /* iVina */ + { idVendor: 0x0638, idProduct: 0x0268 }, /* 1200U */ + /* Microtek */ + { idVendor: 0x05da, idProduct: 0x0099 }, /* ScanMaker X6 - X6U */ + { idVendor: 0x05da, idProduct: 0x0094 }, /* Phantom 336CX - C3 */ + { idVendor: 0x05da, idProduct: 0x00a0 }, /* Phantom 336CX - C3 #2 */ + { idVendor: 0x05da, idProduct: 0x009a }, /* Phantom C6 */ + { idVendor: 0x05da, idProduct: 0x00a3 }, /* ScanMaker V6USL */ + { idVendor: 0x05da, idProduct: 0x80a3 }, /* ScanMaker V6USL #2 */ + { idVendor: 0x05da, idProduct: 0x80ac }, /* ScanMaker V6UL - SpicyU */ + /* Mustek */ + { idVendor: 0x055f, idProduct: 0x0001 }, /* 1200 CU */ + { idVendor: 0x0400, idProduct: 0x1000 }, /* BearPaw 1200 */ + { idVendor: 0x055f, idProduct: 0x0002 }, /* 600 CU */ + { idVendor: 0x055f, idProduct: 0x0003 }, /* 1200 USB */ + { idVendor: 0x055f, idProduct: 0x0006 }, /* 1200 UB */ + /* Primax/Colorado */ + { idVendor: 0x0461, idProduct: 0x0300 }, /* G2-300 #1 */ + { idVendor: 0x0461, idProduct: 0x0380 }, /* G2-600 #1 */ + { idVendor: 0x0461, idProduct: 0x0301 }, /* G2E-300 #1 */ + { idVendor: 0x0461, idProduct: 0x0381 }, /* ReadyScan 636i */ + { idVendor: 0x0461, idProduct: 0x0302 }, /* G2-300 #2 */ + { idVendor: 0x0461, idProduct: 0x0382 }, /* G2-600 #2 */ + { idVendor: 0x0461, idProduct: 0x0303 }, /* G2E-300 #2 */ + { idVendor: 0x0461, idProduct: 0x0383 }, /* G2E-600 */ + { idVendor: 0x0461, idProduct: 0x0340 }, /* Colorado USB 9600 */ + { idVendor: 0x0461, idProduct: 0x0360 }, /* Colorado USB 19200 */ + { idVendor: 0x0461, idProduct: 0x0341 }, /* Colorado 600u */ + { idVendor: 0x0461, idProduct: 0x0361 }, /* Colorado 1200u */ + /* Seiko/Epson Corp. */ + { idVendor: 0x04b8, idProduct: 0x0101 },/* Perfection 636U and 636Photo */ + { idVendor: 0x04b8, idProduct: 0x0103 },/* Perfection 610 */ + { idVendor: 0x04b8, idProduct: 0x0104 },/* Perfection 1200U and 1200Photo*/ + { idVendor: 0x04b8, idProduct: 0x0107 },/* Expression 1600 */ + /* Umax */ + { idVendor: 0x1606, idProduct: 0x0010 }, /* Astra 1220U */ + { idVendor: 0x1606, idProduct: 0x0002 }, /* Astra 1236U */ + { idVendor: 0x1606, idProduct: 0x0030 }, /* Astra 2000U */ + { idVendor: 0x1606, idProduct: 0x0230 }, /* Astra 2200U */ + /* Visioneer */ + { idVendor: 0x04a7, idProduct: 0x0221 }, /* OneTouch 5300 USB */ + { idVendor: 0x04a7, idProduct: 0x0211 }, /* OneTouch 7600 USB */ + { idVendor: 0x04a7, idProduct: 0x0231 }, /* 6100 USB */ + { idVendor: 0x04a7, idProduct: 0x0311 }, /* 6200 EPP/USB */ + { idVendor: 0x04a7, idProduct: 0x0321 }, /* OneTouch 8100 EPP/USB */ + { idVendor: 0x04a7, idProduct: 0x0331 }, /* OneTouch 8600 EPP/USB */ + + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, scanner_device_ids); + + static void irq_scanner(struct urb *urb) { @@ -548,7 +624,8 @@ read_scanner(struct file * file, char * buffer, } static void * -probe_scanner(struct usb_device *dev, unsigned int ifnum) +probe_scanner(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct scn_usb_data *scn; struct usb_interface_descriptor *interface; @@ -591,7 +668,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) * Until we detect a device which is pleasing, we silently punt. */ - for (ix = 0; ix < sizeof (scanner_device_ids) / sizeof (struct scanner_device); ix++) { + for (ix = 0; ix < sizeof (scanner_device_ids) / sizeof (struct usb_device_id); ix++) { if ((dev->descriptor.idVendor == scanner_device_ids [ix].idVendor) && (dev->descriptor.idProduct == scanner_device_ids [ix].idProduct)) { valid_device = 1; @@ -875,12 +952,14 @@ file_operations usb_scanner_fops = { static struct usb_driver scanner_driver = { - "usbscanner", - probe_scanner, - disconnect_scanner, - { NULL, NULL }, - &usb_scanner_fops, - SCN_BASE_MNR + name: "usbscanner", + probe: probe_scanner, + disconnect: disconnect_scanner, + fops: &usb_scanner_fops, + minor: SCN_BASE_MNR, + id_table: NULL, /* This would be scanner_device_ids, but we + need to check every USB device, in case + we match a user defined vendor/product ID. */ }; void __exit diff --git a/drivers/usb/scanner.h b/drivers/usb/scanner.h index c1ec964dc..e052e9a4f 100644 --- a/drivers/usb/scanner.h +++ b/drivers/usb/scanner.h @@ -100,79 +100,4 @@ struct scn_usb_data { static struct scn_usb_data *p_scn_table[SCN_MAX_MNR] = { NULL, /* ... */}; -/* table of scanners that may work with this driver */ -static const struct scanner_device { - __u16 idVendor; - __u16 idProduct; -} scanner_device_ids [] = { - /* Acer */ - { 0x04a5, 0x2060 }, /* Prisa Acerscan 620U & 640U (!) */ - { 0x04a5, 0x2040 }, /* Prisa AcerScan 620U (!) */ - { 0x04a5, 0x2022 }, /* Vuego Scan Brisa 340U */ - /* Agfa */ - { 0x06bd, 0x0001 }, /* SnapScan 1212U */ - { 0x06bd, 0x2061 }, /* Another SnapScan 1212U (?) */ - { 0x06bd, 0x0100 }, /* SnapScan Touch */ - /* Colorado -- See Primax/Colorado below */ - /* Epson -- See Seiko/Epson below */ - /* Genius */ - { 0x0458, 0x2001 }, /* ColorPage-Vivid Pro */ - /* Hewlett Packard */ - { 0x03f0, 0x0205 }, /* 3300C */ - { 0x03f0, 0x0101 }, /* 4100C */ - { 0x03f0, 0x0105 }, /* 4200C */ - { 0x03f0, 0x0102 }, /* PhotoSmart S20 */ - { 0x03f0, 0x0401 }, /* 5200C */ - { 0x03f0, 0x0701 }, /* 5300C */ - { 0x03f0, 0x0201 }, /* 6200C */ - { 0x03f0, 0x0601 }, /* 6300C */ - /* iVina */ - { 0x0638, 0x0268 }, /* 1200U */ - /* Microtek */ - { 0x05da, 0x0099 }, /* ScanMaker X6 - X6U */ - { 0x05da, 0x0094 }, /* Phantom 336CX - C3 */ - { 0x05da, 0x00a0 }, /* Phantom 336CX - C3 #2 */ - { 0x05da, 0x009a }, /* Phantom C6 */ - { 0x05da, 0x00a3 }, /* ScanMaker V6USL */ - { 0x05da, 0x80a3 }, /* ScanMaker V6USL #2 */ - { 0x05da, 0x80ac }, /* ScanMaker V6UL - SpicyU */ - /* Mustek */ - { 0x055f, 0x0001 }, /* 1200 CU */ - { 0x0400, 0x1000 }, /* BearPaw 1200 */ - { 0x055f, 0x0002 }, /* 600 CU */ - { 0x055f, 0x0003 }, /* 1200 USB */ - { 0x055f, 0x0006 }, /* 1200 UB */ - /* Primax/Colorado */ - { 0x0461, 0x0300 }, /* G2-300 #1 */ - { 0x0461, 0x0380 }, /* G2-600 #1 */ - { 0x0461, 0x0301 }, /* G2E-300 #1 */ - { 0x0461, 0x0381 }, /* ReadyScan 636i */ - { 0x0461, 0x0302 }, /* G2-300 #2 */ - { 0x0461, 0x0382 }, /* G2-600 #2 */ - { 0x0461, 0x0303 }, /* G2E-300 #2 */ - { 0x0461, 0x0383 }, /* G2E-600 */ - { 0x0461, 0x0340 }, /* Colorado USB 9600 */ - { 0x0461, 0x0360 }, /* Colorado USB 19200 */ - { 0x0461, 0x0341 }, /* Colorado 600u */ - { 0x0461, 0x0361 }, /* Colorado 1200u */ - /* Seiko/Epson Corp. */ - { 0x04b8, 0x0101 }, /* Perfection 636U and 636Photo */ - { 0x04b8, 0x0103 }, /* Perfection 610 */ - { 0x04b8, 0x0104 }, /* Perfection 1200U and 1200Photo */ - { 0x04b8, 0x0107 }, /* Expression 1600 */ - /* Umax */ - { 0x1606, 0x0010 }, /* Astra 1220U */ - { 0x1606, 0x0002 }, /* Astra 1236U */ - { 0x1606, 0x0030 }, /* Astra 2000U */ - { 0x1606, 0x0230 }, /* Astra 2200U */ - /* Visioneer */ - { 0x04a7, 0x0221 }, /* OneTouch 5300 USB */ - { 0x04a7, 0x0211 }, /* OneTouch 7600 USB */ - { 0x04a7, 0x0231 }, /* 6100 USB */ - { 0x04a7, 0x0311 }, /* 6200 EPP/USB */ - { 0x04a7, 0x0321 }, /* OneTouch 8100 EPP/USB */ - { 0x04a7, 0x0331 }, /* OneTouch 8600 EPP/USB */ -}; - -/* Forward declarations */ static struct usb_driver scanner_driver; diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index ce5d7b128..b90d4f52d 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o obj-$(CONFIG_USB_SERIAL_DIGI_ACCELEPORT) += digi_acceleport.o +obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o # Objects that export symbols. export-objs := usbserial.o diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c new file mode 100644 index 000000000..1bab9d524 --- /dev/null +++ b/drivers/usb/serial/belkin_sa.c @@ -0,0 +1,561 @@ +/* + * Belkin USB Serial Adapter Driver + * + * Copyright (C) 2000 + * William Greathouse (wgreathouse@smva.com) + * + * This program is largely derived from work by the linux-usb group + * and associated source files. Please see the usb/serial files for + * individual credits and copyrights. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * See Documentation/usb/usb-serial.txt for more information on using this driver + * + * TODO: + * -- Add true modem contol line query capability. Currently we track the + * states reported by the interrupt and the states we request. + * -- Add error reporting back to application for UART error conditions. + * Just point me at how to implement this and I'll do it. I've put the + * framework in, but haven't analyzed the "tty_flip" interface yet. + * -- Add support for flush commands + * -- Add everything that is missing :) + * + * (11/06/2000) gkh + * - Added support for the old Belkin and Peracom devices. + * - Made the port able to be opened multiple times. + * - Added some defaults incase the line settings are things these devices + * can't support. + * + * 18-Oct-2000 William Greathouse + * Released into the wild (linux-usb-devel) + * + * 17-Oct-2000 William Greathouse + * Add code to recognize firmware version and set hardware flow control + * appropriately. Belkin states that firmware prior to 3.05 does not + * operate correctly in hardware handshake mode. I have verified this + * on firmware 2.05 -- for both RTS and DTR input flow control, the control + * line is not reset. The test performed by the Belkin Win* driver is + * to enable hardware flow control for firmware 2.06 or greater and + * for 1.00 or prior. I am only enabling for 2.06 or greater. + * + * 12-Oct-2000 William Greathouse + * First cut at supporting Belkin USB Serial Adapter F5U103 + * I did not have a copy of the original work to support this + * adapter, so pardon any stupid mistakes. All of the information + * I am using to write this driver was acquired by using a modified + * UsbSnoop on Windows2000 and from examining the other USB drivers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_SERIAL_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif +#include + +#include "usb-serial.h" +#include "belkin_sa.h" + +/* function prototypes for a Belkin USB Serial Adapter F5U103 */ +static int belkin_sa_startup (struct usb_serial *serial); +static void belkin_sa_shutdown (struct usb_serial *serial); +static int belkin_sa_open (struct usb_serial_port *port, struct file *filp); +static void belkin_sa_close (struct usb_serial_port *port, struct file *filp); +static void belkin_sa_read_int_callback (struct urb *urb); +static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios * old); +static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); +static void belkin_sa_break_ctl (struct usb_serial_port *port, int break_state ); + +/* All of the device info needed for the Belkin serial converter */ +static __u16 belkin_sa_vendor_id = BELKIN_SA_VID; +static __u16 belkin_sa_product_id = BELKIN_SA_PID; +struct usb_serial_device_type belkin_sa_device = { + name: "Belkin F5U103 USB Serial Adapter", + idVendor: &belkin_sa_vendor_id, /* the Belkin vendor ID */ + idProduct: &belkin_sa_product_id, /* the Belkin F5U103 product id */ + needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ + needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ + needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ + num_interrupt_in: 1, + num_bulk_in: 1, + num_bulk_out: 1, + num_ports: 1, + open: belkin_sa_open, + close: belkin_sa_close, + read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ + ioctl: belkin_sa_ioctl, + set_termios: belkin_sa_set_termios, + break_ctl: belkin_sa_break_ctl, + startup: belkin_sa_startup, + shutdown: belkin_sa_shutdown, +}; + + +/* This driver also supports the "old" school Belkin single port adaptor */ +static __u16 belkin_old_vendor_id = BELKIN_OLD_VID; +static __u16 belkin_old_product_id = BELKIN_OLD_PID; +struct usb_serial_device_type belkin_old_device = { + name: "Belkin USB Serial Adapter", + idVendor: &belkin_old_vendor_id, /* the Belkin vendor ID */ + idProduct: &belkin_old_product_id, /* the Belkin product id */ + needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ + needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ + needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ + num_interrupt_in: 1, + num_bulk_in: 1, + num_bulk_out: 1, + num_ports: 1, + open: belkin_sa_open, + close: belkin_sa_close, + read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ + ioctl: belkin_sa_ioctl, + set_termios: belkin_sa_set_termios, + break_ctl: belkin_sa_break_ctl, + startup: belkin_sa_startup, + shutdown: belkin_sa_shutdown, +}; + +/* this driver also works for the Peracom single port adapter */ +static __u16 peracom_vendor_id = PERACOM_VID; +static __u16 peracom_product_id = PERACOM_PID; +struct usb_serial_device_type peracom_device = { + name: "Peracom single port USB Serial Adapter", + idVendor: &peracom_vendor_id, /* the Peracom vendor ID */ + idProduct: &peracom_product_id, /* the Peracom product id */ + needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */ + needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ + needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ + num_interrupt_in: 1, + num_bulk_in: 1, + num_bulk_out: 1, + num_ports: 1, + open: belkin_sa_open, + close: belkin_sa_close, + read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ + ioctl: belkin_sa_ioctl, + set_termios: belkin_sa_set_termios, + break_ctl: belkin_sa_break_ctl, + startup: belkin_sa_startup, + shutdown: belkin_sa_shutdown, +}; + + +struct belkin_sa_private { + unsigned long control_state; + unsigned char last_lsr; + unsigned char last_msr; + int bad_flow_control; +}; + + +/* + * *************************************************************************** + * Belkin USB Serial Adapter F5U103 specific driver functions + * *************************************************************************** + */ + +#define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */ + +/* assumes that struct usb_serial *serial is available */ +#define BSA_USB_CMD(c,v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \ + (c), BELKIN_SA_SET_REQUEST_TYPE, \ + (v), 0, NULL, 0, WDR_TIMEOUT) + +/* do some startup allocations not currently performed by usb_serial_probe() */ +static int belkin_sa_startup (struct usb_serial *serial) +{ + struct usb_device *dev = serial->dev; + struct belkin_sa_private *priv; + + /* allocate the private data structure */ + serial->port->private = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); + if (!serial->port->private) + return (-1); /* error */ + priv = (struct belkin_sa_private *)serial->port->private; + /* set initial values for control structures */ + priv->control_state = 0; + priv->last_lsr = 0; + priv->last_msr = 0; + /* see comments at top of file */ + priv->bad_flow_control = (dev->descriptor.bcdDevice <= 0x0206) ? 1 : 0; + info("bcdDevice: %04x, bfc: %d", dev->descriptor.bcdDevice, priv->bad_flow_control); + + init_waitqueue_head(&serial->port->write_wait); + + return (0); +} + + +static void belkin_sa_shutdown (struct usb_serial *serial) +{ + int i; + + dbg (__FUNCTION__); + + /* stop reads and writes on all ports */ + for (i=0; i < serial->num_ports; ++i) { + while (serial->port[i].open_count > 0) { + belkin_sa_close (&serial->port[i], NULL); + } + /* My special items, the standard routines free my urbs */ + if (serial->port->private) + kfree(serial->port->private); + } +} + + +static int belkin_sa_open (struct usb_serial_port *port, struct file *filp) +{ + unsigned long flags; + + dbg(__FUNCTION__" port %d", port->number); + + spin_lock_irqsave (&port->port_lock, flags); + + ++port->open_count; + MOD_INC_USE_COUNT; + + if (!port->active) { + port->active = 1; + + /*Start reading from the device*/ + /* TODO: Look at possibility of submitting mulitple URBs to device to + * enhance buffering. Win trace shows 16 initial read URBs. + */ + port->read_urb->dev = port->serial->dev; + if (usb_submit_urb(port->read_urb)) + err("usb_submit_urb(read bulk) failed"); + + port->interrupt_in_urb->dev = port->serial->dev; + if (usb_submit_urb(port->interrupt_in_urb)) + err(" usb_submit_urb(read int) failed"); + } + + spin_unlock_irqrestore (&port->port_lock, flags); + + return 0; +} /* belkin_sa_open */ + + +static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) +{ + unsigned long flags; + + dbg(__FUNCTION__" port %d", port->number); + + spin_lock_irqsave (&port->port_lock, flags); + + --port->open_count; + MOD_DEC_USE_COUNT; + + if (port->open_count <= 0) { + /* shutdown our bulk reads and writes */ + usb_unlink_urb (port->write_urb); + usb_unlink_urb (port->read_urb); + usb_unlink_urb (port->interrupt_in_urb); /* wgg - do I need this? I think so. */ + port->active = 0; + } + + spin_unlock_irqrestore (&port->port_lock, flags); +} /* belkin_sa_close */ + + +static void belkin_sa_read_int_callback (struct urb *urb) +{ + struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private; + struct usb_serial *serial; + struct tty_struct *tty; + unsigned char *data = urb->transfer_buffer; + + /* the urb might have been killed. */ + if (urb->status) + return; + + if (port_paranoia_check (port, "belkin_sa_read_interrupt")) return; + + serial = port->serial; + if (serial_paranoia_check (serial, "belkin_sa_read_interrupt")) return; + + usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); + + /* Handle known interrupt data */ + /* ignore data[0] and data[1] */ + + priv->last_msr = data[BELKIN_SA_MSR_INDEX]; + + /* Record Control Line states */ + if (priv->last_msr & BELKIN_SA_MSR_DSR) + priv->control_state |= TIOCM_DSR; + else + priv->control_state &= ~TIOCM_DSR; + + if (priv->last_msr & BELKIN_SA_MSR_CTS) + priv->control_state |= TIOCM_CTS; + else + priv->control_state &= ~TIOCM_CTS; + + if (priv->last_msr & BELKIN_SA_MSR_RI) + priv->control_state |= TIOCM_RI; + else + priv->control_state &= ~TIOCM_RI; + + if (priv->last_msr & BELKIN_SA_MSR_CD) + priv->control_state |= TIOCM_CD; + else + priv->control_state &= ~TIOCM_CD; + + /* Now to report any errors */ + priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; +#if 0 + /* + * fill in the flip buffer here, but I do not know the relation + * to the current/next receive buffer or characters. I need + * to look in to this before committing any code. + */ + if (priv->last_lsr & BELKIN_SA_LSR_ERR) { + tty = port->tty; + /* Overrun Error */ + if (priv->last_lsr & BELKIN_SA_LSR_OE) { + } + /* Parity Error */ + if (priv->last_lsr & BELKIN_SA_LSR_PE) { + } + /* Framing Error */ + if (priv->last_lsr & BELKIN_SA_LSR_FE) { + } + /* Break Indicator */ + if (priv->last_lsr & BELKIN_SA_LSR_BI) { + } + } +#endif + + /* INT urbs are automatically re-submitted */ +} + +static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios *old_termios) +{ + struct usb_serial *serial = port->serial; + struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private; + unsigned int iflag = port->tty->termios->c_iflag; + unsigned int cflag = port->tty->termios->c_cflag; + unsigned int old_iflag = old_termios->c_iflag; + unsigned int old_cflag = old_termios->c_cflag; + __u16 urb_value; /* Will hold the new flags */ + + /* Set the baud rate */ + if( (cflag&CBAUD) != (old_cflag&CBAUD) ) { + /* reassert DTR and (maybe) RTS on transition from B0 */ + if( (old_cflag&CBAUD) == B0 ) { + priv->control_state |= (TIOCM_DTR|TIOCM_RTS); + if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0) + err("Set DTR error"); + /* don't set RTS if using hardware flow control */ + if (!(old_cflag&CRTSCTS) ) + if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0) + err("Set RTS error"); + } + + switch(cflag & CBAUD) { + case B0: /* handled below */ break; + case B300: urb_value = BELKIN_SA_BAUD(300); break; + case B600: urb_value = BELKIN_SA_BAUD(600); break; + case B1200: urb_value = BELKIN_SA_BAUD(1200); break; + case B2400: urb_value = BELKIN_SA_BAUD(2400); break; + case B4800: urb_value = BELKIN_SA_BAUD(4800); break; + case B9600: urb_value = BELKIN_SA_BAUD(9600); break; + case B19200: urb_value = BELKIN_SA_BAUD(19200); break; + case B38400: urb_value = BELKIN_SA_BAUD(38400); break; + case B57600: urb_value = BELKIN_SA_BAUD(57600); break; + case B115200: urb_value = BELKIN_SA_BAUD(115200); break; + case B230400: urb_value = BELKIN_SA_BAUD(230400); break; + default: err("BELKIN USB Serial Adapter: unsupported baudrate request, using default of 9600"); + urb_value = BELKIN_SA_BAUD(9600); break; + } + if ((cflag & CBAUD) != B0 ) { + if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) + err("Set baudrate error"); + } else { + /* Disable flow control */ + if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0) + err("Disable flowcontrol error"); + + /* Drop RTS and DTR */ + priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); + if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0) + err("DTR LOW error"); + if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0) + err("RTS LOW error"); + } + } + + /* set the parity */ + if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) { + if (cflag & PARENB) + urb_value = (cflag & PARODD) ? BELKIN_SA_PARITY_ODD : BELKIN_SA_PARITY_EVEN; + else + urb_value = BELKIN_SA_PARITY_NONE; + if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0) + err("Set parity error"); + } + + /* set the number of data bits */ + if( (cflag&CSIZE) != (old_cflag&CSIZE) ) { + switch (cflag & CSIZE) { + case CS5: urb_value = BELKIN_SA_DATA_BITS(5); break; + case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break; + case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break; + case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break; + default: err("CSIZE was not CS5-CS8, using default of 8"); + urb_value = BELKIN_SA_DATA_BITS(8); + break; + } + if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0) + err("Set data bits error"); + } + + /* set the number of stop bits */ + if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) { + urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2) : BELKIN_SA_STOP_BITS(1); + if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, urb_value) < 0) + err("Set stop bits error"); + } + + /* Set flow control */ + if( (iflag&IXOFF) != (old_iflag&IXOFF) + || (iflag&IXON) != (old_iflag&IXON) + || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { + urb_value = 0; + if ((iflag & IXOFF) || (iflag & IXON)) + urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON); + else + urb_value &= ~(BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON); + + if (cflag & CRTSCTS) + urb_value |= (BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS); + else + urb_value &= ~(BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS); + + if (priv->bad_flow_control) + urb_value &= ~(BELKIN_SA_FLOW_IRTS); + + if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0) + err("Set flow control error"); + } +} /* belkin_sa_set_termios */ + + +static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state ) +{ + struct usb_serial *serial = port->serial; + + if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0) + err("Set break_ctl %d", break_state); +} + + +static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) +{ + struct usb_serial *serial = port->serial; + __u16 urb_value; /* Will hold the new flags */ + struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private; + int ret, mask; + + /* Based on code from acm.c and others */ + switch (cmd) { + case TIOCMGET: + return put_user(priv->control_state, (unsigned long *) arg); + break; + + case TIOCMSET: /* Turns on and off the lines as specified by the mask */ + case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */ + case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */ + if ((ret = get_user(mask, (unsigned long *) arg))) return ret; + + if ((cmd == TIOCMSET) || (mask & TIOCM_RTS)) { + /* RTS needs set */ + urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) || (cmd == TIOCMBIS) ? 1 : 0; + if (urb_value) + priv->control_state |= TIOCM_RTS; + else + priv->control_state &= ~TIOCM_RTS; + + if ((ret = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, urb_value)) < 0) { + err("Set RTS error %d", ret); + return(ret); + } + } + + if ((cmd == TIOCMSET) || (mask & TIOCM_DTR)) { + /* DTR needs set */ + urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_DTR)) || (cmd == TIOCMBIS) ? 1 : 0; + if (urb_value) + priv->control_state |= TIOCM_DTR; + else + priv->control_state &= ~TIOCM_DTR; + if ((ret = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, urb_value)) < 0) { + err("Set DTR error %d", ret); + return(ret); + } + } + break; + + case TIOCMIWAIT: + /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ + /* TODO */ + return( 0 ); + + case TIOCGICOUNT: + /* return count of modemline transitions */ + /* TODO */ + return 0; + + default: + dbg("belkin_sa_ioctl arg not supported - 0x%04x",cmd); + return(-ENOIOCTLCMD); + break; + } + return 0; +} /* belkin_sa_ioctl */ + + +static int __init belkin_sa_init (void) +{ + usb_serial_register (&belkin_sa_device); + usb_serial_register (&belkin_old_device); + usb_serial_register (&peracom_device); + return 0; +} + + +static void __exit belkin_sa_exit (void) +{ + usb_serial_deregister (&belkin_sa_device); + usb_serial_deregister (&belkin_old_device); + usb_serial_deregister (&peracom_device); +} + + +module_init (belkin_sa_init); +module_exit (belkin_sa_exit); + +MODULE_DESCRIPTION("USB Belkin Serial converter driver"); diff --git a/drivers/usb/serial/belkin_sa.h b/drivers/usb/serial/belkin_sa.h new file mode 100644 index 000000000..ee3603863 --- /dev/null +++ b/drivers/usb/serial/belkin_sa.h @@ -0,0 +1,113 @@ +/* + * Definitions for Belkin USB Serial Adapter Driver + * + * Copyright (C) 2000 + * William Greathouse (wgreathouse@smva.com) + * + * This program is largely derived from work by the linux-usb group + * and associated source files. Please see the usb/serial files for + * individual credits and copyrights. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * See Documentation/usb/usb-serial.txt for more information on using this driver + * + * (11/06/2000) gkh + * Added old Belkin and Peracom device ids, which this driver supports + * + * 12-Oct-2000 William Greathouse + * First cut at supporting Belkin USB Serial Adapter F5U103 + * I did not have a copy of the original work to support this + * adapter, so pardon any stupid mistakes. All of the information + * I am using to write this driver was acquired by using a modified + * UsbSnoop on Windows2000. + * + */ + +#ifndef __LINUX_USB_SERIAL_BSA_H +#define __LINUX_USB_SERIAL_BSA_H + +#define BELKIN_SA_VID 0x050d /* Vendor Id */ +#define BELKIN_SA_PID 0x0103 /* Product Id */ + +#define BELKIN_OLD_VID 0x056c /* Belkin's "old" vendor id */ +#define BELKIN_OLD_PID 0x8007 /* Belkin's "old" single port serial converter's id */ + +#define PERACOM_VID 0x0565 /* Peracom's vendor id */ +#define PERACOM_PID 0x0001 /* Peracom's single port serial converter's id */ + +/* Vendor Request Interface */ +#define BELKIN_SA_SET_BAUDRATE_REQUEST 0 /* Set baud rate */ +#define BELKIN_SA_SET_STOP_BITS_REQUEST 1 /* Set stop bits (1,2) */ +#define BELKIN_SA_SET_DATA_BITS_REQUEST 2 /* Set data bits (5,6,7,8) */ +#define BELKIN_SA_SET_PARITY_REQUEST 3 /* Set parity (None, Even, Odd) */ + +#define BELKIN_SA_SET_DTR_REQUEST 10 /* Set DTR state */ +#define BELKIN_SA_SET_RTS_REQUEST 11 /* Set RTS state */ +#define BELKIN_SA_SET_BREAK_REQUEST 12 /* Set BREAK state */ + +#define BELKIN_SA_SET_FLOW_CTRL_REQUEST 16 /* Set flow control mode */ + + +#ifdef WHEN_I_LEARN_THIS +#define BELKIN_SA_SET_MAGIC_REQUEST 17 /* I don't know, possibly flush */ + /* (always in Wininit sequence before flow control) */ +#define BELKIN_SA_RESET xx /* Reset the port */ +#define BELKIN_SA_GET_MODEM_STATUS xx /* Force return of modem status register */ +#endif + +#define BELKIN_SA_SET_REQUEST_TYPE 0x40 + +#define BELKIN_SA_BAUD(b) (230400/b) + +#define BELKIN_SA_STOP_BITS(b) (b-1) + +#define BELKIN_SA_DATA_BITS(b) (b-5) + +#define BELKIN_SA_PARITY_NONE 0 +#define BELKIN_SA_PARITY_EVEN 1 +#define BELKIN_SA_PARITY_ODD 2 +#define BELKIN_SA_PARITY_MARK 3 +#define BELKIN_SA_PARITY_SPACE 4 + +#define BELKIN_SA_FLOW_NONE 0x0000 /* No flow control */ +#define BELKIN_SA_FLOW_OCTS 0x0001 /* use CTS input to throttle output */ +#define BELKIN_SA_FLOW_ODSR 0x0002 /* use DSR input to throttle output */ +#define BELKIN_SA_FLOW_IDSR 0x0004 /* use DSR input to enable receive */ +#define BELKIN_SA_FLOW_IDTR 0x0008 /* use DTR output for input flow control */ +#define BELKIN_SA_FLOW_IRTS 0x0010 /* use RTS output for input flow control */ +#define BELKIN_SA_FLOW_ORTS 0x0020 /* use RTS to indicate data available to send */ +#define BELKIN_SA_FLOW_ERRSUB 0x0040 /* ???? guess ???? substitute inline errors */ +#define BELKIN_SA_FLOW_OXON 0x0080 /* use XON/XOFF for output flow control */ +#define BELKIN_SA_FLOW_IXON 0x0100 /* use XON/XOFF for input flow control */ + +/* + * It seems that the interrupt pipe is closely modelled after the + * 16550 register layout. This is probably because the adapter can + * be used in a "DOS" environment to simulate a standard hardware port. + */ +#define BELKIN_SA_LSR_INDEX 2 /* Line Status Register */ +#define BELKIN_SA_LSR_RDR 0x01 /* receive data ready */ +#define BELKIN_SA_LSR_OE 0x02 /* overrun error */ +#define BELKIN_SA_LSR_PE 0x04 /* parity error */ +#define BELKIN_SA_LSR_FE 0x08 /* framing error */ +#define BELKIN_SA_LSR_BI 0x10 /* break indicator */ +#define BELKIN_SA_LSR_THE 0x20 /* transmit holding register empty */ +#define BELKIN_SA_LSR_TE 0x40 /* transmit register empty */ +#define BELKIN_SA_LSR_ERR 0x80 /* OE | PE | FE | BI */ + +#define BELKIN_SA_MSR_INDEX 3 /* Modem Status Register */ +#define BELKIN_SA_MSR_DCTS 0x01 /* Delta CTS */ +#define BELKIN_SA_MSR_DDSR 0x02 /* Delta DSR */ +#define BELKIN_SA_MSR_DRI 0x04 /* Delta RI */ +#define BELKIN_SA_MSR_DCD 0x08 /* Delta CD */ +#define BELKIN_SA_MSR_CTS 0x10 /* Current CTS */ +#define BELKIN_SA_MSR_DSR 0x20 /* Current DSR */ +#define BELKIN_SA_MSR_RI 0x40 /* Current RI */ +#define BELKIN_SA_MSR_CD 0x80 /* Current CD */ + +#endif /* __LINUX_USB_SERIAL_BSA_H */ + diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index f5635bb01..197752224 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1,5 +1,5 @@ /* -* Digi AccelePort USB-4 Serial Converter +* Digi AccelePort USB-4 and USB-2 Serial Converters * * Copyright 2000 by Digi International * @@ -14,6 +14,16 @@ * Peter Berger (pberger@brimson.com) * Al Borchers (borchers@steinerpoint.com) * +* (11/01/2000) Adam J. Richter +* usb_device_id table support +* +* (11/01/2000) pberger and borchers +* -- Turned off the USB_DISABLE_SPD flag for write bulk urbs--it caused +* USB 4 ports to hang on startup. +* -- Serialized access to write urbs by adding the dp_write_urb_in_use +* flag; otherwise, the driver caused SMP system hangs. Watching the +* urb status is not sufficient. +* * (10/05/2000) gkh * -- Fixed bug with urb->dev not being set properly, now that the usb * core needs it. @@ -213,7 +223,7 @@ * - Following Documentation/DocBook/kernel-locking.pdf no spin locks * are held when calling copy_to/from_user or printk. * -* $Id: digi_acceleport.c,v 1.80 2000/08/09 06:36:18 root Exp $ +* $Id: digi_acceleport.c,v 1.80.1.2 2000/11/02 05:45:08 root Exp $ */ #include @@ -411,6 +421,7 @@ typedef struct digi_port { int dp_in_buf_len; unsigned char dp_in_buf[DIGI_IN_BUF_SIZE]; unsigned char dp_in_flag_buf[DIGI_IN_BUF_SIZE]; + int dp_write_urb_in_use; unsigned int dp_modem_signals; wait_queue_head_t dp_modem_change_wait; int dp_open_count; /* inc on open, dec on close */ @@ -461,15 +472,29 @@ static int digi_read_oob_callback( struct urb *urb ); /* Statics */ +static __devinitdata struct usb_device_id id_table_combined [] = { + { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_2_ID }, + { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_4_ID }, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id id_table_2 [] = { + { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_2_ID }, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id id_table_4 [] = { + { idVendor: DIGI_VENDOR_ID, idProduct: DIGI_4_ID }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, id_table_combined); + /* device info needed for the Digi serial converter */ -static u16 digi_vendor_id = DIGI_VENDOR_ID; -static u16 digi_product_2_id = DIGI_2_ID; /* USB 2 */ -static u16 digi_product_4_id = DIGI_4_ID; /* USB 4 */ static struct usb_serial_device_type digi_acceleport_2_device = { name: "Digi USB", - idVendor: &digi_vendor_id, - idProduct: &digi_product_2_id, + id_table: id_table_2, needs_interrupt_in: DONT_CARE, needs_bulk_in: MUST_HAVE, needs_bulk_out: MUST_HAVE, @@ -495,8 +520,7 @@ static struct usb_serial_device_type digi_acceleport_2_device = { static struct usb_serial_device_type digi_acceleport_4_device = { name: "Digi USB", - idVendor: &digi_vendor_id, - idProduct: &digi_product_4_id, + id_table: id_table_4, needs_interrupt_in: DONT_CARE, needs_bulk_in: MUST_HAVE, needs_bulk_out: MUST_HAVE, @@ -629,7 +653,8 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co while( count > 0 ) { - while( oob_port->write_urb->status == -EINPROGRESS ) { + while( oob_port->write_urb->status == -EINPROGRESS + || oob_priv->dp_write_urb_in_use ) { cond_wait_interruptible_timeout_irqrestore( &oob_port->write_wait, DIGI_RETRY_TIMEOUT, &oob_priv->dp_port_lock, flags ); @@ -647,8 +672,9 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co memcpy( oob_port->write_urb->transfer_buffer, buf, len ); oob_port->write_urb->transfer_buffer_length = len; oob_port->write_urb->dev = port->serial->dev; - + if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) { + oob_priv->dp_write_urb_in_use = 1; count -= len; buf += len; } @@ -702,8 +728,8 @@ count ); while( count > 0 && ret == 0 ) { - while( port->write_urb->status == -EINPROGRESS - && jiffies < timeout ) { + while( (port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use) && jiffies < timeout ) { cond_wait_interruptible_timeout_irqrestore( &port->write_wait, DIGI_RETRY_TIMEOUT, &priv->dp_port_lock, flags ); @@ -736,6 +762,7 @@ count ); port->write_urb->dev = port->serial->dev; if( (ret=usb_submit_urb(port->write_urb)) == 0 ) { + priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; count -= len; buf += len; @@ -783,7 +810,8 @@ port_priv->dp_port_num, modem_signals ); spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); spin_lock( &port_priv->dp_port_lock ); - while( oob_port->write_urb->status == -EINPROGRESS ) { + while( oob_port->write_urb->status == -EINPROGRESS + || oob_priv->dp_write_urb_in_use ) { spin_unlock( &port_priv->dp_port_lock ); cond_wait_interruptible_timeout_irqrestore( &oob_port->write_wait, DIGI_RETRY_TIMEOUT, @@ -811,6 +839,7 @@ port_priv->dp_port_num, modem_signals ); oob_port->write_urb->dev = port->serial->dev; if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) { + oob_priv->dp_write_urb_in_use = 1; port_priv->dp_modem_signals = (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS)) | (modem_signals&(TIOCM_DTR|TIOCM_RTS)); @@ -1249,7 +1278,8 @@ priv->dp_port_num, count, from_user, in_interrupt() ); spin_lock_irqsave( &priv->dp_port_lock, flags ); /* wait for urb status clear to submit another urb */ - if( port->write_urb->status == -EINPROGRESS ) { + if( port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use ) { /* buffer data if count is 1 (probably put_char) if possible */ if( count == 1 ) { @@ -1292,6 +1322,7 @@ priv->dp_port_num, count, from_user, in_interrupt() ); memcpy( data, from_user ? user_buf : buf, new_len ); if( (ret=usb_submit_urb(port->write_urb)) == 0 ) { + priv->dp_write_urb_in_use = 1; ret = new_len; priv->dp_out_buf_len = 0; } @@ -1337,6 +1368,7 @@ dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status ); == ((digi_serial_t *)(serial->private))->ds_oob_port_num ) { dbg( "digi_write_bulk_callback: oob callback" ); spin_lock( &priv->dp_port_lock ); + priv->dp_write_urb_in_use = 0; wake_up_interruptible( &port->write_wait ); spin_unlock( &priv->dp_port_lock ); return; @@ -1349,6 +1381,7 @@ dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status ); /* try to send any buffered data on this port, if it is open */ spin_lock( &priv->dp_port_lock ); + priv->dp_write_urb_in_use = 0; if( priv->dp_open_count && port->write_urb->status != -EINPROGRESS && priv->dp_out_buf_len > 0 ) { @@ -1365,6 +1398,7 @@ dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status ); priv->dp_out_buf_len ); if( (ret=usb_submit_urb(port->write_urb)) == 0 ) { + priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; } @@ -1397,7 +1431,8 @@ static int digi_write_room( struct usb_serial_port *port ) spin_lock_irqsave( &priv->dp_port_lock, flags ); - if( port->write_urb->status == -EINPROGRESS ) + if( port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use ) room = 0; else room = port->bulk_out_size - 2 - priv->dp_out_buf_len; @@ -1416,7 +1451,8 @@ static int digi_chars_in_buffer( struct usb_serial_port *port ) digi_port_t *priv = (digi_port_t *)(port->private); - if( port->write_urb->status == -EINPROGRESS ) { + if( port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use ) { dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, port->bulk_out_size - 2 ); /* return( port->bulk_out_size - 2 ); */ return( 256 ); @@ -1601,6 +1637,7 @@ dbg( "digi_close: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, po spin_lock_irqsave( &priv->dp_port_lock, flags ); port->active = 0; + priv->dp_write_urb_in_use = 0; priv->dp_in_close = 0; --priv->dp_open_count; MOD_DEC_USE_COUNT; @@ -1641,7 +1678,6 @@ static int digi_startup_device( struct usb_serial *serial ) port = &serial->port[i]; - port->write_urb->transfer_flags |= USB_DISABLE_SPD; port->write_urb->dev = port->serial->dev; if( (ret=usb_submit_urb(port->read_urb)) != 0 ) { @@ -1689,6 +1725,7 @@ dbg( "digi_startup: TOP" ); priv->dp_port_num = i; priv->dp_out_buf_len = 0; priv->dp_in_buf_len = 0; + priv->dp_write_urb_in_use = 0; priv->dp_modem_signals = 0; init_waitqueue_head( &priv->dp_modem_change_wait ); priv->dp_open_count = 0; @@ -2047,5 +2084,5 @@ module_exit(digi_exit); MODULE_AUTHOR("Peter Berger , Al Borchers "); -MODULE_DESCRIPTION("Digi AccelePort USB-4 Serial Converter driver"); +MODULE_DESCRIPTION("Digi AccelePort USB-2/USB-4 Serial Converter driver"); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 70f4cd1b0..8fdfd95bd 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -12,6 +12,9 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (11/01/2000) Adam J. Richter + * usb_device_id table support + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. @@ -71,6 +74,14 @@ #define FTDI_VENDOR_ID 0x0403 #define FTDI_SIO_SERIAL_CONVERTER_ID 0x8372 +static __devinitdata struct usb_device_id id_table [] = { + { idVendor: FTDI_VENDOR_ID, idProduct: FTDI_SIO_SERIAL_CONVERTER_ID }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, id_table); + + /* function prototypes for a FTDI serial converter */ static int ftdi_sio_startup (struct usb_serial *serial); static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp); @@ -82,12 +93,9 @@ static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios * static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); /* All of the device info needed for the FTDI SIO serial converter */ -static __u16 ftdi_vendor_id = FTDI_VENDOR_ID; -static __u16 ftdi_sio_product_id = FTDI_SIO_SERIAL_CONVERTER_ID; struct usb_serial_device_type ftdi_sio_device = { name: "FTDI SIO", - idVendor: &ftdi_vendor_id, /* the FTDI vendor ID */ - idProduct: &ftdi_sio_product_id, /* the FTDI SIO product id */ + id_table: id_table, needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */ needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 9c509ff15..885108cd0 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -22,6 +22,9 @@ Tip 'o the hat to Linuxcare for supporting staff in their work on open source projects. + (11/01/2000) Adam J. Richter + usb_device_id table support. + (10/05/2000) gkh Fixed bug with urb->dev not being set properly, now that the usb core needs it. diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 666946181..8d249916c 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -117,28 +117,96 @@ struct ezusb_hex_record { /* Device info for the Keyspan serial converter */ #define KEYSPAN_VENDOR_ID (0x06cd) -static __u16 keyspan_vendor_id = KEYSPAN_VENDOR_ID; /* Product IDs for the five products supported, pre-renumeration */ -static __u16 keyspan_usa18x_pre_product_id = 0x0105; -static __u16 keyspan_usa19_pre_product_id = 0x0103; -static __u16 keyspan_usa19w_pre_product_id = 0x0106; -static __u16 keyspan_usa28_pre_product_id = 0x0101; -static __u16 keyspan_usa28x_pre_product_id = 0x0102; +#define keyspan_usa18x_pre_product_id 0x0105 +#define keyspan_usa19_pre_product_id 0x0103 +#define keyspan_usa19w_pre_product_id 0x0106 +#define keyspan_usa28_pre_product_id 0x0101 +#define keyspan_usa28x_pre_product_id 0x0102 /* Product IDs post-renumeration */ -static __u16 keyspan_usa18x_product_id = 0x0112; -static __u16 keyspan_usa19_product_id = 0x0107; -static __u16 keyspan_usa19w_product_id = 0x0108; -static __u16 keyspan_usa28_product_id = 0x010f; -static __u16 keyspan_usa28x_product_id = 0x0110; +#define keyspan_usa18x_product_id 0x0112 +#define keyspan_usa19_product_id 0x0107 +#define keyspan_usa19w_product_id 0x0108 +#define keyspan_usa28_product_id 0x010f +#define keyspan_usa28x_product_id 0x0110 + +static __devinitdata struct usb_device_id keyspan_ids_combined[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa18x_pre_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19_pre_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19w_pre_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28_pre_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28x_pre_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa18x_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19w_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28x_product_id}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); + +/* Eventually, we will not need separate id tables for each USB + ID pattern. But, for now, it looks like we need slightly different + behavior for each match. */ + +static __devinitdata struct usb_device_id keyspan_usa18x_pre_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa18x_pre_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa19_pre_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19_pre_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa19w_pre_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19w_pre_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa28_pre_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28_pre_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa28x_pre_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28x_pre_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa18x_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa18x_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa19_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa19w_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19w_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa28_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28_product_id}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id keyspan_usa28x_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28x_product_id}, + { } /* Terminating entry */ +}; /* Structs for the devices, pre and post renumeration. These are incomplete at present - HAB 20000708 */ struct usb_serial_device_type keyspan_usa18x_pre_device = { name: "Keyspan USA18X - (prerenumeration)", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa18x_pre_product_id, + id_table: keyspan_usa18x_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -151,8 +219,7 @@ struct usb_serial_device_type keyspan_usa18x_pre_device = { struct usb_serial_device_type keyspan_usa19_pre_device = { name: "Keyspan USA19 - (prerenumeration)", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa19_pre_product_id, + id_table: keyspan_usa19_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -166,8 +233,7 @@ struct usb_serial_device_type keyspan_usa19_pre_device = { struct usb_serial_device_type keyspan_usa19w_pre_device = { name: "Keyspan USA19W - (prerenumeration)", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa19w_pre_product_id, + id_table: keyspan_usa19w_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -181,8 +247,7 @@ struct usb_serial_device_type keyspan_usa19w_pre_device = { struct usb_serial_device_type keyspan_usa28_pre_device = { name: "Keyspan USA28 - (prerenumeration)", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa28_pre_product_id, + id_table: keyspan_usa28_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -195,8 +260,7 @@ struct usb_serial_device_type keyspan_usa28_pre_device = { struct usb_serial_device_type keyspan_usa28x_pre_device = { name: "Keyspan USA28X - (prerenumeration)", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa28x_pre_product_id, + id_table: keyspan_usa28x_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -210,8 +274,7 @@ struct usb_serial_device_type keyspan_usa28x_pre_device = { struct usb_serial_device_type keyspan_usa18x_device = { name: "Keyspan USA18X", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa18x_product_id, + id_table: keyspan_usa18x_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -228,8 +291,7 @@ struct usb_serial_device_type keyspan_usa18x_device = { struct usb_serial_device_type keyspan_usa19_device = { name: "Keyspan USA19", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa19_product_id, + id_table: keyspan_usa19_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: MUST_HAVE, needs_bulk_out: MUST_HAVE, @@ -256,8 +318,7 @@ struct usb_serial_device_type keyspan_usa19_device = { struct usb_serial_device_type keyspan_usa19w_device = { name: "Keyspan USA19W", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa19w_product_id, + id_table: keyspan_usa19w_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -275,8 +336,7 @@ struct usb_serial_device_type keyspan_usa19w_device = { struct usb_serial_device_type keyspan_usa28_device = { name: "Keyspan USA28", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa28_product_id, + id_table: keyspan_usa28_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -294,8 +354,7 @@ struct usb_serial_device_type keyspan_usa28_device = { struct usb_serial_device_type keyspan_usa28x_device = { name: "Keyspan USA28X", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_usa28x_product_id, + id_table: keyspan_usa28x_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 51a1f10df..3114322c8 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -12,6 +12,9 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (11/01/2000) Adam J. Richter + * usb_device_id table support + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. @@ -93,12 +96,23 @@ struct keyspan_pda_private { #define KEYSPAN_PDA_FAKE_ID 0x0103 #define KEYSPAN_PDA_ID 0x0104 /* no clue */ -/* All of the device info needed for the Keyspan PDA serial converter */ -static __u16 keyspan_vendor_id = KEYSPAN_VENDOR_ID; -static __u16 keyspan_pda_fake_product_id = KEYSPAN_PDA_FAKE_ID; -static __u16 keyspan_pda_product_id = KEYSPAN_PDA_ID; +static __devinitdata struct usb_device_id id_table_combined [] = { + { idVendor: KEYSPAN_VENDOR_ID, idProduct: KEYSPAN_PDA_FAKE_ID }, + { idVendor: KEYSPAN_VENDOR_ID, idProduct: KEYSPAN_PDA_ID }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, id_table_combined); +static __devinitdata struct usb_device_id id_table_std [] = { + { idVendor: KEYSPAN_VENDOR_ID, idProduct: KEYSPAN_PDA_ID }, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id id_table_fake [] = { + { idVendor: KEYSPAN_VENDOR_ID, idProduct: KEYSPAN_PDA_FAKE_ID }, + { } /* Terminating entry */ +}; static void keyspan_pda_wakeup_write( struct usb_serial_port *port ) { @@ -746,8 +760,7 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) struct usb_serial_device_type keyspan_pda_fake_device = { name: "Keyspan PDA - (prerenumeration)", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_pda_fake_product_id, + id_table: id_table_fake, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, needs_bulk_out: DONT_CARE, @@ -760,8 +773,7 @@ struct usb_serial_device_type keyspan_pda_fake_device = { struct usb_serial_device_type keyspan_pda_device = { name: "Keyspan PDA", - idVendor: &keyspan_vendor_id, - idProduct: &keyspan_pda_product_id, + id_table: id_table_std, needs_interrupt_in: MUST_HAVE, needs_bulk_in: DONT_CARE, needs_bulk_out: MUST_HAVE, diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index dc832fa53..2b9f99f7c 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -10,6 +10,9 @@ * * Please report both successes and troubles to the author at omninet@kroah.com * + * (11/01/2000) Adam J. Richter + * usb_device_id table support + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. @@ -66,14 +69,17 @@ static int omninet_write (struct usb_serial_port *port, int from_user, const u static int omninet_write_room (struct usb_serial_port *port); static void omninet_shutdown (struct usb_serial *serial); -/* All of the device info needed for the omni.net */ -static __u16 zyxel_vendor_id = ZYXEL_VENDOR_ID; -static __u16 zyxel_omninet_product_id = ZYXEL_OMNINET_ID; +static __devinitdata struct usb_device_id id_table [] = { + { idVendor: ZYXEL_VENDOR_ID, idProduct: ZYXEL_OMNINET_ID }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, id_table); + struct usb_serial_device_type zyxel_omninet_device = { name: "ZyXEL - omni.net lcd plus usb", - idVendor: &zyxel_vendor_id, - idProduct: &zyxel_omninet_product_id, + id_table: id_table, needs_interrupt_in: MUST_HAVE, needs_bulk_in: MUST_HAVE, needs_bulk_out: MUST_HAVE, diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 5dde77426..913fb2f26 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -112,8 +112,7 @@ struct usb_serial { /* This structure defines the individual serial converter. */ struct usb_serial_device_type { char *name; - __u16 *idVendor; - __u16 *idProduct; + const struct usb_device_id *id_table; char needs_interrupt_in; char needs_bulk_in; char needs_bulk_out; @@ -125,7 +124,9 @@ struct usb_serial_device_type { struct list_head driver_list; /* function call to make before accepting driver */ - int (*startup) (struct usb_serial *serial); /* return 0 to continue initialization, anything else to abort */ + /* return 0 to continue initialization, anything else to abort */ + int (*startup) (struct usb_serial *serial); + void (*shutdown) (struct usb_serial *serial); /* serial function calls */ diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index 902a4e1d0..6b5d6e7f0 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -15,6 +15,11 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (11/01/2000) Adam J. Richter + * instead of using idVendor/idProduct pairs, usb serial drivers + * now identify their hardware interest with usb_device_id tables, + * which they usually have anyhow for use with MODULE_DEVICE_TABLE. + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. @@ -288,11 +293,12 @@ MODULE_PARM_DESC(vendor, "User specified USB idVendor"); MODULE_PARM(product, "i"); MODULE_PARM_DESC(product, "User specified USB idProduct"); +static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ + /* All of the device info needed for the Generic Serial Converter */ static struct usb_serial_device_type generic_device = { name: "Generic", - idVendor: &vendor, /* use the user specified vendor id */ - idProduct: &product, /* use the user specified product id */ + id_table: generic_device_ids, needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */ needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */ needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */ @@ -316,15 +322,25 @@ static void serial_unthrottle (struct tty_struct * tty); static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg); static void serial_set_termios (struct tty_struct *tty, struct termios * old); -static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum); +static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); static void usb_serial_disconnect(struct usb_device *dev, void *ptr); static struct usb_driver usb_serial_driver = { name: "serial", probe: usb_serial_probe, disconnect: usb_serial_disconnect, + id_table: NULL, /* check all devices */ }; +/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead + the MODULE_DEVICE_TABLE declarations in each serial driver + cause the "hotplug" program to pull in whatever module is necessary + via modprobe, and modprobe will load usbserial because the serial + drivers depend on it. +*/ + + static int serial_refcount; static struct tty_driver serial_tty_driver; static struct tty_struct * serial_tty[SERIAL_TTY_MINORS]; @@ -957,7 +973,8 @@ static void port_softint(void *private) -static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) +static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_serial *serial = NULL; struct usb_serial_port *port; @@ -981,19 +998,17 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) int num_bulk_out = 0; int num_ports; int max_endpoints; + const struct usb_device_id *id_pattern = NULL; /* loop through our list of known serial converters, and see if this device matches. */ found = 0; + interface = &dev->actconfig->interface[ifnum]; list_for_each (tmp, &usb_serial_driver_list) { type = list_entry(tmp, struct usb_serial_device_type, driver_list); - dbg ("Looking at %s Vendor id=%.4x Product id=%.4x", - type->name, *(type->idVendor), *(type->idProduct)); - - /* look at the device descriptor */ - if ((dev->descriptor.idVendor == *(type->idVendor)) && - (dev->descriptor.idProduct == *(type->idProduct))) { + id_pattern = usb_match_id(dev, interface, type->id_table); + if (id_pattern != NULL) { dbg("descriptor matches"); found = 1; break; @@ -1009,7 +1024,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) interrupt_pipe = bulk_in_pipe = bulk_out_pipe = HAS_NOT; /* check out the endpoints */ - interface = &dev->actconfig->interface[ifnum]; iface_desc = &interface->altsetting[0]; for (i = 0; i < iface_desc->bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i]; @@ -1335,6 +1349,8 @@ int usb_serial_init(void) } #ifdef CONFIG_USB_SERIAL_GENERIC + generic_device_ids[0].idVendor = vendor; + generic_device_ids[0].idProduct = product; /* register our generic driver with ourselves */ usb_serial_register (&generic_device); #endif diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 868333c87..c078704f0 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -11,6 +11,9 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (11/01/2000) Adam J. Richter + * usb_device_id table support + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. @@ -101,13 +104,20 @@ static void visor_set_termios (struct usb_serial_port *port, struct termios *old static void visor_write_bulk_callback (struct urb *urb); static void visor_read_bulk_callback (struct urb *urb); + +static __devinitdata struct usb_device_id id_table [] = { + { idVendor: HANDSPRING_VENDOR_ID, idProduct: HANDSPRING_VISOR_ID }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, id_table); + + + /* All of the device info needed for the Handspring Visor */ -static __u16 handspring_vendor_id = HANDSPRING_VENDOR_ID; -static __u16 handspring_product_id = HANDSPRING_VISOR_ID; struct usb_serial_device_type handspring_device = { name: "Handspring Visor", - idVendor: &handspring_vendor_id, /* the Handspring vendor ID */ - idProduct: &handspring_product_id, /* the Handspring Visor product id */ + id_table: id_table, needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */ needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 55abab383..83a822225 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -11,6 +11,9 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (11/01/2000) Adam J. Richter + * usb_device_id table support + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. @@ -77,6 +80,31 @@ #define CONNECT_TECH_FAKE_WHITE_HEAT_ID 0x0001 #define CONNECT_TECH_WHITE_HEAT_ID 0x8001 +/* + ID tables for whiteheat are unusual, because we want to different + things for different versions of the device. Eventually, this + will be doable from a single table. But, for now, we define two + separate ID tables, and then a third table that combines them + just for the purpose of exporting the autoloading information. +*/ +static __devinitdata struct usb_device_id id_table_std [] = { + {idVendor: CONNECT_TECH_VENDOR_ID, idProduct: CONNECT_TECH_WHITE_HEAT_ID}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id id_table_prerenumeration [] = { + {idVendor: CONNECT_TECH_VENDOR_ID, idProduct: CONNECT_TECH_WHITE_HEAT_ID}, + { } /* Terminating entry */ +}; + +static __devinitdata struct usb_device_id id_table_combined [] = { + {idVendor: CONNECT_TECH_VENDOR_ID, idProduct: CONNECT_TECH_WHITE_HEAT_ID}, + {idVendor: CONNECT_TECH_VENDOR_ID, idProduct: CONNECT_TECH_FAKE_WHITE_HEAT_ID}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, id_table_combined); + /* function prototypes for the Connect Tech WhiteHEAT serial converter */ static int whiteheat_open (struct usb_serial_port *port, struct file *filp); static void whiteheat_close (struct usb_serial_port *port, struct file *filp); @@ -87,14 +115,9 @@ static void whiteheat_unthrottle (struct usb_serial_port *port); static int whiteheat_startup (struct usb_serial *serial); static void whiteheat_shutdown (struct usb_serial *serial); -/* All of the device info needed for the Connect Tech WhiteHEAT */ -static __u16 connecttech_vendor_id = CONNECT_TECH_VENDOR_ID; -static __u16 connecttech_whiteheat_fake_product_id = CONNECT_TECH_FAKE_WHITE_HEAT_ID; -static __u16 connecttech_whiteheat_product_id = CONNECT_TECH_WHITE_HEAT_ID; struct usb_serial_device_type whiteheat_fake_device = { name: "Connect Tech - WhiteHEAT - (prerenumeration)", - idVendor: &connecttech_vendor_id, /* the Connect Tech vendor id */ - idProduct: &connecttech_whiteheat_fake_product_id, /* the White Heat initial product id */ + id_table: id_table_prerenumeration, needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */ needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */ needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */ @@ -104,10 +127,10 @@ struct usb_serial_device_type whiteheat_fake_device = { num_ports: 1, startup: whiteheat_startup }; + struct usb_serial_device_type whiteheat_device = { name: "Connect Tech - WhiteHEAT", - idVendor: &connecttech_vendor_id, /* the Connect Tech vendor id */ - idProduct: &connecttech_whiteheat_product_id, /* the White Heat real product id */ + id_table: id_table_std, needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */ needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */ needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */ diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 80ace9dac..cf82489de 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -1,7 +1,7 @@ /* Driver for USB Mass Storage compliant devices * SCSI layer glue code * - * $Id: scsiglue.c,v 1.15 2000/10/19 18:44:11 mdharm Exp $ + * $Id: scsiglue.c,v 1.17 2000/11/02 21:27:49 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -47,6 +47,7 @@ #include "scsiglue.h" #include "usb.h" #include "debug.h" +#include "transport.h" #include @@ -105,7 +106,7 @@ static int detect(struct SHT *sht) /* Release all resources used by the virtual host * - * NOTE: There is no contention here, because we're allready deregistered + * NOTE: There is no contention here, because we're already deregistered * the driver and we're doing each virtual host in turn, not in parallel */ static int release(struct Scsi_Host *psh) @@ -218,6 +219,7 @@ static int bus_reset( Scsi_Cmnd *srb ) { struct us_data *us = (struct us_data *)srb->host->hostdata[0]; int i; + int result; /* we use the usb_reset_device() function to handle this for us */ US_DEBUGP("bus_reset() called\n"); @@ -228,6 +230,15 @@ static int bus_reset( Scsi_Cmnd *srb ) return SUCCESS; } + /* release the IRQ, if we have one */ + down(&(us->irq_urb_sem)); + if (us->irq_urb) { + US_DEBUGP("-- releasing irq URB\n"); + result = usb_unlink_urb(us->irq_urb); + US_DEBUGP("-- usb_unlink_urb() returned %d\n", result); + } + up(&(us->irq_urb_sem)); + /* attempt to reset the port */ if (usb_reset_device(us->pusb_dev) < 0) return FAILED; @@ -237,6 +248,7 @@ static int bus_reset( Scsi_Cmnd *srb ) for (i = 0; i < us->pusb_dev->actconfig->bNumInterfaces; i++) { struct usb_interface *intf = &us->pusb_dev->actconfig->interface[i]; + struct usb_device_id *id; /* if this is an unclaimed interface, skip it */ if (!intf->driver) { @@ -254,10 +266,22 @@ static int bus_reset( Scsi_Cmnd *srb ) US_DEBUGPX("simulating disconnect/reconnect.\n"); down(&intf->driver->serialize); intf->driver->disconnect(us->pusb_dev, intf->private_data); - intf->driver->probe(us->pusb_dev, i); + id = usb_match_id(us->pusb_dev, intf, intf->driver->id_table); + intf->driver->probe(us->pusb_dev, i, id); up(&intf->driver->serialize); } + /* re-allocate the IRQ URB and submit it to restore connectivity + * for CBI devices + */ + if (us->protocol == US_PR_CBI) { + down(&(us->irq_urb_sem)); + us->irq_urb->dev = us->pusb_dev; + result = usb_submit_urb(us->irq_urb); + US_DEBUGP("usb_submit_urb() returns %d\n", result); + up(&(us->irq_urb_sem)); + } + US_DEBUGP("bus_reset() complete\n"); return SUCCESS; } diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 6551d259c..648db0bc3 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1,6 +1,6 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: transport.c,v 1.30 2000/10/24 02:01:18 mdharm Exp $ + * $Id: transport.c,v 1.32 2000/11/03 00:18:04 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -91,11 +91,11 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) static char *lengths = - /* 0123456789ABCDEF 0123456789ABCDEF */ + /* 0123456789ABCDEF 0123456789ABCDEF */ "00XLZ6XZBXBBXXXB" "00LBBLG0R0L0GG0X" /* 00-1F */ "XXXXT8XXB4B0BBBB" "ZZZ0B00HCSSZTBHH" /* 20-3F */ - "M0HHB0X000H0HH0X" "XHH00HXX0TH0H0XX" /* 40-5F */ + "M0HHB0X000H0HH0X" "XHH0HHXX0TH0H0XX" /* 40-5F */ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 60-7F */ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 80-9F */ "X0XXX00XB0BXBXBB" "ZZZ0XUIDU000XHBX" /* A0-BF */ @@ -185,6 +185,7 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) SEND_MESSAGE_6 0a !!! Same as WRITE_6 - is in bytes SEND_MESSAGE_10 2a !!! Same as WRITE_10 - is in bytes SEND_MESSAGE_12 aa !!! Same as WRITE_12 - is in bytes + SEND_OPC 54 SEND_VOLUME_TAG b6 !!! Think this is in bytes SET_LIMITS 33 SET_LIMITS_12 b3 @@ -544,7 +545,7 @@ int usb_stor_transfer_partial(struct us_data *us, char *buf, int length) /* uh oh... we have an error code, so something went wrong. */ if (result) { - /* NAK - that means we've retried a few times allready */ + /* NAK - that means we've retried a few times already */ if (result == -ETIMEDOUT) { US_DEBUGP("usb_stor_transfer_partial(): device NAKed\n"); return US_BULK_TRANSFER_FAILED; diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 8d41b1c0c..b63f4359c 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -1,6 +1,6 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: usb.c,v 1.51 2000/10/19 18:49:51 mdharm Exp $ + * $Id: usb.c,v 1.54 2000/10/31 21:32:10 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -243,6 +243,7 @@ static int usb_stor_control_thread(void * __us) /* handle those devices which can't do a START_STOP */ if ((us->srb->cmnd[0] == START_STOP) && (us->flags & US_FL_START_STOP)) { + US_DEBUGP("Skipping START_STOP command\n"); us->srb->result = GOOD << 1; set_current_state(TASK_INTERRUPTIBLE); @@ -423,8 +424,8 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { 0x054c, 0x002d, 0x0100, 0x0100, "Sony", "Memorystick MSAC-US1", - US_SC_SCSI, US_PR_CB, NULL, - US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE }, + US_SC_UFI, US_PR_CB, NULL, + US_FL_SINGLE_LUN | US_FL_START_STOP }, { 0x057b, 0x0000, 0x0000, 0x0299, "Y-E Data", @@ -504,7 +505,7 @@ static struct us_unusual_dev us_unusual_dev_list[] = { US_FL_SCM_MULT_TARG }, #ifdef CONFIG_USB_STORAGE_FREECOM - { 0x07ab, 0xfc01, 0x0921, 0x0921, + { 0x07ab, 0xfc01, 0x0000, 0x9999, "Freecom", "USB-IDE", US_SC_QIC, US_PR_FREECOM, freecom_init, 0}, @@ -754,7 +755,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) /* * Now check if we have seen this GUID before * We're looking for a device with a matching GUID that isn't - * allready on the system + * already on the system */ ss = us_list; while ((ss != NULL) && diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index a37a71f75..4535428b7 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -7,6 +7,9 @@ * (C) Copyright Gregory P. Smith 1999 * (C) Copyright Deti Fliegl 1999 (new USB architecture) * (C) Copyright Randy Dunlap 2000 + * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id) + * (C) Copyright Yggdrasil Computing, Inc. 2000 + * (usb_device_id matching changes by Adam J. Richter) * * NOTE! This is not actually a driver at all, rather this is * just a collection of helper routines that implement the @@ -460,6 +463,124 @@ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interfac iface->private_data = NULL; } + +/* usb_match_id searches an array of usb_device_id's and returns + the first one that matches the device and interface. + + Parameters: + "id" is an array of usb_device_id's is terminated by an entry + containing all zeroes. + + "dev" and "interface" are the device and interface for which + a match is sought. + + If no match is found or if the "id" pointer is NULL, then + usb_match_id returns NULL. + + + What constitutes a match: + + A zero in any element of a usb_device_id entry is a wildcard + (i.e., that field always matches). For there to be a match, + *every* nonzero element of the usb_device_id must match the + provided device and interface in. The comparison is for equality, + except for one pair of fields: usb_match_id.bcdDevice_{lo,hi} define + an inclusive range that dev->descriptor.bcdDevice must be in. + + If interface->altsettings does not exist (i.e., there are no + interfaces defined), then bInterface{Class,SubClass,Protocol} + only match if they are all zeroes. + + + What constitutes a good "usb_device_id"? + + The match algorithm is very simple, so that intelligence in + driver selection must come from smart driver id records. + Unless you have good reasons to use another selection policy, + provide match elements only in related groups: + + * device specifiers (vendor and product IDs; and maybe + a revision range for that product); + * generic device specs (class/subclass/protocol); + * interface specs (class/subclass/protocol). + + Within those groups, work from least specific to most specific. + For example, don't give a product version range without vendor + and product IDs. + + "driver_info" is not considered by the kernel matching algorithm, + but you can create a wildcard "matches anything" usb_device_id + as your driver's "modules.usbmap" entry if you provide only an + id with a nonzero "driver_info" field. +*/ + +const struct usb_device_id * +usb_match_id(struct usb_device *dev, struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_interface_descriptor *intf = 0; + + /* proc_connectinfo in devio.c may call us with id == NULL. */ + if (id == NULL) + return NULL; + + /* It is important to check that id->driver_info is nonzero, + since an entry that is all zeroes except for a nonzero + id->driver_info is the way to create an entry that + indicates that the driver want to examine every + device and interface. */ + for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || + id->driver_info; id++) { + + if (id->idVendor && + id->idVendor != dev->descriptor.idVendor) + continue; + + if (id->idProduct && + id->idProduct != dev->descriptor.idProduct) + continue; + + /* No need to test id->bcdDevice_lo != 0, since 0 is never + greater than any unsigned number. */ + if (id->bcdDevice_lo > dev->descriptor.bcdDevice) + continue; + + if (id->bcdDevice_hi && + id->bcdDevice_hi < dev->descriptor.bcdDevice) + continue; + + if (id->bDeviceClass && + id->bDeviceClass != dev->descriptor.bDeviceClass) + continue; + + if (id->bDeviceSubClass && + id->bDeviceSubClass!= dev->descriptor.bDeviceClass) + continue; + + if (id->bDeviceProtocol && + id->bDeviceProtocol != dev->descriptor.bDeviceProtocol) + continue; + + intf = &interface->altsetting [interface->act_altsetting]; + + if (id->bInterfaceClass + && id->bInterfaceClass != intf->bInterfaceClass) + continue; + + if (id->bInterfaceSubClass && + id->bInterfaceSubClass != intf->bInterfaceSubClass) + continue; + + if (id->bInterfaceProtocol + && id->bInterfaceProtocol != intf->bInterfaceProtocol) + continue; + + return id; + } + + return NULL; +} + /* * This entrypoint gets called for each new device. * @@ -478,8 +599,12 @@ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interfac */ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) { - struct list_head *tmp = usb_driver_list.next; + struct list_head *tmp; struct usb_interface *interface; + void *private; + const struct usb_device_id *id; + struct usb_driver *driver; + int i; if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) { err("bad find_interface_driver params"); @@ -491,90 +616,41 @@ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) if (usb_interface_claimed(interface)) return -1; - while (tmp != &usb_driver_list) { - void *private; - struct usb_driver *driver = list_entry(tmp, struct usb_driver, - driver_list); - + private = NULL; + for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) { + + driver = list_entry(tmp, struct usb_driver, driver_list); tmp = tmp->next; - down(&driver->serialize); + down(&driver->serialize); + id = driver->id_table; /* new style driver? */ - if (driver->bind) { - const struct usb_device_id *id = driver->id_table; - - if (id) { - /* scan device ids for a match */ - for (;; id++) { - struct usb_interface_descriptor *intf = 0; - - /* done? */ - if (!id->idVendor && !id->bDeviceClass && !id->bInterfaceClass) { - id = 0; - break; - } + if (id) { + for (i = 0; i < interface->num_altsetting; i++) { + interface->act_altsetting = i; + id = usb_match_id(dev, interface, id); + if (id) { + private = driver->probe(dev,ifnum,id); + if (private != NULL) + break; + } + } + } + else /* "old style" driver */ + private = driver->probe(dev, ifnum, NULL); - /* Vendor match, possibly product-specific? */ - if (id->idVendor && id->idVendor == dev->descriptor.idVendor) { - if (id->idProduct && id->idProduct != dev->descriptor.idProduct) - continue; - break; - } - - /* Device class match? */ - if (id->bDeviceClass - && id->bDeviceClass == dev->descriptor.bDeviceClass) { - if (id->bDeviceSubClass && id->bDeviceSubClass - != dev->descriptor.bDeviceClass) - continue; - if (id->bDeviceProtocol && id->bDeviceProtocol - != dev->descriptor.bDeviceProtocol) - continue; - break; - } - - /* Interface class match? */ - if (!interface->altsetting || interface->num_altsetting < 1) - continue; - intf = &interface->altsetting [0]; - if (id->bInterfaceClass - && id->bInterfaceClass == intf->bInterfaceClass) { - if (id->bInterfaceSubClass && id->bInterfaceSubClass - != intf->bInterfaceClass) - continue; - if (id->bInterfaceProtocol && id->bInterfaceProtocol - != intf->bInterfaceProtocol) - continue; - break; - } - } - - /* is this driver interested in this interface? */ - if (id) - private = driver->bind(dev, ifnum, id); - else - private = 0; - } else { - /* "old style" driver, but using new interface */ - private = driver->bind(dev, ifnum, 0); - } - - /* "old style" driver */ - } else - private = driver->probe(dev, ifnum); up(&driver->serialize); - if (!private) - continue; - usb_driver_claim_interface(driver, interface, private); - - return 0; + if (private) { + usb_driver_claim_interface(driver, interface, private); + return 0; + } } - + return -1; } -#if defined(CONFIG_KMOD) && defined(CONFIG_HOTPLUG) +#if defined(CONFIG_KMOD) /* * USB hotplugging invokes what /proc/sys/kernel/hotplug says @@ -715,6 +791,10 @@ static void call_policy (char *verb, struct usb_device *dev) /* otherwise, use a simple (so far) generic driver binding model */ envp [i++] = scratch; + scratch += sprintf (scratch, "TYPE=%d/%d/%d", + dev->descriptor.bDeviceClass, + dev->descriptor.bDeviceSubClass, + dev->descriptor.bDeviceProtocol) + 1; if (dev->descriptor.bDeviceClass == 0) { int alt = dev->actconfig->interface [0].act_altsetting; @@ -729,10 +809,6 @@ static void call_policy (char *verb, struct usb_device *dev) /* INTERFACE-0, INTERFACE-1, ... ? */ } else { /* simple/common case: generic device, handled generically */ - scratch += sprintf (scratch, "TYPE=%d/%d/%d", - dev->descriptor.bDeviceClass, - dev->descriptor.bDeviceSubClass, - dev->descriptor.bDeviceProtocol) + 1; } envp [i++] = 0; /* assert: (scratch - buf) < sizeof buf */ @@ -753,7 +829,7 @@ static inline void call_policy (char *verb, struct usb_device *dev) { } -#endif /* KMOD && HOTPLUG */ +#endif /* KMOD */ /* @@ -2156,6 +2232,7 @@ EXPORT_SYMBOL(usb_inc_dev_use); EXPORT_SYMBOL(usb_driver_claim_interface); EXPORT_SYMBOL(usb_interface_claimed); EXPORT_SYMBOL(usb_driver_release_interface); +EXPORT_SYMBOL(usb_match_id); EXPORT_SYMBOL(usb_root_hub_string); EXPORT_SYMBOL(usb_new_device); diff --git a/drivers/usb/usbkbd.c b/drivers/usb/usbkbd.c index bbf4b59ac..7fd1ebd7c 100644 --- a/drivers/usb/usbkbd.c +++ b/drivers/usb/usbkbd.c @@ -59,6 +59,7 @@ static unsigned char usb_kbd_keycode[256] = { struct usb_kbd { struct input_dev dev; + struct usb_device *usbdev; unsigned char new[8]; unsigned char old[8]; struct urb irq, led; @@ -116,6 +117,7 @@ int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, i return 0; kbd->leds = kbd->newleds; + kbd->led.dev = kbd->usbdev; if (usb_submit_urb(&kbd->led)) err("usb_submit_urb(leds) failed"); @@ -133,6 +135,7 @@ static void usb_kbd_led(struct urb *urb) return; kbd->leds = kbd->newleds; + kbd->led.dev = kbd->usbdev; if (usb_submit_urb(&kbd->led)) err("usb_submit_urb(leds) failed"); } @@ -144,6 +147,7 @@ static int usb_kbd_open(struct input_dev *dev) if (kbd->open++) return 0; + kbd->irq.dev = kbd->usbdev; if (usb_submit_urb(&kbd->irq)) return -EIO; @@ -158,20 +162,19 @@ static void usb_kbd_close(struct input_dev *dev) usb_unlink_urb(&kbd->irq); } -static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) +static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { + struct usb_interface *iface; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct usb_kbd *kbd; int i, pipe, maxp; char *buf; - if (dev->descriptor.bNumConfigurations != 1) return NULL; - interface = dev->config[0].interface[ifnum].altsetting + 0; + iface = &dev->actconfig->interface[ifnum]; + interface = &iface->altsetting[iface->act_altsetting]; - if (interface->bInterfaceClass != 3) return NULL; - if (interface->bInterfaceSubClass != 1) return NULL; - if (interface->bInterfaceProtocol != 1) return NULL; if (interface->bNumEndpoints != 1) return NULL; endpoint = interface->endpoint + 0; @@ -187,6 +190,8 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; memset(kbd, 0, sizeof(struct usb_kbd)); + kbd->usbdev = dev; + kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); @@ -251,10 +256,18 @@ static void usb_kbd_disconnect(struct usb_device *dev, void *ptr) kfree(kbd); } +static struct usb_device_id usb_kbd_id_table [] = { + { bInterfaceClass: 3, bInterfaceSubClass: 1, bInterfaceProtocol: 1}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); + static struct usb_driver usb_kbd_driver = { name: "keyboard", probe: usb_kbd_probe, - disconnect: usb_kbd_disconnect + disconnect: usb_kbd_disconnect, + id_table: usb_kbd_id_table, }; static int __init usb_kbd_init(void) diff --git a/drivers/usb/usbmouse.c b/drivers/usb/usbmouse.c index 1e873b285..b6473e11a 100644 --- a/drivers/usb/usbmouse.c +++ b/drivers/usb/usbmouse.c @@ -1,5 +1,5 @@ /* - * $Id: usbmouse.c,v 1.5 2000/05/29 09:01:52 vojtech Exp $ + * $Id: usbmouse.c,v 1.6 2000/08/14 21:05:26 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * @@ -41,9 +41,9 @@ MODULE_DESCRIPTION("USB HID Boot Protocol mouse driver"); struct usb_mouse { signed char data[8]; char name[128]; + struct usb_device *usbdev; struct input_dev dev; struct urb irq; - struct usb_device *my_usb_device; // for resubmitting my urb int open; }; @@ -73,7 +73,7 @@ static int usb_mouse_open(struct input_dev *dev) if (mouse->open++) return 0; - mouse->irq.dev = mouse->my_usb_device; + mouse->irq.dev = mouse->usbdev; if (usb_submit_urb(&mouse->irq)) return -EIO; @@ -88,20 +88,19 @@ static void usb_mouse_close(struct input_dev *dev) usb_unlink_urb(&mouse->irq); } -static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum) +static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) { + struct usb_interface *iface; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct usb_mouse *mouse; int pipe, maxp; char *buf; - if (dev->descriptor.bNumConfigurations != 1) return NULL; - interface = dev->config[0].interface[ifnum].altsetting + 0; + iface = &dev->actconfig->interface[ifnum]; + interface = &iface->altsetting[iface->act_altsetting]; - if (interface->bInterfaceClass != 3) return NULL; - if (interface->bInterfaceSubClass != 1) return NULL; - if (interface->bInterfaceProtocol != 2) return NULL; if (interface->bNumEndpoints != 1) return NULL; endpoint = interface->endpoint + 0; @@ -116,6 +115,8 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum) if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL; memset(mouse, 0, sizeof(struct usb_mouse)); + mouse->usbdev = dev; + mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); @@ -150,7 +151,6 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum) kfree(buf); - mouse->my_usb_device = dev; FILL_INT_URB(&mouse->irq, dev, pipe, mouse->data, maxp > 8 ? 8 : maxp, usb_mouse_irq, mouse, endpoint->bInterval); @@ -170,10 +170,18 @@ static void usb_mouse_disconnect(struct usb_device *dev, void *ptr) kfree(mouse); } +static struct usb_device_id usb_mouse_id_table [] = { + { bInterfaceClass: 3, bInterfaceSubClass: 1, bInterfaceProtocol: 2}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); + static struct usb_driver usb_mouse_driver = { name: "usb_mouse", probe: usb_mouse_probe, disconnect: usb_mouse_disconnect, + id_table: usb_mouse_id_table, }; static int __init usb_mouse_init(void) diff --git a/drivers/usb/uss720.c b/drivers/usb/uss720.c index da61b5214..f97f5f639 100644 --- a/drivers/usb/uss720.c +++ b/drivers/usb/uss720.c @@ -32,6 +32,7 @@ * 0.3 10.08.99 fixing merge errors * 0.4 13.08.99 Added Vendor/Product ID of Brad Hard's cable * 0.5 20.09.99 usb_control_msg wrapper used + * Nov01.00 usb_device_table support by Adam J. Richter * */ @@ -534,7 +535,8 @@ static struct parport_operations parport_uss720_ops = /* --------------------------------------------------------------------- */ -static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum) +static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum, + const struct usb_device_id *id) { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; @@ -542,11 +544,6 @@ static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum) struct parport *pp; int i; - if ((usbdev->descriptor.idVendor != 0x047e || usbdev->descriptor.idProduct != 0x1001) && - (usbdev->descriptor.idVendor != 0x0557 || usbdev->descriptor.idProduct != 0x2001) && - (usbdev->descriptor.idVendor != 0x0729 || usbdev->descriptor.idProduct != 0x1284)) - return NULL; - printk(KERN_DEBUG "uss720: probe: vendor id 0x%x, device id 0x%x\n", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); @@ -626,11 +623,22 @@ static void uss720_disconnect(struct usb_device *usbdev, void *ptr) MOD_DEC_USE_COUNT; } +/* table of cables that work through this driver */ +static struct usb_device_id uss720_table [] = { + { idVendor: 0x047e, idProduct: 0x1001}, + { idVendor: 0x0557, idProduct: 0x2001}, + { idVendor: 0x0729, idProduct: 0x1284}, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, uss720_table); + + static struct usb_driver uss720_driver = { - "uss720", - uss720_probe, - uss720_disconnect, - { NULL, NULL } + name: "uss720", + probe: uss720_probe, + disconnect: uss720_disconnect, + id_table: uss720_table, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/usb/wacom.c b/drivers/usb/wacom.c index 4dcc86436..af813ceab 100644 --- a/drivers/usb/wacom.c +++ b/drivers/usb/wacom.c @@ -1,10 +1,11 @@ /* - * $Id: wacom.c,v 1.9 2000/05/29 09:01:52 vojtech Exp $ + * $Id: wacom.c,v 1.11 2000/10/18 12:12:26 vojtech Exp $ * * Copyright (c) 2000 Vojtech Pavlik * Copyright (c) 2000 Andreas Bach Aaen * Copyright (c) 2000 Clifford Wolf * Copyright (c) 2000 Sam Mosel + * Copyright (c) 2000 James E. Blair * * USB Wacom Graphire and Wacom Intuos tablet support * @@ -21,23 +22,25 @@ * v1.8 (vp) - Submit URB only when operating, moved to CVS, * use input_report_key instead of report_btn and * other cleanups + * v1.11 (vp) - Add URB ->dev setting for new kernels + * v1.11 (jb) - Add support for the 4D Mouse & Lens */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to , or by paper mail: * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic @@ -70,17 +73,17 @@ MODULE_DESCRIPTION("USB Wacom Graphire and Wacom Intuos tablet driver"); * byte 5: Y high bits * byte 6: pen pressure low bits / mouse wheel * byte 7: pen presure high bits / mouse distance - * + * * There are also two single-byte feature reports (2 and 3). * * Wacom Intuos status packet: * * byte 0: report ID (2) - * byte 1: bit7 1 - sync bit + * byte 1: bit7 1 - sync bit * bit6 pointer in range * bit5 pointer type report * bit4 0 ? - * bit3 0 ? + * bit3 mouse packet type * bit2 pen button2 * bit1 pen button1 * bit0 0 ? @@ -88,12 +91,38 @@ MODULE_DESCRIPTION("USB Wacom Graphire and Wacom Intuos tablet driver"); * byte 3: X low bits * byte 4: Y high bits * byte 5: Y low bits + * + * Pen packet: + * * byte 6: bits 0-7: pressure (bits 2-9) * byte 7: bits 6-7: pressure (bits 0-1) * byte 7: bits 0-5: X tilt (bits 1-6) * byte 8: bit 7: X tilt (bit 0) * byte 8: bits 0-6: Y tilt (bits 0-6) * byte 9: bits 4-7: distance + * + * Mouse packet type 0: + * + * byte 6: bits 0-7: wheel (bits 2-9) + * byte 7: bits 6-7: wheel (bits 0-1) + * byte 7: bits 0-5: 0 + * byte 8: bits 6-7: 0 + * byte 8: bit 5: left extra button + * byte 8: bit 4: right extra button + * byte 8: bit 3: wheel (sign) + * byte 8: bit 2: right button + * byte 8: bit 1: middle button + * byte 8: bit 0: left button + * byte 9: bits 4-7: distance + * + * Mouse packet type 1: + * + * byte 6: bits 0-7: rotation (bits 2-9) + * byte 7: bits 6-7: rotation (bits 0-1) + * byte 7: bit 5: rotation (sign) + * byte 7: bits 0-4: 0 + * byte 8: bits 0-7: 0 + * byte 9: bits 4-7: distance */ #define USB_VENDOR_ID_WACOM 0x056a @@ -192,7 +221,7 @@ static void wacom_intuos_irq(struct urb *urb) case 0x0fa: wacom->tool = BTN_TOOL_RUBBER; break; /* Eraser */ case 0x112: wacom->tool = BTN_TOOL_AIRBRUSH; break; /* Airbrush */ default: wacom->tool = BTN_TOOL_PEN; break; /* Unknown tool */ - } + } input_report_key(dev, wacom->tool, 1); return; } @@ -205,31 +234,63 @@ static void wacom_intuos_irq(struct urb *urb) input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]); input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]); - input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(dev, ABS_DISTANCE, data[9] >> 4); - input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - input_report_key(dev, BTN_STYLUS, data[1] & 2); - input_report_key(dev, BTN_STYLUS2, data[1] & 4); - input_report_key(dev, BTN_TOUCH, t > 10); + switch (wacom->tool) { + + case BTN_TOOL_PENCIL: + case BTN_TOOL_PEN: + case BTN_TOOL_BRUSH: + case BTN_TOOL_RUBBER: + case BTN_TOOL_AIRBRUSH: + + input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); + input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); + input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); + input_report_key(dev, BTN_STYLUS, data[1] & 2); + input_report_key(dev, BTN_STYLUS2, data[1] & 4); + input_report_key(dev, BTN_TOUCH, t > 10); + break; + + case BTN_TOOL_MOUSE: + case BTN_TOOL_LENS: + + if (data[1] & 0x02) { /* Rotation packet */ + input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? + ((__u32)data[6] << 2) | ((data[7] >> 6) & 3): + (-(((__u32)data[6] << 2) | ((data[7] >> 6) & 3))) - 1); + break; + } + + input_report_key(dev, BTN_LEFT, data[8] & 0x01); + input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); + input_report_key(dev, BTN_RIGHT, data[8] & 0x04); + input_report_key(dev, BTN_SIDE, data[8] & 0x20); + input_report_key(dev, BTN_EXTRA, data[8] & 0x10); + input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? + ((__u32)data[6] << 2) | ((data[7] >> 6) & 3) : + -((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); + break; + } } #define WACOM_INTUOS_TOOLS (BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS)) +#define WACOM_INTUOS_BUTTONS (BIT(BTN_SIDE) | BIT(BTN_EXTRA)) +#define WACOM_INTUOS_ABS (BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE)) struct wacom_features wacom_features[] = { { "Wacom Graphire", 0x10, 8, 10206, 7422, 511, 32, wacom_graphire_irq, - BIT(EV_REL), 0, BIT(REL_WHEEL), BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE), 0 }, + BIT(EV_REL), 0, 0, 0 }, { "Wacom Intuos 4x5", 0x20, 10, 12700, 10360, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 6x8", 0x21, 10, 20320, 15040, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 9x12", 0x22, 10, 30480, 23060, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 12x12", 0x23, 10, 30480, 30480, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { "Wacom Intuos 12x18", 0x24, 10, 47720, 30480, 1023, 15, wacom_intuos_irq, - 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, + 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS }, { NULL , 0 } }; @@ -275,7 +336,7 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum) wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | wacom->features->evbit; wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE) | wacom->features->absbit; wacom->dev.relbit[0] |= wacom->features->relbit; - wacom->dev.keybit[LONG(BTN_LEFT)] |= wacom->features->btnbit; + wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | wacom->features->btnbit; wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2) | wacom->features->digibit; @@ -286,6 +347,14 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum) wacom->dev.absmax[ABS_TILT_X] = 127; wacom->dev.absmax[ABS_TILT_Y] = 127; + wacom->dev.absmin[ABS_RZ] = -900; + wacom->dev.absmax[ABS_RZ] = 899; + wacom->dev.absmin[ABS_THROTTLE] = -1023; + wacom->dev.absmax[ABS_THROTTLE] = 1023; + + wacom->dev.absfuzz[ABS_X] = 4; + wacom->dev.absfuzz[ABS_Y] = 4; + wacom->dev.private = wacom; wacom->dev.open = wacom_open; wacom->dev.close = wacom_close; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index c68d1b5ff..caad14264 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -1,5 +1,5 @@ /* - * linux/drivers/video/rivafb.c - nVidia RIVA 128/TNT/TNT2 fb driver + * linux/drivers/video/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver * * Maintained by Ani Joshi * @@ -17,12 +17,12 @@ * KGI code provided the basis for state storage, init, and mode switching. * * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ /* version number of this driver */ -#define RIVAFB_VERSION "0.7.2" +#define RIVAFB_VERSION "0.7.3" #include #include @@ -311,7 +311,7 @@ static const struct riva_regs reg_template = { /** * riva_set_dispsw - * @rivainfo: pointer to internal driver struct for a given Riva card + * @rinfo: pointer to internal driver struct for a given Riva card * * DESCRIPTION: * Sets up console Low level operations depending on the current? color depth @@ -514,14 +514,14 @@ static int __devinit rivafb_init_one (struct pci_dev *pd, rinfo->ctrl_base = ioremap (rinfo->ctrl_base_phys, rinfo->base0_region_size); if (!rinfo->ctrl_base) { - printk (KERN_ERR PFX "cannot ioremap ctrl base\n"); + printk (KERN_ERR PFX "cannot ioremap MMIO base\n"); goto err_out_free_base1; } rinfo->fb_base = ioremap (rinfo->fb_base_phys, rinfo->base1_region_size); if (!rinfo->fb_base) { - printk (KERN_ERR PFX "cannot ioremap ctrl base\n"); + printk (KERN_ERR PFX "cannot ioremap FB base\n"); goto err_out_iounmap_ctrl; } @@ -539,7 +539,7 @@ static int __devinit rivafb_init_one (struct pci_dev *pd, switch (rinfo->riva.Architecture) { case 3: rinfo->riva.PRAMIN = - (unsigned *) (rinfo->ctrl_base + 0x00C00000); + (unsigned *) (rinfo->fb_base + 0x00C00000); break; case 4: case 5: @@ -584,7 +584,8 @@ static int __devinit rivafb_init_one (struct pci_dev *pd, pci_set_drvdata (pd, rinfo); - printk ("PCI Riva NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n", + printk (KERN_INFO PFX + "PCI Riva NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n", rinfo->riva.Architecture, RIVAFB_VERSION, rinfo->drvr_name, @@ -859,7 +860,7 @@ static int rivafb_set_var (struct fb_var_screeninfo *var, int con, v.blue.offset = 0; #endif v.red.length = 5; - v.green.length = 6; + v.green.length = 5; v.blue.length = 5; break; #endif @@ -1046,7 +1047,7 @@ static int rivafb_set_cmap (struct fb_cmap *cmap, int kspc, int con, /** * rivafb_pan_display * @var: standard kernel fb changeable data - * @par: riva-specific hardware info about current video mode + * @con: * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: @@ -1292,7 +1293,7 @@ static int riva_getcolreg (unsigned regno, unsigned *red, unsigned *green, { struct rivafb_info *rivainfo = (struct rivafb_info *) info; - if (regno > 255) + if (regno >= riva_get_cmap_len(&rivainfo->currcon_display->var)) return 1; *red = rivainfo->palette[regno].red; @@ -1341,10 +1342,15 @@ static int riva_setcolreg (unsigned regno, unsigned red, unsigned green, assert (rivainfo != NULL); assert (rivainfo->currcon_display != NULL); - if (regno > 255) + p = rivainfo->currcon_display; + + if (regno >= riva_get_cmap_len(&p->var)) return -EINVAL; - p = rivainfo->currcon_display; + rivainfo->palette[regno].red = red; + rivainfo->palette[regno].green = green; + rivainfo->palette[regno].blue = blue; + if (p->var.grayscale) { /* gray = 0.30*R + 0.59*G + 0.11*B */ red = green = blue = @@ -1361,27 +1367,14 @@ static int riva_setcolreg (unsigned regno, unsigned red, unsigned green, break; } -#ifdef FBCON_HAS_CFB8 switch (p->var.bits_per_pixel) { +#ifdef FBCON_HAS_CFB8 case 8: /* "transparent" stuff is completely ignored. */ riva_wclut (regno, red >> shift, green >> shift, blue >> shift); break; - default: - /* do nothing */ - break; - } #endif /* FBCON_HAS_CFB8 */ - rivainfo->palette[regno].red = red; - rivainfo->palette[regno].green = green; - rivainfo->palette[regno].blue = blue; - - if (regno >= 16) - return 0; - - switch (p->var.bits_per_pixel) { - #ifdef FBCON_HAS_CFB16 case 16: assert (regno < 16); @@ -1392,8 +1385,8 @@ static int riva_setcolreg (unsigned regno, unsigned red, unsigned green, ((green & 0xf800) << 2) | ((blue & 0xf800) >> 3); #else rivainfo->con_cmap.cfb16[regno] = - ((red & 0xf800) >> 0) | - ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11); + ((red & 0xf800) >> 1) | + ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); #endif break; #endif /* FBCON_HAS_CFB16 */ diff --git a/drivers/video/vgacon.c b/drivers/video/vgacon.c index 8a7e0a0ff..468f02e66 100644 --- a/drivers/video/vgacon.c +++ b/drivers/video/vgacon.c @@ -46,11 +46,13 @@ #include #include #include +#include #include #include #include +static spinlock_t vga_lock = SPIN_LOCK_UNLOCKED; #define BLANK 0x0020 @@ -152,8 +154,7 @@ static inline void write_vga(unsigned char reg, unsigned int val) * ddprintk might set the console position from interrupt * handlers, thus the write has to be IRQ-atomic. */ - save_flags(flags); - cli(); + spin_lock_irqsave(&vga_lock, flags); #ifndef SLOW_VGA v1 = reg + (val & 0xff00); @@ -166,7 +167,7 @@ static inline void write_vga(unsigned char reg, unsigned int val) outb_p(reg+1, vga_video_port_reg); outb_p(val & 0xff, vga_video_port_val); #endif - restore_flags(flags); + spin_unlock_irqrestore(&vga_lock, flags); } static const char __init *vgacon_startup(void) @@ -415,7 +416,7 @@ static void vgacon_set_cursor_size(int xpos, int from, int to) if ((from == lastfrom) && (to == lastto)) return; lastfrom = from; lastto = to; - save_flags(flags); cli(); + spin_lock_irqsave(&vga_lock, flags); outb_p(0x0a, vga_video_port_reg); /* Cursor start */ curs = inb_p(vga_video_port_val); outb_p(0x0b, vga_video_port_reg); /* Cursor end */ @@ -428,7 +429,7 @@ static void vgacon_set_cursor_size(int xpos, int from, int to) outb_p(curs, vga_video_port_val); outb_p(0x0b, vga_video_port_reg); /* Cursor end */ outb_p(cure, vga_video_port_val); - restore_flags(flags); + spin_unlock_irqrestore(&vga_lock, flags); } static void vgacon_cursor(struct vc_data *c, int mode) @@ -533,11 +534,11 @@ static void vga_vesa_blank(int mode) { /* save original values of VGA controller registers */ if(!vga_vesa_blanked) { - cli(); + spin_lock_irq(&vga_lock); vga_state.SeqCtrlIndex = inb_p(seq_port_reg); vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg); vga_state.CrtMiscIO = inb_p(video_misc_rd); - sti(); + spin_unlock_irq(&vga_lock); outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */ vga_state.HorizontalTotal = inb_p(vga_video_port_val); @@ -561,7 +562,7 @@ static void vga_vesa_blank(int mode) /* assure that video is enabled */ /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */ - cli(); + spin_lock_irq(&vga_lock); outb_p(0x01,seq_port_reg); outb_p(vga_state.ClockingMode | 0x20,seq_port_val); @@ -598,13 +599,13 @@ static void vga_vesa_blank(int mode) /* restore both index registers */ outb_p(vga_state.SeqCtrlIndex,seq_port_reg); outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg); - sti(); + spin_unlock_irq(&vga_lock); } static void vga_vesa_unblank(void) { /* restore original values of VGA controller registers */ - cli(); + spin_lock_irq(&vga_lock); outb_p(vga_state.CrtMiscIO,video_misc_wr); outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */ @@ -629,7 +630,7 @@ static void vga_vesa_unblank(void) /* restore index/control registers */ outb_p(vga_state.SeqCtrlIndex,seq_port_reg); outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg); - sti(); + spin_unlock_irq(&vga_lock); } static void vga_pal_blank(void) @@ -750,7 +751,7 @@ vgacon_do_font_op(char *arg, int set, int ch512) charmap += 4*cmapsz; #endif - cli(); + spin_lock_irq(&vga_lock); outb_p( 0x00, seq_port_reg ); /* First, the sequencer */ outb_p( 0x01, seq_port_val ); /* Synchronous reset */ outb_p( 0x02, seq_port_reg ); @@ -766,7 +767,7 @@ vgacon_do_font_op(char *arg, int set, int ch512) outb_p( 0x00, gr_port_val ); /* disable odd-even addressing */ outb_p( 0x06, gr_port_reg ); outb_p( 0x00, gr_port_val ); /* map start at A000:0000 */ - sti(); + spin_unlock_irq(&vga_lock); if (arg) { if (set) @@ -793,7 +794,7 @@ vgacon_do_font_op(char *arg, int set, int ch512) } } - cli(); + spin_lock_irq(&vga_lock); outb_p( 0x00, seq_port_reg ); /* First, the sequencer */ outb_p( 0x01, seq_port_val ); /* Synchronous reset */ outb_p( 0x02, seq_port_reg ); @@ -833,8 +834,7 @@ vgacon_do_font_op(char *arg, int set, int ch512) inb_p( video_port_status ); outb_p ( 0x20, attrib_port ); } - sti(); - + spin_unlock_irq(&vga_lock); return 0; } @@ -865,12 +865,12 @@ vgacon_adjust_height(unsigned fontheight) registers; they are write-only on EGA, but it appears that they are all don't care bits on EGA, so I guess it doesn't matter. */ - cli(); + spin_lock_irq(&vga_lock); outb_p( 0x07, vga_video_port_reg ); /* CRTC overflow register */ ovr = inb_p(vga_video_port_val); outb_p( 0x09, vga_video_port_reg ); /* Font size register */ fsr = inb_p(vga_video_port_val); - sti(); + spin_lock_irq(&vga_lock); vde = maxscan & 0xff; /* Vertical display end reg */ ovr = (ovr & 0xbd) + /* Overflow register */ @@ -878,14 +878,14 @@ vgacon_adjust_height(unsigned fontheight) ((maxscan & 0x200) >> 3); fsr = (fsr & 0xe0) + (fontheight-1); /* Font size register */ - cli(); + spin_lock_irq(&vga_lock); outb_p( 0x07, vga_video_port_reg ); /* CRTC overflow register */ outb_p( ovr, vga_video_port_val ); outb_p( 0x09, vga_video_port_reg ); /* Font size */ outb_p( fsr, vga_video_port_val ); outb_p( 0x12, vga_video_port_reg ); /* Vertical display limit */ outb_p( vde, vga_video_port_val ); - sti(); + spin_unlock_irq(&vga_lock); vc_resize_all(rows, 0); /* Adjust console size */ return 0; diff --git a/fs/buffer.c b/fs/buffer.c index 5bbef41fc..9f9fbbfbd 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -707,11 +707,8 @@ void set_blocksize(kdev_t dev, int size) */ static void refill_freelist(int size) { - if (!grow_buffers(size)) { + if (!grow_buffers(size)) wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ - current->policy |= SCHED_YIELD; - schedule(); - } } void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private) diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index 041dd0785..9261eb453 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -37,7 +37,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; struct page* page; - unsigned long pg_addr; + char *pg_addr; unsigned int already_read; unsigned int count; int bufsize; @@ -71,7 +71,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, if (ncp_read_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, pos, to_read, - (char *) (pg_addr + already_read), + pg_addr + already_read, &read_this_time) != 0) { read_this_time = 0; } @@ -87,8 +87,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, } if (already_read < PAGE_SIZE) - memset((char*)(pg_addr + already_read), 0, - PAGE_SIZE - already_read); + memset(pg_addr + already_read, 0, PAGE_SIZE - already_read); flush_dcache_page(page); kunmap(page); return page; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 4219c505f..83a34f258 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -158,7 +158,6 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) { struct buffer_head *bh = NULL; struct page *page; - unsigned long kaddr = 0; int block; /* from now on we have normal address_space methods */ @@ -183,10 +182,10 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) PAGE_BUG(page); if (!Page_Uptodate(page)) { - kaddr = kmap(page); - memset((char *)kaddr + UDF_I_LENALLOC(inode), 0x00, + char *kaddr = kmap(page); + memset(kaddr + UDF_I_LENALLOC(inode), 0x00, PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode)); - memcpy((char *)kaddr, bh->b_data + udf_file_entry_alloc_offset(inode), + memcpy(kaddr, bh->b_data + udf_file_entry_alloc_offset(inode), UDF_I_LENALLOC(inode)); flush_dcache_page(page); SetPageUptodate(page); diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 76ac26cae..dfb9c0591 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -220,7 +220,11 @@ static inline void clear_in_cr4 (unsigned long mask) /* * Bus types (default is ISA, but people can check others with these..) */ +#ifdef CONFIG_EISA extern int EISA_bus; +#else +#define EISA_bus (0) +#endif extern int MCA_bus; /* from system description table in BIOS. Mostly for MCA use, but diff --git a/include/asm-ppc/8xx_immap.h b/include/asm-ppc/8xx_immap.h index 0223fe275..d470233e3 100644 --- a/include/asm-ppc/8xx_immap.h +++ b/include/asm-ppc/8xx_immap.h @@ -10,6 +10,7 @@ * a combination that I found difficult to separate into logical * functional files.....but anyone else is welcome to try. -- Dan */ +#ifdef __KERNEL__ #ifndef __IMMAP_8XX__ #define __IMMAP_8XX__ @@ -453,3 +454,4 @@ typedef struct immap { } immap_t; #endif /* __IMMAP_8XX__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/amigahw.h b/include/asm-ppc/amigahw.h index 491547376..8c98945e7 100644 --- a/include/asm-ppc/amigahw.h +++ b/include/asm-ppc/amigahw.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef __ASMPPC_AMIGAHW_H #define __ASMPPC_AMIGAHW_H @@ -13,3 +14,4 @@ #endif /* __ASMPPC_AMIGAHW_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/amigaints.h b/include/asm-ppc/amigaints.h index c7a50189e..a5e1c4850 100644 --- a/include/asm-ppc/amigaints.h +++ b/include/asm-ppc/amigaints.h @@ -10,6 +10,7 @@ ** Created 10/2/92 by Greg Harp */ +#ifdef __KERNEL__ #ifndef _ASMm68k_AMIGAINTS_H_ #define _ASMm68k_AMIGAINTS_H_ @@ -133,3 +134,4 @@ extern unsigned char cia_set_irq(unsigned int irq, int set); extern unsigned char cia_able_irq(unsigned int irq, int enable); #endif /* asm-m68k/amigaints.h */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/amigappc.h b/include/asm-ppc/amigappc.h index 96e5e8f09..8750af77a 100644 --- a/include/asm-ppc/amigappc.h +++ b/include/asm-ppc/amigappc.h @@ -11,6 +11,7 @@ ** Created: 7/22/97 by Jesper Skov */ +#ifdef __KERNEL__ #ifndef _M68K_AMIGAPPC_H #define _M68K_AMIGAPPC_H @@ -81,3 +82,4 @@ do { \ #define INTLVL_MASK (0x7f) #endif /* _M68k_AMIGAPPC_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/backlight.h b/include/asm-ppc/backlight.h index 79756eca3..2f070ef6f 100644 --- a/include/asm-ppc/backlight.h +++ b/include/asm-ppc/backlight.h @@ -4,6 +4,7 @@ * For now, implementation resides in arch/ppc/kernel/pmac_support.c * */ +#ifdef __KERNEL__ #ifndef __ASM_PPC_BACKLIGHT_H #define __ASM_PPC_BACKLIGHT_H @@ -26,3 +27,4 @@ extern int set_backlight_level(int level); extern int get_backlight_level(void); #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h index b82a9fc21..c31e5c5eb 100644 --- a/include/asm-ppc/bitops.h +++ b/include/asm-ppc/bitops.h @@ -3,6 +3,7 @@ * bitops.h: Bit string operations on the ppc */ +#ifdef __KERNEL__ #ifndef _PPC_BITOPS_H #define _PPC_BITOPS_H @@ -351,3 +352,4 @@ found_middle: #endif /* __KERNEL__ */ #endif /* _PPC_BITOPS_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/board.h b/include/asm-ppc/board.h index 1476a232a..d1d3ba68a 100644 --- a/include/asm-ppc/board.h +++ b/include/asm-ppc/board.h @@ -10,6 +10,7 @@ * */ +#ifdef __KERNEL__ #ifndef __BOARD_H__ #define __BOARD_H__ @@ -40,3 +41,4 @@ extern unsigned char __res[]; #endif #endif /* __BOARD_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/bootinfo.h b/include/asm-ppc/bootinfo.h index af614d798..84e7a7c8f 100644 --- a/include/asm-ppc/bootinfo.h +++ b/include/asm-ppc/bootinfo.h @@ -6,6 +6,7 @@ */ +#ifdef __KERNEL__ #ifndef _PPC_BOOTINFO_H #define _PPC_BOOTINFO_H @@ -33,3 +34,4 @@ struct bi_record { #endif /* _PPC_BOOTINFO_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h index 02454f6cf..2da8cfd6c 100644 --- a/include/asm-ppc/byteorder.h +++ b/include/asm-ppc/byteorder.h @@ -7,6 +7,7 @@ #include +#ifdef __KERNEL__ #ifdef __GNUC__ extern __inline__ unsigned ld_le16(const volatile unsigned short *addr) @@ -72,11 +73,13 @@ static __inline__ __const__ __u32 ___arch__swab32(__u32 value) #define __arch__swab16s(addr) st_le16(addr,*addr) #define __arch__swab32s(addr) st_le32(addr,*addr) -#endif /* __GNUC__ */ - -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#ifndef __STRICT_ANSI__ #define __BYTEORDER_HAS_U64__ #endif + +#endif /* __GNUC__ */ +#endif /* __KERNEL__ */ + #include #endif /* _PPC_BYTEORDER_H */ diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h index c45fd8409..e4bcdde00 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-ppc/cache.h @@ -1,6 +1,7 @@ /* * include/asm-ppc/cache.h */ +#ifdef __KERNEL__ #ifndef __ARCH_PPC_CACHE_H #define __ARCH_PPC_CACHE_H @@ -83,3 +84,4 @@ extern void flush_dcache_range(unsigned long start, unsigned long stop); #endif /* CONFIG_8xx */ #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h index e635ff599..48c8ca7b5 100644 --- a/include/asm-ppc/checksum.h +++ b/include/asm-ppc/checksum.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_CHECKSUM_H #define _PPC_CHECKSUM_H @@ -111,3 +112,4 @@ extern unsigned short csum_tcpudp_magic(unsigned long saddr, unsigned int sum); #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/cpm_8260.h b/include/asm-ppc/cpm_8260.h index 427ec1884..b612cf02f 100644 --- a/include/asm-ppc/cpm_8260.h +++ b/include/asm-ppc/cpm_8260.h @@ -8,6 +8,7 @@ * All CPM control and status is available through the MPC8260 internal * memory map. See immap.h for details. */ +#ifdef __KERNEL__ #ifndef __CPM_82XX__ #define __CPM_82XX__ @@ -697,3 +698,4 @@ typedef struct iic { #define BD_IIC_START ((ushort)0x0400) #endif /* __CPM_82XX__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/current.h b/include/asm-ppc/current.h index 49415ce9f..8d41501ba 100644 --- a/include/asm-ppc/current.h +++ b/include/asm-ppc/current.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_CURRENT_H #define _PPC_CURRENT_H @@ -7,3 +8,4 @@ register struct task_struct *current asm ("r2"); #endif /* !(_PPC_CURRENT_H) */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/dbdma.h b/include/asm-ppc/dbdma.h index 38cd15803..0590cb454 100644 --- a/include/asm-ppc/dbdma.h +++ b/include/asm-ppc/dbdma.h @@ -5,6 +5,7 @@ * Copyright (C) 1996 Paul Mackerras. */ +#ifdef __KERNEL__ #ifndef _ASM_DBDMA_H_ #define _ASM_DBDMA_H_ /* @@ -90,3 +91,4 @@ struct dbdma_cmd { #define DBDMA_ALIGN(x) (((unsigned)(x) + sizeof(struct dbdma_cmd) - 1) \ & -sizeof(struct dbdma_cmd)) #endif /* _ASM_DBDMA_H_ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/delay.h b/include/asm-ppc/delay.h index 239e0d3ac..2116a2f2c 100644 --- a/include/asm-ppc/delay.h +++ b/include/asm-ppc/delay.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_DELAY_H #define _PPC_DELAY_H @@ -31,3 +32,4 @@ extern __inline__ void udelay(unsigned long usecs) } #endif /* defined(_PPC_DELAY_H) */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h index 5cac2be5e..735d91d1f 100644 --- a/include/asm-ppc/dma.h +++ b/include/asm-ppc/dma.h @@ -6,6 +6,8 @@ * Changes for ppc sound by Christoph Nadig */ +#ifdef __KERNEL__ + #include #include #include @@ -410,3 +412,4 @@ extern int isa_dma_bridge_buggy; #define isa_dma_bridge_buggy (0) #endif #endif /* _ASM_DMA_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h index 75b515e18..6a0e2e874 100644 --- a/include/asm-ppc/elf.h +++ b/include/asm-ppc/elf.h @@ -11,38 +11,41 @@ #define ELF_NVRREG 33 /* includes vscr */ /* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ((x)->e_machine == EM_PPC) - -/* * These are used to set parameters in the core dumps. */ #define ELF_ARCH EM_PPC #define ELF_CLASS ELFCLASS32 #define ELF_DATA ELFDATA2MSB -#define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE 4096 - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE (0x08000000) - +/* General registers */ typedef unsigned long elf_greg_t; typedef elf_greg_t elf_gregset_t[ELF_NGREG]; +/* Floating point registers */ typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; -#ifdef __KERNEL__ /* Altivec registers */ -typedef vector128 elf_vrreg_t; +typedef __vector128 elf_vrreg_t; typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; -#endif /* __KERNEL__ */ + +#ifdef __KERNEL__ + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ + +#define elf_check_arch(x) ((x)->e_machine == EM_PPC) + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE (0x08000000) + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 #define ELF_CORE_COPY_REGS(gregs, regs) \ memcpy(gregs, regs, \ @@ -65,8 +68,7 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; #define ELF_PLATFORM (NULL) -#ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) -#endif +#endif /* __KERNEL__ */ #endif diff --git a/include/asm-ppc/feature.h b/include/asm-ppc/feature.h index ca4ca4692..7a33ea8d3 100644 --- a/include/asm-ppc/feature.h +++ b/include/asm-ppc/feature.h @@ -12,6 +12,7 @@ * * */ +#ifdef __KERNEL__ #ifndef __ASM_PPC_FEATURE_H #define __ASM_PPC_FEATURE_H @@ -93,3 +94,4 @@ extern void feature_prepare_for_sleep(void); extern void feature_wake_up(void); #endif /* __ASM_PPC_FEATURE_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/floppy.h b/include/asm-ppc/floppy.h index f12eae65f..f04178736 100644 --- a/include/asm-ppc/floppy.h +++ b/include/asm-ppc/floppy.h @@ -7,6 +7,7 @@ * * Copyright (C) 1995 */ +#ifdef __KERNEL__ #ifndef __ASM_PPC_FLOPPY_H #define __ASM_PPC_FLOPPY_H @@ -54,3 +55,4 @@ static int FDC2 = -1; #define CROSS_64KB(a,s) (0) #endif /* __ASM_PPC_FLOPPY_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/gemini.h b/include/asm-ppc/gemini.h index 7e681e043..ebd01c9b6 100644 --- a/include/asm-ppc/gemini.h +++ b/include/asm-ppc/gemini.h @@ -6,6 +6,7 @@ * "Gemini" boards. * */ +#ifdef __KERNEL__ #ifndef __PPC_GEMINI_H #define __PPC_GEMINI_H @@ -164,3 +165,4 @@ extern void gemini_prom_init(void); extern void gemini_init_l2(void); #endif /* __ASSEMBLY__ */ #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/gemini_serial.h b/include/asm-ppc/gemini_serial.h index 089a0ce60..e4e08467e 100644 --- a/include/asm-ppc/gemini_serial.h +++ b/include/asm-ppc/gemini_serial.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef __ASMPPC_GEMINI_SERIAL_H #define __ASMPPC_GEMINI_SERIAL_H @@ -37,3 +38,4 @@ PU32_SERIAL_PORT_DEFNS #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h index f7c12df77..8a270c8c1 100644 --- a/include/asm-ppc/hardirq.h +++ b/include/asm-ppc/hardirq.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef __ASM_HARDIRQ_H #define __ASM_HARDIRQ_H @@ -99,3 +100,4 @@ extern void synchronize_irq(void); #endif /* CONFIG_SMP */ #endif /* __ASM_HARDIRQ_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h index 28a47906c..7d4790171 100644 --- a/include/asm-ppc/hw_irq.h +++ b/include/asm-ppc/hw_irq.h @@ -3,6 +3,7 @@ * * Copyright (C) 1999 Cort Dougan */ +#ifdef __KERNEL__ #ifndef _PPC_HW_IRQ_H #define _PPC_HW_IRQ_H @@ -40,3 +41,4 @@ extern atomic_t ppc_n_lost_interrupts; #define mask_and_ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);}) #endif /* _PPC_HW_IRQ_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h index 8b50f862b..179bdec67 100644 --- a/include/asm-ppc/ide.h +++ b/include/asm-ppc/ide.h @@ -10,6 +10,8 @@ #ifndef __ASMPPC_IDE_H #define __ASMPPC_IDE_H +#ifdef __KERNEL__ + #include #include @@ -19,8 +21,6 @@ #include -#ifdef __KERNEL__ - #include #include #include diff --git a/include/asm-ppc/immap_8260.h b/include/asm-ppc/immap_8260.h index 298276363..32eb50b8c 100644 --- a/include/asm-ppc/immap_8260.h +++ b/include/asm-ppc/immap_8260.h @@ -7,6 +7,7 @@ * this will be, as I don't have any knowledge of the subsequent * parts at this time. I copied this from the 8xx_immap.h. */ +#ifdef __KERNEL__ #ifndef __IMMAP_82XX__ #define __IMMAP_82XX__ @@ -433,3 +434,4 @@ typedef struct immap { immap_t *immr; #endif /* __IMMAP_82XX__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/init.h b/include/asm-ppc/init.h index 00a1c79cc..d4976d863 100644 --- a/include/asm-ppc/init.h +++ b/include/asm-ppc/init.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_INIT_H #define _PPC_INIT_H @@ -35,3 +36,4 @@ __argopenfirmware #endif /* _PPC_INIT_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index 45b2531a3..03f9db09a 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_IO_H #define _PPC_IO_H @@ -92,7 +93,7 @@ extern __inline__ unsigned int name(unsigned int port) \ "3: li %0,-1\n" \ " b 2b\n" \ ".previous\n" \ - ".section __ex_table,\"ax\"\n" \ + ".section __ex_table,\"a\"\n" \ " .align 2\n" \ " .long 1b,3b\n" \ ".previous" \ @@ -108,7 +109,7 @@ extern __inline__ void name(unsigned int val, unsigned int port) \ op " %0,0,%1\n" \ "1: sync\n" \ "2:\n" \ - ".section __ex_table,\"ax\"\n" \ + ".section __ex_table,\"a\"\n" \ " .align 2\n" \ " .long 1b,2b\n" \ ".previous" \ @@ -347,7 +348,6 @@ extern inline void out_be32(volatile unsigned *addr, int val) __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val)); } -#ifdef __KERNEL__ static inline int check_signature(unsigned long io_addr, const unsigned char *signature, int length) { @@ -370,6 +370,5 @@ out: #define dma_cache_wback(_start,_size) do { } while (0) #define dma_cache_wback_inv(_start,_size) do { } while (0) -#endif /* __KERNEL__ */ - #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ipcbuf.h b/include/asm-ppc/ipcbuf.h dissimilarity index 64% index 98c75e646..fab6752c7 100644 --- a/include/asm-ppc/ipcbuf.h +++ b/include/asm-ppc/ipcbuf.h @@ -1,11 +1,29 @@ -#ifndef __PPC_IPCBUF_H__ -#define __PPC_IPCBUF_H__ - -/* - * The ipc64_perm structure for the PPC is identical to kern_ipc_perm - * as we have always had 32-bit UIDs and GIDs in the kernel. - */ - -#define ipc64_perm kern_ipc_perm - -#endif /* __PPC_IPCBUF_H__ */ +#ifndef __PPC_IPCBUF_H__ +#define __PPC_IPCBUF_H__ + +/* + * The ipc64_perm structure for PPC architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 1 32-bit value to fill up for 8-byte alignment + * - 2 miscellaneous 64-bit values (so that this structure matches + * PPC64 ipc64_perm) + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid_t uid; + __kernel_gid_t gid; + __kernel_uid_t cuid; + __kernel_gid_t cgid; + __kernel_mode_t mode; + unsigned long seq; + unsigned int __pad2; + unsigned long long __unused1; + unsigned long long __unused2; +}; + +#endif /* __PPC_IPCBUF_H__ */ diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index 86647a0e6..c3ae15763 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -1,8 +1,8 @@ -#include - +#ifdef __KERNEL__ #ifndef _ASM_IRQ_H #define _ASM_IRQ_H +#include #include /* ppc_md */ extern void disable_irq(unsigned int); @@ -217,3 +217,4 @@ static __inline__ int irq_cannonicalize(int irq) extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; #endif /* _ASM_IRQ_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/kgdb.h b/include/asm-ppc/kgdb.h index 51c868b36..7337be058 100644 --- a/include/asm-ppc/kgdb.h +++ b/include/asm-ppc/kgdb.h @@ -6,6 +6,7 @@ * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ +#ifdef __KERNEL__ #ifndef _PPC_KGDB_H #define _PPC_KGDB_H @@ -46,3 +47,4 @@ extern char getDebugChar(void); /* read and return a single char */ #endif /* !(__ASSEMBLY__) */ #endif /* !(_PPC_KGDB_H) */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h index d92d81b20..a1483ed3b 100644 --- a/include/asm-ppc/kmap_types.h +++ b/include/asm-ppc/kmap_types.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H @@ -8,3 +9,4 @@ enum km_type { }; #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/linux_logo.h b/include/asm-ppc/linux_logo.h index 33ad40f64..c35e6db5b 100644 --- a/include/asm-ppc/linux_logo.h +++ b/include/asm-ppc/linux_logo.h @@ -10,6 +10,7 @@ * values have to start from 0x20 * (i.e. linux_logo_{red,green,blue}[0] is color 0x20) */ +#ifdef __KERNEL__ #include @@ -39,3 +40,4 @@ extern unsigned char linux_logo16_blue[]; extern unsigned char linux_logo16[]; #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 709827f29..67111965f 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -1,4 +1,4 @@ - +#ifdef __KERNEL__ #ifndef _PPC_MACHDEP_H #define _PPC_MACHDEP_H @@ -101,3 +101,4 @@ typedef enum sys_ctrler_kind { extern sys_ctrler_t sys_ctrler; #endif /* _PPC_MACHDEP_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mbx.h b/include/asm-ppc/mbx.h index 6c84b8955..a3e8f9b32 100644 --- a/include/asm-ppc/mbx.h +++ b/include/asm-ppc/mbx.h @@ -1,4 +1,3 @@ - /* * A collection of structures, addresses, and values associated with * the Motorola MBX boards. This was originally created for the @@ -8,6 +7,7 @@ * * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) */ +#ifdef __KERNEL__ #ifndef __MACH_MBX_DEFS #define __MACH_MBX_DEFS @@ -87,3 +87,4 @@ typedef struct bd_info { */ #define _MACH_8xx (_MACH_mbx) #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mc146818rtc.h b/include/asm-ppc/mc146818rtc.h index f7a479fff..227018b2f 100644 --- a/include/asm-ppc/mc146818rtc.h +++ b/include/asm-ppc/mc146818rtc.h @@ -1,6 +1,7 @@ /* * Machine dependent access functions for RTC registers. */ +#ifdef __KERNEL__ #ifndef __ASM_PPC_MC146818RTC_H #define __ASM_PPC_MC146818RTC_H @@ -27,3 +28,4 @@ outb_p((val),RTC_PORT(1)); \ #define RTC_IRQ 8 #endif /* __ASM_PPC_MC146818RTC_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/md.h b/include/asm-ppc/md.h index 0ff3e7e92..79c3a22c6 100644 --- a/include/asm-ppc/md.h +++ b/include/asm-ppc/md.h @@ -3,6 +3,7 @@ * */ +#ifdef __KERNEL__ #ifndef __ASM_MD_H #define __ASM_MD_H @@ -11,3 +12,4 @@ #define MD_XORBLOCK_ALIGNMENT sizeof(long) #endif /* __ASM_MD_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mediabay.h b/include/asm-ppc/mediabay.h index a634d7f20..963555776 100644 --- a/include/asm-ppc/mediabay.h +++ b/include/asm-ppc/mediabay.h @@ -7,13 +7,13 @@ #ifndef _PPC_MEDIABAY_H #define _PPC_MEDIABAY_H +#ifdef __KERNEL__ + #define MB_FD 0 /* media bay contains floppy drive */ #define MB_FD1 1 /* media bay contains floppy drive */ #define MB_CD 3 /* media bay contains ATA drive such as CD */ #define MB_NO 7 /* media bay contains nothing */ -#ifdef __KERNEL__ - void media_bay_init(void); int check_media_bay(struct device_node *which_bay, int what); int check_media_bay_by_base(unsigned long base, int what); diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 4a3a42f26..2fe5cfe71 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -2,6 +2,7 @@ * PowerPC memory management structures */ +#ifdef __KERNEL__ #ifndef _PPC_MMU_H_ #define _PPC_MMU_H_ @@ -363,3 +364,4 @@ extern void _tlbia(void); /* invalidate all TLB entries */ #define TLB_G 0x00000001 /* Memory is guarded from prefetch */ #endif /* _PPC_MMU_H_ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index 414dd1cdc..fed474d14 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -1,5 +1,6 @@ #include +#ifdef __KERNEL__ #ifndef __PPC_MMU_CONTEXT_H #define __PPC_MMU_CONTEXT_H @@ -112,3 +113,4 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm ((segment < 8) ? ((segment) | (context)<<4) : (segment)) #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h index 10d586cad..94a054b57 100644 --- a/include/asm-ppc/mpc8260.h +++ b/include/asm-ppc/mpc8260.h @@ -5,6 +5,7 @@ * file that has to include MPC8260 configuration, they all include * this one and the configuration switching is done here. */ +#ifdef __KERNEL__ #ifndef __CONFIG_8260_DEFS #define __CONFIG_8260_DEFS @@ -40,3 +41,4 @@ extern int request_8xxirq(unsigned int irq, #endif /* CONFIG_8260 */ #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h index db327b76a..2476f7540 100644 --- a/include/asm-ppc/mpc8xx.h +++ b/include/asm-ppc/mpc8xx.h @@ -5,6 +5,7 @@ * file that has to include MPC8xx configuration, they all include * this one and the configuration switching is done here. */ +#ifdef __KERNEL__ #ifndef __CONFIG_8xx_DEFS #define __CONFIG_8xx_DEFS @@ -79,3 +80,4 @@ extern int request_8xxirq(unsigned int irq, void *dev_id); #endif /* CONFIG_8xx */ #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/msgbuf.h b/include/asm-ppc/msgbuf.h index ebfb950a2..3432b9b36 100644 --- a/include/asm-ppc/msgbuf.h +++ b/include/asm-ppc/msgbuf.h @@ -7,7 +7,6 @@ struct msqid64_ds { struct ipc64_perm msg_perm; - unsigned int __unused0; unsigned int __unused1; __kernel_time_t msg_stime; /* last msgsnd time */ unsigned int __unused2; diff --git a/include/asm-ppc/namei.h b/include/asm-ppc/namei.h index cd871903d..0bd54a034 100644 --- a/include/asm-ppc/namei.h +++ b/include/asm-ppc/namei.h @@ -5,6 +5,7 @@ * Included from linux/fs/namei.c */ +#ifdef __KERNEL__ #ifndef __PPC_NAMEI_H #define __PPC_NAMEI_H @@ -16,3 +17,4 @@ #define __emul_prefix() NULL #endif /* __PPC_NAMEI_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/nvram.h b/include/asm-ppc/nvram.h index 144d518b9..7f6fc08b1 100644 --- a/include/asm-ppc/nvram.h +++ b/include/asm-ppc/nvram.h @@ -2,6 +2,7 @@ * PreP compliant NVRAM access */ +#ifdef __KERNEL__ #ifndef _PPC_NVRAM_H #define _PPC_NVRAM_H @@ -64,3 +65,4 @@ struct pmac_machine_location { #define PMAC_NVRAM_GET_OFFSET _IOWR('p', 0x40, int) /* Get NVRAM partition offset */ #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/oak.h b/include/asm-ppc/oak.h index c906f5c4d..63f316401 100644 --- a/include/asm-ppc/oak.h +++ b/include/asm-ppc/oak.h @@ -11,6 +11,7 @@ * */ +#ifdef __KERNEL__ #ifndef __OAK_H__ #define __OAK_H__ @@ -66,3 +67,4 @@ typedef struct board_info { #endif #endif /* __OAK_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h index dee0ced3a..d4c104f8d 100644 --- a/include/asm-ppc/page.h +++ b/include/asm-ppc/page.h @@ -1,8 +1,3 @@ -#include -#ifndef __ASSEMBLY__ -#include /* for xmon definition */ -#endif /* ndef __ASSEMBLY__ */ - #ifndef _PPC_PAGE_H #define _PPC_PAGE_H @@ -11,11 +6,14 @@ #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) +#ifdef __KERNEL__ +#include + #define PAGE_OFFSET 0xc0000000 #define KERNELBASE PAGE_OFFSET #ifndef __ASSEMBLY__ -#ifdef __KERNEL__ +#include /* for xmon definition */ #ifdef CONFIG_XMON #define BUG() do { \ @@ -134,6 +132,6 @@ extern __inline__ int get_order(unsigned long size) return order; } -#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ #endif /* _PPC_PAGE_H */ diff --git a/include/asm-ppc/param.h b/include/asm-ppc/param.h index 0cdcc660e..3c5c92c75 100644 --- a/include/asm-ppc/param.h +++ b/include/asm-ppc/param.h @@ -17,4 +17,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ +#endif + #endif diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h index 5aa72d3a2..9e5385e51 100644 --- a/include/asm-ppc/pci-bridge.h +++ b/include/asm-ppc/pci-bridge.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _ASM_PCI_BRIDGE_H #define _ASM_PCI_BRIDGE_H @@ -46,3 +47,4 @@ struct bridge_data { }; #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index a9da1b195..1a661f050 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -1,12 +1,12 @@ #ifndef __PPC_PCI_H #define __PPC_PCI_H +#ifdef __KERNEL__ /* Values for the `which' argument to sys_pciconfig_iobase syscall. */ #define IOBASE_BRIDGE_NUMBER 0 #define IOBASE_MEMORY 1 #define IOBASE_IO 2 -#ifdef __KERNEL__ /* Can be used to override the logic in pci_scan_bus for skipping * already-configured bus numbers - to be used for buggy BIOSes diff --git a/include/asm-ppc/pgalloc.h b/include/asm-ppc/pgalloc.h index 6166a1bfb..7da57a6f2 100644 --- a/include/asm-ppc/pgalloc.h +++ b/include/asm-ppc/pgalloc.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_PGALLOC_H #define _PPC_PGALLOC_H @@ -51,33 +52,6 @@ extern unsigned long get_zero_page_fast(void); extern void __bad_pte(pmd_t *pmd); -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ - struct task_struct * p; - pgd_t *pgd; -#ifdef CONFIG_SMP - int i; -#endif - - read_lock(&tasklist_lock); - for_each_task(p) { - if (!p->mm) - continue; - *pgd_offset(p->mm,address) = entry; - } - read_unlock(&tasklist_lock); -#ifndef CONFIG_SMP - for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -#else - /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can - modify pgd caches of other CPUs as well. -jj */ - for (i = 0; i < NR_CPUS; i++) - for (pgd = (pgd_t *)cpu_data[i].pgd_cache; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -#endif -} - /* We don't use pmd cache, so this is a dummy routine */ extern __inline__ pmd_t *get_pmd_fast(void) { @@ -200,3 +174,4 @@ extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) extern int do_check_pgt_cache(int, int); #endif /* _PPC_PGALLOC_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 8b7a8a1e7..0f4579cd7 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_PGTABLE_H #define _PPC_PGTABLE_H @@ -489,3 +490,4 @@ extern void kernel_set_cachemode (unsigned long address, unsigned long size, #endif __ASSEMBLY__ #endif /* _PPC_PGTABLE_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/pnp.h b/include/asm-ppc/pnp.h index 15335ff35..6f6760b30 100644 --- a/include/asm-ppc/pnp.h +++ b/include/asm-ppc/pnp.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ /* 11/02/95 */ /*----------------------------------------------------------------------------*/ /* Plug and Play header definitions */ @@ -641,3 +642,4 @@ typedef union _PnP_TAG_PACKET { #endif /* __ASSEMBLY__ */ #endif /* ndef _PNP_ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/prep_nvram.h b/include/asm-ppc/prep_nvram.h index 2f0f80b5c..82ec21508 100644 --- a/include/asm-ppc/prep_nvram.h +++ b/include/asm-ppc/prep_nvram.h @@ -17,6 +17,7 @@ For enum's: if given in hex then they are bit significant, i.e. only one bit is on for each enum. */ +#ifdef __KERNEL__ #ifndef _PPC_PREP_NVRAM_H #define _PPC_PREP_NVRAM_H @@ -144,3 +145,4 @@ void prep_nvram_write_val(int addr, unsigned char val); #endif /* _PPC_PREP_NVRAM_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index f99eb4abe..cfd49807e 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef __ASM_PPC_PROCESSOR_H #define __ASM_PPC_PROCESSOR_H @@ -727,3 +728,4 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); #endif /* CONFIG_MACH_SPECIFIC */ #endif /* __ASM_PPC_PROCESSOR_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h index dc98c596d..0c57690ea 100644 --- a/include/asm-ppc/prom.h +++ b/include/asm-ppc/prom.h @@ -4,6 +4,7 @@ * * Copyright (C) 1996 Paul Mackerras. */ +#ifdef __KERNEL__ #ifndef _PPC_PROM_H #define _PPC_PROM_H @@ -98,3 +99,4 @@ extern void map_bootx_text(void); #endif /* _PPC_PROM_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h index 93a75bd87..b154187e6 100644 --- a/include/asm-ppc/ptrace.h +++ b/include/asm-ppc/ptrace.h @@ -17,32 +17,26 @@ * the PT_* values below. This simplifies arch/ppc/kernel/ptrace.c. */ -#include - #ifndef __ASSEMBLY__ -#ifdef CONFIG_PPC64BRIDGE -#define PPC_REG unsigned long /*long*/ -#else -#define PPC_REG unsigned long -#endif struct pt_regs { - PPC_REG gpr[32]; - PPC_REG nip; - PPC_REG msr; - PPC_REG orig_gpr3; /* Used for restarting system calls */ - PPC_REG ctr; - PPC_REG link; - PPC_REG xer; - PPC_REG ccr; - PPC_REG mq; /* 601 only (not used at present) */ - /* Used on APUS to hold IPL value. */ - PPC_REG trap; /* Reason for being here */ - PPC_REG dar; /* Fault registers */ - PPC_REG dsisr; - PPC_REG result; /* Result of a system call */ + unsigned long gpr[32]; + unsigned long nip; + unsigned long msr; + unsigned long orig_gpr3; /* Used for restarting system calls */ + unsigned long ctr; + unsigned long link; + unsigned long xer; + unsigned long ccr; + unsigned long mq; /* 601 only (not used at present) */ + /* Used on APUS to hold IPL value. */ + unsigned long trap; /* Reason for being here */ + unsigned long dar; /* Fault registers */ + unsigned long dsisr; + unsigned long result; /* Result of a system call */ }; #endif +#ifdef __KERNEL__ #define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ /* Size of stack frame allocated when calling signal handler. */ @@ -51,6 +45,8 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->nip) #define user_mode(regs) (((regs)->msr & MSR_PR) != 0) +#endif /* __KERNEL__ */ + /* * Offsets used by 'ptrace' system call interface. * These can't be changed without breaking binary compatibility diff --git a/include/asm-ppc/raven.h b/include/asm-ppc/raven.h index 62f996f66..ee873ff82 100644 --- a/include/asm-ppc/raven.h +++ b/include/asm-ppc/raven.h @@ -8,6 +8,7 @@ * for more details. */ +#ifdef __KERNEL__ #ifndef _ASMPPC_RAVEN_H #define _ASMPPC_RAVEN_H @@ -31,3 +32,4 @@ extern struct hw_interrupt_type raven_pic; extern int raven_init(void); #endif _ASMPPC_RAVEN_H +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/residual.h b/include/asm-ppc/residual.h index c037a4e4a..685c04502 100644 --- a/include/asm-ppc/residual.h +++ b/include/asm-ppc/residual.h @@ -10,6 +10,7 @@ /* i.e. only one bit is on for each enum */ /* Reserved fields must be filled with zeros. */ +#ifdef __KERNEL__ #ifndef _RESIDUAL_ #define _RESIDUAL_ @@ -330,3 +331,4 @@ extern PnP_TAG_PACKET *PnP_find_large_vendor_packet(unsigned char *p, #endif /* __ASSEMBLY__ */ #endif /* ndef _RESIDUAL_ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/rpxclassic.h b/include/asm-ppc/rpxclassic.h index b84a20d12..0583b60fb 100644 --- a/include/asm-ppc/rpxclassic.h +++ b/include/asm-ppc/rpxclassic.h @@ -5,6 +5,7 @@ * * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) */ +#ifdef __KERNEL__ #ifndef __MACH_RPX_DEFS #define __MACH_RPX_DEFS @@ -82,3 +83,4 @@ extern bd_t m8xx_board_info; #define _MACH_8xx (_MACH_classic) #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/rpxlite.h b/include/asm-ppc/rpxlite.h index c0cc7e0a6..1d447082b 100644 --- a/include/asm-ppc/rpxlite.h +++ b/include/asm-ppc/rpxlite.h @@ -5,6 +5,7 @@ * * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) */ +#ifdef __KERNEL__ #ifndef __MACH_RPX_DEFS #define __MACH_RPX_DEFS @@ -65,3 +66,4 @@ extern bd_t m8xx_board_info; #define _MACH_8xx (_MACH_rpxlite) #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/scatterlist.h b/include/asm-ppc/scatterlist.h index f81590716..5c6b01c99 100644 --- a/include/asm-ppc/scatterlist.h +++ b/include/asm-ppc/scatterlist.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_SCATTERLIST_H #define _PPC_SCATTERLIST_H @@ -12,3 +13,4 @@ struct scatterlist { #endif /* !(_PPC_SCATTERLIST_H) */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/semaphore-helper.h b/include/asm-ppc/semaphore-helper.h index 3033272d9..14f2c0e2e 100644 --- a/include/asm-ppc/semaphore-helper.h +++ b/include/asm-ppc/semaphore-helper.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_SEMAPHORE_HELPER_H #define _PPC_SEMAPHORE_HELPER_H @@ -105,3 +106,4 @@ static inline int waking_non_zero_trylock(struct semaphore *sem) } #endif /* _PPC_SEMAPHORE_HELPER_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/sembuf.h b/include/asm-ppc/sembuf.h index 6b6a182a8..d0ab55833 100644 --- a/include/asm-ppc/sembuf.h +++ b/include/asm-ppc/sembuf.h @@ -7,7 +7,6 @@ struct semid64_ds { struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ - unsigned int __unused0; unsigned int __unused1; __kernel_time_t sem_otime; /* last semop time */ unsigned int __unused2; diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h index b6b89dc79..60c1a14ff 100644 --- a/include/asm-ppc/serial.h +++ b/include/asm-ppc/serial.h @@ -2,6 +2,7 @@ * include/asm-ppc/serial.h */ +#ifdef __KERNEL__ #include #ifdef CONFIG_GEMINI @@ -127,3 +128,4 @@ MCA_SERIAL_PORT_DFNS #endif /* CONFIG_GEMINI */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/setup.h b/include/asm-ppc/setup.h index 2f9164160..cd458c4f1 100644 --- a/include/asm-ppc/setup.h +++ b/include/asm-ppc/setup.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_SETUP_H #define _PPC_SETUP_H @@ -7,3 +8,4 @@ #include #endif /* _PPC_SETUP_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/shmbuf.h b/include/asm-ppc/shmbuf.h index df84f0b09..ec614e8c6 100644 --- a/include/asm-ppc/shmbuf.h +++ b/include/asm-ppc/shmbuf.h @@ -7,19 +7,19 @@ struct shmid64_ds { struct ipc64_perm shm_perm; /* operation perms */ - unsigned int __unused0; - size_t shm_segsz; /* size of segment (bytes) */ - unsigned long __unused1; + unsigned int __unused1; __kernel_time_t shm_atime; /* last attach time */ - unsigned long __unused2; + unsigned int __unused2; __kernel_time_t shm_dtime; /* last detach time */ - unsigned long __unused3; + unsigned int __unused3; __kernel_time_t shm_ctime; /* last change time */ + unsigned int __unused4; + size_t shm_segsz; /* size of segment (bytes) */ __kernel_pid_t shm_cpid; /* pid of creator */ __kernel_pid_t shm_lpid; /* pid of last operator */ unsigned long shm_nattch; /* no. of current attaches */ - unsigned long __unused4; unsigned long __unused5; + unsigned long __unused6; }; struct shminfo64 { diff --git a/include/asm-ppc/siginfo.h b/include/asm-ppc/siginfo.h index 3b0bd261d..74a16e0b2 100644 --- a/include/asm-ppc/siginfo.h +++ b/include/asm-ppc/siginfo.h @@ -3,8 +3,6 @@ /* Copied from i386 from alpha. */ -#include - typedef union sigval { int sival_int; void *sival_ptr; diff --git a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h index f5025a161..4958b3f35 100644 --- a/include/asm-ppc/signal.h +++ b/include/asm-ppc/signal.h @@ -1,7 +1,9 @@ #ifndef _ASMPPC_SIGNAL_H #define _ASMPPC_SIGNAL_H +#ifdef __KERNEL__ #include +#endif /* __KERNEL__ */ /* Avoid too many header ordering problems. */ struct siginfo; diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index abbd0ca0c..4851e13fd 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -3,6 +3,7 @@ * Taken from asm-sparc/smp.h */ +#ifdef __KERNEL__ #ifndef _PPC_SMP_H #define _PPC_SMP_H @@ -59,3 +60,4 @@ extern struct klock_info_struct klock_info; #endif /* !(CONFIG_SMP) */ #endif /* !(_PPC_SMP_H) */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/smplock.h b/include/asm-ppc/smplock.h index 96565069c..5fdd5733b 100644 --- a/include/asm-ppc/smplock.h +++ b/include/asm-ppc/smplock.h @@ -3,6 +3,7 @@ * * Default SMP lock implementation */ +#ifdef __KERNEL__ #include #include @@ -49,3 +50,4 @@ extern __inline__ void unlock_kernel(void) if (--current->lock_depth < 0) spin_unlock(&kernel_flag); } +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/softirq.h b/include/asm-ppc/softirq.h index 4eaed0be6..20898d818 100644 --- a/include/asm-ppc/softirq.h +++ b/include/asm-ppc/softirq.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef __ASM_SOFTIRQ_H #define __ASM_SOFTIRQ_H @@ -10,3 +11,4 @@ #define in_softirq() (local_bh_count(smp_processor_id()) != 0) #endif /* __ASM_SOFTIRQ_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h index 292406736..eae7df4a5 100644 --- a/include/asm-ppc/spinlock.h +++ b/include/asm-ppc/spinlock.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H @@ -54,3 +55,4 @@ extern void _write_unlock(rwlock_t *rw); #define read_unlock(rw) _read_unlock(rw) #endif /* __ASM_SPINLOCK_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/stat.h b/include/asm-ppc/stat.h index 204b07e6e..ed382adc8 100644 --- a/include/asm-ppc/stat.h +++ b/include/asm-ppc/stat.h @@ -1,7 +1,9 @@ #ifndef _PPC_STAT_H #define _PPC_STAT_H +#ifdef __KERNEL__ #include +#endif /* __KERNEL__ */ struct __old_kernel_stat { unsigned short st_dev; diff --git a/include/asm-ppc/string.h b/include/asm-ppc/string.h index d912a6b5f..557e3ad0e 100644 --- a/include/asm-ppc/string.h +++ b/include/asm-ppc/string.h @@ -1,6 +1,8 @@ #ifndef _PPC_STRING_H_ #define _PPC_STRING_H_ +#ifdef __KERNEL__ + #define __HAVE_ARCH_STRCPY #define __HAVE_ARCH_STRNCPY #define __HAVE_ARCH_STRLEN @@ -26,4 +28,6 @@ extern void * memmove(void *,const void *,__kernel_size_t); extern int memcmp(const void *,const void *,__kernel_size_t); extern void * memchr(const void *,int,__kernel_size_t); +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 523a427a0..571d2c81f 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -3,6 +3,7 @@ * * Copyright (C) 1999 Cort Dougan */ +#ifdef __KERNEL__ #ifndef __PPC_SYSTEM_H #define __PPC_SYSTEM_H @@ -224,3 +225,4 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) }) #endif /* __PPC_SYSTEM_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/termbits.h b/include/asm-ppc/termbits.h index 324b62600..52e6d2d52 100644 --- a/include/asm-ppc/termbits.h +++ b/include/asm-ppc/termbits.h @@ -1,8 +1,6 @@ #ifndef _PPC_TERMBITS_H #define _PPC_TERMBITS_H -#include - typedef unsigned char cc_t; typedef unsigned int speed_t; typedef unsigned int tcflag_t; diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h index 1eb0ae9f0..8f43219a8 100644 --- a/include/asm-ppc/time.h +++ b/include/asm-ppc/time.h @@ -6,6 +6,7 @@ * Paul Mackerras' version and mine for PReP and Pmac. */ +#ifdef __KERNEL__ #include #include @@ -113,3 +114,4 @@ extern __inline__ unsigned binary_tbl(void) { ({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;}) unsigned mulhwu_scale_factor(unsigned, unsigned); +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/timex.h b/include/asm-ppc/timex.h index df7a8749d..485ad0053 100644 --- a/include/asm-ppc/timex.h +++ b/include/asm-ppc/timex.h @@ -3,6 +3,7 @@ * * ppc architecture timex specifications */ +#ifdef __KERNEL__ #ifndef _ASMppc_TIMEX_H #define _ASMppc_TIMEX_H @@ -39,3 +40,4 @@ static inline cycles_t get_cycles(void) } #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/tqm860.h b/include/asm-ppc/tqm860.h index a42b7b277..733dcccdb 100644 --- a/include/asm-ppc/tqm860.h +++ b/include/asm-ppc/tqm860.h @@ -10,6 +10,7 @@ * * Copyright (c) 1999 Wolfgang Denk (wd@denx.de) */ +#ifdef __KERNEL__ #ifndef __MACH_TQM860_DEFS #define __MACH_TQM860_DEFS @@ -63,3 +64,4 @@ typedef struct bd_info { #endif /* __MACH_TQM860_DEFS */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/tqm8xxL.h b/include/asm-ppc/tqm8xxL.h index e51e98080..338396aa6 100644 --- a/include/asm-ppc/tqm8xxL.h +++ b/include/asm-ppc/tqm8xxL.h @@ -10,6 +10,7 @@ * * Copyright (c) 1999 Wolfgang Denk (wd@denx.de) */ +#ifdef __KERNEL__ #ifndef __MACH_TQM8xxL_DEFS #define __MACH_TQM8xxL_DEFS @@ -64,3 +65,4 @@ typedef struct bd_info { #endif /* __MACH_TQM8xxL_DEFS */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h index 4ebbb9e02..6734fa276 100644 --- a/include/asm-ppc/types.h +++ b/include/asm-ppc/types.h @@ -3,8 +3,6 @@ #ifndef __ASSEMBLY__ -typedef unsigned short umode_t; - typedef __signed__ char __s8; typedef unsigned char __u8; @@ -21,7 +19,7 @@ typedef unsigned long long __u64; typedef struct { __u32 u[4]; -} __attribute((aligned(16))) vector128; +} __attribute((aligned(16))) __vector128; #ifdef __KERNEL__ /* @@ -39,11 +37,15 @@ typedef unsigned int u32; typedef signed long long s64; typedef unsigned long long u64; +typedef __vector128 vector128; + #define BITS_PER_LONG 32 /* DMA addresses are 32-bits wide */ typedef u32 dma_addr_t; +typedef unsigned short umode_t; + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h index 628373b15..cd87905b0 100644 --- a/include/asm-ppc/uaccess.h +++ b/include/asm-ppc/uaccess.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_UACCESS_H #define _PPC_UACCESS_H @@ -274,3 +275,4 @@ extern __inline__ int strnlen_user(const char *str, long len) #endif /* __ASSEMBLY__ */ #endif /* _PPC_UACCESS_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/unaligned.h b/include/asm-ppc/unaligned.h index 90a54eae9..797ffd6e4 100644 --- a/include/asm-ppc/unaligned.h +++ b/include/asm-ppc/unaligned.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef __PPC_UNALIGNED_H #define __PPC_UNALIGNED_H @@ -14,3 +15,4 @@ #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/uninorth.h b/include/asm-ppc/uninorth.h index eefe4389c..b21cc8931 100644 --- a/include/asm-ppc/uninorth.h +++ b/include/asm-ppc/uninorth.h @@ -3,6 +3,7 @@ * from Apple. This chip is used on "Core99" machines * */ +#ifdef __KERNEL__ /* @@ -79,5 +80,4 @@ */ #define UNI_N_HWINIT_STATE_CPU1_FLAG 0x10000000 - - +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/user.h b/include/asm-ppc/user.h index e3bd611b3..d662b2151 100644 --- a/include/asm-ppc/user.h +++ b/include/asm-ppc/user.h @@ -1,3 +1,4 @@ +#ifdef __KERNEL__ #ifndef _PPC_USER_H #define _PPC_USER_H @@ -50,3 +51,4 @@ struct user { #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) #endif /* _PPC_USER_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h index 69e3d7f9a..c5864734e 100644 --- a/include/asm-ppc/vga.h +++ b/include/asm-ppc/vga.h @@ -4,6 +4,7 @@ * (c) 1998 Martin Mares */ +#ifdef __KERNEL__ #ifndef _LINUX_ASM_VGA_H_ #define _LINUX_ASM_VGA_H_ @@ -42,3 +43,4 @@ extern unsigned long vgacon_remap_base; #define vga_writeb(x,y) (*(y) = (x)) #endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/walnut.h b/include/asm-ppc/walnut.h index 84499af8a..45a92bbb3 100644 --- a/include/asm-ppc/walnut.h +++ b/include/asm-ppc/walnut.h @@ -11,6 +11,7 @@ * */ +#ifdef __KERNEL__ #ifndef __WALNUT_H__ #define __WALNUT_H__ @@ -26,3 +27,4 @@ extern "C" { #endif #endif /* __WALNUT_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-sparc/ethtool.h b/include/asm-sparc/ethtool.h deleted file mode 100644 index 572db24fb..000000000 --- a/include/asm-sparc/ethtool.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $Id: ethtool.h,v 1.2 2000/01/31 04:59:17 davem Exp $ - * ethtool.h: Defines for SparcLinux ethtool. - * - * Copyright (C) 1998 David S. Miller (davem@redhat.com) - */ - -#ifndef _SPARC_ETHTOOL_H -#define _SPARC_ETHTOOL_H - -/* We do things like this so it does not matter what kernel - * headers you have on your system etc. - */ -#undef SIOCETHTOOL -#define SIOCETHTOOL (SIOCDEVPRIVATE + 0x0f) - -/* This should work for both 32 and 64 bit userland. */ -struct ethtool_cmd { - u32 cmd; - u32 supported; - u16 speed; - u8 duplex; - u8 port; - u8 phy_address; - u8 transceiver; - u8 autoneg; -}; - -/* CMDs currently supported */ -#define SPARC_ETH_GSET 0x00000001 /* Get settings, non-privileged. */ -#define SPARC_ETH_SSET 0x00000002 /* Set settings, privileged. */ - -/* Indicates what features are supported by the interface. */ -#define SUPPORTED_10baseT_Half 0x00000001 -#define SUPPORTED_10baseT_Full 0x00000002 -#define SUPPORTED_100baseT_Half 0x00000004 -#define SUPPORTED_100baseT_Full 0x00000008 -#define SUPPORTED_1000baseT_Half 0x00000010 -#define SUPPORTED_1000baseT_Full 0x00000020 -#define SUPPORTED_Autoneg 0x00000040 -#define SUPPORTED_TP 0x00000080 -#define SUPPORTED_AUI 0x00000100 -#define SUPPORTED_MII 0x00000200 -#define SUPPORTED_FIBRE 0x00000400 - -/* The following are all involved in forcing a particular link - * mode for the device for setting things. When getting the - * devices settings, these indicate the current mode and whether - * it was foced up into this mode or autonegotiated. - */ - -/* The forced speec, 10Mb, 100Mb, gigabit. */ -#define SPEED_10 10 -#define SPEED_100 100 -#define SPEED_1000 1000 - -/* Duplex, half or full. */ -#define DUPLEX_HALF 0x00 -#define DUPLEX_FULL 0x01 - -/* Which connector port. */ -#define PORT_TP 0x00 -#define PORT_AUI 0x01 -#define PORT_MII 0x02 -#define PORT_FIBRE 0x03 - -/* Which tranceiver to use. */ -#define XCVR_INTERNAL 0x00 -#define XCVR_EXTERNAL 0x01 -#define XCVR_DUMMY1 0x02 -#define XCVR_DUMMY2 0x03 -#define XCVR_DUMMY3 0x04 - -/* Enable or disable autonegotiation. If this is set to enable, - * the forced link modes above are completely ignored. - */ -#define AUTONEG_DISABLE 0x00 -#define AUTONEG_ENABLE 0x01 - -#endif /* _SPARC_ETHTOOL_H */ diff --git a/include/asm-sparc64/ethtool.h b/include/asm-sparc64/ethtool.h deleted file mode 100644 index 18d86c3de..000000000 --- a/include/asm-sparc64/ethtool.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $Id: ethtool.h,v 1.2 2000/01/31 04:59:19 davem Exp $ - * ethtool.h: Defines for SparcLinux ethtool. - * - * Copyright (C) 1998 David S. Miller (davem@redhat.com) - */ - -#ifndef _SPARC64_ETHTOOL_H -#define _SPARC64_ETHTOOL_H - -/* We do things like this so it does not matter what kernel - * headers you have on your system etc. - */ -#undef SIOCETHTOOL -#define SIOCETHTOOL (SIOCDEVPRIVATE + 0x0f) - -/* This should work for both 32 and 64 bit userland. */ -struct ethtool_cmd { - u32 cmd; - u32 supported; - u16 speed; - u8 duplex; - u8 port; - u8 phy_address; - u8 transceiver; - u8 autoneg; -}; - -/* CMDs currently supported */ -#define SPARC_ETH_GSET 0x00000001 /* Get settings, non-privileged. */ -#define SPARC_ETH_SSET 0x00000002 /* Set settings, privileged. */ - -/* Indicates what features are supported by the interface. */ -#define SUPPORTED_10baseT_Half 0x00000001 -#define SUPPORTED_10baseT_Full 0x00000002 -#define SUPPORTED_100baseT_Half 0x00000004 -#define SUPPORTED_100baseT_Full 0x00000008 -#define SUPPORTED_1000baseT_Half 0x00000010 -#define SUPPORTED_1000baseT_Full 0x00000020 -#define SUPPORTED_Autoneg 0x00000040 -#define SUPPORTED_TP 0x00000080 -#define SUPPORTED_AUI 0x00000100 -#define SUPPORTED_MII 0x00000200 -#define SUPPORTED_FIBRE 0x00000400 - -/* The following are all involved in forcing a particular link - * mode for the device for setting things. When getting the - * devices settings, these indicate the current mode and whether - * it was foced up into this mode or autonegotiated. - */ - -/* The forced speec, 10Mb, 100Mb, gigabit. */ -#define SPEED_10 10 -#define SPEED_100 100 -#define SPEED_1000 1000 - -/* Duplex, half or full. */ -#define DUPLEX_HALF 0x00 -#define DUPLEX_FULL 0x01 - -/* Which connector port. */ -#define PORT_TP 0x00 -#define PORT_AUI 0x01 -#define PORT_MII 0x02 -#define PORT_FIBRE 0x03 - -/* Which tranceiver to use. */ -#define XCVR_INTERNAL 0x00 -#define XCVR_EXTERNAL 0x01 -#define XCVR_DUMMY1 0x02 -#define XCVR_DUMMY2 0x03 -#define XCVR_DUMMY3 0x04 - -/* Enable or disable autonegotiation. If this is set to enable, - * the forced link modes above are completely ignored. - */ -#define AUTONEG_DISABLE 0x00 -#define AUTONEG_ENABLE 0x01 - -#endif /* _SPARC64_ETHTOOL_H */ diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h new file mode 100644 index 000000000..6a398694f --- /dev/null +++ b/include/linux/ethtool.h @@ -0,0 +1,96 @@ +/* $Id: ethtool.h,v 1.1 2000/11/10 05:44:33 davem Exp $ + * ethtool.h: Defines for Linux ethtool. + * + * Copyright (C) 1998 David S. Miller (davem@redhat.com) + */ + +#ifndef _LINUX_ETHTOOL_H +#define _LINUX_ETHTOOL_H + + +/* This should work for both 32 and 64 bit userland. */ +struct ethtool_cmd { + u32 cmd; + u32 supported; /* Features this interface supports */ + u32 advertising; /* Features this interface advertises */ + u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ + u8 duplex; /* Duplex, half or full */ + u8 port; /* Which connector port */ + u8 phy_address; + u8 transceiver; /* Which tranceiver to use */ + u8 autoneg; /* Enable or disable autonegotiation */ + u32 maxtxpkt; /* Tx pkts before generating tx int */ + u32 maxrxpkt; /* Rx pkts before generating rx int */ + u32 reserved[4]; +}; + + +/* CMDs currently supported */ +#define ETHTOOL_GSET 0x00000001 /* Get settings, non-privileged. */ +#define ETHTOOL_SSET 0x00000002 /* Set settings, privileged. */ + +/* compatibility with older code */ +#define SPARC_ETH_GSET ETHTOOL_GSET +#define SPARC_ETH_SSET ETHTOOL_SSET + +/* Indicates what features are supported by the interface. */ +#define SUPPORTED_10baseT_Half (1 << 0) +#define SUPPORTED_10baseT_Full (1 << 1) +#define SUPPORTED_100baseT_Half (1 << 2) +#define SUPPORTED_100baseT_Full (1 << 3) +#define SUPPORTED_1000baseT_Half (1 << 4) +#define SUPPORTED_1000baseT_Full (1 << 5) +#define SUPPORTED_Autoneg (1 << 6) +#define SUPPORTED_TP (1 << 7) +#define SUPPORTED_AUI (1 << 8) +#define SUPPORTED_MII (1 << 9) +#define SUPPORTED_FIBRE (1 << 10) + +/* Indicates what features are advertised by the interface. */ +#define ADVERTISED_10baseT_Half (1 << 0) +#define ADVERTISED_10baseT_Full (1 << 1) +#define ADVERTISED_100baseT_Half (1 << 2) +#define ADVERTISED_100baseT_Full (1 << 3) +#define ADVERTISED_1000baseT_Half (1 << 4) +#define ADVERTISED_1000baseT_Full (1 << 5) +#define ADVERTISED_Autoneg (1 << 6) +#define ADVERTISED_TP (1 << 7) +#define ADVERTISED_AUI (1 << 8) +#define ADVERTISED_MII (1 << 9) +#define ADVERTISED_FIBRE (1 << 10) + +/* The following are all involved in forcing a particular link + * mode for the device for setting things. When getting the + * devices settings, these indicate the current mode and whether + * it was foced up into this mode or autonegotiated. + */ + +/* The forced speed, 10Mb, 100Mb, gigabit. */ +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 + +/* Duplex, half or full. */ +#define DUPLEX_HALF 0x00 +#define DUPLEX_FULL 0x01 + +/* Which connector port. */ +#define PORT_TP 0x00 +#define PORT_AUI 0x01 +#define PORT_MII 0x02 +#define PORT_FIBRE 0x03 + +/* Which tranceiver to use. */ +#define XCVR_INTERNAL 0x00 +#define XCVR_EXTERNAL 0x01 +#define XCVR_DUMMY1 0x02 +#define XCVR_DUMMY2 0x03 +#define XCVR_DUMMY3 0x04 + +/* Enable or disable autonegotiation. If this is set to enable, + * the forced link modes above are completely ignored. + */ +#define AUTONEG_DISABLE 0x00 +#define AUTONEG_ENABLE 0x01 + +#endif /* _LINUX_ETHTOOL_H */ diff --git a/include/linux/irda.h b/include/linux/irda.h index d8532c2fc..40aec1c8d 100644 --- a/include/linux/irda.h +++ b/include/linux/irda.h @@ -78,14 +78,17 @@ enum { #define SOL_IRLMP 266 /* Same as SOL_IRDA for now */ #define SOL_IRTTP 266 /* Same as SOL_IRDA for now */ -#define IRLMP_ENUMDEVICES 1 -#define IRLMP_IAS_SET 2 -#define IRLMP_IAS_QUERY 3 -#define IRLMP_HINTS_SET 4 +#define IRLMP_ENUMDEVICES 1 /* Return discovery log */ +#define IRLMP_IAS_SET 2 /* Set an attribute in local IAS */ +#define IRLMP_IAS_QUERY 3 /* Query remote IAS for attribute */ +#define IRLMP_HINTS_SET 4 /* Set hint bits advertised */ #define IRLMP_QOS_SET 5 #define IRLMP_QOS_GET 6 #define IRLMP_MAX_SDU_SIZE 7 -#define IRLMP_IAS_GET 8 +#define IRLMP_IAS_GET 8 /* Get an attribute from local IAS */ +#define IRLMP_IAS_DEL 9 /* Remove attribute from local IAS */ +#define IRLMP_HINT_MASK_SET 10 /* Set discovery filter */ +#define IRLMP_WAITDEVICE 11 /* Wait for a new discovery */ #define IRTTP_MAX_SDU_SIZE IRLMP_MAX_SDU_SIZE /* Compatibility */ @@ -94,6 +97,12 @@ enum { #define IAS_MAX_CLASSNAME 64 #define IAS_MAX_ATTRIBNAME 256 +/* Attribute type needed for struct irda_ias_set */ +#define IAS_MISSING 0 +#define IAS_INTEGER 1 +#define IAS_OCT_SEQ 2 +#define IAS_STRING 3 + #define LSAP_ANY 0xff struct sockaddr_irda { @@ -132,6 +141,7 @@ struct irda_ias_set { __u8 string[IAS_MAX_STRING]; } irda_attrib_string; } attribute; + __u32 daddr; /* Address of device (for some queries only) */ }; /* Some private IOCTL's (max 16) */ diff --git a/include/linux/isdn.h b/include/linux/isdn.h index 7cdd4ff43..51c06aec7 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -1,4 +1,4 @@ -/* $Id: isdn.h,v 1.106 2000/08/10 22:52:46 kai Exp $ +/* $Id: isdn.h,v 1.110 2000/11/01 17:54:01 detabc Exp $ * Main header for the Linux ISDN subsystem (linklevel). * @@ -66,8 +66,7 @@ #undef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE #undef CONFIG_ISDN_WITH_ABC_CONN_ERROR #undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS -#undef CONFIG_ISDN_WITH_ABC_IPV4_RW_SOCKADDR -#undef CONFIG_ISDN_WITH_ABC_IPV4_RWUDP_SOCKADDR +#undef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER /* New ioctl-codes */ diff --git a/include/linux/kernelcapi.h b/include/linux/kernelcapi.h index 40530168e..acbdea338 100644 --- a/include/linux/kernelcapi.h +++ b/include/linux/kernelcapi.h @@ -1,5 +1,5 @@ /* - * $Id: kernelcapi.h,v 1.7 2000/06/12 09:20:20 kai Exp $ + * $Id: kernelcapi.h,v 1.8 2000/08/22 10:11:00 calle Exp $ * * Kernel CAPI 2.0 Interface for Linux * diff --git a/include/linux/kmod.h b/include/linux/kmod.h index bab128898..44e1ea652 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -1,22 +1,38 @@ +#ifndef __LINUX_KMOD_H__ +#define __LINUX_KMOD_H__ + /* - kmod header -*/ + * include/linux/kmod.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #include #include #ifdef CONFIG_KMOD extern int request_module(const char * name); +#else +static inline int request_module(const char * name) { return -ENOSYS; } +#endif + extern int exec_usermodehelper(char *program_path, char *argv[], char *envp[]); +extern int call_usermodehelper(char *path, char *argv[], char *envp[]); + #ifdef CONFIG_HOTPLUG extern char hotplug_path []; -extern int call_usermodehelper(char *path, char *argv[], char *envp[]); -#endif -#else -static inline int request_module(const char * name) { return -ENOSYS; } -static inline int exec_usermodehelper(char *program_path, char *argv[], char *envp[]) -{ - return -EACCES; -} #endif +#endif /* __LINUX_KMOD_H__ */ diff --git a/include/linux/lapb.h b/include/linux/lapb.h index bf1825a6b..2eeb76f2c 100644 --- a/include/linux/lapb.h +++ b/include/linux/lapb.h @@ -28,7 +28,7 @@ struct lapb_register_struct { void (*connect_indication)(void *token, int reason); void (*disconnect_confirmation)(void *token, int reason); void (*disconnect_indication)(void *token, int reason); - void (*data_indication)(void *token, struct sk_buff *skb); + int (*data_indication)(void *token, struct sk_buff *skb); void (*data_transmit)(void *token, struct sk_buff *skb); }; diff --git a/include/linux/mm.h b/include/linux/mm.h index 8713dfd29..70ffe28e4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -417,8 +417,11 @@ extern void si_meminfo(struct sysinfo * val); extern void swapin_readahead(swp_entry_t); /* mmap.c */ +extern void lock_vma_mappings(struct vm_area_struct *); +extern void unlock_vma_mappings(struct vm_area_struct *); extern void merge_segments(struct mm_struct *, unsigned long, unsigned long); extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); +extern void __insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void build_mmap_avl(struct mm_struct *); extern void exit_mmap(struct mm_struct *); extern unsigned long get_unmapped_area(unsigned long, unsigned long); diff --git a/include/linux/module.h b/include/linux/module.h index f5a25b437..249cb0163 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -344,4 +344,10 @@ __attribute__((section("__ksymtab"))) = \ #define EXPORT_NO_SYMBOLS #endif /* MODULE */ +#ifdef CONFIG_MODULES +#define SET_MODULE_OWNER(some_struct) do { some_struct->owner = THIS_MODULE; } while (0) +#else +#define SET_MODULE_OWNER(some_struct) do { } while (0) +#endif + #endif /* _LINUX_MODULE_H */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 32677edae..2c2bfd4d5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -383,6 +383,9 @@ struct net_device int (*neigh_setup)(struct net_device *dev, struct neigh_parms *); int (*accept_fastpath)(struct net_device *, struct dst_entry*); + /* open/release and usage marking */ + struct module *owner; + /* bridge stuff */ struct net_bridge_port *br_port; diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index ec87c2ddd..668ed1c2b 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/include/linux/sched.h b/include/linux/sched.h index da25c001c..471a5325b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -85,7 +85,6 @@ extern int last_pid; #define TASK_UNINTERRUPTIBLE 2 #define TASK_ZOMBIE 4 #define TASK_STOPPED 8 -#define TASK_EXCLUSIVE 32 #define __set_task_state(tsk, state_value) \ do { (tsk)->state = (state_value); } while (0) @@ -533,8 +532,8 @@ extern unsigned long prof_shift; #define CURRENT_TIME (xtime.tv_sec) -extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode)); -extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode)); +extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, unsigned int wq_mode)); +extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, unsigned int wq_mode)); extern void FASTCALL(sleep_on(wait_queue_head_t *q)); extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q, signed long timeout)); @@ -543,12 +542,12 @@ extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long timeout)); extern void FASTCALL(wake_up_process(struct task_struct * tsk)); -#define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE) -#define wake_up_all(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE) -#define wake_up_sync(x) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE) -#define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE) -#define wake_up_interruptible_all(x) __wake_up((x),TASK_INTERRUPTIBLE) -#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE) +#define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,WQ_FLAG_EXCLUSIVE) +#define wake_up_all(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,0) +#define wake_up_sync(x) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,WQ_FLAG_EXCLUSIVE) +#define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE,WQ_FLAG_EXCLUSIVE) +#define wake_up_interruptible_all(x) __wake_up((x),TASK_INTERRUPTIBLE,0) +#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE,WQ_FLAG_EXCLUSIVE) extern int in_group_p(gid_t); extern int in_egroup_p(gid_t); diff --git a/include/linux/sockios.h b/include/linux/sockios.h index e9fd9e275..33ffddc50 100644 --- a/include/linux/sockios.h +++ b/include/linux/sockios.h @@ -75,6 +75,7 @@ #define SIOCGIFDIVERT 0x8944 /* Frame diversion support */ #define SIOCSIFDIVERT 0x8945 /* Set frame diversion options */ +#define SIOCETHTOOL 0x8946 /* Ethtool interface */ /* ARP cache control calls. */ /* 0x8950 - 0x8952 * obsolete calls, don't re-use */ diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h index ca8ad780d..c7be4cc54 100644 --- a/include/linux/soundcard.h +++ b/include/linux/soundcard.h @@ -76,8 +76,8 @@ */ #ifndef _SIOWR -#if defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__INCioctlh) && !defined(__Lynx__))) -/* Use already defined ioctl defines if they exist (except with Sun) */ +#if defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__sparc__) && !defined(__INCioctlh) && !defined(__Lynx__))) +/* Use already defined ioctl defines if they exist (except with Sun or Sparc) */ #define SIOCPARM_MASK IOCPARM_MASK #define SIOC_VOID IOC_VOID #define SIOC_OUT IOC_OUT @@ -179,7 +179,7 @@ typedef struct seq_event_rec { * Some big endian/little endian handling macros */ -#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(HPPA) || defined(PPC) +#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(__sparc__) || defined(HPPA) || defined(PPC) /* Big endian machines */ # define _PATCHKEY(id) (0xfd00|id) # define AFMT_S16_NE AFMT_S16_BE diff --git a/include/linux/usb.h b/include/linux/usb.h index 428866672..2828238ac 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -350,7 +350,11 @@ struct usb_device_id { struct usb_driver { const char *name; - void * (*probe)(struct usb_device *, unsigned int); + void *(*probe)( + struct usb_device *dev, /* the device */ + unsigned intf, /* what interface */ + const struct usb_device_id *id /* from id_table */ + ); void (*disconnect)(struct usb_device *, void *); struct list_head driver_list; @@ -367,11 +371,6 @@ struct usb_driver { * binding policy can be driven from user mode too */ const struct usb_device_id *id_table; - void *(*bind)( - struct usb_device *dev, /* the device */ - unsigned intf, /* what interface */ - const struct usb_device_id *id /* from id_table */ - ); /* suspend before the bus suspends; * disconnect or resume when the bus resumes */ @@ -601,6 +600,9 @@ extern void usb_scan_devices(void); extern void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv); extern int usb_interface_claimed(struct usb_interface *iface); extern void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface); +const struct usb_device_id *usb_match_id(struct usb_device *dev, + struct usb_interface *interface, + const struct usb_device_id *id); extern struct usb_bus *usb_alloc_bus(struct usb_operations *); extern void usb_free_bus(struct usb_bus *); diff --git a/include/linux/wait.h b/include/linux/wait.h index 8629f3241..25414d144 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -44,7 +44,8 @@ extern int printk(const char *fmt, ...); #endif struct __wait_queue { - unsigned int compiler_warning; + unsigned int flags; +#define WQ_FLAG_EXCLUSIVE 0x01 struct task_struct * task; struct list_head task_list; #if WAITQUEUE_DEBUG @@ -109,7 +110,7 @@ typedef struct __wait_queue_head wait_queue_head_t; #endif #define __WAITQUEUE_INITIALIZER(name,task) \ - { 0x1234567, task, { NULL, NULL } __WAITQUEUE_DEBUG_INIT(name)} + { 0x0, task, { NULL, NULL } __WAITQUEUE_DEBUG_INIT(name)} #define DECLARE_WAITQUEUE(name,task) \ wait_queue_t name = __WAITQUEUE_INITIALIZER(name,task) diff --git a/include/net/ax25.h b/include/net/ax25.h index 50d4aa889..525786901 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -159,15 +159,13 @@ typedef struct { unsigned short slave_timeout; /* when? */ } ax25_dama_info; -#ifndef _LINUX_SYSCTL_H -#include -#endif +struct ctl_table; typedef struct ax25_dev { struct ax25_dev *next; - struct net_device *dev; - struct net_device *forward; - struct ctl_table systable[AX25_MAX_VALUES+1]; + struct net_device *dev; + struct net_device *forward; + struct ctl_table *systable; int values[AX25_MAX_VALUES]; #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER) ax25_dama_info dama; diff --git a/include/net/irda/discovery.h b/include/net/irda/discovery.h index 90b8abd41..dccf1246c 100644 --- a/include/net/irda/discovery.h +++ b/include/net/irda/discovery.h @@ -44,8 +44,8 @@ /* * The DISCOVERY structure is used for both discovery requests and responses */ -typedef struct { - queue_t q; /* Must be first! */ +typedef struct discovery_t { + irda_queue_t q; /* Must be first! */ __u32 saddr; /* Which link the device was discovered */ __u32 daddr; /* Remote device address */ @@ -59,10 +59,12 @@ typedef struct { int gen_addr_bit; /* Need to generate a new device address? */ int nslots; /* Number of slots to use when discovering */ unsigned long timestamp; /* Time discovered */ + unsigned long first_timestamp; /* First time discovered */ } discovery_t; void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *discovery); void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log); void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force); +struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, __u16 mask); #endif diff --git a/include/net/irda/ircomm_core.h b/include/net/irda/ircomm_core.h index b555b37e2..3e891c201 100644 --- a/include/net/irda/ircomm_core.h +++ b/include/net/irda/ircomm_core.h @@ -53,7 +53,7 @@ typedef struct { } call_t; struct ircomm_cb { - queue_t queue; + irda_queue_t queue; magic_t magic; notify_t notify; diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 3946ebb98..d66686510 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h @@ -48,7 +48,7 @@ * IrCOMM TTY driver state */ struct ircomm_tty_cb { - queue_t queue; /* Must be first */ + irda_queue_t queue; /* Must be first */ magic_t magic; int state; /* Connect state */ diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index 3bb5e4e77..8bdfee75a 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -110,8 +110,14 @@ if(!(expr)) { \ typedef enum { FLOW_STOP, FLOW_START } LOCAL_FLOW; +/* A few forward declarations (to make compiler happy) */ +struct tsap_cb; /* in */ +struct lsap_cb; /* in */ +struct iriap_cb; /* in */ +struct ias_value; /* in */ +struct discovery_t; /* in */ + /* IrDA Socket */ -struct tsap_cb; struct irda_sock { __u32 saddr; /* my local address */ __u32 daddr; /* peer address */ @@ -137,14 +143,18 @@ struct irda_sock { struct ias_object *ias_obj; /* Our service name + lsap in IAS */ struct iriap_cb *iriap; /* Used to query remote IAS */ - struct ias_value *ias_result; /* Used by getsockopt(IRLMP_IAS_QUERY) */ + struct ias_value *ias_result; /* Result of remote IAS query */ + + hashbin_t *cachelog; /* Result of discovery query */ + struct discovery_t *cachediscovery; /* Result of selective discovery query */ int nslots; /* Number of slots to use for discovery */ int errno; /* status of the IAS query */ struct sock *sk; - wait_queue_head_t ias_wait; /* Wait for LM-IAS answer */ + wait_queue_head_t query_wait; /* Wait for the answer to a query */ + struct timer_list watchdog; /* Timeout for discovery */ LOCAL_FLOW tx_flow; LOCAL_FLOW rx_flow; @@ -166,12 +176,14 @@ typedef union { * (must not exceed 48 bytes, check with struct sk_buff) */ struct irda_skb_cb { - magic_t magic; /* Be sure that we can trust the information */ - __u32 speed; /* The Speed this frame should be sent with */ - __u16 mtt; /* Minimum turn around time */ - int xbofs; /* Number of xbofs required, used by SIR mode */ - __u8 line; /* Used by IrCOMM in IrLPT mode */ - void (*destructor)(struct sk_buff *skb); /* Used for flow control */ + magic_t magic; /* Be sure that we can trust the information */ + __u32 speed; /* The Speed this frame should be sent with */ + __u16 mtt; /* Minimum turn around time */ + __u16 xbofs; /* Number of xbofs required, used by SIR mode */ + void *context; /* May be used by drivers */ + void (*destructor)(struct sk_buff *skb); /* Used for flow control */ + __u16 xbofs_delay; /* Number of xbofs used for generating the mtt */ + __u8 line; /* Used by IrCOMM in IrLPT mode */ }; /* Misc status information */ @@ -232,6 +244,8 @@ typedef struct { void (*disconnect_indication)(void *instance, void *sap, LM_REASON reason, struct sk_buff *); void (*flow_indication)(void *instance, void *sap, LOCAL_FLOW flow); + void (*status_indication)(void *instance, + LINK_STATUS link, LOCK_STATUS lock); void *instance; /* Layer instance pointer */ char name[16]; /* Name of layer */ } notify_t; diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h index d6733d60b..ac66f61bd 100644 --- a/include/net/irda/irda_device.h +++ b/include/net/irda/irda_device.h @@ -79,7 +79,7 @@ struct irda_task; typedef int (*IRDA_TASK_CALLBACK) (struct irda_task *task); struct irda_task { - queue_t q; + irda_queue_t q; magic_t magic; IRDA_TASK_STATE state; @@ -111,7 +111,7 @@ typedef struct { /* Dongle registration info */ struct dongle_reg { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ IRDA_DONGLE type; void (*open)(dongle_t *dongle, struct qos_info *qos); diff --git a/include/net/irda/iriap.h b/include/net/irda/iriap.h index cd0dff5a9..8aed55b1c 100644 --- a/include/net/irda/iriap.h +++ b/include/net/irda/iriap.h @@ -58,7 +58,7 @@ typedef void (*CONFIRM_CALLBACK)(int result, __u16 obj_id, struct ias_value *value, void *priv); struct iriap_cb { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ magic_t magic; /* Magic cookie */ int mode; /* Client or server */ diff --git a/include/net/irda/irias_object.h b/include/net/irda/irias_object.h index cfa8e28ed..ff6b0b7b9 100644 --- a/include/net/irda/irias_object.h +++ b/include/net/irda/irias_object.h @@ -34,11 +34,15 @@ #define IAS_OCT_SEQ 2 #define IAS_STRING 3 +/* Object ownership of attributes (user or kernel) */ +#define IAS_KERNEL_ATTR 0 +#define IAS_USER_ATTR 1 + /* * LM-IAS Object */ struct ias_object { - queue_t q; /* Must be first! */ + irda_queue_t q; /* Must be first! */ magic_t magic; char *name; @@ -51,6 +55,7 @@ struct ias_object { */ struct ias_value { __u8 type; /* Value description */ + __u8 owner; /* Managed from user/kernel space */ int charset; /* Only used by string type */ int len; @@ -66,7 +71,7 @@ struct ias_value { * Attributes used by LM-IAS objects */ struct ias_attrib { - queue_t q; /* Must be first! */ + irda_queue_t q; /* Must be first! */ int magic; char *name; /* Attribute name */ @@ -78,12 +83,15 @@ char *strdup(char *str); struct ias_object *irias_new_object(char *name, int id); void irias_insert_object(struct ias_object *obj); int irias_delete_object(struct ias_object *obj); +int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib); void __irias_delete_object(struct ias_object *obj); -void irias_add_integer_attrib(struct ias_object *obj, char *name, int value); -void irias_add_string_attrib(struct ias_object *obj, char *name, char *value); +void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, + int user); +void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, + int user); void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, - int len); + int len, int user); int irias_object_change_attribute(char *obj_name, char *attrib_name, struct ias_value *new_value); struct ias_object *irias_find_object(char *name); diff --git a/include/net/irda/irlan_client.h b/include/net/irda/irlan_client.h index 62ea6157a..2aab19e90 100644 --- a/include/net/irda/irlan_client.h +++ b/include/net/irda/irlan_client.h @@ -34,7 +34,7 @@ #include void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout); -void irlan_client_discovery_indication(discovery_t *); +void irlan_client_discovery_indication(discovery_t *, void *); void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr); void irlan_client_open_ctrl_tsap( struct irlan_cb *self); diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h index 9ed6a9c36..02ecaf8e3 100644 --- a/include/net/irda/irlan_common.h +++ b/include/net/irda/irlan_common.h @@ -161,28 +161,26 @@ struct irlan_provider_cb { * IrLAN control block */ struct irlan_cb { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ int magic; struct net_device dev; /* Ethernet device structure*/ struct net_device_stats stats; - __u32 saddr; /* Source device address */ - __u32 daddr; /* Destination device address */ - int netdev_registered; - int notify_irmanager; + __u32 saddr; /* Source device address */ + __u32 daddr; /* Destination device address */ + int disconnect_reason; /* Why we got disconnected */ - int media; /* Media type */ - __u8 version[2]; /* IrLAN version */ + int media; /* Media type */ + __u8 version[2]; /* IrLAN version */ - struct tsap_cb *tsap_data; + struct tsap_cb *tsap_data; /* Data TSAP */ - int master; /* Master instance? */ - int use_udata; /* Use Unit Data transfers */ + int use_udata; /* Use Unit Data transfers */ - __u8 stsap_sel_data; /* Source data TSAP selector */ - __u8 dtsap_sel_data; /* Destination data TSAP selector */ - __u8 dtsap_sel_ctrl; /* Destination ctrl TSAP selector */ + __u8 stsap_sel_data; /* Source data TSAP selector */ + __u8 dtsap_sel_data; /* Destination data TSAP selector */ + __u8 dtsap_sel_ctrl; /* Destination ctrl TSAP selector */ struct irlan_client_cb client; /* Client specific fields */ struct irlan_provider_cb provider; /* Provider specific fields */ @@ -190,10 +188,11 @@ struct irlan_cb { __u32 max_sdu_size; __u8 max_header_size; + wait_queue_head_t open_wait; struct timer_list watchdog_timer; }; -struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev); +struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr); void irlan_close(struct irlan_cb *self); void irlan_close_tsaps(struct irlan_cb *self); void irlan_mod_inc_use_count(void); diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h index 36c1c03fd..3c1b95f50 100644 --- a/include/net/irda/irlap.h +++ b/include/net/irda/irlap.h @@ -81,7 +81,7 @@ #define irda_incomp (*self->decompressor.cp->incomp) struct irda_compressor { - queue_t q; + irda_queue_t q; struct compressor *cp; void *state; /* Not used by IrDA */ @@ -90,7 +90,7 @@ struct irda_compressor { /* Main structure of IrLAP */ struct irlap_cb { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ magic_t magic; struct net_device *netdev; @@ -214,7 +214,7 @@ void irlap_unitdata_indication(struct irlap_cb *, struct sk_buff *); void irlap_disconnect_request(struct irlap_cb *); void irlap_disconnect_indication(struct irlap_cb *, LAP_REASON reason); -void irlap_status_indication(int quality_of_link); +void irlap_status_indication(struct irlap_cb *, int quality_of_link); void irlap_test_request(__u8 *info, int len); diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h index 9c9fab54d..0fe946693 100644 --- a/include/net/irda/irlmp.h +++ b/include/net/irda/irlmp.h @@ -71,22 +71,23 @@ typedef enum { S_END, } SERVICE; -typedef void (*DISCOVERY_CALLBACK1) (discovery_t *); -typedef void (*DISCOVERY_CALLBACK2) (hashbin_t *); +typedef void (*DISCOVERY_CALLBACK1) (discovery_t *, void *); +typedef void (*DISCOVERY_CALLBACK2) (hashbin_t *, void *); typedef struct { - queue_t queue; /* Must be first */ + irda_queue_t queue; /* Must be first */ __u16 hints; /* Hint bits */ } irlmp_service_t; typedef struct { - queue_t queue; /* Must be first */ + irda_queue_t queue; /* Must be first */ __u16 hint_mask; - DISCOVERY_CALLBACK1 callback1; - DISCOVERY_CALLBACK2 callback2; + DISCOVERY_CALLBACK1 disco_callback; /* Selective discovery */ + DISCOVERY_CALLBACK1 expir_callback; /* Selective expiration */ + void *priv; /* Used to identify client */ } irlmp_client_t; struct lap_cb; /* Forward decl. */ @@ -95,7 +96,7 @@ struct lap_cb; /* Forward decl. */ * Information about each logical LSAP connection */ struct lsap_cb { - queue_t queue; /* Must be first */ + irda_queue_t queue; /* Must be first */ magic_t magic; int connected; @@ -121,7 +122,7 @@ struct lsap_cb { * Information about each registred IrLAP layer */ struct lap_cb { - queue_t queue; /* Must be first */ + irda_queue_t queue; /* Must be first */ magic_t magic; int reason; /* LAP disconnect reason */ @@ -174,10 +175,10 @@ struct irlmp_cb { hashbin_t *clients; hashbin_t *services; - hashbin_t *cachelog; - int running; + hashbin_t *cachelog; /* Current discovery log */ + spinlock_t log_lock; /* discovery log spinlock */ - spinlock_t lock; + int running; __u16_host_order hints; /* Hint bits */ }; @@ -191,11 +192,12 @@ void irlmp_close_lsap( struct lsap_cb *self); __u16 irlmp_service_to_hint(int service); __u32 irlmp_register_service(__u16 hints); int irlmp_unregister_service(__u32 handle); -__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 callback1, - DISCOVERY_CALLBACK2 callback2); +__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, + DISCOVERY_CALLBACK1 expir_clb, void *priv); int irlmp_unregister_client(__u32 handle); int irlmp_update_client(__u32 handle, __u16 hint_mask, - DISCOVERY_CALLBACK1, DISCOVERY_CALLBACK2); + DISCOVERY_CALLBACK1 disco_clb, + DISCOVERY_CALLBACK1 expir_clb, void *priv); void irlmp_register_link(struct irlap_cb *, __u32 saddr, notify_t *); void irlmp_unregister_link(__u32 saddr); @@ -214,8 +216,10 @@ int irlmp_disconnect_request(struct lsap_cb *, struct sk_buff *userdata); void irlmp_discovery_confirm(hashbin_t *discovery_log); void irlmp_discovery_request(int nslots); +struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask); void irlmp_do_discovery(int nslots); discovery_t *irlmp_get_discovery_response(void); +void irlmp_discovery_expiry(discovery_t *expiry); int irlmp_data_request(struct lsap_cb *, struct sk_buff *); void irlmp_data_indication(struct lsap_cb *, struct sk_buff *); @@ -229,7 +233,7 @@ void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *); #endif /* CONFIG_IRDA_ULTRA */ void irlmp_status_request(void); -void irlmp_status_indication(LINK_STATUS link, LOCK_STATUS lock); +void irlmp_status_indication(struct lap_cb *, LINK_STATUS link, LOCK_STATUS lock); int irlmp_slsap_inuse(__u8 slsap); __u8 irlmp_find_free_slsap(void); @@ -248,9 +252,12 @@ static inline hashbin_t *irlmp_get_cachelog(void) { return irlmp->cachelog; } static inline int irlmp_get_lap_tx_queue_len(struct lsap_cb *self) { - ASSERT(self != NULL, return 0;); - ASSERT(self->lap != NULL, return 0;); - ASSERT(self->lap->irlap != NULL, return 0;); + if (self == NULL) + return 0; + if (self->lap == NULL) + return 0; + if (self->lap->irlap == NULL) + return 0; return IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap); } diff --git a/include/net/irda/irmod.h b/include/net/irda/irmod.h index ae61c8682..f2ccb854c 100644 --- a/include/net/irda/irmod.h +++ b/include/net/irda/irmod.h @@ -69,7 +69,7 @@ typedef void (*TODO_CALLBACK)( void *self, __u32 param); * addtional information */ struct irda_event { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ struct irmanager_event event; }; @@ -78,7 +78,7 @@ struct irda_event { * Funtions with needs to be called with a process context */ struct irda_todo { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ void *self; TODO_CALLBACK callback; @@ -94,8 +94,8 @@ struct irda_cb { int in_use; - queue_t *event_queue; /* Events queued for the irmanager */ - queue_t *todo_queue; /* Todo list */ + irda_queue_t *event_queue; /* Events queued for the irmanager */ + irda_queue_t *todo_queue; /* Todo list */ }; int irmod_init_module(void); diff --git a/include/net/irda/irqueue.h b/include/net/irda/irqueue.h index 3b5bfd492..f7c1ba659 100644 --- a/include/net/irda/irqueue.h +++ b/include/net/irda/irqueue.h @@ -30,8 +30,8 @@ #include #include -#ifndef QUEUE_H -#define QUEUE_H +#ifndef IRDA_QUEUE_H +#define IRDA_QUEUE_H #define NAME_SIZE 32 @@ -62,39 +62,40 @@ typedef void (*FREE_FUNC)(void *arg); */ #define GET_HASHBIN(x) ( x & HASHBIN_MASK ) -struct irqueue { - struct irqueue *q_next; - struct irqueue *q_prev; +struct irda_queue { + struct irda_queue *q_next; + struct irda_queue *q_prev; char q_name[NAME_SIZE]; __u32 q_hash; }; -typedef struct irqueue queue_t; +typedef struct irda_queue irda_queue_t; typedef struct hashbin_t { __u32 magic; int hb_type; int hb_size; spinlock_t hb_mutex[HASHBIN_SIZE] ALIGN; - queue_t *hb_queue[HASHBIN_SIZE] ALIGN; + irda_queue_t *hb_queue[HASHBIN_SIZE] ALIGN; - queue_t* hb_current; + irda_queue_t* hb_current; } hashbin_t; hashbin_t *hashbin_new(int type); int hashbin_delete(hashbin_t* hashbin, FREE_FUNC func); int hashbin_clear(hashbin_t* hashbin, FREE_FUNC free_func); -void hashbin_insert(hashbin_t* hashbin, queue_t* entry, __u32 hashv, +void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, char* name); void* hashbin_find(hashbin_t* hashbin, __u32 hashv, char* name); void* hashbin_remove(hashbin_t* hashbin, __u32 hashv, char* name); void* hashbin_remove_first(hashbin_t *hashbin); -queue_t *hashbin_get_first(hashbin_t *hashbin); -queue_t *hashbin_get_next(hashbin_t *hashbin); +void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry); +irda_queue_t *hashbin_get_first(hashbin_t *hashbin); +irda_queue_t *hashbin_get_next(hashbin_t *hashbin); -void enqueue_last(queue_t **queue, queue_t* element); -void enqueue_first(queue_t **queue, queue_t* element); -queue_t *dequeue_first(queue_t **queue); +void enqueue_last(irda_queue_t **queue, irda_queue_t* element); +void enqueue_first(irda_queue_t **queue, irda_queue_t* element); +irda_queue_t *dequeue_first(irda_queue_t **queue); #define HASHBIN_GET_SIZE(hashbin) hashbin->hb_size diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index 2b2547fa2..a3193d758 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -63,7 +63,7 @@ * connection. */ struct tsap_cb { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ magic_t magic; /* Just in case */ __u8 stsap_sel; /* Source TSAP */ @@ -129,6 +129,8 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb, int priority); void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow); +void irttp_status_indication(void *instance, + LINK_STATUS link, LOCK_STATUS lock); struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance); static __inline __u32 irttp_get_saddr(struct tsap_cb *self) diff --git a/include/net/irda/irtty.h b/include/net/irda/irtty.h index f96976bc3..c6c54e1ad 100644 --- a/include/net/irda/irtty.h +++ b/include/net/irda/irtty.h @@ -45,7 +45,7 @@ struct irtty_info { #define IRTTY_IOC_MAXNR 2 struct irtty_cb { - queue_t q; /* Must be first */ + irda_queue_t q; /* Must be first */ magic_t magic; struct net_device *netdev; /* Yes! we are some kind of netdevice */ diff --git a/include/net/irda/qos.h b/include/net/irda/qos.h index e88f0a3bd..d95f7ead9 100644 --- a/include/net/irda/qos.h +++ b/include/net/irda/qos.h @@ -86,6 +86,9 @@ struct qos_info { #endif }; +extern int sysctl_max_baud_rate; +extern int sysctl_max_inactive_time; + extern __u32 baud_rates[]; extern __u32 data_sizes[]; extern __u32 min_turn_times[]; @@ -100,15 +103,7 @@ __u32 irlap_requested_line_capacity(struct qos_info *qos); __u32 irlap_min_turn_time_in_bytes(__u32 speed, __u32 min_turn_time); int msb_index(__u16 byte); -int value_index(__u32 value, __u32 *array); -__u32 byte_value(__u8 byte, __u32 *array); -__u32 index_value(int index, __u32 *array); - void irda_qos_bits_to_value(struct qos_info *qos); #endif - - - - diff --git a/include/net/irda/timer.h b/include/net/irda/timer.h index af843bee3..f2cc642ec 100644 --- a/include/net/irda/timer.h +++ b/include/net/irda/timer.h @@ -76,12 +76,14 @@ inline void irlap_start_wd_timer(struct irlap_cb *self, int timeout); inline void irlap_start_backoff_timer(struct irlap_cb *self, int timeout); void irlap_start_mbusy_timer(struct irlap_cb *); +void irlap_stop_mbusy_timer(struct irlap_cb *); struct lsap_cb; struct lap_cb; inline void irlmp_start_watchdog_timer(struct lsap_cb *, int timeout); inline void irlmp_start_discovery_timer(struct irlmp_cb *, int timeout); inline void irlmp_start_idle_timer(struct lap_cb *, int timeout); +inline void irlmp_stop_idle_timer(struct lap_cb *self); #endif diff --git a/kernel/fork.c b/kernel/fork.c index f436a6322..13519c5f0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -48,6 +48,7 @@ void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait) unsigned long flags; wq_write_lock_irqsave(&q->lock, flags); + wait->flags |= WQ_FLAG_EXCLUSIVE; __add_wait_queue_tail(q, wait); wq_write_unlock_irqrestore(&q->lock, flags); } diff --git a/kernel/sched.c b/kernel/sched.c index 80643fdf4..f54480e5e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -535,7 +535,7 @@ handle_softirq_back: goto move_rr_last; move_rr_back: - switch (prev->state & ~TASK_EXCLUSIVE) { + switch (prev->state) { case TASK_INTERRUPTIBLE: if (signal_pending(prev)) { prev->state = TASK_RUNNING; @@ -694,7 +694,7 @@ scheduling_in_interrupt: } static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, - const int sync) + unsigned int wq_mode, const int sync) { struct list_head *tmp, *head; struct task_struct *p, *best_exclusive; @@ -730,7 +730,7 @@ static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, #endif p = curr->task; state = p->state; - if (state & (mode & ~TASK_EXCLUSIVE)) { + if (state & mode) { #if WAITQUEUE_DEBUG curr->__waker = (long)__builtin_return_address(0); #endif @@ -739,7 +739,7 @@ static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, * prefer processes which are affine to this * CPU. */ - if (irq && (state & mode & TASK_EXCLUSIVE)) { + if (irq && (curr->flags & wq_mode & WQ_FLAG_EXCLUSIVE)) { if (!best_exclusive) best_exclusive = p; if (p->processor == best_cpu) { @@ -751,7 +751,7 @@ static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, wake_up_process_synchronous(p); else wake_up_process(p); - if (state & mode & TASK_EXCLUSIVE) + if (curr->flags & wq_mode & WQ_FLAG_EXCLUSIVE) break; } } @@ -767,14 +767,14 @@ out: return; } -void __wake_up(wait_queue_head_t *q, unsigned int mode) +void __wake_up(wait_queue_head_t *q, unsigned int mode, unsigned int wq_mode) { - __wake_up_common(q, mode, 0); + __wake_up_common(q, mode, wq_mode, 0); } -void __wake_up_sync(wait_queue_head_t *q, unsigned int mode) +void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, unsigned int wq_mode) { - __wake_up_common(q, mode, 1); + __wake_up_common(q, mode, wq_mode, 1); } #define SLEEP_ON_VAR \ diff --git a/mm/filemap.c b/mm/filemap.c index 98c97b787..55d3fcfe3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1813,11 +1813,13 @@ static long madvise_fixup_start(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = end; - insert_vm_struct(current->mm, n); + __insert_vm_struct(current->mm, n); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } @@ -1837,10 +1839,12 @@ static long madvise_fixup_end(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_end = start; - insert_vm_struct(current->mm, n); + __insert_vm_struct(current->mm, n); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } @@ -1870,15 +1874,17 @@ static long madvise_fixup_middle(struct vm_area_struct * vma, vma->vm_ops->open(left); vma->vm_ops->open(right); } + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = start; vma->vm_end = end; setup_read_behavior(vma, behavior); vma->vm_raend = 0; - insert_vm_struct(current->mm, left); - insert_vm_struct(current->mm, right); + __insert_vm_struct(current->mm, left); + __insert_vm_struct(current->mm, right); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } diff --git a/mm/highmem.c b/mm/highmem.c index 08f20755e..5e8ebde4b 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -307,8 +307,6 @@ repeat_bh: bh = kmem_cache_alloc(bh_cachep, SLAB_BUFFER); if (!bh) { wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ - current->policy |= SCHED_YIELD; - schedule(); goto repeat_bh; } /* @@ -321,8 +319,6 @@ repeat_page: page = alloc_page(GFP_BUFFER); if (!page) { wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ - current->policy |= SCHED_YIELD; - schedule(); goto repeat_page; } set_bh_page(bh, page, 0); diff --git a/mm/mlock.c b/mm/mlock.c index f684a3c60..551d61d39 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -36,11 +36,13 @@ static inline int mlock_fixup_start(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = end; - insert_vm_struct(current->mm, n); + __insert_vm_struct(current->mm, n); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } @@ -61,10 +63,12 @@ static inline int mlock_fixup_end(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_end = start; - insert_vm_struct(current->mm, n); + __insert_vm_struct(current->mm, n); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } @@ -96,15 +100,17 @@ static inline int mlock_fixup_middle(struct vm_area_struct * vma, vma->vm_ops->open(left); vma->vm_ops->open(right); } + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = start; vma->vm_end = end; vma->vm_flags = newflags; vma->vm_raend = 0; - insert_vm_struct(current->mm, left); - insert_vm_struct(current->mm, right); + __insert_vm_struct(current->mm, left); + __insert_vm_struct(current->mm, right); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } diff --git a/mm/mmap.c b/mm/mmap.c index c50de6ed8..da649f2a2 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -67,7 +67,7 @@ int vm_enough_memory(long pages) } /* Remove one vm structure from the inode's i_mapping address space. */ -static inline void remove_shared_vm_struct(struct vm_area_struct *vma) +static inline void __remove_shared_vm_struct(struct vm_area_struct *vma) { struct file * file = vma->vm_file; @@ -75,14 +75,41 @@ static inline void remove_shared_vm_struct(struct vm_area_struct *vma) struct inode *inode = file->f_dentry->d_inode; if (vma->vm_flags & VM_DENYWRITE) atomic_inc(&inode->i_writecount); - spin_lock(&inode->i_mapping->i_shared_lock); if(vma->vm_next_share) vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share; *vma->vm_pprev_share = vma->vm_next_share; - spin_unlock(&inode->i_mapping->i_shared_lock); } } +static inline void remove_shared_vm_struct(struct vm_area_struct *vma) +{ + lock_vma_mappings(vma); + __remove_shared_vm_struct(vma); + unlock_vma_mappings(vma); +} + +void lock_vma_mappings(struct vm_area_struct *vma) +{ + struct address_space *mapping; + + mapping = NULL; + if (vma->vm_file) + mapping = vma->vm_file->f_dentry->d_inode->i_mapping; + if (mapping) + spin_lock(&mapping->i_shared_lock); +} + +void unlock_vma_mappings(struct vm_area_struct *vma) +{ + struct address_space *mapping; + + mapping = NULL; + if (vma->vm_file) + mapping = vma->vm_file->f_dentry->d_inode->i_mapping; + if (mapping) + spin_unlock(&mapping->i_shared_lock); +} + /* * sys_brk() for the most part doesn't need the global kernel * lock, except when an application is doing something nasty @@ -316,13 +343,22 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned lon * after the call. Save the values we need now ... */ flags = vma->vm_flags; - addr = vma->vm_start; /* can addr have changed?? */ + + /* Can addr have changed?? + * + * Answer: Yes, several device drivers can do it in their + * f_op->mmap method. -DaveM + */ + addr = vma->vm_start; + + lock_vma_mappings(vma); spin_lock(&mm->page_table_lock); - insert_vm_struct(mm, vma); + __insert_vm_struct(mm, vma); if (correct_wcount) atomic_inc(&file->f_dentry->d_inode->i_writecount); merge_segments(mm, vma->vm_start, vma->vm_end); spin_unlock(&mm->page_table_lock); + unlock_vma_mappings(vma); mm->total_vm += len >> PAGE_SHIFT; if (flags & VM_LOCKED) { @@ -534,10 +570,12 @@ static struct vm_area_struct * unmap_fixup(struct mm_struct *mm, /* Work out to one of the ends. */ if (end == area->vm_end) { area->vm_end = addr; + lock_vma_mappings(area); spin_lock(&mm->page_table_lock); } else if (addr == area->vm_start) { area->vm_pgoff += (end - area->vm_start) >> PAGE_SHIFT; area->vm_start = end; + lock_vma_mappings(area); spin_lock(&mm->page_table_lock); } else { /* Unmapping a hole: area->vm_start < addr <= end < area->vm_end */ @@ -560,12 +598,18 @@ static struct vm_area_struct * unmap_fixup(struct mm_struct *mm, if (mpnt->vm_ops && mpnt->vm_ops->open) mpnt->vm_ops->open(mpnt); area->vm_end = addr; /* Truncate area */ + + /* Because mpnt->vm_file == area->vm_file this locks + * things correctly. + */ + lock_vma_mappings(area); spin_lock(&mm->page_table_lock); - insert_vm_struct(mm, mpnt); + __insert_vm_struct(mm, mpnt); } - insert_vm_struct(mm, area); + __insert_vm_struct(mm, area); spin_unlock(&mm->page_table_lock); + unlock_vma_mappings(area); return extra; } @@ -811,10 +855,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len) flags = vma->vm_flags; addr = vma->vm_start; + lock_vma_mappings(vma); spin_lock(&mm->page_table_lock); - insert_vm_struct(mm, vma); + __insert_vm_struct(mm, vma); merge_segments(mm, vma->vm_start, vma->vm_end); spin_unlock(&mm->page_table_lock); + unlock_vma_mappings(vma); mm->total_vm += len >> PAGE_SHIFT; if (flags & VM_LOCKED) { @@ -877,9 +923,10 @@ void exit_mmap(struct mm_struct * mm) } /* Insert vm structure into process list sorted by address - * and into the inode's i_mmap ring. + * and into the inode's i_mmap ring. If vm_file is non-NULL + * then the i_shared_lock must be held here. */ -void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) +void __insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) { struct vm_area_struct **pprev; struct file * file; @@ -916,15 +963,20 @@ void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) head = &mapping->i_mmap_shared; /* insert vmp into inode's share list */ - spin_lock(&mapping->i_shared_lock); if((vmp->vm_next_share = *head) != NULL) (*head)->vm_pprev_share = &vmp->vm_next_share; *head = vmp; vmp->vm_pprev_share = head; - spin_unlock(&mapping->i_shared_lock); } } +void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) +{ + lock_vma_mappings(vmp); + __insert_vm_struct(mm, vmp); + unlock_vma_mappings(vmp); +} + /* Merge the list of memory segments if possible. * Redundant vm_area_structs are freed. * This assumes that the list is ordered by address. @@ -986,11 +1038,13 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l mpnt->vm_pgoff += (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; mpnt->vm_start = mpnt->vm_end; spin_unlock(&mm->page_table_lock); + unlock_vma_mappings(mpnt); mpnt->vm_ops->close(mpnt); + lock_vma_mappings(mpnt); spin_lock(&mm->page_table_lock); } mm->map_count--; - remove_shared_vm_struct(mpnt); + __remove_shared_vm_struct(mpnt); if (mpnt->vm_file) fput(mpnt->vm_file); kmem_cache_free(vm_area_cachep, mpnt); diff --git a/mm/mprotect.c b/mm/mprotect.c index 7b61abb3e..64c178b31 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -118,11 +118,13 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = end; - insert_vm_struct(current->mm, n); + __insert_vm_struct(current->mm, n); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } @@ -145,10 +147,12 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_end = start; - insert_vm_struct(current->mm, n); + __insert_vm_struct(current->mm, n); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } @@ -179,6 +183,7 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma, vma->vm_ops->open(left); vma->vm_ops->open(right); } + lock_vma_mappings(vma); spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = start; @@ -186,9 +191,10 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma, vma->vm_flags = newflags; vma->vm_raend = 0; vma->vm_page_prot = prot; - insert_vm_struct(current->mm, left); - insert_vm_struct(current->mm, right); + __insert_vm_struct(current->mm, left); + __insert_vm_struct(current->mm, right); spin_unlock(&vma->vm_mm->page_table_lock); + unlock_vma_mappings(vma); return 0; } diff --git a/mm/mremap.c b/mm/mremap.c index 719ca1ec1..764cfabb8 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -141,10 +141,12 @@ static inline unsigned long move_vma(struct vm_area_struct * vma, get_file(new_vma->vm_file); if (new_vma->vm_ops && new_vma->vm_ops->open) new_vma->vm_ops->open(new_vma); + lock_vma_mappings(vma); spin_lock(¤t->mm->page_table_lock); - insert_vm_struct(current->mm, new_vma); + __insert_vm_struct(current->mm, new_vma); merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end); spin_unlock(¤t->mm->page_table_lock); + unlock_vma_mappings(vma); do_munmap(current->mm, addr, old_len); current->mm->total_vm += new_len >> PAGE_SHIFT; if (new_vma->vm_flags & VM_LOCKED) { diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 9882fe7cd..d49fab93a 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -156,7 +156,7 @@ void oom_kill(void) if (p == NULL) panic("Out of memory and no killable processes...\n"); - printk(KERN_ERR "Out of Memory: Killed process %d (%s).", p->pid, p->comm); + printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm); /* * We give our sacrificial lamb high priority and access to diff --git a/net/atm/pvc.c b/net/atm/pvc.c index 922039cb5..c47d6ca5c 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c @@ -130,7 +130,7 @@ static int __init atmpvc_init(void) error = sock_register(&pvc_family_ops); if (error < 0) { printk(KERN_ERR "ATMPVC: can't register (%d)",error); - return -EINVAL; + return error; } #ifdef CONFIG_ATM_CLIP atm_clip_init(); diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c index 2a88a9716..576744cea 100644 --- a/net/ax25/sysctl_net_ax25.c +++ b/net/ax25/sysctl_net_ax25.c @@ -114,15 +114,18 @@ void ax25_register_sysctl(void) memset(ax25_table, 0x00, ax25_table_size); for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) { + ctl_table *child = kmalloc(sizeof(ax25_param_table, GFP_ATOMIC); + if (!child) { + while (n--) + kfree(ax25_table[n].child); + kfree(ax25_table); + return; + } + memcpy(child, ax25_param_table, sizeof(ax25_param_table)); + ax25_table[n].child = ax25_dev->systable = child; ax25_table[n].ctl_name = n + 1; ax25_table[n].procname = ax25_dev->dev->name; - ax25_table[n].data = NULL; - ax25_table[n].maxlen = 0; ax25_table[n].mode = 0555; - ax25_table[n].child = ax25_dev->systable; - ax25_table[n].proc_handler = NULL; - - memcpy(ax25_dev->systable, ax25_param_table, sizeof(ax25_dev->systable)); #ifndef CONFIG_AX25_DAMA_SLAVE /* @@ -131,13 +134,13 @@ void ax25_register_sysctl(void) * AX.25 DAMA slave code, do we? */ - ax25_dev->systable[AX25_VALUES_DS_TIMEOUT].procname = NULL; + child[AX25_VALUES_DS_TIMEOUT].procname = NULL; #endif - ax25_dev->systable[AX25_MAX_VALUES].ctl_name = 0; /* just in case... */ + child[AX25_MAX_VALUES].ctl_name = 0; /* just in case... */ for (k = 0; k < AX25_MAX_VALUES; k++) - ax25_dev->systable[k].data = &ax25_dev->values[k]; + child[k].data = &ax25_dev->values[k]; n++; } @@ -149,9 +152,11 @@ void ax25_register_sysctl(void) void ax25_unregister_sysctl(void) { + ctl_table *p; unregister_sysctl_table(ax25_table_header); - kfree(ax25_table); - ax25_dir_table[0].child = NULL; + for (p = ax25_table; p->ctl_name; p++) + kfree(p->child); + kfree(ax25_table); } diff --git a/net/core/datagram.c b/net/core/datagram.c index 7f85645f0..0b865f6b9 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -66,7 +66,7 @@ static int wait_for_packet(struct sock * sk, int *err, long *timeo_p) DECLARE_WAITQUEUE(wait, current); - __set_current_state(TASK_INTERRUPTIBLE|TASK_EXCLUSIVE); + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue_exclusive(sk->sleep, &wait); /* Socket errors? */ diff --git a/net/core/dev.c b/net/core/dev.c index 17fae7a1e..491deb0d0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -93,6 +93,7 @@ #include #include #include +#include #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) #include /* Note : will define WIRELESS_EXT */ #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ @@ -666,9 +667,15 @@ int dev_open(struct net_device *dev) /* * Call device private open method */ - - if (dev->open) - ret = dev->open(dev); + if (try_inc_mod_count(dev->owner)) { + if (dev->open) { + ret = dev->open(dev); + if (ret != 0 && dev->owner) + __MOD_DEC_USE_COUNT(dev->owner); + } + } else { + ret = -ENODEV; + } /* * If it went open OK then: @@ -784,6 +791,12 @@ int dev_close(struct net_device *dev) */ notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); + /* + * Drop the module refcount + */ + if (dev->owner) + __MOD_DEC_USE_COUNT(dev->owner); + return(0); } @@ -2056,8 +2069,9 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) */ default: - if (cmd >= SIOCDEVPRIVATE && - cmd <= SIOCDEVPRIVATE + 15) { + if ((cmd >= SIOCDEVPRIVATE && + cmd <= SIOCDEVPRIVATE + 15) || + cmd == SIOCETHTOOL) { if (dev->do_ioctl) { if (!netif_device_present(dev)) return -ENODEV; @@ -2199,8 +2213,9 @@ int dev_ioctl(unsigned int cmd, void *arg) */ default: - if (cmd >= SIOCDEVPRIVATE && - cmd <= SIOCDEVPRIVATE + 15) { + if ((cmd >= SIOCDEVPRIVATE && + cmd <= SIOCDEVPRIVATE + 15) || + cmd == SIOCETHTOOL) { dev_load(ifr.ifr_name); rtnl_lock(); ret = dev_ifsioc(&ifr, cmd); diff --git a/net/core/sock.c b/net/core/sock.c index 8503e364f..7b9484437 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -7,7 +7,7 @@ * handler for protocols to use and generic option handler. * * - * Version: $Id: sock.c,v 1.100 2000/09/18 05:59:48 davem Exp $ + * Version: $Id: sock.c,v 1.101 2000/11/10 04:02:04 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -819,7 +819,7 @@ void __lock_sock(struct sock *sk) add_wait_queue_exclusive(&sk->lock.wq, &wait); for(;;) { - current->state = TASK_EXCLUSIVE | TASK_UNINTERRUPTIBLE; + current->state = TASK_UNINTERRUPTIBLE; spin_unlock_bh(&sk->lock.slock); schedule(); spin_lock_bh(&sk->lock.slock); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 584814ad8..3222d25d1 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -5,7 +5,7 @@ * * PF_INET protocol family socket handler. * - * Version: $Id: af_inet.c,v 1.121 2000/10/24 21:26:18 davem Exp $ + * Version: $Id: af_inet.c,v 1.123 2000/11/10 01:42:43 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0f97c2d27..6b254e2ad 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.176 2000/10/06 22:45:41 davem Exp $ + * Version: $Id: tcp.c,v 1.179 2000/11/10 04:02:04 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -2011,7 +2011,7 @@ static int wait_for_connect(struct sock * sk, long timeo) */ add_wait_queue_exclusive(sk->sleep, &wait); for (;;) { - current->state = TASK_EXCLUSIVE | TASK_INTERRUPTIBLE; + current->state = TASK_INTERRUPTIBLE; release_sock(sk); if (sk->tp_pinfo.af_tcp.accept_queue == NULL) timeo = schedule_timeout(timeo); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1a0f278b4..a72471f99 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.218 2000/10/18 18:04:22 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.219 2000/11/10 04:02:04 davem Exp $ * * IPv4 specific functions * @@ -301,7 +301,7 @@ void tcp_put_port(struct sock *sk) local_bh_enable(); } -/* This lock without TASK_EXCLUSIVE is good on UP and it can be very bad on SMP. +/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP. * Look, when several writers sleep and reader wakes them up, all but one * immediately hit write lock and grab all the cpus. Exclusive sleep solves * this, _but_ remember, it adds useless work on UP machines (wake up each @@ -317,7 +317,7 @@ void tcp_listen_wlock(void) add_wait_queue_exclusive(&tcp_lhash_wait, &wait); for (;;) { - set_current_state(TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE); + set_current_state(TASK_UNINTERRUPTIBLE); if (atomic_read(&tcp_lhash_users) == 0) break; write_unlock_bh(&tcp_lhash_lock); diff --git a/net/irda/Config.in b/net/irda/Config.in index 6f4f716f8..5ab40b985 100644 --- a/net/irda/Config.in +++ b/net/irda/Config.in @@ -11,6 +11,7 @@ if [ "$CONFIG_NET" != "n" ]; then if [ "$CONFIG_IRDA" != "n" ]; then comment 'IrDA protocols' source net/irda/irlan/Config.in + source net/irda/irnet/Config.in source net/irda/ircomm/Config.in bool ' Ultra (connectionless) protocol' CONFIG_IRDA_ULTRA bool ' IrDA protocol options' CONFIG_IRDA_OPTIONS diff --git a/net/irda/Makefile b/net/irda/Makefile index ac2bdc063..3ab07c88d 100644 --- a/net/irda/Makefile +++ b/net/irda/Makefile @@ -7,7 +7,7 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -ALL_SUB_DIRS := irlan ircomm compressors +ALL_SUB_DIRS := irlan irnet ircomm compressors SUB_DIRS := MOD_SUB_DIRS := OX_OBJS := @@ -17,7 +17,7 @@ O_OBJS := iriap.o iriap_event.o irlmp.o irlmp_event.o irlmp_frame.o \ irlap.o irlap_event.o irlap_frame.o timer.o qos.o irqueue.o \ irttp.o irda_device.o irias_object.o crc.o wrapper.o af_irda.o \ discovery.o parameters.o -OX_OBJS := irmod.o +OX_OBJS := irsyms.o ifeq ($(CONFIG_IRDA),m) M_OBJS := $(O_TARGET) @@ -44,6 +44,15 @@ else endif endif +ifeq ($(CONFIG_IRNET),y) +SUB_DIRS += irnet +O_OBJS += irnet/irnet.o +else + ifeq ($(CONFIG_IRNET),m) + MOD_SUB_DIRS += irnet + endif +endif + ifeq ($(CONFIG_IRDA_COMPRESSION),y) SUB_DIRS += compressors MOD_IN_SUB_DIRS += compressors diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 69db79a0e..e5504ee96 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -7,11 +7,11 @@ * Author: Dag Brattli * Created at: Sun May 31 10:12:43 1998 * Modified at: Sat Dec 25 21:10:23 1999 - * Modified by: Dag Brattli + * Modified by: Dag Brattli * Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc. * * Copyright (c) 1999 Dag Brattli - * Copyright (c) 1999 Jean Tourrilhes + * Copyright (c) 1999 Jean Tourrilhes * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -43,10 +43,11 @@ ********************************************************************/ #include -#include +#include #include #include #include +#include #include #include #include @@ -79,11 +80,12 @@ static struct proto_ops irda_ultra_ops; #define ULTRA_MAX_DATA 382 #endif /* CONFIG_IRDA_ULTRA */ -static hashbin_t *cachelog = NULL; -static DECLARE_WAIT_QUEUE_HEAD(discovery_wait); /* Wait for discovery */ - #define IRDA_MAX_HEADER (TTP_MAX_HEADER) +#ifdef CONFIG_IRDA_DEBUG +__u32 irda_debug = IRDA_DEBUG_LEVEL; +#endif + /* * Function irda_data_indication (instance, sap, skb) * @@ -117,7 +119,7 @@ static int irda_data_indication(void *instance, void *sap, struct sk_buff *skb) /* * Function irda_disconnect_indication (instance, sap, reason, skb) * - * Connection has been closed. Chech reason to find out why + * Connection has been closed. Check reason to find out why * */ static void irda_disconnect_indication(void *instance, void *sap, @@ -141,6 +143,27 @@ static void irda_disconnect_indication(void *instance, void *sap, sk->state_change(sk); sk->dead = 1; } + + /* Close our TSAP. + * If we leave it open, IrLMP put it back into the list of + * unconnected LSAPs. The problem is that any incomming request + * can then be matched to this socket (and it will be, because + * it is at the head of the list). This would prevent any + * listening socket waiting on the same TSAP to get those requests. + * Some apps forget to close sockets, or hang to it a bit too long, + * so we may stay in this dead state long enough to be noticed... + * Note : all socket function do check sk->state, so we are safe... + * Jean II + */ + irttp_close_tsap(self->tsap); + self->tsap = NULL; + + /* Note : once we are there, there is not much you want to do + * with the socket anymore, apart from closing it. + * For example, bind() and connect() won't reset sk->err, + * sk->shutdown and sk->dead to valid values... + * Jean II + */ } /* @@ -326,19 +349,19 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) /* * Function irda_getvalue_confirm (obj_id, value, priv) * - * Got answer from remote LM-IAS + * Got answer from remote LM-IAS, just pass object to requester... * + * Note : duplicate from above, but we need our own version that + * doesn't touch the dtsap_sel and save the full value structure... */ static void irda_getvalue_confirm(int result, __u16 obj_id, - struct ias_value *value, void *priv) + struct ias_value *value, void *priv) { struct irda_sock *self; IRDA_DEBUG(2, __FUNCTION__ "()\n"); - ASSERT(priv != NULL, return;); self = (struct irda_sock *) priv; - if (!self) { WARNING(__FUNCTION__ "(), lost myself!\n"); return; @@ -348,51 +371,90 @@ static void irda_getvalue_confirm(int result, __u16 obj_id, iriap_close(self->iriap); self->iriap = NULL; - self->errno = result; - /* Check if request succeeded */ if (result != IAS_SUCCESS) { - IRDA_DEBUG(0, __FUNCTION__ "(), IAS query failed!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), IAS query failed! (%d)\n", + result); + + self->errno = result; /* We really need it later */ /* Wake up any processes waiting for result */ - wake_up_interruptible(&self->ias_wait); + wake_up_interruptible(&self->query_wait); return; } - switch (value->type) { - case IAS_INTEGER: - IRDA_DEBUG(4, __FUNCTION__ "() int=%d\n", value->t.integer); - - if (value->t.integer != -1) { - self->dtsap_sel = value->t.integer; - } else - self->dtsap_sel = 0; - break; - default: - IRDA_DEBUG(0, __FUNCTION__ "(), bad type!\n"); - break; - } - irias_delete_value(value); + /* Pass the object to the caller (so the caller must delete it) */ + self->ias_result = value; + self->errno = 0; /* Wake up any processes waiting for result */ - wake_up_interruptible(&self->ias_wait); + wake_up_interruptible(&self->query_wait); } /* - * Function irda_discovery_indication (log) + * Function irda_selective_discovery_indication (discovery) * - * Got a discovery log from IrLMP, wake ut any process waiting for answer + * Got a selective discovery indication from IrLMP. * + * IrLMP is telling us that this node is matching our hint bit + * filter. Check if it's a newly discovered node (or if node changed its + * hint bits), and then wake up any process waiting for answer... */ -static void irda_discovery_indication(hashbin_t *log) +static void irda_selective_discovery_indication(discovery_t *discovery, + void *priv) { + struct irda_sock *self; + IRDA_DEBUG(2, __FUNCTION__ "()\n"); - cachelog = log; + self = (struct irda_sock *) priv; + if (!self) { + WARNING(__FUNCTION__ "(), lost myself!\n"); + return; + } + + /* Check if node is discovered is a new one or an old one. + * We check when how long ago this node was discovered, with a + * coarse timeout (we may miss some discovery events or be delayed). + * Note : by doing this test here, we avoid waking up a process ;-) + */ + if((jiffies - discovery->first_timestamp) > + (sysctl_discovery_timeout * HZ)) { + return; /* Too old, not interesting -> goodbye */ + } + + /* Pass parameter to the caller */ + self->cachediscovery = discovery; /* Wake up process if its waiting for device to be discovered */ - wake_up_interruptible(&discovery_wait); + wake_up_interruptible(&self->query_wait); +} + +/* + * Function irda_discovery_timeout (priv) + * + * Timeout in the selective discovery process + * + * We were waiting for a node to be discovered, but nothing has come up + * so far. Wake up the user and tell him that we failed... + */ +static void irda_discovery_timeout(u_long priv) +{ + struct irda_sock *self; + + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + + self = (struct irda_sock *) priv; + ASSERT(self != NULL, return;); + + /* Nothing for the caller */ + self->cachelog = NULL; + self->cachediscovery = NULL; + self->errno = -ETIME; + + /* Wake up process if its still waiting... */ + wake_up_interruptible(&self->query_wait); } /* @@ -470,6 +532,11 @@ static int irda_open_lsap(struct irda_sock *self, int pid) * * Try to lookup LSAP selector in remote LM-IAS * + * Basically, we start a IAP query, and then go to sleep. When the query + * return, irda_getvalue_confirm will wake us up, and we can examine the + * result of the query... + * Note that in some case, the query fail even before we go to sleep, + * creating some races... */ static int irda_find_lsap_sel(struct irda_sock *self, char *name) { @@ -485,19 +552,53 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name) self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, irda_getvalue_confirm); + /* Treat unexpected signals as disconnect */ + self->errno = -EHOSTUNREACH; + /* Query remote LM-IAS */ iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr, name, "IrDA:TinyTP:LsapSel"); - /* Wait for answer */ - interruptible_sleep_on(&self->ias_wait); + /* Wait for answer (if not already failed) */ + if(self->iriap != NULL) + interruptible_sleep_on(&self->query_wait); + + /* Check what happened */ + if (self->errno) + { + /* Requested object/attribute doesn't exist */ + if((self->errno == IAS_CLASS_UNKNOWN) || + (self->errno == IAS_ATTRIB_UNKNOWN)) + return (-EADDRNOTAVAIL); + else + return (-EHOSTUNREACH); + } + + /* Get the remote TSAP selector */ + switch (self->ias_result->type) { + case IAS_INTEGER: + IRDA_DEBUG(4, __FUNCTION__ "() int=%d\n", + self->ias_result->t.integer); + + if (self->ias_result->t.integer != -1) + self->dtsap_sel = self->ias_result->t.integer; + else + self->dtsap_sel = 0; + break; + default: + self->dtsap_sel = 0; + IRDA_DEBUG(0, __FUNCTION__ "(), bad type!\n"); + break; + } + if (self->ias_result) + irias_delete_value(self->ias_result); if (self->dtsap_sel) return 0; - return -ENETUNREACH; /* May not be true */ + return -EADDRNOTAVAIL; } - /* +/* * Function irda_discover_daddr_and_lsap_sel (self, name) * * This try to find a device with the requested service. @@ -516,71 +617,78 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name) */ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) { - discovery_t *discovery; - int err = -ENETUNREACH; - __u32 daddr = 0x0; /* Address we found the service on */ + struct irda_device_info *discoveries; /* Copy of the discovery log */ + int number; /* Number of nodes in the log */ + int i; + int err = -ENETUNREACH; + __u32 daddr = DEV_ADDR_ANY; /* Address we found the service on */ __u8 dtsap_sel = 0x0; /* TSAP associated with it */ IRDA_DEBUG(2, __FUNCTION__ "(), name=%s\n", name); ASSERT(self != NULL, return -1;); - /* Tell IrLMP we want to be notified */ - irlmp_update_client(self->ckey, self->mask, NULL, - irda_discovery_indication); - - /* Do some discovery */ - irlmp_discovery_request(self->nslots); - + /* Ask lmp for the current discovery log + * Note : we have to use irlmp_get_discoveries(), as opposed + * to play with the cachelog directly, because while we are + * making our ias query, le log might change... */ + discoveries = irlmp_get_discoveries(&number, self->mask); /* Check if the we got some results */ - if (!cachelog) - /* Wait for answer */ - /*interruptible_sleep_on(&self->discovery_wait);*/ - return -EAGAIN; + if (discoveries == NULL) + return -ENETUNREACH; /* No nodes discovered */ /* * Now, check all discovered devices (if any), and connect * client only about the services that the client is * interested in... */ - discovery = (discovery_t *) hashbin_get_first(cachelog); - while (discovery != NULL) { - /* Mask out the ones we don't want */ - if (discovery->hints.word & self->mask) { - /* Try this address */ - self->daddr = discovery->daddr; - self->saddr = 0x0; - IRDA_DEBUG(1, __FUNCTION__ "(), trying daddr = %08x\n", - self->daddr); - - /* Query remote LM-IAS for this service */ - err = irda_find_lsap_sel(self, name); - if (err == 0) { - /* We found the requested service */ - if(daddr != 0x0) { - IRDA_DEBUG(0, __FUNCTION__ - "(), discovered service ''%s'' in two different devices !!!\n", - name); - return(-ENOTUNIQ); - } - /* First time we foun that one, save it ! */ - daddr = self->daddr; - dtsap_sel = self->dtsap_sel; + for(i = 0; i < number; i++) { + /* Try the address in the log */ + self->daddr = discoveries[i].daddr; + self->saddr = 0x0; + IRDA_DEBUG(1, __FUNCTION__ "(), trying daddr = %08x\n", + self->daddr); + + /* Query remote LM-IAS for this service */ + err = irda_find_lsap_sel(self, name); + switch (err) { + case 0: + /* We found the requested service */ + if(daddr != DEV_ADDR_ANY) { + IRDA_DEBUG(1, __FUNCTION__ + "(), discovered service ''%s'' in two different devices !!!\n", + name); + self->daddr = DEV_ADDR_ANY; + kfree(discoveries); + return(-ENOTUNIQ); } + /* First time we found that one, save it ! */ + daddr = self->daddr; + dtsap_sel = self->dtsap_sel; + break; + case -EADDRNOTAVAIL: + /* Requested service simply doesn't exist on this node */ + break; + default: + /* Something bad did happen :-( */ + IRDA_DEBUG(0, __FUNCTION__ + "(), unexpected IAS query failure\n"); + self->daddr = DEV_ADDR_ANY; + kfree(discoveries); + return(-EHOSTUNREACH); + break; } - - /* Next node, maybe we will be more lucky... */ - discovery = (discovery_t *) hashbin_get_next(cachelog); } - cachelog = NULL; + /* Cleanup our copy of the discovery log */ + kfree(discoveries); /* Check out what we found */ - if(daddr == 0x0) { - IRDA_DEBUG(0, __FUNCTION__ + if(daddr == DEV_ADDR_ANY) { + IRDA_DEBUG(1, __FUNCTION__ "(), cannot discover service ''%s'' in any device !!!\n", name); - self->daddr = 0; /* Guessing */ - return(-ENETUNREACH); + self->daddr = DEV_ADDR_ANY; + return(-EADDRNOTAVAIL); } /* Revert back to discovered device & service */ @@ -588,7 +696,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) self->saddr = 0x0; self->dtsap_sel = dtsap_sel; - IRDA_DEBUG(0, __FUNCTION__ + IRDA_DEBUG(1, __FUNCTION__ "(), discovered requested service ''%s'' at address %08x\n", name, self->daddr); @@ -606,25 +714,26 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, { struct sockaddr_irda saddr; struct sock *sk = sock->sk; + struct irda_sock *self = sk->protinfo.irda; if (peer) { if (sk->state != TCP_ESTABLISHED) return -ENOTCONN; saddr.sir_family = AF_IRDA; - saddr.sir_lsap_sel = sk->protinfo.irda->dtsap_sel; - saddr.sir_addr = sk->protinfo.irda->daddr; + saddr.sir_lsap_sel = self->dtsap_sel; + saddr.sir_addr = self->daddr; } else { saddr.sir_family = AF_IRDA; - saddr.sir_lsap_sel = sk->protinfo.irda->stsap_sel; - saddr.sir_addr = sk->protinfo.irda->saddr; + saddr.sir_lsap_sel = self->stsap_sel; + saddr.sir_addr = self->saddr; } IRDA_DEBUG(1, __FUNCTION__ "(), tsap_sel = %#x\n", saddr.sir_lsap_sel); IRDA_DEBUG(1, __FUNCTION__ "(), addr = %08x\n", saddr.sir_addr); - if (*uaddr_len > sizeof (struct sockaddr_irda)) - *uaddr_len = sizeof (struct sockaddr_irda); + /* uaddr_len come to us uninitialised */ + *uaddr_len = sizeof (struct sockaddr_irda); memcpy(uaddr, &saddr, *uaddr_len); return 0; @@ -709,7 +818,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) /* Register with LM-IAS */ self->ias_obj = irias_new_object(addr->sir_name, jiffies); irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel", - self->stsap_sel); + self->stsap_sel, IAS_KERNEL_ATTR); irias_insert_object(self->ias_obj); #if 1 /* Will be removed in near future */ @@ -821,6 +930,20 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) * * Connect to a IrDA device * + * The main difference with a "standard" connect is that with IrDA we need + * to resolve the service name into a TSAP selector (in TCP, port number + * doesn't have to be resolved). + * Because of this service name resoltion, we can offer "auto-connect", + * where we connect to a service without specifying a destination address. + * + * Note : by consulting "errno", the user space caller may learn the cause + * of the failure. Most of them are visible in the function, others may come + * from subroutines called and are listed here : + * o EBUSY : already processing a connect + * o EHOSTUNREACH : bad addr->sir_addr argument + * o EADDRNOTAVAIL : bad addr->sir_name argument + * o ENOTUNIQ : more than one node has addr->sir_name (auto-connect) + * o ENETUNREACH : no node found on the network (auto-connect) */ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) @@ -858,13 +981,13 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, return -EINVAL; /* Check if user supplied any destination device address */ - if (!addr->sir_addr) { + if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) { /* Try to find one suitable */ err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name); if (err) { IRDA_DEBUG(0, __FUNCTION__ "(), auto-connect failed!\n"); - return -EINVAL; + return err; } } else { /* Use the one provided by the user */ @@ -922,6 +1045,9 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, sti(); + /* At this point, IrLMP has assigned our source address */ + self->saddr = irttp_get_saddr(self->tsap); + return 0; } @@ -957,7 +1083,7 @@ static int irda_create(struct socket *sock, int protocol) return -ENOMEM; memset(self, 0, sizeof(struct irda_sock)); - init_waitqueue_head(&self->ias_wait); + init_waitqueue_head(&self->query_wait); self->sk = sk; sk->protinfo.irda = self; @@ -996,14 +1122,14 @@ static int irda_create(struct socket *sock, int protocol) sk->protocol = protocol; /* Register as a client with IrLMP */ - self->ckey = irlmp_register_client(0, NULL, NULL); + self->ckey = irlmp_register_client(0, NULL, NULL, NULL); self->mask = 0xffff; self->rx_flow = self->tx_flow = FLOW_START; self->nslots = DISCOVERY_DEFAULT_SLOTS; - self->daddr = DEV_ADDR_ANY; + self->daddr = DEV_ADDR_ANY; /* Until we get connected */ + self->saddr = 0x0; /* so IrLMP assign us any link */ - /* Notify that we are using the irda module, so nobody removes it */ - irda_mod_inc_use_count(); + MOD_INC_USE_COUNT; return 0; } @@ -1025,11 +1151,15 @@ void irda_destroy_socket(struct irda_sock *self) irlmp_unregister_service(self->skey); /* Unregister with LM-IAS */ - if (self->ias_obj) + if (self->ias_obj) { irias_delete_object(self->ias_obj); + self->ias_obj = NULL; + } - if (self->iriap) + if (self->iriap) { iriap_close(self->iriap); + self->iriap = NULL; + } if (self->tsap) { irttp_disconnect_request(self->tsap, NULL, P_NORMAL); @@ -1043,10 +1173,8 @@ void irda_destroy_socket(struct irda_sock *self) } #endif /* CONFIG_IRDA_ULTRA */ kfree(self); - - /* Notify that we are not using the irda module anymore */ - irda_mod_dec_use_count(); - + MOD_DEC_USE_COUNT; + return; } @@ -1096,7 +1224,8 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len, IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len); - if (msg->msg_flags & ~MSG_DONTWAIT) + /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ + if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR)) return -EINVAL; if (sk->shutdown & SEND_SHUTDOWN) { @@ -1474,15 +1603,22 @@ static int irda_shutdown(struct socket *sock, int how) sk->shutdown |= SEND_SHUTDOWN; sk->state_change(sk); - if (self->iriap) + if (self->iriap) { iriap_close(self->iriap); - + self->iriap = NULL; + } + if (self->tsap) { irttp_disconnect_request(self->tsap, NULL, P_NORMAL); irttp_close_tsap(self->tsap); self->tsap = NULL; } + /* A few cleanup so the socket look as good as new... */ + self->rx_flow = self->tx_flow = FLOW_START; /* needed ??? */ + self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ + self->saddr = 0x0; /* so IrLMP assign us any link */ + return 0; } @@ -1606,6 +1742,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, struct irda_sock *self; struct irda_ias_set ias_opt; struct ias_object *ias_obj; + struct ias_attrib * ias_attr; /* Attribute in IAS object */ int opt; self = sk->protinfo.irda; @@ -1616,6 +1753,13 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, switch (optname) { case IRLMP_IAS_SET: + /* The user want to add an attribute to an existing IAS object + * (in the IAS database) or to create a new object with this + * attribute. + * We first query IAS to know if the object exist, and then + * create the right attribute... + */ + if (optlen != sizeof(struct irda_ias_set)) return -EINVAL; @@ -1639,9 +1783,11 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, switch(ias_opt.irda_attrib_type) { case IAS_INTEGER: /* Add an integer attribute */ - irias_add_integer_attrib(ias_obj, - ias_opt.irda_attrib_name, - ias_opt.attribute.irda_attrib_int); + irias_add_integer_attrib( + ias_obj, + ias_opt.irda_attrib_name, + ias_opt.attribute.irda_attrib_int, + IAS_USER_ATTR); break; case IAS_OCT_SEQ: /* Check length */ @@ -1653,7 +1799,8 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, ias_obj, ias_opt.irda_attrib_name, ias_opt.attribute.irda_attrib_octet_seq.octet_seq, - ias_opt.attribute.irda_attrib_octet_seq.len); + ias_opt.attribute.irda_attrib_octet_seq.len, + IAS_USER_ATTR); break; case IAS_STRING: /* Should check charset & co */ @@ -1667,16 +1814,49 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, irias_add_string_attrib( ias_obj, ias_opt.irda_attrib_name, - ias_opt.attribute.irda_attrib_string.string); + ias_opt.attribute.irda_attrib_string.string, + IAS_USER_ATTR); break; default : return -EINVAL; } irias_insert_object(ias_obj); break; + case IRLMP_IAS_DEL: + /* The user want to delete an object from our local IAS + * database. We just need to query the IAS, check is the + * object is not owned by the kernel and delete it. + */ - IRDA_DEBUG(0, __FUNCTION__ "(), sorry not impl. yet!\n"); - return -ENOPROTOOPT; + if (optlen != sizeof(struct irda_ias_set)) + return -EINVAL; + + /* Copy query to the driver. */ + if (copy_from_user(&ias_opt, (char *)optval, optlen)) + return -EFAULT; + + /* Find the object we target */ + ias_obj = irias_find_object(ias_opt.irda_class_name); + if(ias_obj == (struct ias_object *) NULL) + return -EINVAL; + + /* Find the attribute (in the object) we target */ + ias_attr = irias_find_attrib(ias_obj, + ias_opt.irda_attrib_name); + if(ias_attr == (struct ias_attrib *) NULL) + return -EINVAL; + + /* Check is the user space own the object */ + if(ias_attr->value->owner != IAS_USER_ATTR) { + IRDA_DEBUG(1, __FUNCTION__ + "(), attempting to delete a kernel attribute\n"); + return -EPERM; + } + + /* Remove the attribute (and maybe the object) */ + irias_delete_attrib(ias_obj, ias_attr); + + break; case IRLMP_MAX_SDU_SIZE: if (optlen < sizeof(int)) return -EINVAL; @@ -1709,60 +1889,31 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, self->skey = irlmp_register_service((__u16) opt); break; - default: - return -ENOPROTOOPT; - } - return 0; -} - - /* - * Function irda_simple_getvalue_confirm (obj_id, value, priv) - * - * Got answer from remote LM-IAS, just copy object to requester... - * - * Note : duplicate from above, but we need our own version that - * doesn't touch the dtsap_sel and save the full value structure... - */ -static void irda_simple_getvalue_confirm(int result, __u16 obj_id, - struct ias_value *value, void *priv) -{ - struct irda_sock *self; - - IRDA_DEBUG(2, __FUNCTION__ "()\n"); - - ASSERT(priv != NULL, return;); - self = (struct irda_sock *) priv; + case IRLMP_HINT_MASK_SET: + /* As opposed to the previous case which set the hint bits + * that we advertise, this one set the filter we use when + * making a discovery (nodes which don't match any hint + * bit in the mask are not reported). + */ + if (optlen < sizeof(int)) + return -EINVAL; - if (!self) { - WARNING(__FUNCTION__ "(), lost myself!\n"); - return; - } - - /* We probably don't need to make any more queries */ - iriap_close(self->iriap); - self->iriap = NULL; - - /* Check if request succeeded */ - if (result != IAS_SUCCESS) { - IRDA_DEBUG(0, __FUNCTION__ "(), IAS query failed!\n"); - - self->errno = -EHOSTUNREACH; + if (get_user(opt, (int *)optval)) + return -EFAULT; - /* Wake up any processes waiting for result */ - wake_up_interruptible(&self->ias_wait); + /* Set the new hint mask */ + self->mask = (__u16) opt; + /* Mask out extension bits */ + self->mask &= 0x7f7f; + /* Check if no bits */ + if(!self->mask) + self->mask = 0xFFFF; - return; + break; + default: + return -ENOPROTOOPT; } - - /* Clone the object (so the requester can free it) */ - self->ias_result = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); - memcpy(self->ias_result, value, sizeof(struct ias_value)); - irias_delete_value(value); - - self->errno = 0; - - /* Wake up any processes waiting for result */ - wake_up_interruptible(&self->ias_wait); + return 0; } /* @@ -1803,6 +1954,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt, /* NULL terminate the string (avoid troubles) */ ias_opt->attribute.irda_attrib_string.string[ias_value->len] = '\0'; break; + case IAS_MISSING: default : return -EINVAL; } @@ -1825,11 +1977,11 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; struct irda_sock *self; struct irda_device_list list; - struct irda_device_info *info; - discovery_t *discovery; + struct irda_device_info *discoveries; struct irda_ias_set ias_opt; /* IAS get/query params */ struct ias_object * ias_obj; /* Object in IAS */ struct ias_attrib * ias_attr; /* Attribute in IAS object */ + int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */ int val = 0; int len = 0; int err; @@ -1845,67 +1997,38 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, switch (optname) { case IRLMP_ENUMDEVICES: - /* Tell IrLMP we want to be notified */ - irlmp_update_client(self->ckey, self->mask, NULL, - irda_discovery_indication); - - /* Do some discovery */ - irlmp_discovery_request(self->nslots); - + /* Ask lmp for the current discovery log */ + discoveries = irlmp_get_discoveries(&list.len, self->mask); /* Check if the we got some results */ - if (!cachelog) - return -EAGAIN; + if (discoveries == NULL) + return -EAGAIN; /* Didn't find any devices */ + err = 0; - info = &list.dev[0]; + /* Write total list length back to client */ + if (copy_to_user(optval, &list, + sizeof(struct irda_device_list) - + sizeof(struct irda_device_info))) + err = -EFAULT; /* Offset to first device entry */ offset = sizeof(struct irda_device_list) - sizeof(struct irda_device_info); - total = offset; /* Initialized to size of the device list */ - list.len = 0; /* Initialize lenght of list */ - - /* - * Now, check all discovered devices (if any), and notify - * client only about the services that the client is - * interested in - */ - discovery = (discovery_t *) hashbin_get_first(cachelog); - while (discovery != NULL) { - /* Mask out the ones we don't want */ - if (discovery->hints.word & self->mask) { - /* Check if room for this device entry */ - if (len-totalsaddr = discovery->saddr; - info->daddr = discovery->daddr; - info->charset = discovery->charset; - info->hints[0] = discovery->hints.byte[0]; - info->hints[1] = discovery->hints.byte[1]; - strncpy(info->info, discovery->nickname, - NICKNAME_MAX_LEN); - - if (copy_to_user(optval+total, info, - sizeof(struct irda_device_info))) - return -EFAULT; - list.len++; - total += sizeof(struct irda_device_info); - } - discovery = (discovery_t *) hashbin_get_next(cachelog); - } - cachelog = NULL; + /* Copy the list itself */ + total = offset + (list.len * sizeof(struct irda_device_info)); + if (total > len) + total = len; + if (copy_to_user(optval+offset, discoveries, total - offset)) + err = -EFAULT; /* Write total number of bytes used back to client */ if (put_user(total, optlen)) - return -EFAULT; + err = -EFAULT; - /* Write total list length back to client */ - if (copy_to_user(optval, &list, - sizeof(struct irda_device_list) - - sizeof(struct irda_device_info))) - return -EFAULT; + /* Free up our buffer */ + kfree(discoveries); + if (err) + return err; break; case IRLMP_MAX_SDU_SIZE: val = self->max_data_size; @@ -1964,6 +2087,26 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, if (copy_from_user((char *) &ias_opt, (char *)optval, len)) return -EFAULT; + /* At this point, there are two cases... + * 1) the socket is connected - that's the easy case, we + * just query the device we are connected to... + * 2) the socket is not connected - the user doesn't want + * to connect and/or may not have a valid service name + * (so can't create a fake connection). In this case, + * we assume that the user pass us a valid destination + * address in the requesting structure... + */ + if(self->daddr != DEV_ADDR_ANY) { + /* We are connected - reuse known daddr */ + daddr = self->daddr; + } else { + /* We are not connected, we must specify a valid + * destination address */ + daddr = ias_opt.daddr; + if((!daddr) || (daddr == DEV_ADDR_ANY)) + return -EINVAL; + } + /* Check that we can proceed with IAP */ if (self->iriap) { WARNING(__FUNCTION__ @@ -1972,26 +2115,34 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, } self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, - irda_simple_getvalue_confirm); + irda_getvalue_confirm); /* Treat unexpected signals as disconnect */ self->errno = -EHOSTUNREACH; /* Query remote LM-IAS */ - iriap_getvaluebyclass_request(self->iriap, - self->saddr, self->daddr, + iriap_getvaluebyclass_request(self->iriap, + self->saddr, daddr, ias_opt.irda_class_name, ias_opt.irda_attrib_name); - /* Wait for answer */ - interruptible_sleep_on(&self->ias_wait); + /* Wait for answer (if not already failed) */ + if(self->iriap != NULL) + interruptible_sleep_on(&self->query_wait); /* Check what happened */ if (self->errno) - return (self->errno); + { + /* Requested object/attribute doesn't exist */ + if((self->errno == IAS_CLASS_UNKNOWN) || + (self->errno == IAS_ATTRIB_UNKNOWN)) + return (-EADDRNOTAVAIL); + else + return (-EHOSTUNREACH); + } /* Translate from internal to user structure */ err = irda_extract_ias_value(&ias_opt, self->ias_result); if (self->ias_result) - kfree(self->ias_result); + irias_delete_value(self->ias_result); if (err) return err; @@ -2001,6 +2152,76 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, return -EFAULT; /* Note : don't need to put optlen, we checked it */ break; + case IRLMP_WAITDEVICE: + /* This function is just another way of seeing life ;-) + * IRLMP_ENUMDEVICES assumes that you have a static network, + * and that you just want to pick one of the devices present. + * On the other hand, in here we assume that no device is + * present and that at some point in the future a device will + * come into range. When this device arrive, we just wake + * up the caller, so that he has time to connect to it before + * the device goes away... + * Note : once the node has been discovered for more than a + * few second, it won't trigger this function, unless it + * goes away and come back changes its hint bits (so we + * might call it IRLMP_WAITNEWDEVICE). + */ + + /* Check that the user is passing us an int */ + if (len != sizeof(int)) + return -EINVAL; + /* Get timeout in ms (max time we block the caller) */ + if (get_user(val, (int *)optval)) + return -EFAULT; + + /* Tell IrLMP we want to be notified */ + irlmp_update_client(self->ckey, self->mask, + irda_selective_discovery_indication, + NULL, (void *) self); + + /* Do some discovery (and also return cached results) */ + irlmp_discovery_request(self->nslots); + + /* Wait until a node is discovered */ + if (!self->cachediscovery) { + IRDA_DEBUG(1, __FUNCTION__ + "(), nothing discovered yet, going to sleep...\n"); + + /* Set watchdog timer to expire in ms. */ + self->watchdog.function = irda_discovery_timeout; + self->watchdog.data = (unsigned long) self; + self->watchdog.expires = jiffies + (val * HZ/1000); + add_timer(&(self->watchdog)); + + /* Wait for IR-LMP to call us back */ + interruptible_sleep_on(&self->query_wait); + + /* If watchdog is still activated, kill it! */ + if(timer_pending(&(self->watchdog))) + del_timer(&(self->watchdog)); + + IRDA_DEBUG(1, __FUNCTION__ + "(), ...waking up !\n"); + } + else + IRDA_DEBUG(1, __FUNCTION__ + "(), found immediately !\n"); + + /* Tell IrLMP that we have been notified */ + irlmp_update_client(self->ckey, self->mask, NULL, NULL, NULL); + + /* Check if the we got some results */ + if (!self->cachediscovery) + return -EAGAIN; /* Didn't find any devices */ + /* Cleanup */ + self->cachediscovery = NULL; + + /* Note : We don't return anything to the user. + * We could return the device that triggered the wake up, + * but it's probably better to force the user to query + * the whole discovery log and let him pick one device... + */ + break; default: return -ENOPROTOOPT; } @@ -2150,24 +2371,44 @@ static struct notifier_block irda_dev_notifier = { }; /* + * Function irda_proc_modcount (inode, fill) + * + * Use by the proc file system functions to prevent the irda module + * being removed while the use is standing in the net/irda directory + */ +void irda_proc_modcount(struct inode *inode, int fill) +{ +#ifdef MODULE +#ifdef CONFIG_PROC_FS + if (fill) + MOD_INC_USE_COUNT; + else + MOD_DEC_USE_COUNT; +#endif /* CONFIG_PROC_FS */ +#endif /* MODULE */ +} + +/* * Function irda_proto_init (pro) * * Initialize IrDA protocol layer * */ -static int __init irda_proto_init(void) +int __init irda_proto_init(void) { - sock_register(&irda_family_ops); - - irda_packet_type.type = htons(ETH_P_IRDA); + sock_register(&irda_family_ops); + + irda_packet_type.type = htons(ETH_P_IRDA); dev_add_pack(&irda_packet_type); - - register_netdevice_notifier(&irda_dev_notifier); - - irda_init(); + + register_netdevice_notifier(&irda_dev_notifier); + + irda_init(); +#ifdef MODULE + irda_device_init(); /* Called by init/main.c when non-modular */ +#endif return 0; } -module_init(irda_proto_init); /* * Function irda_proto_cleanup (void) @@ -2188,5 +2429,11 @@ void irda_proto_cleanup(void) return; } +module_init(irda_proto_init); module_exit(irda_proto_cleanup); + +MODULE_AUTHOR("Dag Brattli "); +MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem"); +MODULE_PARM(irda_debug, "1l"); #endif /* MODULE */ + diff --git a/net/irda/compressors/irda_deflate.c b/net/irda/compressors/irda_deflate.c index 245185500..f0d2cbb0d 100644 --- a/net/irda/compressors/irda_deflate.c +++ b/net/irda/compressors/irda_deflate.c @@ -561,37 +561,37 @@ extern void irda_unregister_compressor (struct compressor *cp); * Procedures exported to if_ppp.c. */ static struct compressor irda_deflate = { - CI_DEFLATE, /* compress_proto */ - z_comp_alloc, /* comp_alloc */ - z_comp_free, /* comp_free */ - z_comp_init, /* comp_init */ - z_comp_reset, /* comp_reset */ - z_compress, /* compress */ - z_comp_stats, /* comp_stat */ - z_decomp_alloc, /* decomp_alloc */ - z_decomp_free, /* decomp_free */ - z_decomp_init, /* decomp_init */ - z_decomp_reset, /* decomp_reset */ - z_decompress, /* decompress */ - z_incomp, /* incomp */ - z_comp_stats, /* decomp_stat */ +compress_proto: CI_DEFLATE, +comp_alloc: z_comp_alloc, +comp_free: z_comp_free, +comp_init: z_comp_init, +comp_reset: z_comp_reset, +compress: z_compress, +comp_stat: z_comp_stats, +decomp_alloc: z_decomp_alloc, +decomp_free: z_decomp_free, +decomp_init: z_decomp_init, +decomp_reset: z_decomp_reset, +decompress: z_decompress, +incomp: z_incomp, +decomp_stat: z_comp_stats }; static struct compressor irda_deflate_draft = { - CI_DEFLATE_DRAFT, /* compress_proto */ - z_comp_alloc, /* comp_alloc */ - z_comp_free, /* comp_free */ - z_comp_init, /* comp_init */ - z_comp_reset, /* comp_reset */ - z_compress, /* compress */ - z_comp_stats, /* comp_stat */ - z_decomp_alloc, /* decomp_alloc */ - z_decomp_free, /* decomp_free */ - z_decomp_init, /* decomp_init */ - z_decomp_reset, /* decomp_reset */ - z_decompress, /* decompress */ - z_incomp, /* incomp */ - z_comp_stats, /* decomp_stat */ +compress_proto: CI_DEFLATE_DRAFT, +comp_alloc: z_comp_alloc, +comp_free: z_comp_free, +comp_init: z_comp_init, +comp_reset: z_comp_reset, +compress: z_compress, +comp_stat: z_comp_stats, +decomp_alloc: z_decomp_alloc, +decomp_free: z_decomp_free, +decomp_init: z_decomp_init, +decomp_reset: z_decomp_reset, +decompress: z_decompress, +incomp: z_incomp, +decomp_stat: z_comp_stats }; int __init irda_deflate_init(void) diff --git a/net/irda/discovery.c b/net/irda/discovery.c index 957426154..d2fe17ff8 100644 --- a/net/irda/discovery.c +++ b/net/irda/discovery.c @@ -43,13 +43,25 @@ * * Add a new discovery to the cachelog, and remove any old discoveries * from the same device + * + * Note : we try to preserve the time this device was *first* discovered + * (as opposed to the time of last discovery used for cleanup). This is + * used by clients waiting for discovery events to tell if the device + * discovered is "new" or just the same old one. They can't rely there + * on a binary flag (new/old), because not all discovery events are + * propagated to them, and they might not always listen, so they would + * miss some new devices popping up... + * Jean II */ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new) { discovery_t *discovery, *node; unsigned long flags; - spin_lock_irqsave(&irlmp->lock, flags); + /* Set time of first discovery if node is new (see below) */ + new->first_timestamp = new->timestamp; + + spin_lock_irqsave(&irlmp->log_lock, flags); /* * Remove all discoveries of devices that has previously been @@ -59,27 +71,31 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new) */ discovery = (discovery_t *) hashbin_get_first(cachelog); while (discovery != NULL ) { - node = discovery; + node = discovery; - /* Be sure to stay one item ahead */ - discovery = (discovery_t *) hashbin_get_next(cachelog); - - if ((node->daddr == new->daddr) || - (strcmp(node->nickname, new->nickname) == 0)) - { - /* This discovery is a previous discovery - * from the same device, so just remove it - */ - hashbin_remove(cachelog, node->daddr, NULL); - kfree(node); - } - } + /* Be sure to stay one item ahead */ + discovery = (discovery_t *) hashbin_get_next(cachelog); + if ((node->saddr == new->saddr) && + ((node->daddr == new->daddr) || + (strcmp(node->nickname, new->nickname) == 0))) + { + /* This discovery is a previous discovery + * from the same device, so just remove it + */ + hashbin_remove_this(cachelog, (irda_queue_t *) node); + /* Check if hints bits have changed */ + if(node->hints.word == new->hints.word) + /* Set time of first discovery for this node */ + new->first_timestamp = node->first_timestamp; + kfree(node); + } + } /* Insert the new and updated version */ - hashbin_insert(cachelog, (queue_t *) new, new->daddr, NULL); + hashbin_insert(cachelog, (irda_queue_t *) new, new->daddr, NULL); - spin_unlock_irqrestore(&irlmp->lock, flags); + spin_unlock_irqrestore(&irlmp->log_lock, flags); } /* @@ -120,13 +136,18 @@ void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log) * * Go through all discoveries and expire all that has stayed to long * + * Note : this assume that IrLAP won't change its saddr, which + * currently is a valid assumption... */ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force) { discovery_t *discovery, *curr; + unsigned long flags; IRDA_DEBUG(4, __FUNCTION__ "()\n"); + spin_lock_irqsave(&irlmp->log_lock, flags); + discovery = (discovery_t *) hashbin_get_first(log); while (discovery != NULL) { curr = discovery; @@ -135,14 +156,20 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force) discovery = (discovery_t *) hashbin_get_next(log); /* Test if it's time to expire this discovery */ - if ((curr->saddr == saddr) && (force || - ((jiffies - curr->timestamp) > DISCOVERY_EXPIRE_TIMEOUT))) + if ((curr->saddr == saddr) && + (force || + ((jiffies - curr->timestamp) > DISCOVERY_EXPIRE_TIMEOUT))) { - curr = hashbin_remove(log, curr->daddr, NULL); + /* Tell IrLMP and registered clients about it */ + irlmp_discovery_expiry(curr); + /* Remove it from the log */ + curr = hashbin_remove_this(log, (irda_queue_t *) curr); if (curr) kfree(curr); } } + + spin_unlock_irqrestore(&irlmp->log_lock, flags); } /* @@ -169,6 +196,75 @@ void irlmp_dump_discoveries(hashbin_t *log) } /* + * Function irlmp_copy_discoveries (log, pn, mask) + * + * Copy all discoveries in a buffer + * + * This function implement a safe way for lmp clients to access the + * discovery log. The basic problem is that we don't want the log + * to change (add/remove) while the client is reading it. If the + * lmp client manipulate directly the hashbin, he is sure to get + * into troubles... + * The idea is that we copy all the current discovery log in a buffer + * which is specific to the client and pass this copy to him. As we + * do this operation with the spinlock grabbed, we are safe... + * Note : we don't want those clients to grab the spinlock, because + * we have no control on how long they will hold it... + * Note : we choose to copy the log in "struct irda_device_info" to + * save space... + * Note : the client must kfree himself() the log... + * Jean II + */ +struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, __u16 mask) +{ + discovery_t * discovery; + unsigned long flags; + struct irda_device_info * buffer; + int i = 0; + int n; + + ASSERT(pn != NULL, return NULL;); + + /* Check if log is empty */ + if(log == NULL) + return NULL; + + /* Save spin lock - spinlock should be discovery specific */ + spin_lock_irqsave(&irlmp->log_lock, flags); + + /* Create the client specific buffer */ + n = HASHBIN_GET_SIZE(log); + buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC); + if (buffer == NULL) { + spin_unlock_irqrestore(&irlmp->log_lock, flags); + return NULL; + } + + discovery = (discovery_t *) hashbin_get_first(log); + while ((discovery != NULL) && (i < n)) { + /* Mask out the ones we don't want */ + if (discovery->hints.word & mask) { + /* Copy discovery information */ + buffer[i].saddr = discovery->saddr; + buffer[i].daddr = discovery->daddr; + buffer[i].charset = discovery->charset; + buffer[i].hints[0] = discovery->hints.byte[0]; + buffer[i].hints[1] = discovery->hints.byte[1]; + strncpy(buffer[i].info, discovery->nickname, + NICKNAME_MAX_LEN); + i++; + } + discovery = (discovery_t *) hashbin_get_next(log); + } + + spin_unlock_irqrestore(&irlmp->log_lock, flags); + + /* Get the actual number of device in the buffer and return */ + *pn = i; + return(buffer); +} + +/* * Function irlmp_find_device (name, saddr) * * Look through the discovery log at each of the links and try to find @@ -180,7 +276,7 @@ __u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr) unsigned long flags; discovery_t *d; - spin_lock_irqsave(&irlmp->lock, flags); + spin_lock_irqsave(&irlmp->log_lock, flags); /* Look at all discoveries for that link */ d = (discovery_t *) hashbin_get_first(cachelog); @@ -192,13 +288,13 @@ __u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr) if (strcmp(name, d->nickname) == 0) { *saddr = d->saddr; - spin_unlock_irqrestore(&irlmp->lock, flags); + spin_unlock_irqrestore(&irlmp->log_lock, flags); return d->daddr; } d = (discovery_t *) hashbin_get_next(cachelog); } - spin_unlock_irqrestore(&irlmp->lock, flags); + spin_unlock_irqrestore(&irlmp->log_lock, flags); return 0; } @@ -209,23 +305,23 @@ __u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr) * Print discovery information in /proc file system * */ -int discovery_proc_read(char *buf, char **start, off_t offset, int len, +int discovery_proc_read(char *buf, char **start, off_t offset, int length, int unused) { discovery_t *discovery; unsigned long flags; hashbin_t *cachelog = irlmp_get_cachelog(); + int len = 0; if (!irlmp) return len; len = sprintf(buf, "IrLMP: Discovery log:\n\n"); - save_flags(flags); - cli(); - + spin_lock_irqsave(&irlmp->log_lock, flags); + discovery = (discovery_t *) hashbin_get_first(cachelog); - while ( discovery != NULL) { + while (( discovery != NULL) && (len < length)) { len += sprintf(buf+len, "nickname: %s,", discovery->nickname); len += sprintf(buf+len, " hint: 0x%02x%02x", @@ -266,7 +362,7 @@ int discovery_proc_read(char *buf, char **start, off_t offset, int len, discovery = (discovery_t *) hashbin_get_next(cachelog); } - restore_flags(flags); + spin_unlock_irqrestore(&irlmp->log_lock, flags); return len; } diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c index 805186128..ae626e08b 100644 --- a/net/irda/ircomm/ircomm_core.c +++ b/net/irda/ircomm/ircomm_core.c @@ -127,7 +127,7 @@ struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line) self->service_type = service_type; self->line = line; - hashbin_insert(ircomm, (queue_t *) self, line, NULL); + hashbin_insert(ircomm, (irda_queue_t *) self, line, NULL); ircomm_next_state(self, IRCOMM_IDLE); @@ -512,6 +512,9 @@ int ircomm_proc_read(char *buf, char **start, off_t offset, int len) #endif /* CONFIG_PROC_FS */ #ifdef MODULE +MODULE_AUTHOR("Dag Brattli "); +MODULE_DESCRIPTION("IrCOMM protocol"); + int init_module(void) { return ircomm_init(); diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index d785983da..f23b5bcf5 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -69,9 +69,10 @@ static int ircomm_tty_control_indication(void *instance, void *sap, struct sk_buff *skb); static void ircomm_tty_flow_indication(void *instance, void *sap, LOCAL_FLOW cmd); +#ifdef CONFIG_PROC_FS static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused); - +#endif /* CONFIG_PROC_FS */ static struct tty_driver driver; static int ircomm_tty_refcount; /* If we manage several devices */ @@ -126,8 +127,9 @@ int __init ircomm_tty_init(void) driver.start = ircomm_tty_start; driver.hangup = ircomm_tty_hangup; driver.wait_until_sent = ircomm_tty_wait_until_sent; +#ifdef CONFIG_PROC_FS driver.read_proc = ircomm_tty_read_proc; - +#endif /* CONFIG_PROC_FS */ if (tty_register_driver(&driver)) { ERROR(__FUNCTION__ "Couldn't register serial driver\n"); return -1; @@ -429,7 +431,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) tty->termios->c_oflag = 0; /* Insert into hash */ - hashbin_insert(ircomm_tty, (queue_t *) self, line, NULL); + hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); } self->open_count++; @@ -1319,6 +1321,7 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf) * * */ +#ifdef CONFIG_PROC_FS static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused) { @@ -1349,9 +1352,12 @@ done: *start = buf + (offset-begin); return ((len < begin+count-offset) ? len : begin+count-offset); } - +#endif /* CONFIG_PROC_FS */ #ifdef MODULE +MODULE_AUTHOR("Dag Brattli "); +MODULE_DESCRIPTION("IrCOMM serial TTY driver"); + int init_module(void) { return ircomm_tty_init(); diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index 94c9fee09..ad5ee4b0f 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c @@ -46,7 +46,8 @@ #include static void ircomm_tty_ias_register(struct ircomm_tty_cb *self); -static void ircomm_tty_discovery_indication(discovery_t *discovery); +static void ircomm_tty_discovery_indication(discovery_t *discovery, + void *priv); static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id, struct ias_value *value, void *priv); void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self, int timeout); @@ -213,7 +214,7 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self) /* Register IrLPT with LM-IAS */ self->obj = irias_new_object("IrLPT", IAS_IRLPT_ID); irias_add_integer_attrib(self->obj, "IrDA:IrLMP:LsapSel", - self->slsap_sel); + self->slsap_sel, IAS_KERNEL_ATTR); irias_insert_object(self->obj); } else { hints = irlmp_service_to_hint(S_COMM); @@ -221,7 +222,7 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self) /* Register IrCOMM with LM-IAS */ self->obj = irias_new_object("IrDA:IrCOMM", IAS_IRCOMM_ID); irias_add_integer_attrib(self->obj, "IrDA:TinyTP:LsapSel", - self->slsap_sel); + self->slsap_sel, IAS_KERNEL_ATTR); /* Code the parameters into the buffer */ irda_param_pack(oct_seq, "bbbbbb", @@ -229,12 +230,13 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self) IRCOMM_PORT_TYPE, 1, IRCOMM_SERIAL); /* Register parameters with LM-IAS */ - irias_add_octseq_attrib(self->obj, "Parameters", oct_seq, 6); + irias_add_octseq_attrib(self->obj, "Parameters", oct_seq, 6, + IAS_KERNEL_ATTR); irias_insert_object(self->obj); } self->skey = irlmp_register_service(hints); self->ckey = irlmp_register_client( - hints, ircomm_tty_discovery_indication, NULL); + hints, ircomm_tty_discovery_indication, NULL, (void *) self); } /* @@ -302,7 +304,8 @@ int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self) * device it is, and which services it has. * */ -static void ircomm_tty_discovery_indication(discovery_t *discovery) +static void ircomm_tty_discovery_indication(discovery_t *discovery, + void *priv) { struct ircomm_tty_cb *self; struct ircomm_tty_info info; diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c index ca2903316..c77ca6268 100644 --- a/net/irda/irda_device.c +++ b/net/irda/irda_device.c @@ -58,6 +58,8 @@ extern int irtty_init(void); extern int nsc_ircc_init(void); extern int ircc_init(void); +extern int toshoboe_init(void); +extern int litelink_init(void); extern int w83977af_init(void); extern int esi_init(void); extern int tekram_init(void); @@ -183,7 +185,7 @@ void irda_device_set_media_busy(struct net_device *dev, int status) IRDA_DEBUG( 4, "Media busy!\n"); } else { self->media_busy = FALSE; - del_timer(&self->media_busy_timer); + irlap_stop_mbusy_timer(self); } } @@ -379,7 +381,7 @@ struct irda_task *irda_task_execute(void *instance, init_timer(&task->timer); /* Register task */ - hashbin_insert(tasks, (queue_t *) task, (int) task, NULL); + hashbin_insert(tasks, (irda_queue_t *) task, (int) task, NULL); /* No time to waste, so lets get going! */ ret = irda_task_kick(task); @@ -518,7 +520,7 @@ int irda_device_register_dongle(struct dongle_reg *new) } /* Insert IrDA dongle into hashbin */ - hashbin_insert(dongles, (queue_t *) new, new->type, NULL); + hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL); return 0; } diff --git a/net/irda/iriap.c b/net/irda/iriap.c index 5f1140525..03014ac0d 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -107,7 +107,7 @@ int __init iriap_init(void) /* Register the Device object with LM-IAS */ obj = irias_new_object("Device", IAS_DEVICE_ID); - irias_add_string_attrib(obj, "DeviceName", "Linux"); + irias_add_string_attrib(obj, "DeviceName", "Linux", IAS_KERNEL_ATTR); oct_seq[0] = 0x01; /* Version 1 */ oct_seq[1] = 0x00; /* IAS support bits */ @@ -115,7 +115,8 @@ int __init iriap_init(void) #ifdef CONFIG_IRDA_ULTRA oct_seq[2] |= 0x04; /* Connectionless Data support */ #endif - irias_add_octseq_attrib(obj, "IrLMPSupport", oct_seq, 3); + irias_add_octseq_attrib(obj, "IrLMPSupport", oct_seq, 3, + IAS_KERNEL_ATTR); irias_insert_object(obj); /* @@ -179,7 +180,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, init_timer(&self->watchdog_timer); - hashbin_insert(iriap, (queue_t *) self, (int) self, NULL); + hashbin_insert(iriap, (irda_queue_t *) self, (int) self, NULL); /* Initialize state machines */ iriap_next_client_state(self, S_DISCONNECT); @@ -866,7 +867,7 @@ static int iriap_data_indication(void *instance, void *sap, iriap_getvaluebyclass_confirm(self, skb); break; case IAS_CLASS_UNKNOWN: - WARNING(__FUNCTION__ "(), No such class!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), No such class!\n"); /* Finished, close connection! */ iriap_disconnect_request(self); @@ -880,7 +881,7 @@ static int iriap_data_indication(void *instance, void *sap, dev_kfree_skb(skb); break; case IAS_ATTRIB_UNKNOWN: - WARNING(__FUNCTION__ "(), No such attribute!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), No such attribute!\n"); /* Finished, close connection! */ iriap_disconnect_request(self); @@ -889,7 +890,7 @@ static int iriap_data_indication(void *instance, void *sap, * no to use self anymore after calling confirm */ if (self->confirm) - self->confirm(IAS_CLASS_UNKNOWN, 0, NULL, + self->confirm(IAS_ATTRIB_UNKNOWN, 0, NULL, self->priv); dev_kfree_skb(skb); break; diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c index 17ad3801d..4a8fbed4c 100644 --- a/net/irda/irias_object.c +++ b/net/irda/irias_object.c @@ -148,6 +148,37 @@ int irias_delete_object(struct ias_object *obj) } /* + * Function irias_delete_attrib (obj) + * + * Remove attribute from hashbin and, if it was the last attribute of + * the object, remove the object as well. + * + */ +int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib) +{ + struct ias_attrib *node; + + ASSERT(obj != NULL, return -1;); + ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;); + ASSERT(attrib != NULL, return -1;); + + /* Remove atribute from object */ + node = hashbin_remove(obj->attribs, 0, attrib->name); + if (!node) + return 0; /* Already removed or non-existent */ + + /* Deallocate attribute */ + __irias_delete_attrib(node); + + /* Check if object has still some attributes */ + node = (struct ias_attrib *) hashbin_get_first(obj->attribs); + if (!node) + irias_delete_object(obj); + + return 0; +} + +/* * Function irias_insert_object (obj) * * Insert an object into the LM-IAS database @@ -158,7 +189,7 @@ void irias_insert_object(struct ias_object *obj) ASSERT(obj != NULL, return;); ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); - hashbin_insert(objects, (queue_t *) obj, 0, obj->name); + hashbin_insert(objects, (irda_queue_t *) obj, 0, obj->name); } /* @@ -201,7 +232,8 @@ struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name) * Add attribute to object * */ -void irias_add_attrib( struct ias_object *obj, struct ias_attrib *attrib) +void irias_add_attrib( struct ias_object *obj, struct ias_attrib *attrib, + int owner) { ASSERT(obj != NULL, return;); ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); @@ -209,7 +241,10 @@ void irias_add_attrib( struct ias_object *obj, struct ias_attrib *attrib) ASSERT(attrib != NULL, return;); ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;); - hashbin_insert(obj->attribs, (queue_t *) attrib, 0, attrib->name); + /* Set if attrib is owned by kernel or user space */ + attrib->value->owner = owner; + + hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name); } /* @@ -262,7 +297,8 @@ int irias_object_change_attribute(char *obj_name, char *attrib_name, * Add an integer attribute to an LM-IAS object * */ -void irias_add_integer_attrib(struct ias_object *obj, char *name, int value) +void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, + int owner) { struct ias_attrib *attrib; @@ -284,7 +320,7 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value) /* Insert value */ attrib->value = irias_new_integer_value(value); - irias_add_attrib(obj, attrib); + irias_add_attrib(obj, attrib, owner); } /* @@ -295,7 +331,7 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value) */ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, - int len) + int len, int owner) { struct ias_attrib *attrib; @@ -319,7 +355,7 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, attrib->value = irias_new_octseq_value( octets, len); - irias_add_attrib(obj, attrib); + irias_add_attrib(obj, attrib, owner); } /* @@ -328,7 +364,8 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, * Add a string attribute to an LM-IAS object * */ -void irias_add_string_attrib(struct ias_object *obj, char *name, char *value) +void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, + int owner) { struct ias_attrib *attrib; @@ -351,7 +388,7 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value) attrib->value = irias_new_string_value(value); - irias_add_attrib(obj, attrib); + irias_add_attrib(obj, attrib, owner); } /* diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c index 7c2d5b94e..e3a3ada15 100644 --- a/net/irda/irlan/irlan_client.c +++ b/net/irda/irlan/irlan_client.c @@ -104,8 +104,6 @@ void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout) */ void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr) { - struct irmanager_event mgr_event; - IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); @@ -117,41 +115,24 @@ void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr) */ if ((self->client.state != IRLAN_IDLE) || (self->provider.access_type == ACCESS_DIRECT)) - return; + { + IRDA_DEBUG(0, __FUNCTION__ "(), already awake!\n"); + return; + } - /* saddr may have changed! */ + /* Address may have changed! */ self->saddr = saddr; - - /* Before we try to connect, we check if network device is up. If it - * is up, that means that the "user" really wants to connect. If not - * we notify the user about the possibility of an IrLAN connection - */ - if (netif_running(&self->dev)) { - /* Open TSAPs */ - irlan_client_open_ctrl_tsap(self); - irlan_open_data_tsap(self); - - irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL); - } else if (self->notify_irmanager) { - /* - * Tell irmanager that the device can now be - * configured but only if the device was not taken - * down by the user - */ - mgr_event.event = EVENT_IRLAN_START; - strcpy(mgr_event.devname, self->dev.name); - irmanager_notify(&mgr_event); - - /* - * We set this so that we only notify once, since if - * configuration of the network device fails, the user - * will have to sort it out first anyway. No need to - * try again. - */ - self->notify_irmanager = FALSE; + + if (self->disconnect_reason == LM_USER_REQUEST) { + IRDA_DEBUG(0, __FUNCTION__ "(), still stopped by user\n"); + return; } - /* Restart watchdog timer */ - irlan_start_watchdog_timer(self, IRLAN_TIMEOUT); + + /* Open TSAPs */ + irlan_client_open_ctrl_tsap(self); + irlan_open_data_tsap(self); + + irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL); /* Start kick timer */ irlan_client_start_kick_timer(self, 2*HZ); @@ -163,7 +144,7 @@ void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr) * Remote device with IrLAN server support discovered * */ -void irlan_client_discovery_indication(discovery_t *discovery) +void irlan_client_discovery_indication(discovery_t *discovery, void *priv) { struct irlan_cb *self; __u32 saddr, daddr; @@ -176,29 +157,16 @@ void irlan_client_discovery_indication(discovery_t *discovery) saddr = discovery->saddr; daddr = discovery->daddr; - /* - * Check if we already dealing with this provider. - */ - self = (struct irlan_cb *) hashbin_find(irlan, daddr, NULL); - if (self) { + /* Find instance */ + self = (struct irlan_cb *) hashbin_get_first(irlan); + if (self) { ASSERT(self->magic == IRLAN_MAGIC, return;); IRDA_DEBUG(1, __FUNCTION__ "(), Found instance (%08x)!\n", daddr); irlan_client_wakeup(self, saddr, daddr); - - return; } - - /* - * We have no instance for daddr, so start a new one - */ - IRDA_DEBUG(1, __FUNCTION__ "(), starting new instance!\n"); - self = irlan_open(saddr, daddr, TRUE); - - /* Restart watchdog timer */ - irlan_start_watchdog_timer(self, IRLAN_TIMEOUT); } /* @@ -449,9 +417,7 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param, ASSERT(self != NULL, return;); ASSERT(self->magic == IRLAN_MAGIC, return;); - /* - * Media type - */ + /* Media type */ if (strcmp(param, "MEDIA") == 0) { if (strcmp(value, "802.3") == 0) self->media = MEDIA_802_3; @@ -487,9 +453,7 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param, IRDA_DEBUG(2, __FUNCTION__ "(), unknown access type!\n"); } } - /* - * IRLAN version - */ + /* IRLAN version */ if (strcmp(param, "IRLAN_VER") == 0) { IRDA_DEBUG(4, "IrLAN version %d.%d\n", (__u8) value[0], (__u8) value[1]); @@ -498,9 +462,7 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param, self->version[1] = value[1]; return; } - /* - * Which remote TSAP to use for data channel - */ + /* Which remote TSAP to use for data channel */ if (strcmp(param, "DATA_CHAN") == 0) { self->dtsap_sel_data = value[0]; IRDA_DEBUG(4, "Data TSAP = %02x\n", self->dtsap_sel_data); @@ -521,9 +483,7 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param, self->client.max_frame); } - /* - * RECONNECT_KEY, in case the link goes down! - */ + /* RECONNECT_KEY, in case the link goes down! */ if (strcmp(param, "RECONNECT_KEY") == 0) { IRDA_DEBUG(4, "Got reconnect key: "); /* for (i = 0; i < val_len; i++) */ @@ -532,9 +492,7 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param, self->client.key_len = val_len; IRDA_DEBUG(4, "\n"); } - /* - * FILTER_ENTRY, have we got an ethernet address? - */ + /* FILTER_ENTRY, have we got an ethernet address? */ if (strcmp(param, "FILTER_ENTRY") == 0) { bytes = value; IRDA_DEBUG(4, "Ethernet address = %02x:%02x:%02x:%02x:%02x:%02x\n", diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index 5975909fe..686c163dc 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c @@ -50,6 +50,14 @@ #include #include + +/* + * Send gratuitous ARP when connected to a new AP or not. May be a clever + * thing to do, but for some reason the machine crashes if you use DHCP. So + * lets not use it by default. + */ +#undef CONFIG_IRLAN_SEND_GRATUITOUS_ARP + /* extern char sysctl_devname[]; */ /* @@ -62,6 +70,7 @@ static __u32 ckey, skey; static int eth = 0; /* Use "eth" or "irlan" name for devices */ static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */ +#ifdef CONFIG_PROC_FS static char *irlan_state[] = { "IRLAN_IDLE", "IRLAN_QUERY", @@ -88,6 +97,7 @@ static char *irlan_media[] = { "802.3", "802.5" }; +#endif /* CONFIG_PROC_FS */ static void __irlan_close(struct irlan_cb *self); static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, @@ -102,59 +112,6 @@ extern struct proc_dir_entry *proc_irda; #endif /* CONFIG_PROC_FS */ /* - * Function irlan_watchdog_timer_expired (data) - * - * Something has gone wrong during the connection establishment - * - */ -void irlan_watchdog_timer_expired(void *data) -{ - struct irmanager_event mgr_event; - struct irlan_cb *self; - - IRDA_DEBUG(0, __FUNCTION__ "()\n"); - - self = (struct irlan_cb *) data; - - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRLAN_MAGIC, return;); - - /* Check if device still configured */ - if (netif_running(&self->dev)) { - IRDA_DEBUG(0, __FUNCTION__ - "(), notifying irmanager to stop irlan!\n"); - mgr_event.event = EVENT_IRLAN_STOP; - sprintf(mgr_event.devname, "%s", self->dev.name); - irmanager_notify(&mgr_event); - - /* - * We set this to false, so that irlan_dev_close known that - * notify_irmanager should actually be set to TRUE again - * instead of FALSE, since this close has not been initiated - * by the user. - */ - self->notify_irmanager = FALSE; - } else { - IRDA_DEBUG(0, __FUNCTION__ "(), closing instance!\n"); - /*irlan_close(self);*/ - } -} - -/* - * Function irlan_start_watchdog_timer (self, timeout) - * - * - * - */ -void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout) -{ - IRDA_DEBUG(4, __FUNCTION__ "()\n"); - - irda_start_timer(&self->watchdog_timer, timeout, (void *) self, - irlan_watchdog_timer_expired); -} - -/* * Function irlan_init (void) * * Initialize IrLAN layer @@ -165,8 +122,7 @@ int __init irlan_init(void) struct irlan_cb *new; __u16 hints; - IRDA_DEBUG(4, __FUNCTION__"()\n"); - + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Allocate master structure */ irlan = hashbin_new(HB_LOCAL); if (irlan == NULL) { @@ -178,22 +134,20 @@ int __init irlan_init(void) #endif /* CONFIG_PROC_FS */ IRDA_DEBUG(4, __FUNCTION__ "()\n"); - hints = irlmp_service_to_hint(S_LAN); /* Register with IrLMP as a client */ - ckey = irlmp_register_client(hints, irlan_client_discovery_indication, - NULL); + ckey = irlmp_register_client(hints, &irlan_client_discovery_indication, + NULL, NULL); /* Register with IrLMP as a service */ skey = irlmp_register_service(hints); - /* Start the master IrLAN instance */ - new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY, FALSE); + /* Start the master IrLAN instance (the only one for now) */ + new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY); /* The master will only open its (listen) control TSAP */ irlan_provider_open_ctrl_tsap(new); - new->master = TRUE; /* Do some fast discovery! */ irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS); @@ -206,7 +160,6 @@ void irlan_cleanup(void) IRDA_DEBUG(4, __FUNCTION__ "()\n"); irlmp_unregister_client(ckey); - irlmp_unregister_service(skey); #ifdef CONFIG_PROC_FS @@ -242,8 +195,6 @@ int irlan_register_netdev(struct irlan_cb *self) IRDA_DEBUG(2, __FUNCTION__ "(), register_netdev() failed!\n"); return -1; } - self->netdev_registered = TRUE; - return 0; } @@ -253,7 +204,7 @@ int irlan_register_netdev(struct irlan_cb *self) * Open new instance of a client/provider, we should only register the * network device if this instance is ment for a particular client/provider */ -struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev) +struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr) { struct irlan_cb *self; @@ -287,32 +238,28 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev) /* Provider access can only be PEER, DIRECT, or HOSTED */ self->provider.access_type = access; self->media = MEDIA_802_3; - - self->notify_irmanager = TRUE; - + self->disconnect_reason = LM_USER_REQUEST; init_timer(&self->watchdog_timer); init_timer(&self->client.kick_timer); + init_waitqueue_head(&self->open_wait); - hashbin_insert(irlan, (queue_t *) self, daddr, NULL); + hashbin_insert(irlan, (irda_queue_t *) self, daddr, NULL); skb_queue_head_init(&self->client.txq); irlan_next_client_state(self, IRLAN_IDLE); irlan_next_provider_state(self, IRLAN_IDLE); - /* Register network device now, or wait until some later time? */ - if (netdev) - irlan_register_netdev(self); + irlan_register_netdev(self); return self; } /* - * Function irlan_close (self) + * Function __irlan_close (self) * * This function closes and deallocates the IrLAN client instances. Be * aware that other functions which calles client_close() must call * hashbin_remove() first!!! - * */ static void __irlan_close(struct irlan_cb *self) { @@ -333,49 +280,13 @@ static void __irlan_close(struct irlan_cb *self) iriap_close(self->client.iriap); /* Remove frames queued on the control channel */ - while ((skb = skb_dequeue(&self->client.txq))) { + while ((skb = skb_dequeue(&self->client.txq))) dev_kfree_skb(skb); - } - if (self->netdev_registered) { - unregister_netdev(&self->dev); - self->netdev_registered = FALSE; - } + unregister_netdev(&self->dev); self->magic = 0; - kfree(self); -} - -/* - * Function irlan_close (self) - * - * Close instance - * - */ -void irlan_close(struct irlan_cb *self) -{ - struct irlan_cb *entry; - - IRDA_DEBUG(0, __FUNCTION__ "()\n"); - - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRLAN_MAGIC, return;); - - /* Check if device is still configured */ - if (netif_running(&self->dev)) { - IRDA_DEBUG(0, __FUNCTION__ - "(), Device still configured, closing later!\n"); - - /* Give it a chance to reconnect */ - irlan_start_watchdog_timer(self, IRLAN_TIMEOUT); - return; - } - IRDA_DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr); - entry = hashbin_remove(irlan, self->daddr, NULL); - - ASSERT(entry == self, return;); - - __irlan_close(self); + kfree(self); } /* @@ -419,7 +330,7 @@ void irlan_connect_indication(void *instance, void *sap, struct qos_info *qos, irlan_open_unicast_addr(self); } /* Ready to transfer Ethernet frames (at last) */ - netif_start_queue(&self->dev); + netif_start_queue(&self->dev); /* Clear reason */ } void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos, @@ -454,7 +365,11 @@ void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos, /* Ready to transfer Ethernet frames */ netif_start_queue(&self->dev); + self->disconnect_reason = 0; /* Clear reason */ +#ifdef CONFIG_IRLAN_SEND_GRATUITOUS_ARP irlan_eth_send_gratuitous_arp(&self->dev); +#endif + wake_up_interruptible(&self->open_wait); } /* @@ -483,28 +398,34 @@ void irlan_disconnect_indication(void *instance, void *sap, LM_REASON reason, IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n"); - switch(reason) { + /* Save reason so we know if we should try to reconnect or not */ + self->disconnect_reason = reason; + + switch (reason) { case LM_USER_REQUEST: /* User request */ - irlan_close(self); + IRDA_DEBUG(2, __FUNCTION__ "(), User requested\n"); break; case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */ - irlan_start_watchdog_timer(self, IRLAN_TIMEOUT); + IRDA_DEBUG(2, __FUNCTION__ "(), Unexpected IrLAP disconnect\n"); break; case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */ - IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), IrLAP connect failed\n"); break; case LM_LAP_RESET: /* IrLAP reset */ - IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), IrLAP reset\n"); break; case LM_INIT_DISCONNECT: - IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), IrLMP connect failed\n"); break; default: + ERROR(__FUNCTION__ "(), Unknown disconnect reason\n"); break; } irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL); irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL); + + wake_up_interruptible(&self->open_wait); } void irlan_open_data_tsap(struct irlan_cb *self) @@ -553,9 +474,7 @@ void irlan_close_tsaps(struct irlan_cb *self) ASSERT(self != NULL, return;); ASSERT(self->magic == IRLAN_MAGIC, return;); - /* - * Disconnect and close all open TSAP connections - */ + /* Disconnect and close all open TSAP connections */ if (self->tsap_data) { irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL); irttp_close_tsap(self->tsap_data); @@ -573,6 +492,7 @@ void irlan_close_tsaps(struct irlan_cb *self) irttp_close_tsap(self->provider.tsap_ctrl); self->provider.tsap_ctrl = NULL; } + self->disconnect_reason = LM_USER_REQUEST; } /* @@ -595,7 +515,8 @@ void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel) */ if (!irias_find_object("IrLAN")) { obj = irias_new_object("IrLAN", IAS_IRLAN_ID); - irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel); + irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel, + IAS_KERNEL_ATTR); irias_insert_object(obj); } else { new_value = irias_new_integer_value(tsap_sel); @@ -607,18 +528,23 @@ void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel) if (!irias_find_object("PnP")) { obj = irias_new_object("PnP", IAS_PNP_ID); #if 0 - irias_add_string_attrib(obj, "Name", sysctl_devname); + irias_add_string_attrib(obj, "Name", sysctl_devname, + IAS_KERNEL_ATTR); #else - irias_add_string_attrib(obj, "Name", "Linux"); + irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR); #endif - irias_add_string_attrib(obj, "DeviceID", "HWP19F0"); - irias_add_integer_attrib(obj, "CompCnt", 1); + irias_add_string_attrib(obj, "DeviceID", "HWP19F0", + IAS_KERNEL_ATTR); + irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR); if (self->provider.access_type == ACCESS_PEER) - irias_add_string_attrib(obj, "Comp#01", "PNP8389"); + irias_add_string_attrib(obj, "Comp#01", "PNP8389", + IAS_KERNEL_ATTR); else - irias_add_string_attrib(obj, "Comp#01", "PNP8294"); + irias_add_string_attrib(obj, "Comp#01", "PNP8294", + IAS_KERNEL_ATTR); - irias_add_string_attrib(obj, "Manufacturer", "Linux-IrDA Project"); + irias_add_string_attrib(obj, "Manufacturer", + "Linux-IrDA Project", IAS_KERNEL_ATTR); irias_insert_object(obj); } } @@ -633,7 +559,7 @@ int irlan_run_ctrl_tx_queue(struct irlan_cb *self) { struct sk_buff *skb; - IRDA_DEBUG(3, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); if (irda_lock(&self->client.tx_busy) == FALSE) return -EBUSY; @@ -652,7 +578,7 @@ int irlan_run_ctrl_tx_queue(struct irlan_cb *self) dev_kfree_skb(skb); return -1; } - IRDA_DEBUG(3, __FUNCTION__ "(), sending ...\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), sending ...\n"); return irttp_data_request(self->client.tsap_ctrl, skb); } @@ -741,7 +667,6 @@ void irlan_open_data_channel(struct irlan_cb *self) /* self->use_udata = TRUE; */ - /* irttp_data_request(self->client.tsap_ctrl, skb); */ irlan_ctrl_data_request(self, skb); } @@ -810,7 +735,6 @@ void irlan_open_unicast_addr(struct irlan_cb *self) irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED"); irlan_insert_string_param(skb, "FILTER_MODE", "FILTER"); - /* irttp_data_request(self->client.tsap_ctrl, skb); */ irlan_ctrl_data_request(self, skb); } @@ -852,7 +776,6 @@ void irlan_set_broadcast_filter(struct irlan_cb *self, int status) else irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); - /* irttp_data_request(self->client.tsap_ctrl, skb); */ irlan_ctrl_data_request(self, skb); } @@ -892,7 +815,6 @@ void irlan_set_multicast_filter(struct irlan_cb *self, int status) else irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); - /* irttp_data_request(self->client.tsap_ctrl, skb); */ irlan_ctrl_data_request(self, skb); } @@ -930,7 +852,6 @@ void irlan_get_unicast_addr(struct irlan_cb *self) irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED"); irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC"); - /* irttp_data_request(self->client.tsap_ctrl, skb); */ irlan_ctrl_data_request(self, skb); } @@ -965,8 +886,6 @@ void irlan_get_media_char(struct irlan_cb *self) frame[1] = 0x01; /* One parameter */ irlan_insert_string_param(skb, "MEDIA", "802.3"); - - /* irttp_data_request(self->client.tsap_ctrl, skb); */ irlan_ctrl_data_request(self, skb); } @@ -1169,35 +1088,32 @@ static int irlan_proc_read(char *buf, char **start, off_t offset, int len) while (self != NULL) { ASSERT(self->magic == IRLAN_MAGIC, return len;); - /* Don't display the master server */ - if (self->master == 0) { - len += sprintf(buf+len, "ifname: %s,\n", - self->dev.name); - len += sprintf(buf+len, "client state: %s, ", - irlan_state[ self->client.state]); - len += sprintf(buf+len, "provider state: %s,\n", - irlan_state[ self->provider.state]); - len += sprintf(buf+len, "saddr: %#08x, ", - self->saddr); - len += sprintf(buf+len, "daddr: %#08x\n", - self->daddr); - len += sprintf(buf+len, "version: %d.%d,\n", - self->version[1], self->version[0]); - len += sprintf(buf+len, "access type: %s\n", - irlan_access[self->client.access_type]); - len += sprintf(buf+len, "media: %s\n", - irlan_media[self->media]); - - len += sprintf(buf+len, "local filter:\n"); - len += sprintf(buf+len, "remote filter: "); - len += irlan_print_filter(self->client.filter_type, - buf+len); + len += sprintf(buf+len, "ifname: %s,\n", + self->dev.name); + len += sprintf(buf+len, "client state: %s, ", + irlan_state[ self->client.state]); + len += sprintf(buf+len, "provider state: %s,\n", + irlan_state[ self->provider.state]); + len += sprintf(buf+len, "saddr: %#08x, ", + self->saddr); + len += sprintf(buf+len, "daddr: %#08x\n", + self->daddr); + len += sprintf(buf+len, "version: %d.%d,\n", + self->version[1], self->version[0]); + len += sprintf(buf+len, "access type: %s\n", + irlan_access[self->client.access_type]); + len += sprintf(buf+len, "media: %s\n", + irlan_media[self->media]); + + len += sprintf(buf+len, "local filter:\n"); + len += sprintf(buf+len, "remote filter: "); + len += irlan_print_filter(self->client.filter_type, + buf+len); - len += sprintf(buf+len, "tx busy: %s\n", - netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE"); + len += sprintf(buf+len, "tx busy: %s\n", + netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE"); - len += sprintf(buf+len, "\n"); - } + len += sprintf(buf+len, "\n"); self = (struct irlan_cb *) hashbin_get_next(irlan); } @@ -1272,8 +1188,9 @@ MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); MODULE_PARM(eth, "i"); +MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)"); MODULE_PARM(access, "i"); -MODULE_PARM(timeout, "i"); +MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3"); /* * Function init_module (void) diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index 1b46ab5b8..007c4acfd 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -48,7 +48,6 @@ */ int irlan_eth_init(struct net_device *dev) { - struct irmanager_event mgr_event; struct irlan_cb *self; IRDA_DEBUG(2, __FUNCTION__"()\n"); @@ -85,22 +84,6 @@ int irlan_eth_init(struct net_device *dev) get_random_bytes(dev->dev_addr+5, 1); } - /* - * Network device has now been registered, so tell irmanager about - * it, so it can be configured with network parameters - */ - mgr_event.event = EVENT_IRLAN_START; - sprintf(mgr_event.devname, "%s", self->dev.name); - irmanager_notify(&mgr_event); - - /* - * We set this so that we only notify once, since if - * configuration of the network device fails, the user - * will have to sort it out first anyway. No need to - * try again. - */ - self->notify_irmanager = FALSE; - return 0; } @@ -123,14 +106,16 @@ int irlan_eth_open(struct net_device *dev) ASSERT(self != NULL, return -1;); /* Ready to play! */ -/* netif_start_queue(dev) */ /* Wait until data link is ready */ - - self->notify_irmanager = TRUE; + netif_stop_queue(dev); /* Wait until data link is ready */ /* We are now open, so time to do some work */ + self->disconnect_reason = 0; irlan_client_wakeup(self, self->saddr, self->daddr); irlan_mod_inc_use_count(); + + /* Make sure we have a hardware address before we return, so DHCP clients gets happy */ + interruptible_sleep_on(&self->open_wait); return 0; } @@ -146,7 +131,8 @@ int irlan_eth_open(struct net_device *dev) int irlan_eth_close(struct net_device *dev) { struct irlan_cb *self = (struct irlan_cb *) dev->priv; - + struct sk_buff *skb; + IRDA_DEBUG(2, __FUNCTION__ "()\n"); /* Stop device */ @@ -155,20 +141,17 @@ int irlan_eth_close(struct net_device *dev) irlan_mod_dec_use_count(); irlan_close_data_channel(self); - irlan_close_tsaps(self); irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL); irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL); - irlan_start_watchdog_timer(self, IRLAN_TIMEOUT); - - /* Device closed by user! */ - if (self->notify_irmanager) - self->notify_irmanager = FALSE; - else - self->notify_irmanager = TRUE; + /* Remove frames queued on the control channel */ + while ((skb = skb_dequeue(&self->client.txq))) + dev_kfree_skb(skb); + self->client.tx_busy = 0; + return 0; } diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c index aeac03f7b..e06807bd9 100644 --- a/net/irda/irlan/irlan_provider.c +++ b/net/irda/irlan/irlan_provider.c @@ -116,16 +116,16 @@ static int irlan_provider_data_indication(void *instance, void *sap, /* * Function irlan_provider_connect_indication (handle, skb, priv) * - * Got connection from peer IrLAN layer + * Got connection from peer IrLAN client * */ static void irlan_provider_connect_indication(void *instance, void *sap, struct qos_info *qos, __u32 max_sdu_size, __u8 max_header_size, - struct sk_buff *skb) + struct sk_buff *skb) { - struct irlan_cb *self, *new; + struct irlan_cb *self; struct tsap_cb *tsap; __u32 saddr, daddr; @@ -137,82 +137,24 @@ static void irlan_provider_connect_indication(void *instance, void *sap, ASSERT(self != NULL, return;); ASSERT(self->magic == IRLAN_MAGIC, return;); - self->provider.max_sdu_size = max_sdu_size; - self->provider.max_header_size = max_header_size; - ASSERT(tsap == self->provider.tsap_ctrl,return;); ASSERT(self->provider.state == IRLAN_IDLE, return;); daddr = irttp_get_daddr(tsap); saddr = irttp_get_saddr(tsap); + self->provider.max_sdu_size = max_sdu_size; + self->provider.max_header_size = max_header_size; - /* Check if we already dealing with this client or peer */ - new = (struct irlan_cb *) hashbin_find(irlan, daddr, NULL); - if (new) { - ASSERT(new->magic == IRLAN_MAGIC, return;); - IRDA_DEBUG(0, __FUNCTION__ "(), found instance!\n"); - - /* Update saddr, since client may have moved to a new link */ - new->saddr = saddr; - IRDA_DEBUG(2, __FUNCTION__ "(), saddr=%08x\n", new->saddr); - - /* Make sure that any old provider control TSAP is removed */ - if ((new != self) && new->provider.tsap_ctrl) { - irttp_disconnect_request(new->provider.tsap_ctrl, - NULL, P_NORMAL); - irttp_close_tsap(new->provider.tsap_ctrl); - new->provider.tsap_ctrl = NULL; - } - } else { - /* This must be the master instance, so start a new instance */ - IRDA_DEBUG(0, __FUNCTION__ "(), starting new provider!\n"); - - new = irlan_open(saddr, daddr, TRUE); - } - - /* - * Check if the connection came in on the master server, or the - * slave server. If it came on the slave, then everything is - * really, OK (reconnect), if not we need to dup the connection and - * hand it over to the slave. - */ - if (new != self) { - - /* Now attach up the new "socket" */ - new->provider.tsap_ctrl = irttp_dup(self->provider.tsap_ctrl, - new); - if (!new->provider.tsap_ctrl) { - IRDA_DEBUG(0, __FUNCTION__ "(), dup failed!\n"); - return; - } - - /* new->stsap_sel = new->tsap->stsap_sel; */ - new->dtsap_sel_ctrl = new->provider.tsap_ctrl->dtsap_sel; - - /* Clean up the original one to keep it in listen state */ - self->provider.tsap_ctrl->dtsap_sel = LSAP_ANY; - self->provider.tsap_ctrl->lsap->dlsap_sel = LSAP_ANY; - self->provider.tsap_ctrl->lsap->lsap_state = LSAP_DISCONNECTED; - - /* - * Use the new instance from here instead of the master - * struct! - */ - self = new; - } - /* Check if network device has been registered */ - if (!self->netdev_registered) - irlan_register_netdev(self); - irlan_do_provider_event(self, IRLAN_CONNECT_INDICATION, NULL); /* * If we are in peer mode, the client may not have got the discovery * indication it needs to make progress. If the client is still in - * IDLE state, we must kick it to + * IDLE state, we must kick it. */ if ((self->provider.access_type == ACCESS_PEER) && - (self->client.state == IRLAN_IDLE)) { + (self->client.state == IRLAN_IDLE)) + { irlan_client_wakeup(self, self->saddr, self->daddr); } } @@ -231,11 +173,6 @@ void irlan_provider_connect_response(struct irlan_cb *self, /* Just accept */ irttp_connect_response(tsap, IRLAN_MTU, NULL); - - /* Check if network device has been registered */ - if (!self->netdev_registered) - irlan_register_netdev(self); - } void irlan_provider_disconnect_indication(void *instance, void *sap, diff --git a/net/irda/irlap.c b/net/irda/irlap.c index 1c2958c4b..38d66d327 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -154,7 +154,7 @@ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos) irlap_next_state(self, LAP_NDM); - hashbin_insert(irlap, (queue_t *) self, self->saddr, NULL); + hashbin_insert(irlap, (irda_queue_t *) self, self->saddr, NULL); irlmp_register_link(self, self->saddr, &self->notify); @@ -232,7 +232,8 @@ void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) ASSERT(self->magic == LAP_MAGIC, return;); irlap_init_qos_capabilities(self, NULL); /* No user QoS! */ - + + skb_get(skb); /*LEVEL4*/ irlmp_link_connect_indication(self->notify.instance, self->saddr, self->daddr, &self->qos_tx, skb); } @@ -248,6 +249,7 @@ void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb) IRDA_DEBUG(4, __FUNCTION__ "()\n"); irlap_do_event(self, CONNECT_RESPONSE, skb, NULL); + kfree_skb(skb); } /* @@ -292,6 +294,7 @@ void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb) ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); + skb_get(skb); /*LEVEL4*/ irlmp_link_connect_confirm(self->notify.instance, &self->qos_tx, skb); } @@ -310,6 +313,7 @@ void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb, #ifdef CONFIG_IRDA_COMPRESSION if (self->qos_tx.compression.value) { + skb_get(skb); /*LEVEL4*/ skb = irlap_decompress_frame(self, skb); if (!skb) { IRDA_DEBUG(1, __FUNCTION__ "(), Decompress error!\n"); @@ -317,6 +321,7 @@ void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb, } } #endif + skb_get(skb); /*LEVEL4*/ irlmp_link_data_indication(self->notify.instance, skb, unreliable); } @@ -373,6 +378,7 @@ void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb, ASSERT(skb != NULL, return;); } irlap_do_event(self, SEND_I_CMD, skb, NULL); + kfree_skb(skb); } else skb_queue_tail(&self->txq, skb); } @@ -422,6 +428,7 @@ void irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb) /* Hide LAP header from IrLMP layer */ skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER); + skb_get(skb); /*LEVEL4*/ irlmp_link_unitdata_indication(self->notify.instance, skb); } #endif /* CONFIG_IRDA_ULTRA */ @@ -610,7 +617,7 @@ void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery) * * */ -void irlap_status_indication(int quality_of_link) +void irlap_status_indication(struct irlap_cb *self, int quality_of_link) { switch (quality_of_link) { case STATUS_NO_ACTIVITY: @@ -622,7 +629,8 @@ void irlap_status_indication(int quality_of_link) default: break; } - irlmp_status_indication(quality_of_link, LOCK_NO_CHANGE); + irlmp_status_indication(self->notify.instance, + quality_of_link, LOCK_NO_CHANGE); } /* @@ -664,11 +672,16 @@ void irlap_reset_confirm(void) */ int irlap_generate_rand_time_slot(int S, int s) { + static int rand; int slot; ASSERT((S - s) > 0, return 0;); - slot = s + jiffies % (S-s); + rand += jiffies; + rand ^= (rand << 12); + rand ^= (rand >> 20); + + slot = s + rand % (S-s); ASSERT((slot >= s) || (slot < S), return 0;); @@ -863,6 +876,8 @@ void irlap_flush_all_queues(struct irlap_cb *self) */ void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now) { + struct sk_buff *skb; + IRDA_DEBUG(0, __FUNCTION__ "(), setting speed to %d\n", speed); ASSERT(self != NULL, return;); @@ -871,8 +886,11 @@ void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now) self->speed = speed; /* Change speed now, or just piggyback speed on frames */ - if (now) - irda_device_change_speed(self->netdev, speed); + if (now) { + /* Send down empty frame to trigger speed change */ + skb = dev_alloc_skb(0); + irlap_queue_xmit(self, skb); + } } #ifdef CONFIG_IRDA_COMPRESSION @@ -973,8 +991,8 @@ void irlap_init_qos_capabilities(struct irlap_cb *self, /* Set data size */ /*self->qos_rx.data_size.bits &= 0x03;*/ - /* Set disconnect time */ - self->qos_rx.link_disc_time.bits &= 0x07; + /* Set disconnect time -> done properly in qos.c */ + /*self->qos_rx.link_disc_time.bits &= 0x07;*/ irda_qos_bits_to_value(&self->qos_rx); } @@ -998,7 +1016,7 @@ void irlap_apply_default_connection_parameters(struct irlap_cb *self) irda_device_set_media_busy(self->netdev, TRUE); /* Default value in NDM */ - self->bofs_count = 11; + self->bofs_count = 12; /* * Generate random connection address for this session, which must @@ -1026,8 +1044,8 @@ void irlap_apply_default_connection_parameters(struct irlap_cb *self) self->qos_rx.data_size.value = 64; self->qos_tx.window_size.value = 1; self->qos_rx.window_size.value = 1; - self->qos_tx.additional_bofs.value = 11; - self->qos_rx.additional_bofs.value = 11; + self->qos_tx.additional_bofs.value = 12; + self->qos_rx.additional_bofs.value = 12; self->qos_tx.link_disc_time.value = 0; self->qos_rx.link_disc_time.value = 0; @@ -1071,7 +1089,12 @@ void irlap_apply_connection_parameters(struct irlap_cb *self) */ ASSERT(self->qos_tx.max_turn_time.value != 0, return;); if (self->qos_tx.link_disc_time.value == 3) - self->N1 = 0; + /* + * If we set N1 to 0, it will trigger immediately, which is + * not what we want. What we really want is to disable it, + * Jean II + */ + self->N1 = -1; /* Disable */ else self->N1 = 3000 / self->qos_tx.max_turn_time.value; diff --git a/net/irda/irlap_comp.c b/net/irda/irlap_comp.c index 942949ac8..e81fc7e4a 100644 --- a/net/irda/irlap_comp.c +++ b/net/irda/irlap_comp.c @@ -63,7 +63,7 @@ int irda_register_compressor( struct compressor *cp) new->cp = cp; /* Insert IrDA compressor into hashbin */ - hashbin_insert( irlap_compressors, (queue_t *) new, cp->compress_proto, + hashbin_insert( irlap_compressors, (irda_queue_t *) new, cp->compress_proto, NULL); return 0; diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c index 08501162e..ec5f6611c 100644 --- a/net/irda/irlap_event.c +++ b/net/irda/irlap_event.c @@ -9,8 +9,8 @@ * Modified at: Sat Dec 25 21:07:57 1999 * Modified by: Dag Brattli * - * Copyright (c) 1998-1999 Dag Brattli , - * Thomas Davis + * Copyright (c) 1998-2000 Dag Brattli , + * Copyright (c) 1998 Thomas Davis * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -230,7 +230,7 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, if (!self || self->magic != LAP_MAGIC) return; - + IRDA_DEBUG(3, __FUNCTION__ "(), event = %s, state = %s\n", irlap_event[event], irlap_state[self->state]); @@ -252,6 +252,7 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, while ((skb = skb_dequeue(&self->txq)) != NULL) { ret = (*state[self->state])(self, SEND_I_CMD, skb, NULL); + kfree_skb(skb); if (ret == -EPROTO) break; /* Try again later! */ } @@ -304,6 +305,17 @@ void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state) if ((state != LAP_XMIT_P) && (state != LAP_XMIT_S)) self->bytes_left = self->line_capacity; #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */ +#ifdef CONFIG_IRDA_ULTRA + /* Send any pending Ultra frames if any */ + /* The higher layers may have sent a few Ultra frames while we + * were doing discovery (either query or reply). Those frames + * have been queued, but were never sent. It is now time to + * send them... + * Jean II */ + if ((state == LAP_NDM) && (!skb_queue_empty(&self->txq_ultra))) + /* Force us to listen 500 ms before sending Ultra */ + irda_device_set_media_busy(self->netdev, TRUE); +#endif /* CONFIG_IRDA_ULTRA */ } /* @@ -351,12 +363,11 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, self->caddr = info->caddr; irlap_next_state(self, LAP_CONN); - + irlap_connect_indication(self, skb); } else { IRDA_DEBUG(0, __FUNCTION__ "(), SNRM frame does not " "contain an I field!\n"); - dev_kfree_skb(skb); } break; case DISCOVERY_REQUEST: @@ -375,6 +386,7 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, self->s = info->s; irlap_send_discovery_xid_frame(self, info->S, info->s, TRUE, info->discovery); + self->frame_sent = FALSE; self->s++; irlap_start_slot_timer(self, self->slot_timeout); @@ -385,12 +397,8 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, /* Assert that this is not the final slot */ if (info->s <= info->S) { - /* self->daddr = info->daddr; */ self->slot = irlap_generate_rand_time_slot(info->S, info->s); - IRDA_DEBUG(4, "XID_CMD: S=%d, s=%d, slot %d\n", info->S, - info->s, self->slot); - if (self->slot == info->s) { discovery_rsp = irlmp_get_discovery_response(); discovery_rsp->daddr = info->daddr; @@ -410,14 +418,34 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_query_timer(self, QUERY_TIMEOUT*info->S); irlap_next_state(self, LAP_REPLY); } - dev_kfree_skb(skb); + else { + /* This is the final slot. How is it possible ? + * This would happen is both discoveries are just slightly + * offset (if they are in sync, all packets are lost). + * Most often, all the discovery requests will be received + * in QUERY state (see my comment there), except for the + * last frame that will come here. + * The big trouble when it happen is that active discovery + * doesn't happen, because nobody answer the discoveries + * frame of the other guy, so the log shows up empty. + * What should we do ? + * Not much. It's too late to answer those discovery frames, + * so we just pass the info to IrLMP who will put it in the + * log (and post an event). + * Jean II + */ + IRDA_DEBUG(1, __FUNCTION__ "(), Receiving final discovery request, missed the discovery slots :-(\n"); + + /* Last discovery request -> in the log */ + irlap_discovery_indication(self, info->discovery); + } break; #ifdef CONFIG_IRDA_ULTRA case SEND_UI_FRAME: /* Only allowed to repeat an operation twice */ for (i=0; ((i<2) && (self->media_busy == FALSE)); i++) { skb = skb_dequeue(&self->txq_ultra); - if (skb) + if (skb) irlap_send_ui_frame(self, skb, CBROADCAST, CMD_FRAME); else @@ -433,7 +461,6 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, if (info->caddr != CBROADCAST) { IRDA_DEBUG(0, __FUNCTION__ "(), not a broadcast frame!\n"); - dev_kfree_skb(skb); } else irlap_unitdata_indication(self, skb); break; @@ -447,19 +474,14 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, * will only be used to send out the same info as the cmd */ irlap_send_test_frame(self, CBROADCAST, info->daddr, skb); - dev_kfree_skb(skb); break; case RECV_TEST_RSP: IRDA_DEBUG(0, __FUNCTION__ "() not implemented!\n"); - dev_kfree_skb(skb); break; default: IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); - if (skb) - dev_kfree_skb(skb); - ret = -1; break; } @@ -492,19 +514,51 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event, WARNING(__FUNCTION__ "(), discovery log is gone! " "maybe the discovery timeout has been set to " "short?\n"); - dev_kfree_skb(skb); break; } hashbin_insert(self->discovery_log, - (queue_t *) info->discovery, + (irda_queue_t *) info->discovery, info->discovery->daddr, NULL); /* Keep state */ /* irlap_next_state(self, LAP_QUERY); */ - dev_kfree_skb(skb); + break; + case RECV_DISCOVERY_XID_CMD: + /* Yes, it is possible to receive those frames in this mode. + * Note that most often the last discovery request won't + * occur here but in NDM state (see my comment there). + * What should we do ? + * Not much. We are currently performing our own discovery, + * therefore we can't answer those frames. We don't want + * to change state either. We just pass the info to + * IrLMP who will put it in the log (and post an event). + * Jean II + */ + + ASSERT(info != NULL, return -1;); + + IRDA_DEBUG(1, __FUNCTION__ "(), Receiving discovery request (s = %d) while performing discovery :-(\n", info->s); + + /* Last discovery request ? */ + if (info->s == 0xff) + irlap_discovery_indication(self, info->discovery); break; case SLOT_TIMER_EXPIRED: + /* + * Wait a little longer if we detect an incomming frame. This + * is not mentioned in the spec, but is a good thing to do, + * since we want to work even with devices that violate the + * timing requirements. + */ + if (irda_device_is_receiving(self->netdev)) { + IRDA_DEBUG(1, __FUNCTION__ + "(), device is slow to answer, " + "waiting some more!\n"); + irlap_start_slot_timer(self, MSECS_TO_JIFFIES(10)); + return ret; + } + if (self->s < self->S) { irlap_send_discovery_xid_frame(self, self->S, self->s, TRUE, @@ -537,9 +591,6 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event, IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); - if (skb) - dev_kfree_skb(skb); - ret = -1; break; } @@ -572,9 +623,7 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event, break; case RECV_DISCOVERY_XID_CMD: ASSERT(info != NULL, return -1;); - /* - * Last frame? - */ + /* Last frame? */ if (info->s == 0xff) { del_timer(&self->query_timer); @@ -595,15 +644,11 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event, self->frame_sent = TRUE; irlap_next_state(self, LAP_REPLY); } - dev_kfree_skb(skb); break; default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); - if (skb) - dev_kfree_skb(skb); - ret = -1; break; } @@ -665,14 +710,12 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_wd_timer(self, self->wd_timeout); irlap_next_state(self, LAP_NRM_S); - dev_kfree_skb(skb); break; case RECV_DISCOVERY_XID_CMD: IRDA_DEBUG(3, __FUNCTION__ "(), event RECV_DISCOVER_XID_CMD!\n"); irlap_next_state(self, LAP_NDM); - dev_kfree_skb(skb); break; case DISCONNECT_REQUEST: irlap_send_dm_frame(self); @@ -682,9 +725,6 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event, IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); - if (skb) - dev_kfree_skb(skb); - ret = -1; break; } @@ -766,7 +806,6 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_wd_timer(self, self->wd_timeout); } else { /* We just ignore the other device! */ - dev_kfree_skb(skb); irlap_next_state(self, LAP_SETUP); } break; @@ -803,14 +842,11 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state(self, LAP_NDM); irlap_disconnect_indication(self, LAP_DISC_INDICATION); - dev_kfree_skb(skb); break; default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); - if (skb) - dev_kfree_skb(skb); - + ret = -1; break; } @@ -860,14 +896,13 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, IRDA_DEBUG(4, __FUNCTION__ "(), Not allowed to transmit more " "bytes!\n"); - skb_queue_head(&self->txq, skb); - + skb_queue_head(&self->txq, skb_get(skb)); /* * We should switch state to LAP_NRM_P, but * that is not possible since we must be sure * that we poll the other side. Since we have * used up our time, the poll timer should - * trigger anyway now,so we just wait for it + * trigger anyway now, so we just wait for it * DB */ return -EPROTO; @@ -900,7 +935,7 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, } else { IRDA_DEBUG(4, __FUNCTION__ "(), Unable to send! remote busy?\n"); - skb_queue_head(&self->txq, skb); + skb_queue_head(&self->txq, skb_get(skb)); /* * The next ret is important, because it tells @@ -929,9 +964,6 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); - if (skb) - dev_kfree_skb(skb); - ret = -EINVAL; break; } @@ -964,7 +996,6 @@ static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state(self, LAP_NDM); irlap_disconnect_indication(self, LAP_DISC_INDICATION); - dev_kfree_skb(skb); break; case FINAL_TIMER_EXPIRED: if (self->retry_count < self->N3) { @@ -985,9 +1016,6 @@ static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event, default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event); - if (skb) - dev_kfree_skb(skb); - ret = -1; break; } @@ -1041,7 +1069,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, /* Keep state, do not move this line */ irlap_next_state(self, LAP_NRM_P); - + irlap_data_indication(self, skb, FALSE); } else { del_timer(&self->final_timer); @@ -1065,7 +1093,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, * upper layers */ irlap_next_state(self, LAP_XMIT_P); - + irlap_data_indication(self, skb, FALSE); /* This is the last frame */ @@ -1102,7 +1130,6 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_final_timer(self, self->final_timeout); irlap_next_state(self, LAP_NRM_P); } - dev_kfree_skb(skb); break; } /* @@ -1124,7 +1151,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, /* Keep state, do not move this line */ irlap_next_state(self, LAP_NRM_P); - + irlap_data_indication(self, skb, FALSE); } else { /* @@ -1142,7 +1169,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, /* Keep state, do not move this line!*/ irlap_next_state(self, LAP_NRM_P); - + irlap_data_indication(self, skb, FALSE); } break; @@ -1171,7 +1198,6 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, self->ack_required = FALSE; } - dev_kfree_skb(skb); break; } @@ -1193,7 +1219,6 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, self->xmitflag = FALSE; } - dev_kfree_skb(skb); break; } IRDA_DEBUG(1, __FUNCTION__ "(), Not implemented!\n"); @@ -1209,6 +1234,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, } else { del_timer(&self->final_timer); irlap_data_indication(self, skb, TRUE); + printk(__FUNCTION__ "(): RECV_UI_FRAME: next state %s\n", irlap_state[self->state]); irlap_start_poll_timer(self, self->poll_timeout); } break; @@ -1270,7 +1296,6 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, irlap_disconnect_indication(self, LAP_RESET_INDICATION); self->xmitflag = TRUE; } - dev_kfree_skb(skb); break; case RECV_RNR_RSP: ASSERT(info != NULL, return -1;); @@ -1285,14 +1310,12 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, /* Start poll timer */ irlap_start_poll_timer(self, self->poll_timeout); - dev_kfree_skb(skb); break; case RECV_FRMR_RSP: del_timer(&self->final_timer); self->xmitflag = TRUE; irlap_next_state(self, LAP_RESET_WAIT); irlap_reset_indication(self); - dev_kfree_skb(skb); break; case FINAL_TIMER_EXPIRED: /* @@ -1331,7 +1354,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, " retry_count=%d\n", self->retry_count); /* Keep state */ } else if (self->retry_count == self->N1) { - irlap_status_indication(STATUS_NO_ACTIVITY); + irlap_status_indication(self, STATUS_NO_ACTIVITY); irlap_wait_min_turn_around(self, &self->qos_tx); irlap_send_rr_frame(self, CMD_FRAME); @@ -1357,7 +1380,6 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, } else irlap_resend_rejected_frames(self, CMD_FRAME); irlap_start_final_timer(self, self->final_timeout); - dev_kfree_skb(skb); break; case RECV_SREJ_RSP: irlap_update_nr_received(self, info->nr); @@ -1367,7 +1389,6 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, } else irlap_resend_rejected_frame(self, CMD_FRAME); irlap_start_final_timer(self, self->final_timeout); - dev_kfree_skb(skb); break; case RECV_RD_RSP: IRDA_DEBUG(0, __FUNCTION__ "(), RECV_RD_RSP\n"); @@ -1381,8 +1402,6 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); - if (skb) - dev_kfree_skb(skb); ret = -1; break; @@ -1428,10 +1447,8 @@ static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state( self, LAP_PCLOSE); break; default: - IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", + IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); - if (skb) - dev_kfree_skb(skb); ret = -1; break; @@ -1467,7 +1484,6 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, irlap_disconnect_indication(self, LAP_NO_RESPONSE); - dev_kfree_skb(skb); break; case RECV_UA_RSP: del_timer(&self->final_timer); @@ -1483,7 +1499,6 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_poll_timer(self, self->poll_timeout); - dev_kfree_skb(skb); break; case FINAL_TIMER_EXPIRED: if (self->retry_count < 3) { @@ -1522,13 +1537,10 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, IRDA_DEBUG(0, __FUNCTION__ "(), SNRM frame contained an I field!\n"); } - dev_kfree_skb(skb); break; default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); - if (skb) - dev_kfree_skb(skb); ret = -1; break; @@ -1566,7 +1578,7 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, * speed and turn-around-time. */ if (skb->len > self->bytes_left) { - skb_queue_head(&self->txq, skb); + skb_queue_head(&self->txq, skb_get(skb)); /* * Switch to NRM_S, this is only possible * when we are in secondary mode, since we @@ -1600,7 +1612,7 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, } } else { IRDA_DEBUG(2, __FUNCTION__ "(), Unable to send!\n"); - skb_queue_head(&self->txq, skb); + skb_queue_head(&self->txq, skb_get(skb)); ret = -EPROTO; } break; @@ -1613,8 +1625,6 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, default: IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); - if (skb) - dev_kfree_skb(skb); ret = -EINVAL; break; @@ -1676,7 +1686,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, #endif /* Keep state, do not move this line */ irlap_next_state(self, LAP_NRM_S); - + irlap_data_indication(self, skb, FALSE); break; } else { @@ -1739,7 +1749,6 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_wd_timer(self, self->wd_timeout); } - dev_kfree_skb(skb); break; } @@ -1778,7 +1787,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, /* Keep state, do not move this line */ irlap_next_state(self, LAP_NRM_S); - + irlap_data_indication(self, skb, FALSE); irlap_start_wd_timer(self, self->wd_timeout); } @@ -1787,11 +1796,9 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, if (ret == NR_INVALID) { IRDA_DEBUG(0, "NRM_S, NR_INVALID not implemented!\n"); - dev_kfree_skb(skb); } if (ret == NS_INVALID) { IRDA_DEBUG(0, "NRM_S, NS_INVALID not implemented!\n"); - dev_kfree_skb(skb); } break; case RECV_UI_FRAME: @@ -1870,7 +1877,6 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, IRDA_DEBUG(1, __FUNCTION__ "(), invalid nr not implemented!\n"); } - dev_kfree_skb(skb); break; case RECV_SNRM_CMD: /* SNRM frame is not allowed to contain an I-field */ @@ -1885,7 +1891,6 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, "(), SNRM frame contained an I-field!\n"); } - dev_kfree_skb(skb); break; case RECV_REJ_CMD: irlap_update_nr_received(self, info->nr); @@ -1895,7 +1900,6 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, } else irlap_resend_rejected_frames(self, CMD_FRAME); irlap_start_wd_timer(self, self->wd_timeout); - dev_kfree_skb(skb); break; case RECV_SREJ_CMD: irlap_update_nr_received(self, info->nr); @@ -1905,31 +1909,34 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, } else irlap_resend_rejected_frame(self, CMD_FRAME); irlap_start_wd_timer(self, self->wd_timeout); - dev_kfree_skb(skb); break; case WD_TIMER_EXPIRED: /* * Wait until retry_count * n matches negotiated threshold/ * disconnect time (note 2 in IrLAP p. 82) + * + * Note : self->wd_timeout = (self->poll_timeout * 2), + * and self->final_timeout == self->poll_timeout, + * which explain why we use (self->retry_count * 2) here !!! + * Jean II */ IRDA_DEBUG(1, __FUNCTION__ "(), retry_count = %d\n", self->retry_count); - if ((self->retry_count < (self->N2/2)) && - (self->retry_count != self->N1/2)) { + if (((self->retry_count * 2) < self->N2) && + ((self->retry_count * 2) != self->N1)) { irlap_start_wd_timer(self, self->wd_timeout); - self->retry_count++; - } else if (self->retry_count == (self->N1/2)) { - irlap_status_indication(STATUS_NO_ACTIVITY); + self->retry_count++; + } else if ((self->retry_count * 2) == self->N1) { + irlap_status_indication(self, STATUS_NO_ACTIVITY); irlap_start_wd_timer(self, self->wd_timeout); self->retry_count++; - } else if (self->retry_count >= self->N2/2) { + } else if ((self->retry_count * 2) >= self->N2) { irlap_apply_default_connection_parameters(self); /* Always switch state before calling upper layers */ irlap_next_state(self, LAP_NDM); - irlap_disconnect_indication(self, LAP_NO_RESPONSE); } break; @@ -1944,7 +1951,6 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, irlap_apply_default_connection_parameters(self); irlap_disconnect_indication(self, LAP_DISC_INDICATION); - dev_kfree_skb(skb); break; case RECV_DISCOVERY_XID_CMD: irlap_wait_min_turn_around(self, &self->qos_tx); @@ -1953,24 +1959,20 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_wd_timer(self, self->wd_timeout); irlap_next_state(self, LAP_NRM_S); - dev_kfree_skb(skb); break; case RECV_TEST_CMD: - /* Remove test frame header */ - skb_pull(skb, sizeof(struct test_frame)); + /* Remove test frame header (only LAP header in NRM) */ + skb_pull(skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER); irlap_wait_min_turn_around(self, &self->qos_tx); irlap_start_wd_timer(self, self->wd_timeout); /* Send response (info will be copied) */ irlap_send_test_frame(self, self->caddr, info->daddr, skb); - dev_kfree_skb(skb); break; default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", event, irlap_event[event]); - if (skb) - dev_kfree_skb(skb); ret = -EINVAL; break; @@ -2005,7 +2007,6 @@ static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event, irlap_apply_default_connection_parameters(self); irlap_disconnect_indication(self, LAP_DISC_INDICATION); - dev_kfree_skb(skb); break; case RECV_DM_RSP: /* Always switch state before calling upper layers */ @@ -2015,7 +2016,6 @@ static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event, irlap_apply_default_connection_parameters(self); irlap_disconnect_indication(self, LAP_DISC_INDICATION); - dev_kfree_skb(skb); break; case WD_TIMER_EXPIRED: irlap_apply_default_connection_parameters(self); @@ -2025,9 +2025,7 @@ static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event, default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", event, irlap_event[event]); - if (skb) - dev_kfree_skb(skb); - + ret = -EINVAL; break; } @@ -2064,8 +2062,6 @@ static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event, default: IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", event, irlap_event[event]); - if (skb) - dev_kfree_skb(skb); ret = -EINVAL; break; diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 830fe6ef7..fff5bef93 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -69,7 +69,8 @@ static inline void irlap_insert_info(struct irlap_cb *self, * Delay equals negotiated BOFs count, plus the number of BOFs to * force the negotiated minimum turnaround time */ - cb->xbofs = self->bofs_count+self->xbofs_delay; + cb->xbofs = self->bofs_count; + cb->xbofs_delay = self->xbofs_delay; /* Reset XBOF's delay (used only for getting min turn time) */ self->xbofs_delay = 0; @@ -164,7 +165,6 @@ static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb, if ((info->caddr == 0x00) || (info->caddr == 0xfe)) { IRDA_DEBUG(3, __FUNCTION__ "(), invalid connection address!\n"); - dev_kfree_skb(skb); return; } @@ -175,13 +175,13 @@ static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb, /* Only accept if addressed directly to us */ if (info->saddr != self->saddr) { IRDA_DEBUG(2, __FUNCTION__ "(), not addressed to us!\n"); - dev_kfree_skb(skb); return; } irlap_do_event(self, RECV_SNRM_CMD, skb, info); - } else + } else { /* Signal that this SNRM frame does not contain and I-field */ irlap_do_event(self, RECV_SNRM_CMD, skb, NULL); + } } /* @@ -408,13 +408,11 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) { IRDA_DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n"); - dev_kfree_skb(skb); return; } if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) { WARNING(__FUNCTION__ "(), kmalloc failed!\n"); - dev_kfree_skb(skb); return; } memset(discovery, 0, sizeof(discovery_t)); @@ -476,7 +474,6 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) { IRDA_DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n"); - dev_kfree_skb(skb); return; } @@ -506,13 +503,18 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, * Check if last frame */ if (info->s == 0xff) { + /* Check if things are sane at this point... */ + if((discovery_info == NULL) || (skb->len < 3)) { + ERROR(__FUNCTION__ "(), discovery frame to short!\n"); + return; + } + /* * We now have some discovery info to deliver! */ discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC); if (!discovery) { WARNING(__FUNCTION__ "(), unable to malloc!\n"); - dev_kfree_skb(skb); return; } @@ -541,7 +543,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, info->discovery = discovery; } else info->discovery = NULL; - + irlap_do_event(self, RECV_DISCOVERY_XID_CMD, skb, info); } @@ -734,7 +736,6 @@ void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb) /* Copy buffer */ tx_skb = skb_clone(skb, GFP_ATOMIC); if (tx_skb == NULL) { - dev_kfree_skb(skb); return; } @@ -747,7 +748,7 @@ void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb) /* * Insert frame in store, in case of retransmissions */ - skb_queue_tail(&self->wx_list, skb); + skb_queue_tail(&self->wx_list, skb_get(skb)); self->vs = (self->vs + 1) % 8; self->ack_required = FALSE; @@ -756,7 +757,7 @@ void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb) irlap_send_i_frame( self, tx_skb, CMD_FRAME); } else { IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n"); - irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME); + irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME); self->window -= 1; } } @@ -781,7 +782,6 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) /* Copy buffer */ tx_skb = skb_clone(skb, GFP_ATOMIC); if (tx_skb == NULL) { - dev_kfree_skb(skb); return; } @@ -794,7 +794,7 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) /* * Insert frame in store, in case of retransmissions */ - skb_queue_tail(&self->wx_list, skb); + skb_queue_tail(&self->wx_list, skb_get(skb)); /* * Set poll bit if necessary. We do this to the copied @@ -819,12 +819,12 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) del_timer(&self->poll_timer); if (self->ack_required) { - irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME); + irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME); irlap_send_rr_frame(self, CMD_FRAME); self->ack_required = FALSE; } else { skb->data[1] |= PF_BIT; - irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME); + irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME); } self->window = self->window_size; irlap_start_final_timer(self, self->final_timeout); @@ -857,7 +857,6 @@ void irlap_send_data_secondary_final(struct irlap_cb *self, tx_skb = skb_clone(skb, GFP_ATOMIC); if (tx_skb == NULL) { - dev_kfree_skb(skb); return; } @@ -865,7 +864,7 @@ void irlap_send_data_secondary_final(struct irlap_cb *self, skb_set_owner_w(tx_skb, skb->sk); /* Insert frame in store */ - skb_queue_tail(&self->wx_list, skb); + skb_queue_tail(&self->wx_list, skb_get(skb)); tx_skb->data[1] |= PF_BIT; @@ -878,12 +877,12 @@ void irlap_send_data_secondary_final(struct irlap_cb *self, irlap_send_i_frame(self, tx_skb, RSP_FRAME); } else { if (self->ack_required) { - irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME); + irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME); irlap_send_rr_frame(self, RSP_FRAME); self->ack_required = FALSE; } else { skb->data[1] |= PF_BIT; - irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME); + irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME); } self->window = self->window_size; @@ -912,7 +911,6 @@ void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb) tx_skb = skb_clone(skb, GFP_ATOMIC); if (tx_skb == NULL) { - dev_kfree_skb(skb); return; } @@ -920,7 +918,7 @@ void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb) skb_set_owner_w(tx_skb, skb->sk); /* Insert frame in store */ - skb_queue_tail(&self->wx_list, skb); + skb_queue_tail(&self->wx_list, skb_get(skb)); self->vs = (self->vs + 1) % 8; self->ack_required = FALSE; @@ -928,7 +926,7 @@ void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb) irlap_send_i_frame(self, tx_skb, RSP_FRAME); } else { - irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME); + irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME); self->window -= 1; } } @@ -1023,6 +1021,7 @@ void irlap_resend_rejected_frames(struct irlap_cb *self, int command) } else { irlap_send_data_primary_poll(self, skb); } + kfree_skb(skb); } } #endif @@ -1212,7 +1211,7 @@ void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, struct test_frame *frame; __u8 *info; - skb = dev_alloc_skb(32); + skb = dev_alloc_skb(cmd->len+sizeof(struct test_frame)); if (!skb) return; @@ -1225,10 +1224,10 @@ void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, frame->saddr = cpu_to_le32(self->saddr); frame->daddr = cpu_to_le32(daddr); } else - frame = (struct test_frame *) skb_put(skb, LAP_MAX_HEADER); + frame = (struct test_frame *) skb_put(skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER); frame->caddr = caddr; - frame->control = TEST_RSP; + frame->control = TEST_RSP | PF_BIT; /* Copy info */ info = skb_put(skb, cmd->len); @@ -1259,7 +1258,6 @@ static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb, if (skb->len < sizeof(struct test_frame)) { IRDA_DEBUG(0, __FUNCTION__ "() test frame to short!\n"); - dev_kfree_skb(skb); return; } @@ -1270,7 +1268,6 @@ static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb, /* Make sure frame is addressed to us */ if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) { - dev_kfree_skb(skb); return; } } @@ -1323,8 +1320,7 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, /* First we check if this frame has a valid connection address */ if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) { IRDA_DEBUG(0, __FUNCTION__ "(), wrong connection address!\n"); - dev_kfree_skb(skb); - return 0; + goto out; } /* * Optimize for the common case and check if the frame is an @@ -1332,7 +1328,7 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, */ if (~control & 0x01) { irlap_recv_i_frame(self, skb, &info, command); - return 0; + goto out; } /* * We now check is the frame is an S(upervisory) frame. Only @@ -1360,10 +1356,9 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, WARNING(__FUNCTION__ "() Unknown S-frame %02x received!\n", info.control); - dev_kfree_skb(skb); break; } - return 0; + goto out; } /* * This must be a C(ontrol) frame @@ -1399,8 +1394,9 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, default: WARNING(__FUNCTION__ "(), Unknown frame %02x received!\n", info.control); - dev_kfree_skb(skb); break; } +out: + dev_kfree_skb(skb); return 0; } diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 5be0298a9..8b4d47caa 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -74,6 +74,7 @@ int irlmp_proc_read(char *buf, char **start, off_t offst, int len); */ int __init irlmp_init(void) { + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Initialize the irlmp structure. */ irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL); if (irlmp == NULL) @@ -81,7 +82,7 @@ int __init irlmp_init(void) memset(irlmp, 0, sizeof(struct irlmp_cb)); irlmp->magic = LMP_MAGIC; - spin_lock_init(&irlmp->lock); + spin_lock_init(&irlmp->log_lock); irlmp->clients = hashbin_new(HB_GLOBAL); irlmp->services = hashbin_new(HB_GLOBAL); @@ -178,7 +179,7 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid) irlmp_next_lsap_state(self, LSAP_DISCONNECTED); /* Insert into queue of unconnected LSAPs */ - hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) self, (int) self, + hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, NULL); return self; @@ -284,9 +285,9 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) init_timer(&lap->idle_timer); /* - * Insert into queue of unconnected LSAPs + * Insert into queue of LMP links */ - hashbin_insert(irlmp->links, (queue_t *) lap, lap->saddr, NULL); + hashbin_insert(irlmp->links, (irda_queue_t *) lap, lap->saddr, NULL); /* * We set only this variable so IrLAP can tell us on which link the @@ -395,9 +396,25 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, return -EHOSTUNREACH; } + /* Check if LAP is disconnected or already connected */ if (lap->daddr == DEV_ADDR_ANY) lap->daddr = daddr; else if (lap->daddr != daddr) { + struct lsap_cb *any_lsap; + + /* Check if some LSAPs are active on this LAP */ + any_lsap = (struct lsap_cb *) hashbin_get_first(lap->lsaps); + if (any_lsap == NULL) { + /* No active connection, but LAP hasn't been + * disconnected yet (waiting for timeout in LAP). + * Maybe we could give LAP a bit of help in this case. + */ + IRDA_DEBUG(0, __FUNCTION__ "(), sorry, but I'm waiting for LAP to timeout!\n"); + return -EAGAIN; + } + + /* LAP is already connected to a different node, and LAP + * can only talk to one node at a time */ IRDA_DEBUG(0, __FUNCTION__ "(), sorry, but link is busy!\n"); return -EBUSY; } @@ -415,7 +432,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, ASSERT(lsap->lap != NULL, return -1;); ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;); - hashbin_insert(self->lap->lsaps, (queue_t *) self, (int) self, NULL); + hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, NULL); self->connected = TRUE; @@ -557,7 +574,7 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) init_timer(&new->watchdog_timer); - hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) new, (int) new, + hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new, (int) new, NULL); /* Make sure that we invalidate the cache */ @@ -612,7 +629,7 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata) ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;); ASSERT(lsap == self, return -1;); - hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) self, (int) self, + hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, NULL); /* Reset some values */ @@ -658,7 +675,7 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, ASSERT(lsap != NULL, return;); ASSERT(lsap == self, return;); - hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) lsap, (int) lsap, + hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap, (int) lsap, NULL); self->lap = NULL; @@ -749,6 +766,18 @@ void irlmp_discovery_request(int nslots) irlmp_do_discovery(nslots); } +/* + * Function irlmp_get_discoveries (pn, mask) + * + * Return the current discovery log + * + */ +struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask) +{ + /* Return current cached discovery log */ + return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask)); +} + #if 0 /* * Function irlmp_check_services (discovery) @@ -759,7 +788,6 @@ void irlmp_discovery_request(int nslots) void irlmp_check_services(discovery_t *discovery) { struct irlmp_client *client; - struct irmanager_event event; __u8 *service_log; __u8 service; int i = 0; @@ -787,14 +815,7 @@ void irlmp_check_services(discovery_t *discovery) continue; /* * Found no clients for dealing with this service, - * so ask the user space irmanager to try to load - * the right module for us */ - event.event = EVENT_DEVICE_DISCOVERED; - event.service = service; - event.daddr = discovery->daddr; - sprintf(event.info, "%s", discovery->info); - irmanager_notify(&event); } } kfree(service_log); @@ -805,17 +826,24 @@ void irlmp_check_services(discovery_t *discovery) * * Notify all about discovered devices * + * Clients registered with IrLMP are : + * o IrComm + * o IrLAN + * o Any socket (in any state - ouch, that may be a lot !) + * The client may have defined a callback to be notified in case of + * partial/selective discovery based on the hints that it passed to IrLMP. */ -void irlmp_notify_client(irlmp_client_t *client, hashbin_t *log) +static inline void +irlmp_notify_client(irlmp_client_t *client, hashbin_t *log) { discovery_t *discovery; IRDA_DEBUG(3, __FUNCTION__ "()\n"); - /* Check if client wants the whole log */ - if (client->callback2) - client->callback2(log); - + /* Check if client wants or not partial/selective log (optimisation) */ + if (!client->disco_callback) + return; + /* * Now, check all discovered devices (if any), and notify client * only about the services that the client is interested in @@ -828,10 +856,9 @@ void irlmp_notify_client(irlmp_client_t *client, hashbin_t *log) * Any common hint bits? Remember to mask away the extension * bits ;-) */ - if (client->hint_mask & discovery->hints.word & 0x7f7f) { - if (client->callback1) - client->callback1(discovery); - } + if (client->hint_mask & discovery->hints.word & 0x7f7f) + client->disco_callback(discovery, client->priv); + discovery = (discovery_t *) hashbin_get_next(log); } } @@ -864,9 +891,40 @@ void irlmp_discovery_confirm(hashbin_t *log) } /* + * Function irlmp_discovery_expiry (expiry) + * + * This device is no longer been discovered, and therefore it is beeing + * purged from the discovery log. Inform all clients who have + * registered for this event... + * + * Note : called exclusively from discovery.c + * Note : as we are currently processing the log, the clients callback + * should *NOT* attempt to touch the log now. + */ +void irlmp_discovery_expiry(discovery_t *expiry) +{ + irlmp_client_t *client; + + IRDA_DEBUG(3, __FUNCTION__ "()\n"); + + ASSERT(expiry != NULL, return;); + + client = (irlmp_client_t *) hashbin_get_first(irlmp->clients); + while (client != NULL) { + /* Check if we should notify client */ + if ((client->expir_callback) && + (client->hint_mask & expiry->hints.word & 0x7f7f)) + client->expir_callback(expiry, client->priv); + + /* Next client */ + client = (irlmp_client_t *) hashbin_get_next(irlmp->clients); + } +} + +/* * Function irlmp_get_discovery_response () * - * Used by IrLAP to get the disocvery info it needs when answering + * Used by IrLAP to get the discovery info it needs when answering * discovery requests by other devices. */ discovery_t *irlmp_get_discovery_response() @@ -1046,9 +1104,35 @@ void irlmp_status_request(void) IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n"); } -void irlmp_status_indication(LINK_STATUS link, LOCK_STATUS lock) +/* + * Propagate status indication from LAP to LSAPs (via LMP) + * This don't trigger any change of state in lap_cb, lmp_cb or lsap_cb, + * and the event is stateless, therefore we can bypass both state machines + * and send the event direct to the LSAP user. + * Jean II + */ +void irlmp_status_indication(struct lap_cb *self, + LINK_STATUS link, LOCK_STATUS lock) { - IRDA_DEBUG(1, __FUNCTION__ "(), Not implemented\n"); + struct lsap_cb *next; + struct lsap_cb *curr; + + /* Send status_indication to all LSAPs using this link */ + next = (struct lsap_cb *) hashbin_get_first( self->lsaps); + while (next != NULL ) { + curr = next; + next = (struct lsap_cb *) hashbin_get_next(self->lsaps); + + ASSERT(curr->magic == LMP_LSAP_MAGIC, return;); + /* + * Inform service user if he has requested it + */ + if (curr->notify.status_indication != NULL) + curr->notify.status_indication(curr->notify.instance, + link, lock); + else + IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n"); + } } /* @@ -1207,7 +1291,7 @@ __u32 irlmp_register_service(__u16 hints) return 0; } service->hints = hints; - hashbin_insert(irlmp->services, (queue_t *) service, handle, NULL); + hashbin_insert(irlmp->services, (irda_queue_t *) service, handle, NULL); return handle; } @@ -1255,15 +1339,20 @@ int irlmp_unregister_service(__u32 handle) * Function irlmp_register_client (hint_mask, callback1, callback2) * * Register a local client with IrLMP + * First callback is selective discovery (based on hints) + * Second callback is for selective discovery expiries * * Returns: handle > 0 on success, 0 on error */ -__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 callback1, - DISCOVERY_CALLBACK2 callback2) +__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, + DISCOVERY_CALLBACK1 expir_clb, void *priv) { irlmp_client_t *client; __u32 handle; + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + ASSERT(irlmp != NULL, return 0;); + /* Get a unique handle for this client */ get_random_bytes(&handle, sizeof(handle)); while (hashbin_find(irlmp->clients, handle, NULL) || !handle) @@ -1273,16 +1362,16 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 callback1, client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC); if (!client) { IRDA_DEBUG( 1, __FUNCTION__ "(), Unable to kmalloc!\n"); - return 0; } /* Register the details */ client->hint_mask = hint_mask; - client->callback1 = callback1; - client->callback2 = callback2; + client->disco_callback = disco_clb; + client->expir_callback = expir_clb; + client->priv = priv; - hashbin_insert(irlmp->clients, (queue_t *) client, handle, NULL); + hashbin_insert(irlmp->clients, (irda_queue_t *) client, handle, NULL); return handle; } @@ -1296,8 +1385,8 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 callback1, * Returns: 0 on success, -1 on error */ int irlmp_update_client(__u32 handle, __u16 hint_mask, - DISCOVERY_CALLBACK1 callback1, - DISCOVERY_CALLBACK2 callback2) + DISCOVERY_CALLBACK1 disco_clb, + DISCOVERY_CALLBACK1 expir_clb, void *priv) { irlmp_client_t *client; @@ -1311,8 +1400,9 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask, } client->hint_mask = hint_mask; - client->callback1 = callback1; - client->callback2 = callback2; + client->disco_callback = disco_clb; + client->expir_callback = expir_clb; + client->priv = priv; return 0; } diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c index ace20d70e..a4646b274 100644 --- a/net/irda/irlmp_event.c +++ b/net/irda/irlmp_event.c @@ -122,7 +122,7 @@ int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); IRDA_DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n", - irlmp_event[event], irlmp_state[ self->lsap_state]); + irlmp_event[event], irlsap_state[ self->lsap_state]); return (*lsap_state[self->lsap_state]) (self, event, skb); } @@ -393,6 +393,14 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, irlmp_next_lap_state(self, LAP_STANDBY); self->refcount = 0; + /* In some case, at this point our side has already closed + * all lsaps, and we are waiting for the idle_timer to + * expire. If another device reconnect immediately, the + * idle timer will expire in the midle of the connection + * initialisation, screwing up things a lot... + * Therefore, we must stop the timer... */ + irlmp_stop_idle_timer(self); + /* * Inform all connected LSAP's using this link */ @@ -410,7 +418,8 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, } break; default: - IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", + irlmp_event[event]); if (skb) dev_kfree_skb(skb); break; @@ -514,7 +523,7 @@ static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event, ASSERT(self->lap != NULL, return -1;); ASSERT(self->lap->lsaps != NULL, return -1;); - hashbin_insert(self->lap->lsaps, (queue_t *) self, (int) self, + hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, NULL); irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c index c9bca1ea2..56287afbb 100644 --- a/net/irda/irlmp_frame.c +++ b/net/irda/irlmp_frame.c @@ -34,6 +34,9 @@ #include #include +#define DISCO_SMALL_DELAY 250 /* Delay for some discoveries in ms */ +struct timer_list disco_delay; /* The timer associated */ + static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap, __u8 slsap, int status, hashbin_t *); @@ -124,9 +127,11 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb, irlmp->unconnected_lsaps); /* Maybe LSAP was already connected, so try one more time */ - if (!lsap) + if (!lsap) { + IRDA_DEBUG(1, __FUNCTION__ "(), incoming connection for LSAP already connected\n"); lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, 0, self->lsaps); + } } else lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, 0, self->lsaps); @@ -338,10 +343,50 @@ void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos, } /* + * Function irlmp_discovery_timeout (priv) + * + * Create a discovery event to the state machine (called after a delay) + * + * Note : irlmp_do_lap_event will handle the very rare case where the LAP + * is destroyed while we were sleeping. + */ +static void irlmp_discovery_timeout(u_long priv) +{ + struct lap_cb *self; + + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + + self = (struct lap_cb *) priv; + ASSERT(self != NULL, return;); + + /* Just handle it the same way as a discovery confirm */ + irlmp_do_lap_event(self, LM_LAP_DISCOVERY_CONFIRM, NULL); +} + +/* * Function irlmp_link_discovery_indication (self, log) * * Device is discovering us * + * It's not an answer to our own discoveries, just another device trying + * to perform discovery, but we don't want to miss the opportunity + * to exploit this information, because : + * o We may not actively perform discovery (just passive discovery) + * o This type of discovery is much more reliable. In some cases, it + * seem that less than 50% of our discoveries get an answer, while + * we always get ~100% of these. + * o Make faster discovery, statistically divide time of discovery + * events by 2 (important for the latency aspect and user feel) + * However, when both devices discover each other, they might attempt to + * connect to each other, and it would create collisions on the medium. + * The trick here is to defer the event by a little delay to avoid both + * devices to jump in exactly at the same time... + * + * The delay is currently set to 0.25s, which leave enough time to perform + * a connection and don't interfer with next discovery (the lowest discovery + * period/timeout that may be set is 1s). The message triggering this + * event was the last of the discovery, so the medium is now free... + * Maybe more testing is needed to get the value right... */ void irlmp_link_discovery_indication(struct lap_cb *self, discovery_t *discovery) @@ -351,11 +396,14 @@ void irlmp_link_discovery_indication(struct lap_cb *self, irlmp_add_discovery(irlmp->cachelog, discovery); -#if 0 /* This will just cause a lot of connection collisions */ - - /* Just handle it the same way as a discovery confirm */ - irlmp_do_lap_event(self, LM_LAP_DISCOVERY_CONFIRM, NULL); -#endif + /* If delay was activated, kill it! */ + if(timer_pending(&disco_delay)) + del_timer(&disco_delay); + /* Set delay timer to expire in 0.25s. */ + disco_delay.expires = jiffies + (DISCO_SMALL_DELAY * HZ/1000); + disco_delay.function = irlmp_discovery_timeout; + disco_delay.data = (unsigned long) self; + add_timer(&disco_delay); } /* @@ -374,7 +422,12 @@ void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log) ASSERT(self->magic == LMP_LAP_MAGIC, return;); irlmp_add_discovery_log(irlmp->cachelog, log); - + + /* If discovery delay was activated, kill it! */ + if(timer_pending(&disco_delay)) + del_timer(&disco_delay); + + /* Propagate event to the state machine */ irlmp_do_lap_event(self, LM_LAP_DISCOVERY_CONFIRM, NULL); } diff --git a/net/irda/irnet/Config.in b/net/irda/irnet/Config.in new file mode 100644 index 000000000..d578593f1 --- /dev/null +++ b/net/irda/irnet/Config.in @@ -0,0 +1 @@ +dep_tristate ' IrNET protocol' CONFIG_IRNET $CONFIG_IRDA diff --git a/net/irda/irnet/Makefile b/net/irda/irnet/Makefile new file mode 100644 index 000000000..50554ac72 --- /dev/null +++ b/net/irda/irnet/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for the Linux IrDA IrNET protocol layer. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now in the main makefile... + +MOD_LIST_NAME := IRDA_MODULES +O_TARGET := irnet.o +#O_OBJS := irnet_ppp.o +O_OBJS := irnet_ppp.o irnet_irda.o +M_OBJS := $(O_TARGET) +MI_OBJS := + +OX_OBJS += + +include $(TOPDIR)/Rules.make + +tar: + tar -cvf /dev/f1 . diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h new file mode 100644 index 000000000..6c9df66b3 --- /dev/null +++ b/net/irda/irnet/irnet.h @@ -0,0 +1,453 @@ +/* + * IrNET protocol module : Synchronous PPP over an IrDA socket. + * + * Jean II - HPL `00 - + * + * This file contains definitions and declarations global to the IrNET module, + * all grouped in one place... + * This file is a private header, so other modules don't want to know + * what's in there... + * + * Note : as most part of the Linux kernel, this module is available + * under the GNU Public License (GPL). + */ + +#ifndef IRNET_H +#define IRNET_H + +/************************** DOCUMENTATION ***************************/ +/* + * What is IrNET + * ------------- + * IrNET is a protocol allowing to carry TCP/IP traffic between two + * IrDA peers in an efficient fashion. It is a thin layer, passing PPP + * packets to IrTTP and vice versa. It uses PPP in synchronous mode, + * because IrTTP offer a reliable sequenced packet service (as opposed + * to a byte stream). In fact, you could see IrNET as carrying TCP/IP + * in a IrDA socket, using PPP to provide the glue. + * + * The main difference with traditional PPP over IrCOMM is that we + * avoid the framing and serial emulation which are a performance + * bottleneck. It also allows multipoint communications in a sensible + * fashion. + * + * The main difference with IrLAN is that we use PPP for the link + * management, which is more standard, interoperable and flexible than + * the IrLAN protocol. For example, PPP adds authentication, + * encryption, compression, header compression and automated routing + * setup. And, as IrNET let PPP do the hard work, the implementation + * is much simpler than IrLAN. + * + * The Linux implementation + * ------------------------ + * IrNET is written on top of the Linux-IrDA stack, and interface with + * the generic Linux PPP driver. Because IrNET depend on recent + * changes of the PPP driver interface, IrNET will work only with very + * recent kernel (2.3.99-pre6 and up). + * + * The present implementation offer the following features : + * o simple user interface using pppd + * o efficient implementation (interface directly to PPP and IrTTP) + * o addressing (you can specify the name of the IrNET recipient) + * o multipoint operation (limited by IrLAP specification) + * o information in /proc/net/irda/irnet + * o IrNET events on /dev/irnet (for user space daemon) + * o IrNET deamon (irnetd) to automatically handle incomming requests + * o Windows 2000 compatibility (tested, but need more work) + * Currently missing : + * o Lot's of testing (that's your job) + * o Connection retries (may be too hard to do) + * o Check pppd persist mode + * o User space deamon (to automatically handle incomming requests) + * o A registered device number (comming, waiting from an answer) + * o Final integration in Linux-IrDA (up to Dag) + * + * The setup is not currently the most easy, but this should get much + * better when everything will get integrated... + * + * Acknowledgements + * ---------------- + * This module is based on : + * o The PPP driver (ppp_synctty/ppp_generic) by Paul Mackerras + * o The IrLAN protocol (irlan_common/XXX) by Dag Brattli + * o The IrSock interface (af_irda) by Dag Brattli + * o Some other bits from the kernel and my drivers... + * Infinite thanks to those brave souls for providing the infrastructure + * upon which IrNET is built. + * + * Thanks to all my collegues in HP for helping me. In particular, + * thanks to Salil Pradhan and Bill Serra for W2k testing... + * Thanks to Luiz Magalhaes for irnetd and much testing... + * + * Thanks to Alan Cox for answering lot's of my stupid questions, and + * to Paul Mackerras answering my questions on how to best integrate + * IrNET and pppd. + * + * Jean II + * + * Note on some implementations choices... + * ------------------------------------ + * 1) Direct interface vs tty/socket + * I could have used a tty interface to hook to ppp and use the full + * socket API to connect to IrDA. The code would have been easier to + * maintain, and maybe the code would have been smaller... + * Instead, we hook directly to ppp_generic and to IrTTP, which make + * things more complicated... + * + * The first reason is flexibility : this allow us to create IrNET + * instances on demand (no /dev/ircommX crap) and to allow linkname + * specification on pppd command line... + * + * Second reason is speed optimisation. If you look closely at the + * transmit and receive paths, you will notice that they are "super lean" + * (that's why they look ugly), with no function calls and as little data + * copy and modification as I could... + * + * 2) irnetd in user space + * irnetd is implemented in user space, which is necessary to call pppd. + * This also give maximum benefits in term of flexibility and customability, + * and allow to offer the event channel, useful for other stuff like debug. + * + * On the other hand, this require a loose coordination between the + * present module and irnetd. One critical area is how incomming request + * are handled. + * When irnet receive an incomming request, it send an event to irnetd and + * drop the incomming IrNET socket. + * irnetd start a pppd instance, which create a new IrNET socket. This new + * socket is then connected in the originating node to the pppd instance. + * At this point, in the originating node, the first socket is closed. + * + * I admit, this is a bit messy and waste some ressources. The alternative + * is caching incomming socket, and that's also quite messy and waste + * ressources. + * We also make connection time slower. For example, on a 115 kb/s link it + * adds 60ms to the connection time (770 ms). However, this is slower than + * the time it takes to fire up pppd on my P133... + * + * + * History : + * ------- + * + * v1 - 15/5/00 - Jean II + * o Basic IrNET (hook to ppp_generic & IrTTP - incl. multipoint) + * o control channel on /dev/irnet (set name/address) + * o event channel on /dev/irnet (for user space daemon) + * + * v2 - 5/6/00 - Jean II + * o Enable DROP_NOT_READY to avoid PPP timeouts & other weirdness... + * o Add DISCONNECT_TO event and rename DISCONNECT_FROM. + * o Set official device number alloaction on /dev/irnet + * + * v3 - 30/8/00 - Jean II + * o Update to latest Linux-IrDA changes : + * - queue_t => irda_queue_t + * o Update to ppp-2.4.0 : + * - move irda_irnet_connect from PPPIOCATTACH to TIOCSETD + * o Add EXPIRE event (depend on new IrDA-Linux patch) + * o Switch from `hashbin_remove' to `hashbin_remove_this' to fix + * a multilink bug... (depend on new IrDA-Linux patch) + * o fix a self->daddr to self->raddr in irda_irnet_connect to fix + * another multilink bug (darn !) + * o Remove LINKNAME_IOCTL cruft + * + * v3b - 31/8/00 - Jean II + * o Dump discovery log at event channel startup + * + * v4 - 28/9/00 - Jean II + * o Fix interaction between poll/select and dump discovery log + * o Add IRNET_BLOCKED_LINK event (depend on new IrDA-Linux patch) + * o Add IRNET_NOANSWER_FROM event (mostly to help support) + * o Release flow control in disconnect_indication + * o Block packets while connecting (speed up connections) + */ + +/***************************** INCLUDES *****************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/***************************** OPTIONS *****************************/ +/* + * Define or undefine to compile or not some optional part of the + * IrNET driver... + * Note : the present defaults make sense, play with that at your + * own risk... + */ +/* IrDA side of the business... */ +#define DISCOVERY_NOMASK /* To enable W2k compatibility... */ +#define ADVERTISE_HINT /* Advertise IrLAN hint bit */ +#define ALLOW_SIMULT_CONNECT /* This seem to work, cross fingers... */ +#define DISCOVERY_EVENTS /* Query the discovery log to post events */ +#define INITIAL_DISCOVERY /* Dump current discovery log as events */ +#undef STREAM_COMPAT /* Not needed - potentially messy */ +#undef CONNECT_INDIC_KICK /* Might mess IrDA, not needed */ +#undef FAIL_SEND_DISCONNECT /* Might mess IrDA, not needed */ +#undef PASS_CONNECT_PACKETS /* Not needed ? Safe */ + +/* PPP side of the business */ +#define BLOCK_WHEN_CONNECT /* Block packets when connecting */ +#undef CONNECT_IN_SEND /* Will crash hard your box... */ +#undef FLUSH_TO_PPP /* Not sure about this one, let's play safe */ +#undef SECURE_DEVIRNET /* Bah... */ + +/****************************** DEBUG ******************************/ + +/* + * This set of flags enable and disable all the various warning, + * error and debug message of this driver. + * Each section can be enabled and disabled independantly + */ +/* In the PPP part */ +#define DEBUG_CTRL_TRACE 0 /* Control channel */ +#define DEBUG_CTRL_INFO 0 /* various info */ +#define DEBUG_CTRL_ERROR 1 /* problems */ +#define DEBUG_FS_TRACE 0 /* filesystem callbacks */ +#define DEBUG_FS_INFO 0 /* various info */ +#define DEBUG_FS_ERROR 1 /* problems */ +#define DEBUG_PPP_TRACE 0 /* PPP related functions */ +#define DEBUG_PPP_INFO 0 /* various info */ +#define DEBUG_PPP_ERROR 1 /* problems */ +#define DEBUG_MODULE_TRACE 0 /* module insertion/removal */ +#define DEBUG_MODULE_ERROR 1 /* problems */ + +/* In the IrDA part */ +#define DEBUG_IRDA_SR_TRACE 0 /* IRDA subroutines */ +#define DEBUG_IRDA_SR_INFO 0 /* various info */ +#define DEBUG_IRDA_SR_ERROR 1 /* problems */ +#define DEBUG_IRDA_SOCK_TRACE 0 /* IRDA main socket functions */ +#define DEBUG_IRDA_SOCK_INFO 0 /* various info */ +#define DEBUG_IRDA_SOCK_ERROR 1 /* problems */ +#define DEBUG_IRDA_SERV_TRACE 0 /* The IrNET server */ +#define DEBUG_IRDA_SERV_INFO 0 /* various info */ +#define DEBUG_IRDA_SERV_ERROR 1 /* problems */ +#define DEBUG_IRDA_TCB_TRACE 0 /* IRDA IrTTP callbacks */ +#define DEBUG_IRDA_OCB_TRACE 0 /* IRDA other callbacks */ +#define DEBUG_IRDA_CB_INFO 0 /* various info */ +#define DEBUG_IRDA_CB_ERROR 1 /* problems */ + +#define DEBUG_ASSERT 0 /* Verify all assertions */ + +/* + * These are the macros we are using to actually print the debug + * statements. Don't look at it, it's ugly... + * + * One of the trick is that, as the DEBUG_XXX are constant, the + * compiler will optimise away the if() in all cases. + */ +/* All error messages (will show up in the normal logs) */ +#define DERROR(dbg, args...) \ + {if(DEBUG_##dbg) \ + printk(KERN_INFO "irnet: " __FUNCTION__ "(): " args);} + +/* Normal debug message (will show up in /var/log/debug) */ +#define DEBUG(dbg, args...) \ + {if(DEBUG_##dbg) \ + printk(KERN_DEBUG "irnet: " __FUNCTION__ "(): " args);} + +/* Entering a function (trace) */ +#define DENTER(dbg, args...) \ + {if(DEBUG_##dbg) \ + printk(KERN_DEBUG "irnet: ->" __FUNCTION__ args);} + +/* Entering and exiting a function in one go (trace) */ +#define DPASS(dbg, args...) \ + {if(DEBUG_##dbg) \ + printk(KERN_DEBUG "irnet: <>" __FUNCTION__ args);} + +/* Exiting a function (trace) */ +#define DEXIT(dbg, args...) \ + {if(DEBUG_##dbg) \ + printk(KERN_DEBUG "irnet: <-" __FUNCTION__ "()" args);} + +/* Exit a function with debug */ +#define DRETURN(ret, dbg, args...) \ + {DEXIT(dbg, ": " args);\ + return(ret); } + +/* Exit a function on failed condition */ +#define DABORT(cond, ret, dbg, args...) \ + {if(cond) {\ + DERROR(dbg, args);\ + return(ret); }} + +/* Invalid assertion, print out an error and exit... */ +#define DASSERT(cond, ret, dbg, args...) \ + {if((DEBUG_ASSERT) && !(cond)) {\ + DERROR(dbg, "Invalid assertion: " args);\ + return ret; }} + +/************************ CONSTANTS & MACROS ************************/ + +/* Paranoia */ +#define IRNET_MAGIC 0xB00754 + +/* Number of control events in the control channel buffer... */ +#define IRNET_MAX_EVENTS 8 /* Should be more than enough... */ + +/****************************** TYPES ******************************/ + +/* + * This is the main structure where we store all the data pertaining to + * one instance of irnet. + * Note : in irnet functions, a pointer this structure is usually called + * "ap" or "self". If the code is borrowed from the IrDA stack, it tend + * to be called "self", and if it is borrowed from the PPP driver it is + * "ap". Apart from that, it's exactly the same structure ;-) + */ +typedef struct irnet_socket +{ + /* ------------------- Instance management ------------------- */ + /* We manage a linked list of IrNET socket instances */ + irda_queue_t q; /* Must be first - for hasbin */ + int magic; /* Paranoia */ + + /* --------------------- FileSystem part --------------------- */ + /* "pppd" interact directly with us on a /dev/ file */ + struct file * file; /* File descriptor of this instance */ + /* TTY stuff - to keep "pppd" happy */ + struct termios termios; /* Various tty flags */ + /* Stuff for the control channel */ + int event_index; /* Last read in the event log */ + + /* ------------------------- PPP part ------------------------- */ + /* We interface directly to the ppp_generic driver in the kernel */ + int ppp_open; /* registered with ppp_generic */ + struct ppp_channel chan; /* Interface to generic ppp layer */ + + int mru; /* Max size of PPP payload */ + u32 xaccm[8]; /* Asynchronous character map (just */ + u32 raccm; /* to please pppd - dummy) */ + unsigned int flags; /* PPP flags (compression, ...) */ + unsigned int rbits; /* Unused receive flags ??? */ + + /* ------------------------ IrTTP part ------------------------ */ + /* We create a pseudo "socket" over the IrDA tranport */ + int ttp_open; /* Set when IrTTP is ready */ + struct tsap_cb * tsap; /* IrTTP instance (the connection) */ + + char rname[NICKNAME_MAX_LEN + 1]; + /* IrDA nickname of destination */ + __u32 raddr; /* Requested peer IrDA address */ + __u32 saddr; /* my local IrDA address */ + __u32 daddr; /* actual peer IrDA address */ + __u8 dtsap_sel; /* Remote TSAP selector */ + __u8 stsap_sel; /* Local TSAP selector */ + + __u32 max_sdu_size_rx;/* Socket parameters used for IrTTP */ + __u32 max_sdu_size_tx; + __u32 max_data_size; + __u8 max_header_size; + LOCAL_FLOW tx_flow; /* State of the Tx path in IrTTP */ + + /* ------------------- IrLMP and IrIAS part ------------------- */ + /* Used for IrDA Discovery and socket name resolution */ + __u32 ckey; /* IrLMP client handle */ + __u16 mask; /* Hint bits mask (filter discov.)*/ + int nslots; /* Number of slots for discovery */ + + struct iriap_cb * iriap; /* Used to query remote IAS */ + wait_queue_head_t query_wait; /* Wait for the answer to a query */ + struct ias_value * ias_result; /* Result of remote IAS query */ + int errno; /* status of the IAS query */ + + /* ---------------------- Optional parts ---------------------- */ +#ifdef INITIAL_DISCOVERY + /* Stuff used to dump discovery log */ + struct irda_device_info *discoveries; /* Copy of the discovery log */ + int disco_index; /* Last read in the discovery log */ + int disco_number; /* Size of the discovery log */ +#endif INITIAL_DISCOVERY + +} irnet_socket; + +/* + * This is the various event that we will generate on the control channel + */ +typedef enum irnet_event +{ + IRNET_DISCOVER, /* New IrNET node discovered */ + IRNET_EXPIRE, /* IrNET node expired */ + IRNET_CONNECT_TO, /* IrNET socket has connected to other node */ + IRNET_CONNECT_FROM, /* Other node has connected to IrNET socket */ + IRNET_REQUEST_FROM, /* Non satisfied connection request */ + IRNET_NOANSWER_FROM, /* Failed connection request */ + IRNET_BLOCKED_LINK, /* Link (IrLAP) is blocked for > 3s */ + IRNET_DISCONNECT_FROM, /* IrNET socket has disconnected */ + IRNET_DISCONNECT_TO /* Closing IrNET socket */ +} irnet_event; + +/* + * This is the storage for an event and its arguments + */ +typedef struct irnet_log +{ + irnet_event event; + int unit; + __u32 addr; + char name[NICKNAME_MAX_LEN + 1]; +} irnet_log; + +/* + * This is the storage for all events and related stuff... + */ +typedef struct irnet_ctrl_channel +{ + irnet_log log[IRNET_MAX_EVENTS]; /* Event log */ + int index; /* Current index in log */ + spinlock_t spinlock; /* Serialize access to the event log */ + wait_queue_head_t rwait; /* processes blocked on read (or poll) */ +} irnet_ctrl_channel; + +/**************************** PROTOTYPES ****************************/ +/* + * Global functions of the IrNET module + * Note : we list here also functions called from one file to the other. + */ + +/* -------------------------- IRDA PART -------------------------- */ +extern int + irda_irnet_create(irnet_socket *); /* Initialise a IrNET socket */ +extern int + irda_irnet_connect(irnet_socket *); /* Try to connect over IrDA */ +extern void + irda_irnet_destroy(irnet_socket *); /* Teardown a IrNET socket */ +extern int + irda_irnet_init(void); /* Initialise IrDA part of IrNET */ +extern void + irda_irnet_cleanup(void); /* Teardown IrDA part of IrNET */ +/* --------------------------- PPP PART --------------------------- */ +extern int + ppp_irnet_init(void); /* Initialise PPP part of IrNET */ +extern void + ppp_irnet_cleanup(void); /* Teardown PPP part of IrNET */ +/* ---------------------------- MODULE ---------------------------- */ +extern int + init_module(void); /* Initialise IrNET module */ +extern void + cleanup_module(void); /* Teardown IrNET module */ + +/**************************** VARIABLES ****************************/ + +/* Control channel stuff - allocated in irnet_irda.h */ +extern struct irnet_ctrl_channel irnet_events; + +#endif IRNET_H diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c new file mode 100644 index 000000000..e34a758b8 --- /dev/null +++ b/net/irda/irnet/irnet_irda.c @@ -0,0 +1,1480 @@ +/* + * IrNET protocol module : Synchronous PPP over an IrDA socket. + * + * Jean II - HPL `00 - + * + * This file implement the IRDA interface of IrNET. + * Basically, we sit on top of IrTTP. We set up IrTTP, IrIAS properly, + * and exchange frames with IrTTP. + */ + +#include "irnet_irda.h" /* Private header */ + +/************************* CONTROL CHANNEL *************************/ +/* + * When ppp is not active, /dev/irnet act as a control channel. + * Writting allow to set up the IrDA destination of the IrNET channel, + * and any application may be read events happening on IrNET... + */ + +/*------------------------------------------------------------------*/ +/* + * Post an event to the control channel... + * Put the event in the log, and then wait all process blocked on read + * so they can read the log... + */ +static void +irnet_post_event(irnet_socket * ap, + irnet_event event, + __u32 addr, + char * name) +{ + unsigned long flags; /* For spinlock */ + int index; /* In the log */ + + DENTER(CTRL_TRACE, "(ap=0x%X, event=%d, addr=%08x, name=``%s'')\n", + (unsigned int) ap, event, addr, name); + + /* Protect this section via spinlock. + * Note : as we are the only event producer, we only need to exclude + * ourself when touching the log, which is nice and easy. + */ + spin_lock_irqsave(&irnet_events.spinlock, flags); + + /* Copy the event in the log */ + index = irnet_events.index; + irnet_events.log[index].event = event; + irnet_events.log[index].addr = addr; + /* Try to copy IrDA nickname */ + if(name) + strcpy(irnet_events.log[index].name, name); + else + irnet_events.log[index].name[0] = '\0'; + /* Try to get ppp unit number */ + if((ap != (irnet_socket *) NULL) && (ap->ppp_open)) + irnet_events.log[index].unit = ppp_unit_number(&ap->chan); + else + irnet_events.log[index].unit = -1; + + /* Increment the index + * Note that we increment the index only after the event is written, + * to make sure that the readers don't get garbage... */ + irnet_events.index = (index + 1) % IRNET_MAX_EVENTS; + + DEBUG(CTRL_INFO, "New event index is %d\n", irnet_events.index); + + /* Spin lock end */ + spin_unlock_irqrestore(&irnet_events.spinlock, flags); + + /* Now : wake up everybody waiting for events... */ + wake_up_interruptible_all(&irnet_events.rwait); + + DEXIT(CTRL_TRACE, "\n"); +} + +/************************* IRDA SUBROUTINES *************************/ +/* + * These are a bunch of subroutines called from other functions + * down there, mostly common code or to improve readability... + * + * Note : we duplicate quite heavily some routines of af_irda.c, + * because our input structure (self) is quite different + * (struct irnet instead of struct irda_sock), which make sharing + * the same code impossible (at least, without templates). + */ + +/*------------------------------------------------------------------*/ +/* + * Function irda_open_tsap (self) + * + * Open local Transport Service Access Point (TSAP) + * + * Create a IrTTP instance for us and set all the IrTTP callbacks. + */ +static inline int +irnet_open_tsap(irnet_socket * self) +{ + notify_t notify; /* Callback structure */ + + DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self); + + DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n"); + + /* Initialize IrTTP callbacks to be used by the IrDA stack */ + irda_notify_init(¬ify); + notify.connect_confirm = irnet_connect_confirm; + notify.connect_indication = irnet_connect_indication; + notify.disconnect_indication = irnet_disconnect_indication; + notify.data_indication = irnet_data_indication; + /*notify.udata_indication = NULL;*/ + notify.flow_indication = irnet_flow_indication; + notify.status_indication = irnet_status_indication; + notify.instance = self; + strncpy(notify.name, IRNET_NOTIFY_NAME, NOTIFY_MAX_NAME); + + /* Open an IrTTP instance */ + self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, + ¬ify); + DABORT(self->tsap == NULL, -ENOMEM, + IRDA_SR_ERROR, "Unable to allocate TSAP !\n"); + + /* Remember which TSAP selector we actually got */ + self->stsap_sel = self->tsap->stsap_sel; + + DEXIT(IRDA_SR_TRACE, " - tsap=0x%X, sel=0x%X\n", + (unsigned int) self->tsap, self->stsap_sel); + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_find_lsap_sel (self) + * + * Try to lookup LSAP selector in remote LM-IAS + * + * Basically, we start a IAP query, and then go to sleep. When the query + * return, irnet_getvalue_confirm will wake us up, and we can examine the + * result of the query... + * Note that in some case, the query fail even before we go to sleep, + * creating some races... + */ +static int +irnet_find_lsap_sel(irnet_socket * self) +{ + DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* This should not happen */ + DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n"); + + /* Create an IAP instance, will be closed in irnet_getvalue_confirm() */ + self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, + irnet_getvalue_confirm); + + /* Treat unexpected signals as disconnect */ + self->errno = -EHOSTUNREACH; + + /* Query remote LM-IAS */ + iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr, + IRNET_SERVICE_NAME, IRNET_IAS_VALUE); + /* Wait for answer (if not already failed) */ + if(self->iriap != NULL) + interruptible_sleep_on(&self->query_wait); + + /* Check what happened */ + if(self->errno) + { + DEBUG(IRDA_SR_INFO, "IAS query failed! (%d)\n", self->errno); + /* Requested object/attribute doesn't exist */ + if((self->errno == IAS_CLASS_UNKNOWN) || + (self->errno == IAS_ATTRIB_UNKNOWN)) + return (-EADDRNOTAVAIL); + else + return (-EHOSTUNREACH); + } + + /* Get the remote TSAP selector */ + switch(self->ias_result->type) + { + case IAS_INTEGER: + DEBUG(IRDA_SR_INFO, "result=%d\n", self->ias_result->t.integer); + if(self->ias_result->t.integer != -1) + self->dtsap_sel = self->ias_result->t.integer; + else + self->dtsap_sel = 0; + break; + default: + self->dtsap_sel = 0; + DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", self->ias_result->type); + break; + } + /* Cleanup */ + if(self->ias_result) + irias_delete_value(self->ias_result); + + DEXIT(IRDA_SR_TRACE, "\n"); + if(self->dtsap_sel) + return 0; + + return -EADDRNOTAVAIL; +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_discover_daddr_and_lsap_sel (self) + * + * This try to find a device with the requested service. + * + * It basically look into the discovery log. For each address in the list, + * it queries the LM-IAS of the device to find if this device offer + * the requested service. + * If there is more than one node supporting the service, we complain + * to the user (it should move devices around). + * The, we set both the destination address and the lsap selector to point + * on the service on the unique device we have found. + * + * Note : this function fails if there is more than one device in range, + * because IrLMP doesn't disconnect the LAP when the last LSAP is closed. + * Moreover, we would need to wait the LAP disconnection... + */ +static inline int +irnet_discover_daddr_and_lsap_sel(irnet_socket * self) +{ + struct irda_device_info *discoveries; /* Copy of the discovery log */ + int number; /* Number of nodes in the log */ + int i; + int err = -ENETUNREACH; + __u32 daddr = DEV_ADDR_ANY; /* Address we found the service on */ + __u8 dtsap_sel = 0x0; /* TSAP associated with it */ + + DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* Ask lmp for the current discovery log + * Note : we have to use irlmp_get_discoveries(), as opposed + * to play with the cachelog directly, because while we are + * making our ias query, le log might change... */ + discoveries = irlmp_get_discoveries(&number, self->mask); + /* Check if the we got some results */ + if (discoveries == NULL) + DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n"); + + /* + * Now, check all discovered devices (if any), and connect + * client only about the services that the client is + * interested in... + */ + for(i = 0; i < number; i++) + { + /* Try the address in the log */ + self->daddr = discoveries[i].daddr; + self->saddr = 0x0; + DEBUG(IRDA_SR_INFO, "trying daddr = %08x\n", self->daddr); + + /* Query remote LM-IAS for this service */ + err = irnet_find_lsap_sel(self); + switch(err) + { + case 0: + /* We found the requested service */ + if(daddr != DEV_ADDR_ANY) + { + DEBUG(IRDA_SR_INFO, "More than one device in range supports IrNET...\n"); + } + else + { + /* First time we found that one, save it ! */ + daddr = self->daddr; + dtsap_sel = self->dtsap_sel; + } + break; + case -EADDRNOTAVAIL: + /* Requested service simply doesn't exist on this node */ + break; + default: + /* Something bad did happen :-( */ + DERROR(IRDA_SR_ERROR, "unexpected IAS query failure\n"); + self->daddr = DEV_ADDR_ANY; + kfree(discoveries); + return(-EHOSTUNREACH); + break; + } + } + /* Cleanup our copy of the discovery log */ + kfree(discoveries); + + /* Check out what we found */ + if(daddr == DEV_ADDR_ANY) + { + self->daddr = DEV_ADDR_ANY; + DEXIT(IRDA_SR_INFO, "cannot discover IrNET in any device !!!\n"); + return(-EADDRNOTAVAIL); + } + + /* Revert back to discovered device & service */ + self->daddr = daddr; + self->saddr = 0x0; + self->dtsap_sel = dtsap_sel; + + DEBUG(IRDA_SR_INFO, "discovered IrNET at address %08x\n", self->daddr); + DEXIT(IRDA_SR_TRACE, "\n"); + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_dname_to_daddr (self) + * + * Convert an IrDA nickname to a valid IrDA address + * + * It basically look into the discovery log until there is a match. + */ +static inline int +irnet_dname_to_daddr(irnet_socket * self) +{ + struct irda_device_info *discoveries; /* Copy of the discovery log */ + int number; /* Number of nodes in the log */ + int i; + + DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* Ask lmp for the current discovery log */ + discoveries = irlmp_get_discoveries(&number, 0xffff); + /* Check if the we got some results */ + if(discoveries == NULL) + DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n"); + + /* + * Now, check all discovered devices (if any), and connect + * client only about the services that the client is + * interested in... + */ + for(i = 0; i < number; i++) + { + /* Does the name match ? */ + if(!strncmp(discoveries[i].info, self->rname, NICKNAME_MAX_LEN)) + { + /* Yes !!! Get it.. */ + self->daddr = discoveries[i].daddr; + DEBUG(IRDA_SR_INFO, "discovered device ``%s'' at address 0x%08x.\n", + self->rname, self->daddr); + kfree(discoveries); + DEXIT(IRDA_SR_TRACE, "\n"); + return 0; + } + } + /* No luck ! */ + DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname); + kfree(discoveries); + return(-EADDRNOTAVAIL); +} + + +/************************* SOCKET ROUTINES *************************/ +/* + * This are the main operations on IrNET sockets, basically to create + * and destroy IrNET sockets. These are called from the PPP part... + */ + +/*------------------------------------------------------------------*/ +/* + * Create a IrNET instance : just initialise some parameters... + */ +int +irda_irnet_create(irnet_socket * self) +{ + DENTER(IRDA_SOCK_TRACE, "(self=0x%X)\n", (unsigned int) self); + + self->magic = IRNET_MAGIC; /* Paranoia */ + + init_waitqueue_head(&self->query_wait); + + self->ttp_open = 0; /* Prevent higher layer from accessing IrTTP */ + self->rname[0] = '\0'; /* May be set via control channel */ + self->raddr = DEV_ADDR_ANY; /* May be set via control channel */ + self->daddr = DEV_ADDR_ANY; /* Until we get connected */ + self->saddr = 0x0; /* so IrLMP assign us any link */ + self->max_sdu_size_rx = TTP_SAR_UNBOUND; + + /* Register as a client with IrLMP */ + self->ckey = irlmp_register_client(0, NULL, NULL, NULL); +#ifdef DISCOVERY_NOMASK + self->mask = 0xffff; /* For W2k compatibility */ +#else DISCOVERY_NOMASK + self->mask = irlmp_service_to_hint(S_LAN); +#endif DISCOVERY_NOMASK + self->tx_flow = FLOW_START; /* Flow control from IrTTP */ + + DEXIT(IRDA_SOCK_TRACE, "\n"); + return(0); +} + +/*------------------------------------------------------------------*/ +/* + * Connect to the other side : + * o convert device name to an address + * o find the socket number (dlsap) + * o Establish the connection + */ +int +irda_irnet_connect(irnet_socket * self) +{ + int err; + + DENTER(IRDA_SOCK_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* Check if we have opened a local TSAP : + * If we have already opened a TSAP, it means that either we are already + * connected or in the process of doing so... */ + if(self->tsap != NULL) + DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n"); + + /* Insert ourselves in the hashbin so that the IrNET server can find us. + * Notes : 4th arg is string of 32 char max and must be null terminated + * When 4th arg is used (string), 3rd arg isn't (int) + * Can't re-insert (MUST remove first) so check for that... */ + if((irnet_server.running) && (self->q.q_next == NULL)) + { + unsigned long flags; + spin_lock_irqsave(&irnet_server.spinlock, flags); + hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname); + spin_unlock_irqrestore(&irnet_server.spinlock, flags); + DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname); + } + + /* If we don't have anything (no address, no name) */ + if((self->raddr == DEV_ADDR_ANY) && (self->rname[0] == '\0')) + { + /* Try to find a suitable address */ + if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0) + DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n"); + } + else + { + /* If we have only the name (no address), try to get an address */ + if(self->raddr == DEV_ADDR_ANY) + { + if((err = irnet_dname_to_daddr(self)) != 0) + DRETURN(err, IRDA_SOCK_INFO, "name-connect failed!\n"); + } + else + /* Use the requested destination address */ + self->daddr = self->raddr; + + /* Query remote LM-IAS to find LSAP selector */ + if((err = irnet_find_lsap_sel(self)) != 0) + DRETURN(err, IRDA_SOCK_INFO, "connect failed!\n"); + } + DEBUG(IRDA_SOCK_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n", + self->daddr, self->dtsap_sel); + + /* Open a local TSAP (an IrTTP instance) */ + err = irnet_open_tsap(self); + DABORT(err != 0, err, IRDA_SOCK_ERROR, "connect aborted!\n"); + + /* Connect to remote device */ + err = irttp_connect_request(self->tsap, self->dtsap_sel, + self->saddr, self->daddr, NULL, + self->max_sdu_size_rx, NULL); + DABORT(err != 0, err, IRDA_SOCK_ERROR, "connect aborted!\n"); + + DEXIT(IRDA_SOCK_TRACE, "\n"); + return(0); +} + +/*------------------------------------------------------------------*/ +/* + * Function irda_irnet_destroy(self) + * + * Destroy irnet instance + * + */ +void +irda_irnet_destroy(irnet_socket * self) +{ + DENTER(IRDA_SOCK_TRACE, "(self=0x%X)\n", (unsigned int) self); + if(self == NULL) + return; + + /* Remove ourselves from hashbin (if we are queued in hashbin) + * Note : `irnet_server.running' protect us from calls in hashbin_delete() */ + if((irnet_server.running) && (self->q.q_next != NULL)) + { + struct irnet_socket * entry; + unsigned long flags; + DEBUG(IRDA_SOCK_INFO, "Removing from hash..\n"); + spin_lock_irqsave(&irnet_server.spinlock, flags); + entry = hashbin_remove_this(irnet_server.list, (irda_queue_t *) self); + self->q.q_next = NULL; + spin_unlock_irqrestore(&irnet_server.spinlock, flags); + DASSERT(entry == self, , IRDA_SOCK_ERROR, "Can't remove from hash.\n"); + } + + /* Unregister with IrLMP */ + irlmp_unregister_client(self->ckey); + + /* Unregister with LM-IAS */ + if(self->iriap) + iriap_close(self->iriap); + + /* Prevent higher layer from accessing IrTTP */ + self->ttp_open = 0; + + /* Close our IrTTP connection */ + if(self->tsap) + { + DEBUG(IRDA_SOCK_INFO, "Closing our TTP connection.\n"); + irttp_disconnect_request(self->tsap, NULL, P_NORMAL); + irttp_close_tsap(self->tsap); + self->tsap = NULL; + /* Note : as the disconnect comes from ppp_generic, the unit number + * doesn't exist anymore when we post the event, so we need to pass + * NULL as the first arg... */ + irnet_post_event(NULL, IRNET_DISCONNECT_TO, self->daddr, self->rname); + } + self->stsap_sel = 0; + + DEXIT(IRDA_SOCK_TRACE, "\n"); + return; +} + + +/************************** SERVER SOCKET **************************/ +/* + * The IrNET service is composed of one server socket and a variable + * number of regular IrNET sockets. The server socket is supposed to + * handle incomming connections and redirect them to one IrNET sockets. + * It's a superset of the regular IrNET socket, but has a very distinct + * behaviour... + */ + +/*------------------------------------------------------------------*/ +/* + * Function irnet_daddr_to_dname (self) + * + * Convert an IrDA address to a IrDA nickname + * + * It basically look into the discovery log until there is a match. + */ +static inline int +irnet_daddr_to_dname(irnet_socket * self) +{ + struct irda_device_info *discoveries; /* Copy of the discovery log */ + int number; /* Number of nodes in the log */ + int i; + + DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* Ask lmp for the current discovery log */ + discoveries = irlmp_get_discoveries(&number, 0xffff); + /* Check if the we got some results */ + if (discoveries == NULL) + DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n"); + + /* Now, check all discovered devices (if any) */ + for(i = 0; i < number; i++) + { + /* Does the name match ? */ + if(discoveries[i].daddr == self->daddr) + { + /* Yes !!! Get it.. */ + strncpy(self->rname, discoveries[i].info, NICKNAME_MAX_LEN); + self->rname[NICKNAME_MAX_LEN + 1] = '\0'; + DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n", + self->daddr, self->rname); + kfree(discoveries); + DEXIT(IRDA_SERV_TRACE, "\n"); + return 0; + } + } + /* No luck ! */ + DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr); + kfree(discoveries); + return(-EADDRNOTAVAIL); +} + +/*------------------------------------------------------------------*/ +/* + * Function irda_find_socket (self) + * + * Find the correct IrNET socket + * + * Look into the list of IrNET sockets and finds one with the right + * properties... + */ +static inline irnet_socket * +irnet_find_socket(irnet_socket * self) +{ + irnet_socket * new = (irnet_socket *) NULL; + unsigned long flags; + int err; + + DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* Get the address of the requester */ + self->daddr = irttp_get_daddr(self->tsap); + + /* Try to get the IrDA nickname of the requester */ + err = irnet_daddr_to_dname(self); + + /* Protect access to the instance list */ + spin_lock_irqsave(&irnet_server.spinlock, flags); + + /* So now, try to get an socket having specifically + * requested that nickname */ + if(err == 0) + { + new = (irnet_socket *) hashbin_find(irnet_server.list, + 0, self->rname); + if(new) + DEBUG(IRDA_SERV_INFO, "Socket 0x%X matches rname ``%s''.\n", + (unsigned int) new, new->rname); + } + + /* If no name matches, try to find an socket by the destination address */ + /* It can be either the requested destination address (set via the + * control channel), or the current destination address if the + * socket is in the middle of a connection request */ + if(new == (irnet_socket *) NULL) + { + new = (irnet_socket *) hashbin_get_first(irnet_server.list); + while(new !=(irnet_socket *) NULL) + { + /* Does it have the same address ? */ + if((new->raddr == self->daddr) || (new->daddr == self->daddr)) + { + /* Yes !!! Get it.. */ + DEBUG(IRDA_SERV_INFO, "Socket 0x%X matches daddr %#08x.\n", + (unsigned int) new, self->daddr); + break; + } + new = (irnet_socket *) hashbin_get_next(irnet_server.list); + } + } + + /* If we don't have any socket, get the first unconnected socket */ + if(new == (irnet_socket *) NULL) + { + new = (irnet_socket *) hashbin_get_first(irnet_server.list); + while(new !=(irnet_socket *) NULL) + { + /* Is it available ? */ + if(!(new->ttp_open) && (new->raddr == DEV_ADDR_ANY) && + (new->rname[0] == '\0') && (new->ppp_open)) + { + /* Yes !!! Get it.. */ + DEBUG(IRDA_SERV_INFO, "Socket 0x%X is free.\n", + (unsigned int) new); + break; + } + new = (irnet_socket *) hashbin_get_next(irnet_server.list); + } + } + + /* Spin lock end */ + spin_unlock_irqrestore(&irnet_server.spinlock, flags); + + DEXIT(IRDA_SERV_TRACE, " - new = 0x%X\n", (unsigned int) new); + return new; +} + +/*------------------------------------------------------------------*/ +/* + * Function irda_connect_socket (self) + * + * Connect an incomming connection to the socket + * + */ +static inline int +irnet_connect_socket(irnet_socket * self, + irnet_socket * new, + struct qos_info * qos, + __u32 max_sdu_size, + __u8 max_header_size) +{ + DENTER(IRDA_SERV_TRACE, "(self=0x%X, new=0x%X)\n", + (unsigned int) self, (unsigned int) new); + + /* Now attach up the new socket */ + new->tsap = irttp_dup(self->tsap, new); + DABORT(new->tsap == NULL, -1, IRDA_SERV_ERROR, "dup failed!\n"); + + /* Set up all the relevant parameters on the new socket */ + new->stsap_sel = new->tsap->stsap_sel; + new->dtsap_sel = new->tsap->dtsap_sel; + new->saddr = irttp_get_saddr(new->tsap); + new->daddr = irttp_get_daddr(new->tsap); + + new->max_header_size = max_header_size; + new->max_sdu_size_tx = max_sdu_size; + new->max_data_size = max_sdu_size; +#ifdef STREAM_COMPAT + /* If we want to receive "stream sockets" */ + if(max_sdu_size == 0) + new->max_data_size = irttp_get_max_seg_size(new->tsap); +#endif STREAM_COMPAT + + /* Clean up the original one to keep it in listen state */ + self->tsap->dtsap_sel = self->tsap->lsap->dlsap_sel = LSAP_ANY; + self->tsap->lsap->lsap_state = LSAP_DISCONNECTED; + + /* Send a connection response on the new socket */ + irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL); + + /* Allow PPP to send its junk over the new socket... */ + new->ttp_open = 1; +#ifdef CONNECT_INDIC_KICK + /* As currently we don't packets in ppp_irnet_send(), this is not needed... + * Also, not doing it give IrDA a chance to finish the setup properly + * before beeing swamped with packets... */ + ppp_output_wakeup(&new->chan); +#endif CONNECT_INDIC_KICK + + /* Notify the control channel */ + irnet_post_event(new, IRNET_CONNECT_FROM, new->daddr, self->rname); + + DEXIT(IRDA_SERV_TRACE, "\n"); + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Function irda_disconnect_server (self) + * + * Cleanup the server socket when the incomming connection abort + * + */ +static inline void +irnet_disconnect_server(irnet_socket * self, + struct sk_buff *skb) +{ + DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* Put the received packet in the black hole */ + kfree_skb(skb); + +#ifdef FAIL_SEND_DISCONNECT + /* Tell the other party we don't want to be connected */ + /* Hum... Is it the right thing to do ? And do we need to send + * a connect response before ? It looks ok without this... */ + irttp_disconnect_request(self->tsap, NULL, P_NORMAL); +#endif FAIL_SEND_DISCONNECT + + /* Clean up the server to keep it in listen state */ + self->tsap->dtsap_sel = self->tsap->lsap->dlsap_sel = LSAP_ANY; + self->tsap->lsap->lsap_state = LSAP_DISCONNECTED; + + /* Notify the control channel */ + irnet_post_event(NULL, IRNET_REQUEST_FROM, self->daddr, self->rname); + + DEXIT(IRDA_SERV_TRACE, "\n"); + return; +} + +/*------------------------------------------------------------------*/ +/* + * Function irda_setup_server (self) + * + * Create a IrTTP server and set it up... + * + * Register the IrLAN hint bit, create a IrTTP instance for us, + * set all the IrTTP callbacks and create an IrIAS entry... + */ +static inline int +irnet_setup_server(void) +{ + __u16 hints; + + DENTER(IRDA_SERV_TRACE, "()\n"); + + /* Initialise the regular socket part of the server */ + irda_irnet_create(&irnet_server.s); + + /* Open a local TSAP (an IrTTP instance) for the server */ + irnet_open_tsap(&irnet_server.s); + + /* PPP part setup */ + irnet_server.s.ppp_open = 0; + irnet_server.s.chan.private = NULL; + irnet_server.s.file = NULL; + + /* Get the hint bit corresponding to IrLAN */ + /* Note : we overload the IrLAN hint bit. As it is only a "hint", and as + * we provide roughly the same functionality as IrLAN, this is ok. + * In fact, the situation is similar as JetSend overloading the Obex hint + */ + hints = irlmp_service_to_hint(S_LAN); + +#ifdef ADVERTISE_HINT + /* Register with IrLMP as a service (advertise our hint bit) */ + irnet_server.skey = irlmp_register_service(hints); +#endif ADVERTISE_HINT + + /* Register with LM-IAS (so that people can connect to us) */ + irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies); + irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE, + irnet_server.s.stsap_sel, IAS_KERNEL_ATTR); + irias_insert_object(irnet_server.ias_obj); + +#ifdef DISCOVERY_EVENTS + /* Tell IrLMP we want to be notified of newly discovered nodes */ + irlmp_update_client(irnet_server.s.ckey, hints, + irnet_discovery_indication, irnet_expiry_indication, + (void *) &irnet_server.s); +#endif + + DEXIT(IRDA_SERV_TRACE, " - self=0x%X\n", (unsigned int) &irnet_server.s); + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Function irda_destroy_server (self) + * + * Destroy the IrTTP server... + * + * Reverse of the previous function... + */ +static inline void +irnet_destroy_server(void) +{ + DENTER(IRDA_SERV_TRACE, "()\n"); + +#ifdef ADVERTISE_HINT + /* Unregister with IrLMP */ + irlmp_unregister_service(irnet_server.skey); +#endif ADVERTISE_HINT + + /* Unregister with LM-IAS */ + if(irnet_server.ias_obj) + irias_delete_object(irnet_server.ias_obj); + + /* Cleanup the socket part */ + irda_irnet_destroy(&irnet_server.s); + + DEXIT(IRDA_SERV_TRACE, "\n"); + return; +} + + +/************************ IRDA-TTP CALLBACKS ************************/ +/* + * When we create a IrTTP instance, we pass to it a set of callbacks + * that IrTTP will call in case of various events. + * We take care of those events here. + */ + +/*------------------------------------------------------------------*/ +/* + * Function irnet_data_indication (instance, sap, skb) + * + * Received some data from TinyTP. Just queue it on the receive queue + * + */ +static int +irnet_data_indication(void * instance, + void * sap, + struct sk_buff *skb) +{ + irnet_socket * ap = (irnet_socket *) instance; + unsigned char * p; + int code = 0; + + DENTER(IRDA_TCB_TRACE, "(self/ap=0x%X, skb=0x%X)\n", + (unsigned int) ap,(unsigned int) skb); + DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n"); + + /* Check is ppp is ready to receive our packet */ + if(!ap->ppp_open) + { + DERROR(IRDA_CB_ERROR, "PPP not ready, dropping packet...\n"); + /* When we return error, TTP will need to requeue the skb and + * will stop the sender. IrTTP will stall until we send it a + * flow control request... */ + return -ENOMEM; + } + + /* strip address/control field if present */ + p = skb->data; + if((p[0] == PPP_ALLSTATIONS) && (p[1] == PPP_UI)) + { + /* chop off address/control */ + if(skb->len < 3) + goto err_exit; + p = skb_pull(skb, 2); + } + + /* decompress protocol field if compressed */ + if(p[0] & 1) + { + /* protocol is compressed */ + skb_push(skb, 1)[0] = 0; + } + else + if(skb->len < 2) + goto err_exit; + + /* pass to generic ppp layer */ + /* Note : how do I know if ppp can accept or not the packet ? This is + * essential if I want to manage flow control smoothly... */ + ppp_input(&ap->chan, skb); + + DEXIT(IRDA_TCB_TRACE, "\n"); + return 0; + + err_exit: + DERROR(IRDA_CB_ERROR, "Packet too small, dropping...\n"); + kfree_skb(skb); + ppp_input_error(&ap->chan, code); + return 0; /* Don't return an error code, only for flow control... */ +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_disconnect_indication (instance, sap, reason, skb) + * + * Connection has been closed. Chech reason to find out why + * + * Note : there are many cases where we come here : + * o attempted to connect, timeout + * o connected, link is broken, LAP has timeout + * o connected, other side close the link + * o connection request on the server no handled + */ +static void +irnet_disconnect_indication(void * instance, + void * sap, + LM_REASON reason, + struct sk_buff *skb) +{ + irnet_socket * self = (irnet_socket *) instance; + + DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self); + DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n"); + + /* If we were active, notify the control channel */ + if(self->ttp_open) + irnet_post_event(self, IRNET_DISCONNECT_FROM, self->daddr, self->rname); + else + /* If we were trying to connect, notify the control channel */ + if((self->tsap) && (self != &irnet_server.s)) + irnet_post_event(self, IRNET_NOANSWER_FROM, self->daddr, self->rname); + + /* Prevent higher layer from accessing IrTTP */ + self->ttp_open = 0; + + /* Close our IrTTP connection */ + if((self->tsap) && (self != &irnet_server.s)) + { + DEBUG(IRDA_CB_INFO, "Closing our TTP connection.\n"); + irttp_disconnect_request(self->tsap, NULL, P_NORMAL); + irttp_close_tsap(self->tsap); + self->tsap = NULL; + + /* Flush (drain) ppp_generic Tx queue (most often we have blocked it) */ + if(self->ppp_open) + ppp_output_wakeup(&self->chan); + } + /* Cleanup the socket in case we want to reconnect */ + self->stsap_sel = 0; + self->daddr = DEV_ADDR_ANY; + self->tx_flow = FLOW_START; + + /* Note : what should we say to ppp ? + * It seem the ppp_generic and pppd are happy that way and will eventually + * timeout gracefully, so don't bother them... */ + + DEXIT(IRDA_TCB_TRACE, "\n"); +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_connect_confirm (instance, sap, qos, max_sdu_size, skb) + * + * Connections has been confirmed by the remote device + * + */ +static void +irnet_connect_confirm(void * instance, + void * sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb) +{ + irnet_socket * self = (irnet_socket *) instance; + + DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self); + + /* How much header space do we need to reserve */ + self->max_header_size = max_header_size; + + /* IrTTP max SDU size in transmit direction */ + self->max_sdu_size_tx = max_sdu_size; + self->max_data_size = max_sdu_size; +#ifdef STREAM_COMPAT + if(max_sdu_size == 0) + self->max_data_size = irttp_get_max_seg_size(self->tsap); +#endif STREAM_COMPAT + + /* At this point, IrLMP has assigned our source address */ + self->saddr = irttp_get_saddr(self->tsap); + + /* Allow higher layer to access IrTTP */ + self->ttp_open = 1; + /* Give a kick in the ass of ppp_generic so that he sends us some data */ + ppp_output_wakeup(&self->chan); + + /* Check size of received packet */ + if(skb->len > 0) + { +#ifdef PASS_CONNECT_PACKETS + DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n"); + /* Try to pass it to PPP */ + irnet_data_indication(instance, sap, skb); +#else PASS_CONNECT_PACKETS + DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n"); + kfree_skb(skb); /* Note : will be optimised with other kfree... */ +#endif PASS_CONNECT_PACKETS + } + else + kfree_skb(skb); + + /* Notify the control channel */ + irnet_post_event(self, IRNET_CONNECT_TO, self->daddr, self->rname); + + DEXIT(IRDA_TCB_TRACE, "\n"); +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_flow_indication (instance, sap, flow) + * + * Used by TinyTP to tell us if it can accept more data or not + * + */ +static void +irnet_flow_indication(void * instance, + void * sap, + LOCAL_FLOW flow) +{ + irnet_socket * self = (irnet_socket *) instance; + + DENTER(IRDA_TCB_TRACE, "(self=0x%X, flow=%d)\n", (unsigned int) self, flow); + + /* Update our state */ + self->tx_flow = flow; + + /* Check what IrTTP want us to do... */ + switch(flow) + { + case FLOW_START: + DEBUG(IRDA_CB_INFO, "IrTTP wants us to start again\n"); + ppp_output_wakeup(&self->chan); + break; + case FLOW_STOP: + DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow down\n"); + break; + default: + DEBUG(IRDA_CB_INFO, "Unknown flow command!\n"); + break; + } + + DEXIT(IRDA_TCB_TRACE, "\n"); +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_status_indication (instance, sap, reason, skb) + * + * Link (IrLAP) status report. + * + */ +static void +irnet_status_indication(void * instance, + LINK_STATUS link, + LOCK_STATUS lock) +{ + irnet_socket * self = (irnet_socket *) instance; + + DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self); + DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n"); + + /* We can only get this event if we are connected */ + switch(link) + { + case STATUS_NO_ACTIVITY: + irnet_post_event(self, IRNET_BLOCKED_LINK, self->daddr, self->rname); + break; + default: + DEBUG(IRDA_CB_INFO, "Unknown status...\n"); + } + + DEXIT(IRDA_TCB_TRACE, "\n"); +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_connect_indication(instance, sap, qos, max_sdu_size, userdata) + * + * Incomming connection + * + * In theory, this function is called only on the server socket. + * Some other node is attempting to connect to the IrNET service, and has + * sent a connection request on our server socket. + * We just redirect the connection to the relevant IrNET socket. + * + * Note : we also make sure that between 2 irnet nodes, there can + * exist only one irnet connection. + */ +static void +irnet_connect_indication(void * instance, + void * sap, + struct qos_info *qos, + __u32 max_sdu_size, + __u8 max_header_size, + struct sk_buff *skb) +{ + irnet_socket * self = &irnet_server.s; + irnet_socket * new = (irnet_socket *) NULL; + + DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self); + DASSERT(instance == &irnet_server, , IRDA_CB_ERROR, + "Invalid instance (0x%X) !!!\n", (unsigned int) instance); + DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n"); + + /* Try to find the most appropriate IrNET socket */ + new = irnet_find_socket(self); + + /* After all this hard work, do we have an socket ? */ + if(new == (irnet_socket *) NULL) + { + DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.\n"); + irnet_disconnect_server(self, skb); + return; + } + + /* Is the socket already busy ? */ + if(new->ttp_open) + { + DEXIT(IRDA_CB_INFO, ": Socket already connected.\n"); + irnet_disconnect_server(self, skb); + return; + } + + /* Socket connecting */ + if(new->tsap != NULL) + { + /* The socket has sent a IrTTP connection request and is waiting for + * a connection response (that may never come). + * Now, the pain is that the socket has open a tsap and is waiting on it, + * while the other end is trying to connect to it on another tsap. + * Argh ! We will deal with that later... + */ + DERROR(IRDA_CB_ERROR, "Socket already connecting. Ouch !\n"); +#ifdef ALLOW_SIMULT_CONNECT + /* Close the connection the new socket was attempting. + * WARNING : This need more testing ! */ + irttp_close_tsap(new->tsap); + /* Note : no return, fall through... */ +#else ALLOW_SIMULT_CONNECT + irnet_disconnect_server(self, skb); + return; +#endif ALLOW_SIMULT_CONNECT + } + + /* So : at this point, we have a socket, and it is idle. Good ! */ + irnet_connect_socket(self, new, qos, max_sdu_size, max_header_size); + + /* Check size of received packet */ + if(skb->len > 0) + { +#ifdef PASS_CONNECT_PACKETS + DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n"); + /* Try to pass it to PPP */ + irnet_data_indication(new, new->tsap, skb); +#else PASS_CONNECT_PACKETS + DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n"); + kfree_skb(skb); /* Note : will be optimised with other kfree... */ +#endif PASS_CONNECT_PACKETS + } + else + kfree_skb(skb); + + DEXIT(IRDA_TCB_TRACE, "\n"); +} + + +/********************** IRDA-IAS/LMP CALLBACKS **********************/ +/* + * These are the callbacks called by other layers of the IrDA stack, + * mainly LMP for discovery and IAS for name queries. + */ + +/*------------------------------------------------------------------*/ +/* + * Function irnet_getvalue_confirm (obj_id, value, priv) + * + * Got answer from remote LM-IAS, just pass object to requester... + * + */ +static void +irnet_getvalue_confirm(int result, + __u16 obj_id, + struct ias_value *value, + void * priv) +{ + irnet_socket * self = (irnet_socket *) priv; + + DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self); + DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n"); + + /* We probably don't need to make any more queries */ + iriap_close(self->iriap); + self->iriap = NULL; + + /* Check if request succeeded */ + if(result != IAS_SUCCESS) + { + DEBUG(IRDA_CB_INFO, "IAS query failed! (%d)\n", result); + self->errno = result; /* We really need it later */ + } + else + { + /* Pass the object to the caller (so the caller must delete it) */ + self->ias_result = value; + self->errno = 0; + } + + /* Wake up any processes waiting for result */ + wake_up_interruptible(&self->query_wait); + + DEXIT(IRDA_OCB_TRACE, "\n"); +} + +#ifdef DISCOVERY_EVENTS +/*------------------------------------------------------------------*/ +/* + * Function irnet_discovery_indication (discovery) + * + * Got a discovery indication from IrLMP, post an event + * + * Note : IrLMP take care of matching the hint mask for us, we only + * check if it is a "new" node... + * + * As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET + * nodes, so it's only at connection time that we will know if the + * node support IrNET, IrLAN or both. The other solution is to check + * in IAS the PNP ids and service name. + * Note : even if a node support IrNET (or IrLAN), it's no guarantee + * that we will be able to connect to it, the node might already be + * busy... + * + * One last thing : in some case, this function will trigger duplicate + * discovery events. On the other hand, we should catch all + * discoveries properly (i.e. not miss one). Filtering duplicate here + * is to messy, so we leave that to user space... + */ +static void +irnet_discovery_indication(discovery_t *discovery, + void * priv) +{ + irnet_socket * self = &irnet_server.s; + + DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self); + DASSERT(priv == &irnet_server, , IRDA_CB_ERROR, + "Invalid instance (0x%X) !!!\n", (unsigned int) priv); + + /* Check if node is discovered is a new one or an old one. + * We check when how long ago this node was discovered, with a + * coarse timeout (we may miss some discovery events or be delayed). + */ + if((jiffies - discovery->first_timestamp) >= (sysctl_discovery_timeout * HZ)) + { + return; /* Too old, not interesting -> goodbye */ + } + + DEBUG(IRDA_CB_INFO, "Discovered new IrNET/IrLAN node %s...\n", + discovery->nickname); + + /* Notify the control channel */ + irnet_post_event(NULL, IRNET_DISCOVER, discovery->daddr, + discovery->nickname); + + DEXIT(IRDA_OCB_TRACE, "\n"); +} + +/*------------------------------------------------------------------*/ +/* + * Function irnet_expiry_indication (expiry) + * + * Got a expiry indication from IrLMP, post an event + * + * Note : IrLMP take care of matching the hint mask for us, we only + * check if it is a "new" node... + */ +static void +irnet_expiry_indication(discovery_t * expiry, + void * priv) +{ + irnet_socket * self = &irnet_server.s; + + DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self); + DASSERT(priv == &irnet_server, , IRDA_CB_ERROR, + "Invalid instance (0x%X) !!!\n", (unsigned int) priv); + + DEBUG(IRDA_CB_INFO, "IrNET/IrLAN node %s expired...\n", + expiry->nickname); + + /* Notify the control channel */ + irnet_post_event(NULL, IRNET_EXPIRE, expiry->daddr, + expiry->nickname); + + DEXIT(IRDA_OCB_TRACE, "\n"); +} +#endif DISCOVERY_EVENTS + + +/*********************** PROC ENTRY CALLBACKS ***********************/ +/* + * We create a instance in the /proc filesystem, and here we take care + * of that... + */ + +#ifdef CONFIG_PROC_FS +/*------------------------------------------------------------------*/ +/* + * Function irnet_proc_read (buf, start, offset, len, unused) + * + * Give some info to the /proc file system + */ +static int +irnet_proc_read(char * buf, + char ** start, + off_t offset, + int len) +{ + irnet_socket * self; + char * state; + unsigned long flags; + int i = 0; + + len = 0; + + /* Get the IrNET server information... */ + len += sprintf(buf+len, "IrNET server - "); + len += sprintf(buf+len, "IrDA state: %s, ", + (irnet_server.running ? "running" : "dead")); + len += sprintf(buf+len, "stsap_sel: %02x, ", irnet_server.s.stsap_sel); + len += sprintf(buf+len, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel); + + /* Do we need to continue ? */ + if(!irnet_server.running) + return len; + + /* Protect access to the instance list */ + spin_lock_irqsave(&irnet_server.spinlock, flags); + + /* Get the sockets one by one... */ + self = (irnet_socket *) hashbin_get_first(irnet_server.list); + while(self != NULL) + { + /* Start printing info about the socket. */ + len += sprintf(buf+len, "\nIrNET socket %d - ", i++); + + /* First, get the requested configuration */ + len += sprintf(buf+len, "Requested IrDA name: \"%s\", ", self->rname); + len += sprintf(buf+len, "addr: %08x\n", self->raddr); + + /* Second, get all the PPP info */ + len += sprintf(buf+len, " PPP state: %s", + (self->ppp_open ? "registered" : "unregistered")); + if(self->ppp_open) + { + len += sprintf(buf+len, ", unit: ppp%d", + ppp_unit_number(&self->chan)); + len += sprintf(buf+len, ", channel: %d", + ppp_channel_index(&self->chan)); + len += sprintf(buf+len, ", mru: %d", + self->mru); + /* Maybe add self->flags ? Later... */ + } + + /* Then, get all the IrDA specific info... */ + if(self->ttp_open) + state = "connected"; + else + if(self->tsap != NULL) + state = "connecting"; + else + state = "idle"; + len += sprintf(buf+len, "\n IrDA state: %s, ", state); + len += sprintf(buf+len, "daddr: %08x, ", self->daddr); + len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel); + len += sprintf(buf+len, "dtsap_sel: %02x\n", self->dtsap_sel); + + /* Next socket, please... */ + self = (irnet_socket *) hashbin_get_next(irnet_server.list); + } + + /* Spin lock end */ + spin_unlock_irqrestore(&irnet_server.spinlock, flags); + + return len; +} +#endif /* PROC_FS */ + + +/********************** CONFIGURATION/CLEANUP **********************/ +/* + * Initialisation and teardown of the IrDA part, called at module + * insertion and removal... + */ + +/*------------------------------------------------------------------*/ +/* + * Prepare the IrNET layer for operation... + */ +int +irda_irnet_init(void) +{ + int err = 0; + + DENTER(MODULE_TRACE, "()\n"); + + /* Pure paranoia - should be redundant */ + memset(&irnet_server, 0, sizeof(struct irnet_root)); + + /* Setup start of irnet instance list */ + irnet_server.list = hashbin_new(HB_LOCAL); + DABORT(irnet_server.list == NULL, -ENOMEM, + MODULE_ERROR, "Can't allocate hashbin!\n"); + /* Init spinlock for instance list */ + spin_lock_init(&irnet_server.spinlock); + + /* Initialise control channel */ + init_waitqueue_head(&irnet_events.rwait); + irnet_events.index = 0; + /* Init spinlock for event logging */ + spin_lock_init(&irnet_events.spinlock); + +#ifdef CONFIG_PROC_FS + /* Add a /proc file for irnet infos */ + create_proc_info_entry("irnet", 0, proc_irda, irnet_proc_read); +#endif /* CONFIG_PROC_FS */ + + /* Setup the IrNET server */ + err = irnet_setup_server(); + + if(!err) + /* We are no longer functional... */ + irnet_server.running = 1; + + DEXIT(MODULE_TRACE, "\n"); + return err; +} + +/*------------------------------------------------------------------*/ +/* + * Cleanup at exit... + */ +void +irda_irnet_cleanup(void) +{ + DENTER(MODULE_TRACE, "()\n"); + + /* We are no longer there... */ + irnet_server.running = 0; + +#ifdef CONFIG_PROC_FS + /* Remove our /proc file */ + remove_proc_entry("irnet", proc_irda); +#endif CONFIG_PROC_FS + + /* Remove our IrNET server from existence */ + irnet_destroy_server(); + + /* Remove all instances of IrNET socket still present */ + hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy); + + DEXIT(MODULE_TRACE, "\n"); +} diff --git a/net/irda/irnet/irnet_irda.h b/net/irda/irnet/irnet_irda.h new file mode 100644 index 000000000..a37d49be3 --- /dev/null +++ b/net/irda/irnet/irnet_irda.h @@ -0,0 +1,168 @@ +/* + * IrNET protocol module : Synchronous PPP over an IrDA socket. + * + * Jean II - HPL `00 - + * + * This file contains all definitions and declarations necessary for the + * IRDA part of the IrNET module (dealing with IrTTP, IrIAS and co). + * This file is a private header, so other modules don't want to know + * what's in there... + */ + +#ifndef IRNET_IRDA_H +#define IRNET_IRDA_H + +/***************************** INCLUDES *****************************/ + +#include "irnet.h" /* Module global include */ + +/************************ CONSTANTS & MACROS ************************/ + +/* + * Name of the service (socket name) used by IrNET + */ +/* IAS object name (or part of it) */ +#define IRNET_SERVICE_NAME "IrNetv1" +/* IAS attribute */ +#define IRNET_IAS_VALUE "IrDA:TinyTP:LsapSel" +/* LMP notify name for client (only for /proc/net/irda/irlmp) */ +#define IRNET_NOTIFY_NAME "IrNET socket" +/* LMP notify name for server (only for /proc/net/irda/irlmp) */ +#define IRNET_NOTIFY_NAME_SERV "IrNET server" + +/****************************** TYPES ******************************/ + +/* + * This is the main structure where we store all the data pertaining to + * the IrNET server (listen for connection requests) and the root + * of the IrNET socket list + */ +typedef struct irnet_root +{ + irnet_socket s; /* To pretend we are a client... */ + + /* Generic stuff */ + int magic; /* Paranoia */ + int running; /* Are we operational ? */ + + /* Link list of all IrNET instances opened */ + hashbin_t * list; + spinlock_t spinlock; /* Serialize access to the list */ + /* Note : the way hashbin has been designed is absolutely not + * reentrant, beware... So, we blindly protect all with spinlock */ + + /* Handle for the hint bit advertised in IrLMP */ + __u32 skey; + + /* Server socket part */ + struct ias_object * ias_obj; /* Our service name + lsap in IAS */ + +} irnet_root; + + +/**************************** PROTOTYPES ****************************/ + +/* ----------------------- CONTROL CHANNEL ----------------------- */ +static void + irnet_post_event(irnet_socket *, + irnet_event, + __u32, + char *); +/* ----------------------- IRDA SUBROUTINES ----------------------- */ +static inline int + irnet_open_tsap(irnet_socket *); +static int + irnet_find_lsap_sel(irnet_socket *); +static inline int + irnet_discover_daddr_and_lsap_sel(irnet_socket *); +static inline int + irnet_dname_to_daddr(irnet_socket *); +/* ------------------------ SERVER SOCKET ------------------------ */ +static inline int + irnet_daddr_to_dname(irnet_socket *); +static inline irnet_socket * + irnet_find_socket(irnet_socket *); +static inline int + irnet_connect_socket(irnet_socket *, + irnet_socket *, + struct qos_info *, + __u32, + __u8); +static inline void + irnet_disconnect_server(irnet_socket *, + struct sk_buff *); +static inline int + irnet_setup_server(void); +static inline void + irnet_destroy_server(void); +/* ---------------------- IRDA-TTP CALLBACKS ---------------------- */ +static int + irnet_data_indication(void *, /* instance */ + void *, /* sap */ + struct sk_buff *); +static void + irnet_disconnect_indication(void *, + void *, + LM_REASON, + struct sk_buff *); +static void + irnet_connect_confirm(void *, + void *, + struct qos_info *, + __u32, + __u8, + struct sk_buff *); +static void + irnet_flow_indication(void *, + void *, + LOCAL_FLOW); +static void + irnet_status_indication(void *, + LINK_STATUS, + LOCK_STATUS); +static void + irnet_connect_indication(void *, + void *, + struct qos_info *, + __u32, + __u8, + struct sk_buff *); +/* -------------------- IRDA-IAS/LMP CALLBACKS -------------------- */ +static void + irnet_getvalue_confirm(int, + __u16, + struct ias_value *, + void *); +#ifdef DISCOVERY_EVENTS +static void + irnet_discovery_indication(discovery_t *, + void *); +static void + irnet_expiry_indication(discovery_t *, + void *); +#endif +/* -------------------------- PROC ENTRY -------------------------- */ +#ifdef CONFIG_PROC_FS +static int + irnet_proc_read(char *, + char **, + off_t, + int); +#endif CONFIG_PROC_FS + +/**************************** VARIABLES ****************************/ + +/* + * The IrNET server. Listen to connection requests and co... + */ +static struct irnet_root irnet_server; + +/* Control channel stuff (note : extern) */ +struct irnet_ctrl_channel irnet_events; + +/* The /proc/net/irda directory, defined elsewhere... */ +#ifdef CONFIG_PROC_FS +extern struct proc_dir_entry *proc_irda; +#endif CONFIG_PROC_FS + +#endif IRNET_IRDA_H diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c new file mode 100644 index 000000000..96a5c4114 --- /dev/null +++ b/net/irda/irnet/irnet_ppp.c @@ -0,0 +1,1052 @@ +/* + * IrNET protocol module : Synchronous PPP over an IrDA socket. + * + * Jean II - HPL `00 - + * + * This file implement the PPP interface and /dev/irnet character device. + * The PPP interface hook to the ppp_generic module, handle all our + * relationship to the PPP code in the kernel (and by extension to pppd), + * and exchange PPP frames with this module (send/receive). + * The /dev/irnet device is used primarily for 2 functions : + * 1) as a stub for pppd (the ppp daemon), so that we can appropriately + * generate PPP sessions (we pretend we are a tty). + * 2) as a control channel (write commands, read events) + */ + +#include "irnet_ppp.h" /* Private header */ + +/************************* CONTROL CHANNEL *************************/ +/* + * When a pppd instance is not active on /dev/irnet, it acts as a control + * channel. + * Writting allow to set up the IrDA destination of the IrNET channel, + * and any application may be read events happening in IrNET... + */ + +/*------------------------------------------------------------------*/ +/* + * Write is used to send a command to configure a IrNET channel + * before it is open by pppd. The syntax is : "command argument" + * Currently there is only two defined commands : + * o name : set the requested IrDA nickname of the IrNET peer. + * o addr : set the requested IrDA address of the IrNET peer. + * Note : the code is crude, but effective... + */ +static inline ssize_t +irnet_ctrl_write(irnet_socket * ap, + const char * buf, + size_t count) +{ + char command[5 + NICKNAME_MAX_LEN + 2]; + int length = count; + + DENTER(CTRL_TRACE, "(ap=0x%X, count=%d)\n", (unsigned int) ap, count); + + /* Check for overflow... */ + DABORT(count > (5 + NICKNAME_MAX_LEN + 1), -ENOMEM, + CTRL_ERROR, "Too much data !!!\n"); + + /* Get the data in the driver */ + if(copy_from_user(command, buf, count)) + { + DERROR(CTRL_ERROR, "Invalid user space pointer.\n"); + return -EFAULT; + } + + /* Strip out '\n' if needed, and safe terminate the string */ + if(command[length - 1] == '\0') + length--; + if(command[length - 1] == '\n') + length--; + command[length] = '\0'; + DEBUG(CTRL_INFO, "Command received is ``%s'' (%d-%d).\n", + command, length, count); + + /* Check if we recognised the command */ + /* First command : name */ + if(!strncmp(command, "name", 4)) + { + /* Copy the name only if is included and not "any" */ + if((length > 5) && (strcmp(command + 5, "any"))) + { + /* Copy the name for later reuse (including the '/0') */ + memcpy(ap->rname, command + 5, length - 5 + 1); + } + else + ap->rname[0] = '\0'; + DEXIT(CTRL_TRACE, " - rname = ``%s''\n", ap->rname); + return(count); + } + + /* Second command : addr */ + if(!strncmp(command, "addr", 4)) + { + /* Copy the address only if is included and not "any" */ + if((length > 5) && (strcmp(command + 5, "any"))) + { + char * endp; + __u32 daddr; + + /* Convert argument to a number (last arg is the base) */ + daddr = simple_strtoul(command + 5, &endp, 16); + /* Has it worked ? (endp should be command + count) */ + DABORT(endp <= (command + 5), -EINVAL, + CTRL_ERROR, "Invalid address.\n"); + /* Save it */ + ap->raddr = daddr; + } + else + ap->raddr = DEV_ADDR_ANY; + DEXIT(CTRL_TRACE, " - raddr = %08x\n", ap->raddr); + return(count); + } + + /* Other possible command : connect N (number of retries) */ + + /* Failed... */ + DABORT(1, -EINVAL, CTRL_ERROR, "Not a recognised IrNET command.\n"); +} + +#ifdef INITIAL_DISCOVERY +/*------------------------------------------------------------------*/ +/* + * Function irnet_read_discovery_log (self) + * + * Read the content on the discovery log + * + * This function dump the current content of the discovery log + * at the startup of the event channel. + * Return 1 if written on the control channel... + * + * State of the ap->disco_XXX variables : + * at socket creation : disco_index = 0 ; disco_number = 0 + * while reading : disco_index = X ; disco_number = Y + * After reading : disco_index = Y ; disco_number = -1 + */ +static inline int +irnet_read_discovery_log(irnet_socket * ap, + char * event) +{ + int done_event = 0; + + DENTER(CTRL_TRACE, "(ap=0x%X, event=0x%X)\n", + (unsigned int) ap, (unsigned int) event); + + /* Test if we have some work to do or we have already finished */ + if(ap->disco_number == -1) + { + DEBUG(CTRL_INFO, "Already done\n"); + return 0; + } + + /* Test if it's the first time and therefore we need to get the log */ + if(ap->disco_index == 0) + { + __u16 mask = irlmp_service_to_hint(S_LAN); + + /* Ask IrLMP for the current discovery log */ + ap->discoveries = irlmp_get_discoveries(&ap->disco_number, mask); + /* Check if the we got some results */ + if(ap->discoveries == NULL) + ap->disco_number = -1; + DEBUG(CTRL_INFO, "Got the log (0x%X), size is %d\n", + (unsigned int) ap->discoveries, ap->disco_number); + } + + /* Check if we have more item to dump */ + if(ap->disco_index < ap->disco_number) + { + /* Write an event */ + sprintf(event, "Found %08x (%s)\n", + ap->discoveries[ap->disco_index].daddr, + ap->discoveries[ap->disco_index].info); + DEBUG(CTRL_INFO, "Writing discovery %d : %s\n", + ap->disco_index, ap->discoveries[ap->disco_index].info); + + /* We have an event */ + done_event = 1; + /* Next discovery */ + ap->disco_index++; + } + + /* Check if we have done the last item */ + if(ap->disco_index >= ap->disco_number) + { + /* No more items : remove the log and signal termination */ + DEBUG(CTRL_INFO, "Cleaning up log (0x%X)\n", + (unsigned int) ap->discoveries); + if(ap->discoveries != NULL) + { + /* Cleanup our copy of the discovery log */ + kfree(ap->discoveries); + ap->discoveries = NULL; + } + ap->disco_number = -1; + } + + return done_event; +} +#endif INITIAL_DISCOVERY + +/*------------------------------------------------------------------*/ +/* + * Read is used to get IrNET events + */ +static inline ssize_t +irnet_ctrl_read(irnet_socket * ap, + struct file * file, + char * buf, + size_t count) +{ + DECLARE_WAITQUEUE(wait, current); + char event[64]; /* Max event is 61 char */ + ssize_t ret = 0; + + DENTER(CTRL_TRACE, "(ap=0x%X, count=%d)\n", (unsigned int) ap, count); + + /* Check if we can write an event out in one go */ + DABORT(count < sizeof(event), -EOVERFLOW, CTRL_ERROR, "Buffer to small.\n"); + +#ifdef INITIAL_DISCOVERY + /* Check if we have read the log */ + if(irnet_read_discovery_log(ap, event)) + { + /* We have an event !!! Copy it to the user */ + if(copy_to_user(buf, event, strlen(event))) + { + DERROR(CTRL_ERROR, "Invalid user space pointer.\n"); + return -EFAULT; + } + + DEXIT(CTRL_TRACE, "\n"); + return(strlen(event)); + } +#endif INITIAL_DISCOVERY + + /* Put ourselves on the wait queue to be woken up */ + add_wait_queue(&irnet_events.rwait, &wait); + current->state = TASK_INTERRUPTIBLE; + for(;;) + { + /* If there is unread events */ + ret = 0; + if(ap->event_index != irnet_events.index) + break; + ret = -EAGAIN; + if(file->f_flags & O_NONBLOCK) + break; + ret = -ERESTARTSYS; + if(signal_pending(current)) + break; + /* Yield and wait to be woken up */ + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&irnet_events.rwait, &wait); + + /* Did we got it ? */ + if(ret != 0) + { + /* No, return the error code */ + DEXIT(CTRL_TRACE, " - ret %d\n", ret); + return ret; + } + + /* Which event is it ? */ + switch(irnet_events.log[ap->event_index].event) + { + case IRNET_DISCOVER: + sprintf(event, "Discovered %08x (%s)\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name); + break; + case IRNET_EXPIRE: + sprintf(event, "Expired %08x (%s)\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name); + break; + case IRNET_CONNECT_TO: + sprintf(event, "Connected to %08x (%s) on ppp%d\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name, + irnet_events.log[ap->event_index].unit); + break; + case IRNET_CONNECT_FROM: + sprintf(event, "Connection from %08x (%s) on ppp%d\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name, + irnet_events.log[ap->event_index].unit); + break; + case IRNET_REQUEST_FROM: + sprintf(event, "Request from %08x (%s)\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name); + break; + case IRNET_NOANSWER_FROM: + sprintf(event, "No-answer from %08x (%s) on ppp%d\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name, + irnet_events.log[ap->event_index].unit); + break; + case IRNET_BLOCKED_LINK: + sprintf(event, "Blocked link with %08x (%s) on ppp%d\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name, + irnet_events.log[ap->event_index].unit); + break; + case IRNET_DISCONNECT_FROM: + sprintf(event, "Disconnection from %08x (%s) on ppp%d\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name, + irnet_events.log[ap->event_index].unit); + break; + case IRNET_DISCONNECT_TO: + sprintf(event, "Disconnected to %08x (%s)\n", + irnet_events.log[ap->event_index].addr, + irnet_events.log[ap->event_index].name); + break; + default: + sprintf(event, "Bug\n"); + } + /* Increment our event index */ + ap->event_index = (ap->event_index + 1) % IRNET_MAX_EVENTS; + + DEBUG(CTRL_INFO, "Event is :%s", event); + + /* Copy it to the user */ + if(copy_to_user(buf, event, strlen(event))) + { + DERROR(CTRL_ERROR, "Invalid user space pointer.\n"); + return -EFAULT; + } + + DEXIT(CTRL_TRACE, "\n"); + return(strlen(event)); +} + +/*------------------------------------------------------------------*/ +/* + * Poll : called when someone do a select on /dev/irnet. + * Just check if there are new events... + */ +static inline unsigned int +irnet_ctrl_poll(irnet_socket * ap, + struct file * file, + poll_table * wait) +{ + unsigned int mask; + + DENTER(CTRL_TRACE, "(ap=0x%X)\n", (unsigned int) ap); + + poll_wait(file, &irnet_events.rwait, wait); + mask = POLLOUT | POLLWRNORM; + /* If there is unread events */ + if(ap->event_index != irnet_events.index) + mask |= POLLIN | POLLRDNORM; +#ifdef INITIAL_DISCOVERY + if(ap->disco_number != -1) + mask |= POLLIN | POLLRDNORM; +#endif INITIAL_DISCOVERY + + DEXIT(CTRL_TRACE, " - mask=0x%X\n", mask); + return mask; +} + + +/*********************** FILESYSTEM CALLBACKS ***********************/ +/* + * Implement the usual open, read, write functions that will be called + * by the file system when some action is performed on /dev/irnet. + * Most of those actions will in fact be performed by "pppd" or + * the control channel, we just act as a redirector... + */ + +/*------------------------------------------------------------------*/ +/* + * Open : when somebody open /dev/irnet + * We basically create a new instance of irnet and initialise it. + */ +static int +dev_irnet_open(struct inode * inode, + struct file * file) +{ + struct irnet_socket * ap; + int err; + + DENTER(FS_TRACE, "(file=0x%X)\n", (unsigned int) file); + +#ifdef SECURE_DEVIRNET + /* This could (should?) be enforced by the permissions on /dev/irnet. */ + if(!capable(CAP_NET_ADMIN)) + return -EPERM; +#endif SECURE_DEVIRNET + + /* Allocate a private structure for this IrNET instance */ + ap = kmalloc(sizeof(*ap), GFP_KERNEL); + DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n"); + + MOD_INC_USE_COUNT; + + /* initialize the irnet structure */ + memset(ap, 0, sizeof(*ap)); + ap->file = file; + + /* PPP channel setup */ + ap->ppp_open = 0; + ap->chan.private = ap; + /* PPP parameters */ + ap->mru = PPP_MRU; + ap->xaccm[0] = ~0U; + ap->xaccm[3] = 0x60000000U; + ap->raccm = ~0U; + + /* Setup the IrDA part... */ + err = irda_irnet_create(ap); + if(err) + { + DERROR(FS_ERROR, "Can't setup IrDA link...\n"); + kfree(ap); + MOD_DEC_USE_COUNT; + return err; + } + + /* For the control channel */ + ap->event_index = irnet_events.index; /* Cancel all past events */ + + /* Put our stuff where we will be able to find it later */ + file->private_data = ap; + + DEXIT(FS_TRACE, " - ap=0x%X\n", (unsigned int) ap); + return 0; +} + + +/*------------------------------------------------------------------*/ +/* + * Close : when somebody close /dev/irnet + * Destroy the instance of /dev/irnet + */ +static int +dev_irnet_close(struct inode * inode, + struct file * file) +{ + irnet_socket * ap = (struct irnet_socket *) file->private_data; + + DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)\n", + (unsigned int) file, (unsigned int) ap); + DABORT(ap == NULL, 0, FS_ERROR, "ap is NULL !!!\n"); + + /* Detach ourselves */ + file->private_data = NULL; + + /* Close IrDA stuff */ + irda_irnet_destroy(ap); + + /* Disconnect from the generic PPP layer if not already done */ + if(ap->ppp_open) + { + DERROR(FS_ERROR, "Channel still registered - deregistering !\n"); + ppp_unregister_channel(&ap->chan); + ap->ppp_open = 0; + } + + kfree(ap); + MOD_DEC_USE_COUNT; + + DEXIT(FS_TRACE, "\n"); + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Write does nothing. + * (we receive packet from ppp_generic through ppp_irnet_send()) + */ +static ssize_t +dev_irnet_write(struct file * file, + const char * buf, + size_t count, + loff_t * ppos) +{ + irnet_socket * ap = (struct irnet_socket *) file->private_data; + + DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)\n", + (unsigned int) file, (unsigned int) ap, count); + DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n"); + + /* If we are connected to ppp_generic, let it handle the job */ + if(ap->ppp_open) + return ppp_channel_write(&ap->chan, buf, count); + else + return irnet_ctrl_write(ap, buf, count); +} + +/*------------------------------------------------------------------*/ +/* + * Read doesn't do much either. + * (pppd poll us, but ultimately reads through /dev/ppp) + */ +static ssize_t +dev_irnet_read(struct file * file, + char * buf, + size_t count, + loff_t * ppos) +{ + irnet_socket * ap = (struct irnet_socket *) file->private_data; + + DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)\n", + (unsigned int) file, (unsigned int) ap, count); + DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n"); + + /* If we are connected to ppp_generic, let it handle the job */ + if(ap->ppp_open) + return ppp_channel_read(&ap->chan, file, buf, count); + else + return irnet_ctrl_read(ap, file, buf, count); +} + +/*------------------------------------------------------------------*/ +/* + * Poll : called when someone do a select on /dev/irnet + */ +static unsigned int +dev_irnet_poll(struct file * file, + poll_table * wait) +{ + irnet_socket * ap = (struct irnet_socket *) file->private_data; + unsigned int mask; + + DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)\n", + (unsigned int) file, (unsigned int) ap); + + mask = POLLOUT | POLLWRNORM; + DABORT(ap == NULL, mask, FS_ERROR, "ap is NULL !!!\n"); + + /* If we are connected to ppp_generic, let it handle the job */ + if(ap->ppp_open) + mask |= ppp_channel_poll(&ap->chan, file, wait); + else + mask |= irnet_ctrl_poll(ap, file, wait); + + DEXIT(FS_TRACE, " - mask=0x%X\n", mask); + return(mask); +} + +/*------------------------------------------------------------------*/ +/* + * IOCtl : Called when someone does some ioctls on /dev/irnet + * This is the way pppd configure us and control us while the PPP + * instance is active. + */ +static int +dev_irnet_ioctl(struct inode * inode, + struct file * file, + unsigned int cmd, + unsigned long arg) +{ + irnet_socket * ap = (struct irnet_socket *) file->private_data; + int err; + int val; + + DENTER(FS_TRACE, "(file=0x%X, ap=0x%X, cmd=0x%X)\n", + (unsigned int) file, (unsigned int) ap, cmd); + + /* Basic checks... */ + DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...\n"); +#ifdef SECURE_DEVIRNET + if(!capable(CAP_NET_ADMIN)) + return -EPERM; +#endif SECURE_DEVIRNET + + err = -EFAULT; + switch(cmd) + { + /* Set discipline (should be N_SYNC_PPP or N_TTY) */ + case TIOCSETD: + if(get_user(val, (int *) arg)) + break; + if((val == N_SYNC_PPP) || (val == N_PPP)) + { + DEBUG(FS_INFO, "Entering PPP discipline.\n"); + /* PPP channel setup */ + ap->chan.private = ap; + ap->chan.ops = &irnet_ppp_ops; + ap->chan.mtu = PPP_MRU; + err = ppp_register_channel(&ap->chan); + if(err == 0) + { + /* Our ppp side is active */ + ap->ppp_open = 1; + + DEBUG(FS_INFO, "Trying to establish a connection.\n"); + /* Setup the IrDA link now - may fail... */ + irda_irnet_connect(ap); + } + else + DERROR(FS_ERROR, "Can't setup PPP channel...\n"); + } + else + { + /* In theory, should be N_TTY */ + DEBUG(FS_INFO, "Exiting PPP discipline.\n"); + /* Disconnect from the generic PPP layer */ + if(ap->ppp_open) + ppp_unregister_channel(&ap->chan); + else + DERROR(FS_ERROR, "Channel not registered !\n"); + ap->ppp_open = 0; + err = 0; + } + break; + + /* Attach this PPP instance to the PPP driver (set it active) */ + case PPPIOCATTACH: + case PPPIOCDETACH: + if(ap->ppp_open) + err = ppp_channel_ioctl(&ap->chan, cmd, arg); + else + DERROR(FS_ERROR, "Channel not registered !\n"); + break; + + /* Query PPP channel and unit number */ + case PPPIOCGCHAN: + if(!ap->ppp_open) + break; + if(put_user(ppp_channel_index(&ap->chan), (int *) arg)) + break; + DEBUG(FS_INFO, "Query channel.\n"); + err = 0; + break; + case PPPIOCGUNIT: + if(!ap->ppp_open) + break; + if(put_user(ppp_unit_number(&ap->chan), (int *) arg)) + break; + DEBUG(FS_INFO, "Query unit number.\n"); + err = 0; + break; + + /* All these ioctls can be passed both directly and from ppp_generic, + * so we just deal with them in one place... + */ + case PPPIOCGFLAGS: + case PPPIOCSFLAGS: + case PPPIOCGASYNCMAP: + case PPPIOCSASYNCMAP: + case PPPIOCGRASYNCMAP: + case PPPIOCSRASYNCMAP: + case PPPIOCGXASYNCMAP: + case PPPIOCSXASYNCMAP: + case PPPIOCGMRU: + case PPPIOCSMRU: + DEBUG(FS_INFO, "Standard PPP ioctl.\n"); + if(!capable(CAP_NET_ADMIN)) + err = -EPERM; + else + err = ppp_irnet_ioctl(&ap->chan, cmd, arg); + break; + + /* TTY IOCTLs : Pretend that we are a tty, to keep pppd happy */ + /* Get termios */ + case TCGETS: + DEBUG(FS_INFO, "Get termios.\n"); + if(kernel_termios_to_user_termios((struct termios *)arg, &ap->termios)) + break; + err = 0; + break; + /* Set termios */ + case TCSETSF: + DEBUG(FS_INFO, "Set termios.\n"); + if(user_termios_to_kernel_termios(&ap->termios, (struct termios *) arg)) + break; + err = 0; + break; + + /* Set DTR/RTS */ + case TIOCMBIS: + case TIOCMBIC: + /* Set exclusive/non-exclusive mode */ + case TIOCEXCL: + case TIOCNXCL: + DEBUG(FS_INFO, "TTY compatibility.\n"); + err = 0; + break; + + case TCGETA: + DEBUG(FS_INFO, "TCGETA\n"); + break; + + case TCFLSH: + DEBUG(FS_INFO, "TCFLSH\n"); + /* Note : this will flush buffers in PPP, so it *must* be done + * We should also worry that we don't accept junk here and that + * we get rid of our own buffers */ +#ifdef FLUSH_TO_PPP + ppp_output_wakeup(&ap->chan); +#endif FLUSH_TO_PPP + err = 0; + break; + + case FIONREAD: + DEBUG(FS_INFO, "FIONREAD\n"); + val = 0; + if(put_user(val, (int *) arg)) + break; + err = 0; + break; + + default: + DERROR(FS_ERROR, "Unsupported ioctl (0x%X)\n", cmd); + err = -ENOIOCTLCMD; + } + + DEXIT(FS_TRACE, " - err = 0x%X\n", err); + return err; +} + +/************************** PPP CALLBACKS **************************/ +/* + * This are the functions that the generic PPP driver in the kernel + * will call to communicate to us. + */ + +/*------------------------------------------------------------------*/ +/* + * Prepare the ppp frame for transmission over the IrDA socket. + * We make sure that the header space is enough, and we change ppp header + * according to flags passed by pppd. + * This is not a callback, but just a helper function used in ppp_irnet_send() + */ +static inline struct sk_buff * +irnet_prepare_skb(irnet_socket * ap, + struct sk_buff * skb) +{ + unsigned char * data; + int proto; /* PPP protocol */ + int islcp; /* Protocol == LCP */ + int needaddr; /* Need PPP address */ + + DENTER(PPP_TRACE, "(ap=0x%X, skb=0x%X)\n", + (unsigned int) ap, (unsigned int) skb); + + /* Extract PPP protocol from the frame */ + data = skb->data; + proto = (data[0] << 8) + data[1]; + + /* LCP packets with codes between 1 (configure-request) + * and 7 (code-reject) must be sent as though no options + * have been negotiated. */ + islcp = (proto == PPP_LCP) && (1 <= data[2]) && (data[2] <= 7); + + /* compress protocol field if option enabled */ + if((data[0] == 0) && (ap->flags & SC_COMP_PROT) && (!islcp)) + skb_pull(skb,1); + + /* Check if we need address/control fields */ + needaddr = 2*((ap->flags & SC_COMP_AC) == 0 || islcp); + + /* Is the skb headroom large enough to contain all IrDA-headers? */ + if((skb_headroom(skb) < (ap->max_header_size + needaddr)) || + (skb_shared(skb))) + { + struct sk_buff * new_skb; + + DEBUG(PPP_INFO, "Reallocating skb\n"); + + /* Create a new skb */ + new_skb = skb_realloc_headroom(skb, ap->max_header_size + needaddr); + + /* We have to free the original skb anyway */ + dev_kfree_skb(skb); + + /* Did the realloc succeed ? */ + DABORT(new_skb == NULL, NULL, PPP_ERROR, "Could not realloc skb\n"); + + /* Use the new skb instead */ + skb = new_skb; + } + + /* prepend address/control fields if necessary */ + if(needaddr) + { + skb_push(skb,2); + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI; + } + + DEXIT(PPP_TRACE, "\n"); + + return skb; +} + +/*------------------------------------------------------------------*/ +/* + * Send a packet to the peer over the IrTTP connection. + * Returns 1 iff the packet was accepted. + * Returns 0 iff packet was not consumed. + * If the packet was not accepted, we will call ppp_output_wakeup + * at some later time to reactivate flow control in ppp_generic. + */ +static int +ppp_irnet_send(struct ppp_channel * chan, + struct sk_buff * skb) +{ + irnet_socket * self = (struct irnet_socket *) chan->private; + int ret; + + DENTER(PPP_TRACE, "(channel=0x%X, ap/self=0x%X)\n", + (unsigned int) chan, (unsigned int) self); + + /* Check if things are somewhat valid... */ + DASSERT(self != NULL, 0, PPP_ERROR, "Self is NULL !!!\n"); + + /* Check if we are connected */ + if(self->ttp_open == 0) + { +#ifdef CONNECT_IN_SEND + /* Let's try to connect one more time... */ + /* Note : we won't connect fully yet, but we should be ready for + * next packet... */ + /* Note : we can't do that, we need to have a process context to + * go through interruptible_sleep_on() in irnet_find_lsap_sel() + * We need to find another way... */ + irda_irnet_connect(self); +#endif CONNECT_IN_SEND + + DEBUG(PPP_INFO, "IrTTP not ready ! (%d-0x%X)\n", + self->ttp_open, (unsigned int) self->tsap); + + /* Note : we can either drop the packet or block the packet. + * + * Blocking the packet allow us a better connection time, + * because by calling ppp_output_wakeup() we can have + * ppp_generic resending the LCP request immediately to us, + * rather than waiting for one of pppd periodic transmission of + * LCP request. + * + * On the other hand, if we block all packet, all those periodic + * transmissions of pppd accumulate in ppp_generic, creating a + * backlog of LCP request. When we eventually connect later on, + * we have to transmit all this backlog before we can connect + * proper (if we don't timeout before). + * + * The current strategy is as follow : + * While we are attempting to connect, we block packets to get + * a better connection time. + * If we fail to connect, we drain the queue and start dropping packets + */ +#ifdef BLOCK_WHEN_CONNECT + /* If we are attempting to connect */ + if(self->tsap) + { + /* Blocking packet, ppp_generic will retry later */ + return 0; + } +#endif BLOCK_WHEN_CONNECT + + /* Dropping packet, pppd will retry later */ + dev_kfree_skb(skb); + return 1; + } + + /* Check if the queue can accept any packet, otherwise block */ + if(self->tx_flow != FLOW_START) + DRETURN(0, PPP_INFO, "IrTTP queue full (%d skbs)...\n", + skb_queue_len(&self->tsap->tx_queue)); + + /* Prepare ppp frame for transmission */ + skb = irnet_prepare_skb(self, skb); + DABORT(skb == NULL, 1, PPP_ERROR, "Prepare skb for Tx failed.\n"); + + /* Send the packet to IrTTP */ + ret = irttp_data_request(self->tsap, skb); + if(ret < 0) + { + /* + * > IrTTPs tx queue is full, so we just have to + * > drop the frame! You might think that we should + * > just return -1 and don't deallocate the frame, + * > but that is dangerous since it's possible that + * > we have replaced the original skb with a new + * > one with larger headroom, and that would really + * > confuse do_dev_queue_xmit() in dev.c! I have + * > tried :-) DB + * Correction : we verify the flow control above (self->tx_flow), + * so we come here only if IrTTP doesn't like the packet (empty, + * too large, IrTTP not connected). In those rare cases, it's ok + * to drop it, we don't want to see it here again... + * Jean II + */ + DERROR(PPP_ERROR, "IrTTP doesn't like this packet !!! (0x%X)\n", ret); + dev_kfree_skb(skb); + } + + DEXIT(PPP_TRACE, "\n"); + return 1; /* Packet has been consumed */ +} + +/*------------------------------------------------------------------*/ +/* + * Take care of the ioctls that ppp_generic doesn't want to deal with... + * Note : we are also called from dev_irnet_ioctl(). + */ +static int +ppp_irnet_ioctl(struct ppp_channel * chan, + unsigned int cmd, + unsigned long arg) +{ + irnet_socket * ap = (struct irnet_socket *) chan->private; + int err; + int val; + u32 accm[8]; + + DENTER(PPP_TRACE, "(channel=0x%X, ap=0x%X, cmd=0x%X)\n", + (unsigned int) chan, (unsigned int) ap, cmd); + + /* Basic checks... */ + DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...\n"); + + err = -EFAULT; + switch(cmd) + { + /* PPP flags */ + case PPPIOCGFLAGS: + val = ap->flags | ap->rbits; + if(put_user(val, (int *) arg)) + break; + err = 0; + break; + case PPPIOCSFLAGS: + if(get_user(val, (int *) arg)) + break; + ap->flags = val & ~SC_RCV_BITS; + ap->rbits = val & SC_RCV_BITS; + err = 0; + break; + + /* Async map stuff - all dummy to please pppd */ + case PPPIOCGASYNCMAP: + if(put_user(ap->xaccm[0], (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCSASYNCMAP: + if(get_user(ap->xaccm[0], (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCGRASYNCMAP: + if(put_user(ap->raccm, (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCSRASYNCMAP: + if(get_user(ap->raccm, (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCGXASYNCMAP: + if(copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm))) + break; + err = 0; + break; + case PPPIOCSXASYNCMAP: + if(copy_from_user(accm, (void *) arg, sizeof(accm))) + break; + accm[2] &= ~0x40000000U; /* can't escape 0x5e */ + accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ + memcpy(ap->xaccm, accm, sizeof(ap->xaccm)); + err = 0; + break; + + /* Max PPP frame size */ + case PPPIOCGMRU: + if(put_user(ap->mru, (int *) arg)) + break; + err = 0; + break; + case PPPIOCSMRU: + if(get_user(val, (int *) arg)) + break; + if(val < PPP_MRU) + val = PPP_MRU; + ap->mru = val; + err = 0; + break; + + default: + DEBUG(PPP_INFO, "Unsupported ioctl (0x%X)\n", cmd); + err = -ENOIOCTLCMD; + } + + DEXIT(PPP_TRACE, " - err = 0x%X\n", err); + return err; +} + +/************************** INITIALISATION **************************/ +/* + * Module initialisation and all that jazz... + */ + +/*------------------------------------------------------------------*/ +/* + * Hook our device callbacks in the filesystem, to connect our code + * to /dev/irnet + */ +int +ppp_irnet_init(void) +{ + int err = 0; + + DENTER(MODULE_TRACE, "()\n"); + + /* Allocate ourselves as a minor in the misc range */ + err = misc_register(&irnet_misc_device); + + DEXIT(MODULE_TRACE, "\n"); + return err; +} + +/*------------------------------------------------------------------*/ +/* + * Cleanup at exit... + */ +void +ppp_irnet_cleanup(void) +{ + DENTER(MODULE_TRACE, "()\n"); + + /* De-allocate /dev/irnet minor in misc range */ + misc_deregister(&irnet_misc_device); + + DEXIT(MODULE_TRACE, "\n"); +} + +#ifdef MODULE +/*------------------------------------------------------------------*/ +/* + * Module main entry point + */ +int +init_module(void) +{ + int err; + + /* Initialise both parts... */ + err = irda_irnet_init(); + if(!err) + err = ppp_irnet_init(); + return err; +} + +/*------------------------------------------------------------------*/ +/* + * Module exit + */ +void +cleanup_module(void) +{ + irda_irnet_cleanup(); + return ppp_irnet_cleanup(); +} +#endif /* MODULE */ diff --git a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h new file mode 100644 index 000000000..8e8365374 --- /dev/null +++ b/net/irda/irnet/irnet_ppp.h @@ -0,0 +1,130 @@ +/* + * IrNET protocol module : Synchronous PPP over an IrDA socket. + * + * Jean II - HPL `00 - + * + * This file contains all definitions and declarations necessary for the + * PPP part of the IrNET module. + * This file is a private header, so other modules don't want to know + * what's in there... + */ + +#ifndef IRNET_PPP_H +#define IRNET_PPP_H + +/***************************** INCLUDES *****************************/ + +#include "irnet.h" /* Module global include */ + +/************************ CONSTANTS & MACROS ************************/ + +/* /dev/irnet file constants */ +#define IRNET_MAJOR 10 /* Misc range */ +#define IRNET_MINOR 187 /* Official allocation */ + +#ifdef LINKNAME_IOCTL +/* Compatibility with old ppp drivers + * Should be defined in */ +#ifndef PPPIOCSLINKNAME +#define PPPIOCSLINKNAME _IOW('t', 74, struct ppp_option_data) +#endif PPPIOCSLINKNAME +#endif LINKNAME_IOCTL + +/* PPP hardcore stuff */ + +/* Bits in rbits (PPP flags in irnet struct) */ +#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) + +/* Bit numbers in busy */ +#define XMIT_BUSY 0 +#define RECV_BUSY 1 +#define XMIT_WAKEUP 2 +#define XMIT_FULL 3 + +/* Queue management */ +#define PPPSYNC_MAX_RQLEN 32 /* arbitrary */ + +/****************************** TYPES ******************************/ + + +/**************************** PROTOTYPES ****************************/ + +/* ----------------------- CONTROL CHANNEL ----------------------- */ +static inline ssize_t + irnet_ctrl_write(irnet_socket *, + const char *, + size_t); +static inline ssize_t + irnet_ctrl_read(irnet_socket *, + struct file *, + char *, + size_t); +static inline unsigned int + irnet_ctrl_poll(irnet_socket *, + struct file *, + poll_table *); +/* ----------------------- CHARACTER DEVICE ----------------------- */ +static int + dev_irnet_open(struct inode *, /* fs callback : open */ + struct file *), + dev_irnet_close(struct inode *, + struct file *); +static ssize_t + dev_irnet_write(struct file *, + const char *, + size_t, + loff_t *), + dev_irnet_read(struct file *, + char *, + size_t, + loff_t *); +static unsigned int + dev_irnet_poll(struct file *, + poll_table *); +static int + dev_irnet_ioctl(struct inode *, + struct file *, + unsigned int, + unsigned long); +/* ------------------------ PPP INTERFACE ------------------------ */ +static inline struct sk_buff * + irnet_prepare_skb(irnet_socket *, + struct sk_buff *); +static int + ppp_irnet_send(struct ppp_channel *, + struct sk_buff *); +static int + ppp_irnet_ioctl(struct ppp_channel *, + unsigned int, + unsigned long); + +/**************************** VARIABLES ****************************/ + +/* Filesystem callbacks (to call us) */ +static struct file_operations irnet_device_fops = +{ + read: dev_irnet_read, + write: dev_irnet_write, + poll: dev_irnet_poll, + ioctl: dev_irnet_ioctl, + open: dev_irnet_open, + release: dev_irnet_close + /* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */ +}; + +/* Structure so that the misc major (drivers/char/misc.c) take care of us... */ +static struct miscdevice irnet_misc_device = +{ + IRNET_MINOR, + "irnet", + &irnet_device_fops +}; + +/* Generic PPP callbacks (to call us) */ +struct ppp_channel_ops irnet_ppp_ops = +{ + ppp_irnet_send, + ppp_irnet_ioctl +}; + +#endif IRNET_PPP_H diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c index 1d26d8f19..d2e4da720 100644 --- a/net/irda/irqueue.c +++ b/net/irda/irqueue.c @@ -36,7 +36,7 @@ #include #include -static queue_t *dequeue_general( queue_t **queue, queue_t* element); +static irda_queue_t *dequeue_general( irda_queue_t **queue, irda_queue_t* element); static __u32 hash( char* name); /* @@ -79,7 +79,7 @@ hashbin_t *hashbin_new(int type) */ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func) { - queue_t* queue; + irda_queue_t* queue; int i; ASSERT(hashbin != NULL, return -1;); @@ -89,12 +89,12 @@ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func) * Free the entries in the hashbin */ for (i = 0; i < HASHBIN_SIZE; i ++ ) { - queue = dequeue_first( (queue_t**) &hashbin->hb_queue[i]); + queue = dequeue_first( (irda_queue_t**) &hashbin->hb_queue[i]); while (queue) { if (free_func) (*free_func)(queue); queue = dequeue_first( - (queue_t**) &hashbin->hb_queue[i]); + (irda_queue_t**) &hashbin->hb_queue[i]); } } hashbin->hb_size = 0; @@ -112,7 +112,7 @@ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func) */ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) { - queue_t* queue; + irda_queue_t* queue; int i; ASSERT(hashbin != NULL, return -1;); @@ -123,12 +123,12 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) * it has been shown to work */ for (i = 0; i < HASHBIN_SIZE; i ++ ) { - queue = dequeue_first((queue_t**) &hashbin->hb_queue[i]); + queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]); while (queue ) { if (free_func) (*free_func)(queue); queue = dequeue_first( - (queue_t**) &hashbin->hb_queue[i]); + (irda_queue_t**) &hashbin->hb_queue[i]); } } @@ -210,7 +210,7 @@ void hashbin_unlock(hashbin_t* hashbin, __u32 hashv, char* name, * Insert an entry into the hashbin * */ -void hashbin_insert(hashbin_t* hashbin, queue_t* entry, __u32 hashv, char* name) +void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, char* name) { unsigned long flags = 0; int bin; @@ -250,7 +250,7 @@ void hashbin_insert(hashbin_t* hashbin, queue_t* entry, __u32 hashv, char* name) */ if ( hashbin->hb_type & HB_SORTED) { } else { - enqueue_first( (queue_t**) &hashbin->hb_queue[ bin ], + enqueue_first( (irda_queue_t**) &hashbin->hb_queue[ bin ], entry); } hashbin->hb_size++; @@ -275,7 +275,7 @@ void* hashbin_find( hashbin_t* hashbin, __u32 hashv, char* name ) { int bin, found = FALSE; unsigned long flags = 0; - queue_t* entry; + irda_queue_t* entry; IRDA_DEBUG( 4, "hashbin_find()\n"); @@ -342,7 +342,7 @@ void* hashbin_find( hashbin_t* hashbin, __u32 hashv, char* name ) void *hashbin_remove_first( hashbin_t *hashbin) { unsigned long flags; - queue_t *entry = NULL; + irda_queue_t *entry = NULL; save_flags(flags); cli(); @@ -367,7 +367,7 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) { int bin, found = FALSE; unsigned long flags = 0; - queue_t* entry; + irda_queue_t* entry; IRDA_DEBUG( 4, __FUNCTION__ "()\n"); @@ -381,6 +381,7 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) hashv = hash( name ); bin = GET_HASHBIN( hashv ); + /* Synchronize */ if ( hashbin->hb_type & HB_GLOBAL ) { spin_lock_irqsave( &hashbin->hb_mutex[ bin ], flags); @@ -421,8 +422,8 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) * If entry was found, dequeue it */ if ( found ) { - dequeue_general( (queue_t**) &hashbin->hb_queue[ bin ], - (queue_t*) entry ); + dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ], + (irda_queue_t*) entry ); hashbin->hb_size--; /* @@ -450,6 +451,75 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) } +/* + * Function hashbin_remove (hashbin, hashv, name) + * + * Remove entry with the given name + * + * In some cases, the user of hashbin can't guarantee the unicity + * of either the hashv or name. + * In those cases, using the above function is guaranteed to cause troubles, + * so we use this one instead... + * And by the way, it's also faster, because we skip the search phase ;-) + */ +void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry) +{ + unsigned long flags = 0; + int bin; + __u32 hashv; + + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); + + ASSERT( hashbin != NULL, return NULL;); + ASSERT( hashbin->magic == HB_MAGIC, return NULL;); + ASSERT( entry != NULL, return NULL;); + + /* Check if valid and not already removed... */ + if((entry->q_next == NULL) || (entry->q_prev == NULL)) + return NULL; + + /* + * Locate hashbin + */ + hashv = entry->q_hash; + bin = GET_HASHBIN( hashv ); + + /* Synchronize */ + if ( hashbin->hb_type & HB_GLOBAL ) { + spin_lock_irqsave( &hashbin->hb_mutex[ bin ], flags); + + } else if ( hashbin->hb_type & HB_LOCAL ) { + save_flags(flags); + cli(); + } /* Default is no-lock */ + + /* + * Dequeue the entry... + */ + dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ], + (irda_queue_t*) entry ); + hashbin->hb_size--; + entry->q_next = NULL; + entry->q_prev = NULL; + + /* + * Check if this item is the currently selected item, and in + * that case we must reset hb_current + */ + if ( entry == hashbin->hb_current) + hashbin->hb_current = NULL; + + /* Release lock */ + if ( hashbin->hb_type & HB_GLOBAL) { + spin_unlock_irq( &hashbin->hb_mutex[ bin]); + + } else if ( hashbin->hb_type & HB_LOCAL) { + restore_flags( flags); + } + + return entry; +} + /* * Function hashbin_get_first (hashbin) * @@ -457,9 +527,9 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) * called before any calls to hashbin_get_next()! * */ -queue_t *hashbin_get_first( hashbin_t* hashbin) +irda_queue_t *hashbin_get_first( hashbin_t* hashbin) { - queue_t *entry; + irda_queue_t *entry; int i; ASSERT( hashbin != NULL, return NULL;); @@ -489,9 +559,9 @@ queue_t *hashbin_get_first( hashbin_t* hashbin) * NULL when all items have been traversed * */ -queue_t *hashbin_get_next( hashbin_t *hashbin) +irda_queue_t *hashbin_get_next( hashbin_t *hashbin) { - queue_t* entry; + irda_queue_t* entry; int bin; int i; @@ -542,7 +612,7 @@ queue_t *hashbin_get_next( hashbin_t *hashbin) * Insert item into end of queue. * */ -static void __enqueue_last( queue_t **queue, queue_t* element) +static void __enqueue_last( irda_queue_t **queue, irda_queue_t* element) { IRDA_DEBUG( 4, __FUNCTION__ "()\n"); @@ -566,7 +636,7 @@ static void __enqueue_last( queue_t **queue, queue_t* element) } } -inline void enqueue_last( queue_t **queue, queue_t* element) +inline void enqueue_last( irda_queue_t **queue, irda_queue_t* element) { unsigned long flags; @@ -584,7 +654,7 @@ inline void enqueue_last( queue_t **queue, queue_t* element) * Insert item first in queue. * */ -void enqueue_first(queue_t **queue, queue_t* element) +void enqueue_first(irda_queue_t **queue, irda_queue_t* element) { IRDA_DEBUG( 4, __FUNCTION__ "()\n"); @@ -616,9 +686,9 @@ void enqueue_first(queue_t **queue, queue_t* element) * Insert a queue (list) into the start of the first queue * */ -void enqueue_queue( queue_t** queue, queue_t** list ) +void enqueue_queue( irda_queue_t** queue, irda_queue_t** list ) { - queue_t* tmp; + irda_queue_t* tmp; /* * Check if queue is empty @@ -643,7 +713,7 @@ void enqueue_queue( queue_t** queue, queue_t** list ) * */ #if 0 -static void enqueue_second(queue_t **queue, queue_t* element) +static void enqueue_second(irda_queue_t **queue, irda_queue_t* element) { IRDA_DEBUG( 0, "enqueue_second()\n"); @@ -674,9 +744,9 @@ static void enqueue_second(queue_t **queue, queue_t* element) * Remove first entry in queue * */ -queue_t *dequeue_first(queue_t **queue) +irda_queue_t *dequeue_first(irda_queue_t **queue) { - queue_t *ret; + irda_queue_t *ret; IRDA_DEBUG( 4, "dequeue_first()\n"); @@ -715,9 +785,9 @@ queue_t *dequeue_first(queue_t **queue) * * */ -static queue_t *dequeue_general(queue_t **queue, queue_t* element) +static irda_queue_t *dequeue_general(irda_queue_t **queue, irda_queue_t* element) { - queue_t *ret; + irda_queue_t *ret; IRDA_DEBUG( 4, "dequeue_general()\n"); diff --git a/net/irda/irmod.c b/net/irda/irsyms.c similarity index 52% rename from net/irda/irmod.c rename to net/irda/irsyms.c index 39257f87a..cbfd650de 100644 --- a/net/irda/irmod.c +++ b/net/irda/irsyms.c @@ -1,8 +1,8 @@ /********************************************************************* * - * Filename: irmod.c - * Version: 0.8 - * Description: IrDA module code and some other stuff + * Filename: irsyms.c + * Version: 0.9 + * Description: IrDA module symbols * Status: Experimental. * Author: Dag Brattli * Created at: Mon Dec 15 13:55:39 1997 @@ -23,7 +23,7 @@ ********************************************************************/ #include -#include +#include #include #include @@ -49,18 +49,12 @@ extern struct proc_dir_entry *proc_irda; -struct irda_cb irda; /* One global instance */ - -#ifdef CONFIG_IRDA_DEBUG -__u32 irda_debug = IRDA_DEBUG_LEVEL; -#endif - extern void irda_proc_register(void); extern void irda_proc_unregister(void); extern int irda_sysctl_register(void); extern void irda_sysctl_unregister(void); -extern void irda_proto_init(struct net_proto *pro); +extern int irda_proto_init(void); extern void irda_proto_cleanup(void); extern int irda_device_init(void); @@ -78,26 +72,6 @@ extern irda_deflate_init(); #endif /* CONFIG_IRDA_DEFLATE */ #endif /* CONFIG_IRDA_COMPRESSION */ -static int irda_open(struct inode * inode, struct file *file); -static int irda_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -static int irda_close(struct inode *inode, struct file *file); -static ssize_t irda_read(struct file *file, char *buffer, size_t count, - loff_t *noidea); -static ssize_t irda_write(struct file *file, const char *buffer, - size_t count, loff_t *noidea); -static u_int irda_poll(struct file *file, poll_table *wait); - -static struct file_operations irda_fops = { - owner: THIS_MODULE, - read: irda_read, - write: irda_write, - poll: irda_poll, - ioctl: irda_ioctl, - open: irda_open, - release: irda_close, -}; - /* IrTTP */ EXPORT_SYMBOL(irttp_open_tsap); EXPORT_SYMBOL(irttp_close_tsap); @@ -114,7 +88,6 @@ EXPORT_SYMBOL(irttp_dup); EXPORT_SYMBOL(irda_debug); #endif EXPORT_SYMBOL(irda_notify_init); -EXPORT_SYMBOL(irmanager_notify); EXPORT_SYMBOL(irda_lock); #ifdef CONFIG_PROC_FS EXPORT_SYMBOL(proc_irda); @@ -145,6 +118,8 @@ EXPORT_SYMBOL(irias_new_octseq_value); /* IrLMP */ EXPORT_SYMBOL(irlmp_discovery_request); +EXPORT_SYMBOL(irlmp_get_discoveries); +EXPORT_SYMBOL(sysctl_discovery_timeout); EXPORT_SYMBOL(irlmp_register_client); EXPORT_SYMBOL(irlmp_unregister_client); EXPORT_SYMBOL(irlmp_update_client); @@ -168,6 +143,7 @@ EXPORT_SYMBOL(hashbin_new); EXPORT_SYMBOL(hashbin_insert); EXPORT_SYMBOL(hashbin_delete); EXPORT_SYMBOL(hashbin_remove); +EXPORT_SYMBOL(hashbin_remove_this); EXPORT_SYMBOL(hashbin_get_next); EXPORT_SYMBOL(hashbin_get_first); @@ -206,16 +182,13 @@ EXPORT_SYMBOL(irtty_unregister_dongle); EXPORT_SYMBOL(irtty_set_packet_mode); #endif -int __init irda_init(void) +static int __init irda_init(void) { - MESSAGE("IrDA (tm) Protocols for Linux-2.3 (Dag Brattli)\n"); - + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + irlmp_init(); irlap_init(); -#ifdef MODULE - irda_device_init(); /* Called by init/main.c when non-modular */ -#endif iriap_init(); irttp_init(); @@ -225,17 +198,6 @@ int __init irda_init(void) #ifdef CONFIG_SYSCTL irda_sysctl_register(); #endif - init_waitqueue_head(&irda.wait_queue); - irda.dev.minor = MISC_DYNAMIC_MINOR; - irda.dev.name = "irda"; - irda.dev.fops = &irda_fops; - - misc_register(&irda.dev); - - irda.in_use = FALSE; - - init_waitqueue_head(&irda.wait_queue); - /* * Initialize modules that got compiled into the kernel */ @@ -256,11 +218,8 @@ int __init irda_init(void) return 0; } -#ifdef MODULE -void irda_cleanup(void) +static void __exit irda_cleanup(void) { - misc_deregister(&irda.dev); - #ifdef CONFIG_SYSCTL irda_sysctl_unregister(); #endif @@ -279,7 +238,6 @@ void irda_cleanup(void) /* Remove middle layer */ irlmp_cleanup(); } -#endif /* MODULE */ /* * Function irda_unlock (lock) @@ -310,241 +268,8 @@ void irda_notify_init(notify_t *notify) notify->connect_indication = NULL; notify->disconnect_indication = NULL; notify->flow_indication = NULL; + notify->status_indication = NULL; notify->instance = NULL; strncpy(notify->name, "Unknown", NOTIFY_MAX_NAME); } -/* - * Function irda_execute_as_process (self, callback, param) - * - * If a layer needs to have a function executed with a process context, - * then it can register the function here, and the function will then - * be executed as fast as possible. - * - */ -void irda_execute_as_process( void *self, TODO_CALLBACK callback, __u32 param) -{ - struct irda_todo *new; - struct irmanager_event event; - - /* Make sure irmanager is running */ - if (!irda.in_use) { - return; - } - - /* Make new todo event */ - new = (struct irda_todo *) kmalloc( sizeof(struct irda_todo), - GFP_ATOMIC); - if ( new == NULL) { - return; - } - memset( new, 0, sizeof( struct irda_todo)); - - new->self = self; - new->callback = callback; - new->param = param; - - /* Queue todo */ - enqueue_last(&irda.todo_queue, (queue_t *) new); - - event.event = EVENT_NEED_PROCESS_CONTEXT; - - /* Notify the user space manager */ - irmanager_notify(&event); -} - -/* - * Function irmanger_notify (event) - * - * Send an event to the user space manager - * - */ -void irmanager_notify( struct irmanager_event *event) -{ - struct irda_event *new; - - IRDA_DEBUG(4, __FUNCTION__ "()\n"); - - /* Make sure irmanager is running */ - if (!irda.in_use) { - return; - } - - /* Make new IrDA Event */ - new = (struct irda_event *) kmalloc( sizeof(struct irda_event), - GFP_ATOMIC); - if ( new == NULL) { - return; - } - memset(new, 0, sizeof( struct irda_event)); - new->event = *event; - - /* Queue event */ - enqueue_last(&irda.event_queue, (queue_t *) new); - - /* Wake up irmanager sleeping on read */ - wake_up_interruptible(&irda.wait_queue); -} - -static int irda_open( struct inode * inode, struct file *file) -{ - IRDA_DEBUG( 4, __FUNCTION__ "()\n"); - - lock_kernel(); - if (irda.in_use) { - unlock_kernel(); - IRDA_DEBUG(0, __FUNCTION__ - "(), irmanager is already running!\n"); - return -1; - } - irda.in_use = TRUE; - unlock_kernel(); - - return 0; -} - -/* - * Function irda_ioctl (inode, filp, cmd, arg) - * - * Ioctl, used by irmanager to ... - * - */ -static int irda_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct irda_todo *todo; - int err = 0; - int size = _IOC_SIZE(cmd); - - IRDA_DEBUG(4, __FUNCTION__ "()\n"); - - if (_IOC_DIR(cmd) & _IOC_READ) - err = verify_area( VERIFY_WRITE, (void *) arg, size); - else if (_IOC_DIR(cmd) & _IOC_WRITE) - err = verify_area( VERIFY_READ, (void *) arg, size); - if (err) - return err; - - switch (cmd) { - case IRMGR_IOCTNPC: - /* Got process context! */ - IRDA_DEBUG(4, __FUNCTION__ "(), got process context!\n"); - - while ((todo = (struct irda_todo *) dequeue_first( - &irda.todo_queue)) != NULL) - { - todo->callback(todo->self, todo->param); - - kfree(todo); - } - break; - - default: - return -ENOIOCTLCMD; - } - - return 0; -} - -static int irda_close(struct inode *inode, struct file *file) -{ - IRDA_DEBUG(4, __FUNCTION__ "()\n"); - - lock_kernel(); - irda.in_use = FALSE; - unlock_kernel(); - - return 0; -} - -static ssize_t irda_read(struct file *file, char *buffer, size_t count, - loff_t *noidea) -{ - struct irda_event *event; - unsigned long flags; - int len; - - IRDA_DEBUG(4, __FUNCTION__ "()\n"); - - /* * Go to sleep and wait for event if there is no event to be read! */ - save_flags( flags); - cli(); - if ( !irda.event_queue) - interruptible_sleep_on( &irda.wait_queue); - restore_flags(flags); - - /* - * Ensure proper reaction to signals, and screen out - * blocked signals (page 112. linux device drivers) - */ - if (signal_pending( current)) - return -ERESTARTSYS; - - event = (struct irda_event *) dequeue_first( &irda.event_queue); - if (!event) - return 0; - - len = sizeof(struct irmanager_event); - copy_to_user(buffer, &event->event, len); - - /* Finished with event */ - kfree(event); - - return len; -} - -static ssize_t irda_write(struct file *file, const char *buffer, - size_t count, loff_t *noidea) -{ - IRDA_DEBUG(0, __FUNCTION__ "()\n"); - - return 0; -} - -static u_int irda_poll(struct file *file, poll_table *wait) -{ - IRDA_DEBUG(0, __FUNCTION__ "(), Sorry not implemented yet!\n"); - - return 0; -} - -void irda_mod_inc_use_count(void) -{ -#ifdef MODULE - MOD_INC_USE_COUNT; -#endif -} - -void irda_mod_dec_use_count(void) -{ -#ifdef MODULE - MOD_DEC_USE_COUNT; -#endif -} - -/* - * Function irda_proc_modcount (inode, fill) - * - * Use by the proc file system functions to prevent the irda module - * being removed while the use is standing in the net/irda directory - */ -void irda_proc_modcount(struct inode *inode, int fill) -{ -#ifdef MODULE -#ifdef CONFIG_PROC_FS - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -#endif /* CONFIG_PROC_FS */ -#endif /* MODULE */ -} - -#ifdef MODULE - -MODULE_AUTHOR("Dag Brattli "); -MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem"); -MODULE_PARM(irda_debug, "1l"); -module_exit(irda_proto_cleanup); -#endif /* MODULE */ - diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c index 1efeedc69..4c6218527 100644 --- a/net/irda/irsysctl.c +++ b/net/irda/irsysctl.c @@ -29,10 +29,11 @@ #include #include +#include #define NET_IRDA 412 /* Random number */ enum { DISCOVERY=1, DEVNAME, COMPRESSION, DEBUG, SLOTS, DISCOVERY_TIMEOUT, - SLOT_TIMEOUT }; + SLOT_TIMEOUT, MAX_BAUD_RATE, MAX_INACTIVE_TIME }; extern int sysctl_discovery; extern int sysctl_discovery_slots; @@ -41,17 +42,35 @@ extern int sysctl_slot_timeout; extern int sysctl_fast_poll_increase; int sysctl_compression = 0; extern char sysctl_devname[]; +extern int sysctl_max_baud_rate; +extern int sysctl_max_inactive_time; #ifdef CONFIG_IRDA_DEBUG extern unsigned int irda_debug; #endif +static int do_devname(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int ret; + + ret = proc_dostring(table, write, filp, buffer, lenp); + if (ret == 0 && write) { + struct ias_value *val; + + val = irias_new_string_value(sysctl_devname); + if (val) + irias_object_change_attribute("Device", "DeviceName", val); + } + return ret; +} + /* One file */ static ctl_table irda_table[] = { { DISCOVERY, "discovery", &sysctl_discovery, sizeof(int), 0644, NULL, &proc_dointvec }, { DEVNAME, "devname", sysctl_devname, - 65, 0644, NULL, &proc_dostring, &sysctl_string}, + 65, 0644, NULL, &do_devname, &sysctl_string}, { COMPRESSION, "compression", &sysctl_compression, sizeof(int), 0644, NULL, &proc_dointvec }, #ifdef CONFIG_IRDA_DEBUG @@ -68,6 +87,10 @@ static ctl_table irda_table[] = { sizeof(int), 0644, NULL, &proc_dointvec }, { SLOT_TIMEOUT, "slot_timeout", &sysctl_slot_timeout, sizeof(int), 0644, NULL, &proc_dointvec }, + { MAX_BAUD_RATE, "max_baud_rate", &sysctl_max_baud_rate, + sizeof(int), 0644, NULL, &proc_dointvec }, + { MAX_INACTIVE_TIME, "max_inactive_time", &sysctl_max_inactive_time, + sizeof(int), 0644, NULL, &proc_dointvec }, { 0 } }; diff --git a/net/irda/irttp.c b/net/irda/irttp.c index e9d120efb..645815835 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -156,6 +156,8 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) ttp_notify.disconnect_indication = irttp_disconnect_indication; ttp_notify.data_indication = irttp_data_indication; ttp_notify.udata_indication = irttp_udata_indication; + if(notify->status_indication != NULL) + ttp_notify.status_indication = irttp_status_indication; ttp_notify.instance = self; strncpy(ttp_notify.name, notify->name, NOTIFY_MAX_NAME); @@ -185,7 +187,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) self->notify = *notify; self->lsap = lsap; - hashbin_insert(irttp->tsaps, (queue_t *) self, (int) self, NULL); + hashbin_insert(irttp->tsaps, (irda_queue_t *) self, (int) self, NULL); if (credit > TTP_MAX_QUEUE) self->initial_credit = TTP_MAX_QUEUE; @@ -608,6 +610,34 @@ static int irttp_data_indication(void *instance, void *sap, } /* + * Function irttp_status_indication (self, reason) + * + * Status_indication, just pass to the higher layer... + * + */ +void irttp_status_indication(void *instance, + LINK_STATUS link, LOCK_STATUS lock) +{ + struct tsap_cb *self; + + IRDA_DEBUG(4, __FUNCTION__ "()\n"); + + self = (struct tsap_cb *) instance; + + ASSERT(self != NULL, return;); + ASSERT(self->magic == TTP_TSAP_MAGIC, return;); + + /* + * Inform service user if he has requested it + */ + if (self->notify.status_indication != NULL) + self->notify.status_indication(self->notify.instance, + link, lock); + else + IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n"); +} + +/* * Function irttp_flow_request (self, command) * * This funtion could be used by the upper layers to tell IrTTP to stop @@ -1002,7 +1032,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) skb_queue_head_init(&new->tx_queue); skb_queue_head_init(&new->rx_fragments); - hashbin_insert(irttp->tsaps, (queue_t *) new, (int) new, NULL); + hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (int) new, NULL); return new; } diff --git a/net/irda/parameters.c b/net/irda/parameters.c index b43bbd70e..2b013ff43 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -513,10 +513,7 @@ int irda_param_extract(void *self, __u8 *buf, int len, pi_param_info_t *info) buf[0]); /* Skip this parameter */ - n += (2 + buf[n+1]); - len -= (2 + buf[n+1]); - - return 0; /* Continue */ + return 2 + buf[n + 1]; /* Continue */ } /* Lookup the info on how to parse this parameter */ @@ -532,10 +529,7 @@ int irda_param_extract(void *self, __u8 *buf, int len, pi_param_info_t *info) if (!pi_minor_info->func) { MESSAGE(__FUNCTION__"(), no handler for pi=%#x\n", buf[n]); /* Skip this parameter */ - n += (2 + buf[n+1]); - len -= (2 + buf[n+1]); - - return 0; /* Continue */ + return 2 + buf[n + 1]; /* Continue */ } /* Parse parameter value */ diff --git a/net/irda/qos.c b/net/irda/qos.c index 10a7765cb..997b3e8ff 100644 --- a/net/irda/qos.c +++ b/net/irda/qos.c @@ -43,6 +43,21 @@ #define CI_BZIP2 27 /* Random pick */ #endif +/* + * Maximum values of the baud rate we negociate with the other end. + * Most often, you don't have to change that, because Linux-IrDA will + * use the maximum offered by the link layer, which usually works fine. + * In some very rare cases, you may want to limit it to lower speeds... + */ +int sysctl_max_baud_rate = 16000000; +/* + * Maximum value of the lap disconnect timer we negociate with the other end. + * Most often, the value below represent the best compromise, but some user + * may want to keep the LAP alive longuer or shorter in case of link failure. + * Remember that the threshold time (early warning) is fixed to 3s... + */ +int sysctl_max_inactive_time = 12; + static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get); static int irlap_param_link_disconnect(void *instance, irda_param_t *parm, int get); @@ -55,6 +70,10 @@ static int irlap_param_additional_bofs(void *instance, irda_param_t *parm, int get); static int irlap_param_min_turn_time(void *instance, irda_param_t *param, int get); +static int value_index(__u32 value, __u32 *array, int size); +static __u32 byte_value(__u8 byte, __u32 *array); +static __u32 index_value(int index, __u32 *array); +static int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field); __u32 min_turn_times[] = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */ __u32 baud_rates[] = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, @@ -147,19 +166,31 @@ void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new) */ void irda_init_max_qos_capabilies(struct qos_info *qos) { + int i; /* * These are the maximum supported values as specified on pages * 39-43 in IrLAP */ + /* Use sysctl to set some configurable values... */ + /* Set configured max speed */ + i = value_lower_bits(sysctl_max_baud_rate, baud_rates, 10, + &qos->baud_rate.bits); + sysctl_max_baud_rate = index_value(i, baud_rates); + + /* Set configured max disc time */ + i = value_lower_bits(sysctl_max_inactive_time, link_disc_times, 8, + &qos->link_disc_time.bits); + sysctl_max_inactive_time = index_value(i, link_disc_times); + /* LSB is first byte, MSB is second byte */ - qos->baud_rate.bits = 0x01ff; + qos->baud_rate.bits &= 0x03ff; qos->window_size.bits = 0x7f; qos->min_turn_time.bits = 0xff; qos->max_turn_time.bits = 0x0f; qos->data_size.bits = 0x3f; - qos->link_disc_time.bits = 0xff; + qos->link_disc_time.bits &= 0xff; qos->additional_bofs.bits = 0xff; #ifdef CONFIG_IRDA_COMPRESSION @@ -197,7 +228,7 @@ void irlap_adjust_qos_settings(struct qos_info *qos) * The data size must be adjusted according to the baud rate and max * turn time */ - index = value_index(qos->data_size.value, data_sizes); + index = value_index(qos->data_size.value, data_sizes, 6); line_capacity = irlap_max_line_capacity(qos->baud_rate.value, qos->max_turn_time.value); @@ -537,8 +568,8 @@ __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time) IRDA_DEBUG(2, __FUNCTION__ "(), speed=%d, max_turn_time=%d\n", speed, max_turn_time); - i = value_index(speed, baud_rates); - j = value_index(max_turn_time, max_turn_times); + i = value_index(speed, baud_rates, 10); + j = value_index(max_turn_time, max_turn_times, 4); ASSERT(((i >=0) && (i <=10)), return 0;); ASSERT(((j >=0) && (j <=4)), return 0;); @@ -574,7 +605,7 @@ __u32 irlap_min_turn_time_in_bytes(__u32 speed, __u32 min_turn_time) return bytes; } -__u32 byte_value(__u8 byte, __u32 *array) +static __u32 byte_value(__u8 byte, __u32 *array) { int index; @@ -602,20 +633,19 @@ int msb_index (__u16 word) msb >>=1; index--; } - return index; } /* - * Function value_index (value, array) + * Function value_index (value, array, size) * * Returns the index to the value in the specified array */ -int value_index(__u32 value, __u32 *array) +static int value_index(__u32 value, __u32 *array, int size) { int i; - for (i=0;i<8;i++) + for (i=0; i < size; i++) if (array[i] == value) break; return i; @@ -627,11 +657,38 @@ int value_index(__u32 value, __u32 *array) * Returns value to index in array, easy! * */ -__u32 index_value(int index, __u32 *array) +static __u32 index_value(int index, __u32 *array) { return array[index]; } +/* + * Function value_lower_bits (value, array) + * + * Returns a bit field marking all possibility lower than value. + * We may need a "value_higher_bits" in the future... + */ +static int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field) +{ + int i; + __u16 mask = 0x1; + __u16 result = 0x0; + + for (i=0; i < size; i++) { + /* Add the current value to the bit field, shift mask */ + result |= mask; + mask <<= 1; + /* Finished ? */ + if (array[i] >= value) + break; + } + /* Send back a valid index */ + if(i >= size) + i = size - 1; /* Last item */ + *field = result; + return i; +} + void irda_qos_bits_to_value(struct qos_info *qos) { int index; @@ -667,10 +724,3 @@ void irda_qos_bits_to_value(struct qos_info *qos) qos->compression.value = 0; #endif } - - - - - - - diff --git a/net/irda/timer.c b/net/irda/timer.c index 7625eecfc..8cdc0a0dd 100644 --- a/net/irda/timer.c +++ b/net/irda/timer.c @@ -99,6 +99,25 @@ void irlap_start_mbusy_timer(struct irlap_cb *self) (void *) self, irlap_media_busy_expired); } +void irlap_stop_mbusy_timer(struct irlap_cb *self) +{ + /* If timer is activated, kill it! */ + if(timer_pending(&self->media_busy_timer)) + del_timer(&self->media_busy_timer); + +#ifdef CONFIG_IRDA_ULTRA + /* Send any pending Ultra frames if any */ + if (!skb_queue_empty(&self->txq_ultra)) + /* Note : we don't send the frame, just post an event. + * Frames will be sent only if we are in NDM mode (see + * irlap_event.c). + * Also, moved this code from irlap_media_busy_expired() + * to here to catch properly all cases... + * Jean II */ + irlap_do_event(self, SEND_UI_FRAME, NULL, NULL); +#endif /* CONFIG_IRDA_ULTRA */ +} + void irlmp_start_watchdog_timer(struct lsap_cb *self, int timeout) { irda_start_timer(&self->watchdog_timer, timeout, (void *) self, @@ -117,6 +136,13 @@ void irlmp_start_idle_timer(struct lap_cb *self, int timeout) irlmp_idle_timer_expired); } +void irlmp_stop_idle_timer(struct lap_cb *self) +{ + /* If timer is activated, kill it! */ + if(timer_pending(&self->idle_timer)) + del_timer(&self->idle_timer); +} + /* * Function irlap_slot_timer_expired (data) * @@ -210,8 +236,5 @@ void irlap_media_busy_expired(void* data) ASSERT(self != NULL, return;); irda_device_set_media_busy(self->netdev, FALSE); - - /* Send any pending Ultra frames if any */ - if (!skb_queue_empty(&self->txq_ultra)) - irlap_do_event(self, SEND_UI_FRAME, NULL, NULL); + /* Note : will deal with Ultra frames */ } diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c index 623328af1..a9f6d7328 100644 --- a/net/irda/wrapper.c +++ b/net/irda/wrapper.c @@ -69,6 +69,7 @@ static void (*state[])(struct net_device *dev, struct net_device_stats *stats, */ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) { + struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb; int xbofs; int i; int n; @@ -85,7 +86,8 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) * Send XBOF's for required min. turn time and for the negotiated * additional XBOFS */ - if (((struct irda_skb_cb *)(skb->cb))->magic != LAP_MAGIC) { + + if (cb->magic != LAP_MAGIC) { /* * This will happen for all frames sent from user-space. * Nothing to worry about, but we set the default number of @@ -94,7 +96,7 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) IRDA_DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n"); xbofs = 10; } else - xbofs = ((struct irda_skb_cb *)(skb->cb))->xbofs; + xbofs = cb->xbofs + cb->xbofs_delay; IRDA_DEBUG(4, __FUNCTION__ "(), xbofs=%d\n", xbofs); @@ -287,6 +289,8 @@ static void state_link_escape(struct net_device *dev, { switch (byte) { case BOF: /* New frame? */ + IRDA_DEBUG(1, __FUNCTION__ + "(), Discarding incomplete frame\n"); rx_buff->state = BEGIN_FRAME; irda_device_set_media_busy(dev, TRUE); break; @@ -328,6 +332,8 @@ static void state_inside_frame(struct net_device *dev, switch (byte) { case BOF: /* New frame? */ + IRDA_DEBUG(1, __FUNCTION__ + "(), Discarding incomplete frame\n"); rx_buff->state = BEGIN_FRAME; irda_device_set_media_busy(dev, TRUE); break; diff --git a/net/khttpd/main.c b/net/khttpd/main.c index 5c39c59b9..45909a0cd 100644 --- a/net/khttpd/main.c +++ b/net/khttpd/main.c @@ -101,8 +101,6 @@ static int MainDaemon(void *cpu_pointer) MOD_INC_USE_COUNT; - current->state |= TASK_EXCLUSIVE; - CPUNR=0; if (cpu_pointer!=NULL) CPUNR=(int)*(int*)cpu_pointer; @@ -148,7 +146,7 @@ static int MainDaemon(void *cpu_pointer) changes +=AcceptConnections(CPUNR,MainSocket); } - set_current_state(TASK_INTERRUPTIBLE|TASK_EXCLUSIVE); + set_current_state(TASK_INTERRUPTIBLE); if (changes==0) { (void)interruptible_sleep_on_timeout(&(DummyWQ[CPUNR]),1); diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c index bdc84d72f..1723588da 100644 --- a/net/lapb/lapb_iface.c +++ b/net/lapb/lapb_iface.c @@ -12,6 +12,7 @@ * History * LAPB 001 Jonathan Naylor Started Coding * LAPB 002 Jonathan Naylor New timer architecture. + * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ #include @@ -370,14 +371,11 @@ void lapb_disconnect_indication(lapb_cb *lapb, int reason) int lapb_data_indication(lapb_cb *lapb, struct sk_buff *skb) { - int used = 0; - if (lapb->callbacks.data_indication != NULL) { - (lapb->callbacks.data_indication)(lapb->token, skb); - used = 1; + return (lapb->callbacks.data_indication)(lapb->token, skb); } - - return used; + kfree_skb(skb); + return NET_RX_CN_HIGH; /* For now; must be != NET_RX_DROP */ } int lapb_data_transmit(lapb_cb *lapb, struct sk_buff *skb) diff --git a/net/lapb/lapb_in.c b/net/lapb/lapb_in.c index 4e7a9ca4d..0b45f57f5 100644 --- a/net/lapb/lapb_in.c +++ b/net/lapb/lapb_in.c @@ -12,6 +12,7 @@ * History * LAPB 001 Jonathan Naulor Started Coding * LAPB 002 Jonathan Naylor New timer architecture. + * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ #include @@ -464,8 +465,21 @@ static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_ lapb_check_iframes_acked(lapb, frame->nr); } if (frame->ns == lapb->vr) { + int cn; + cn = lapb_data_indication(lapb, skb); + queued = 1; + /* + * If upper layer has dropped the frame, we + * basically ignore any further protocol + * processing. This will cause the peer + * to re-transmit the frame later like + * a frame lost on the wire. + */ + if(cn == NET_RX_DROP){ + printk(KERN_DEBUG "LAPB: rx congestion\n"); + break; + } lapb->vr = (lapb->vr + 1) % modulus; - queued = lapb_data_indication(lapb, skb); lapb->condition &= ~LAPB_REJECT_CONDITION; if (frame->pf) { lapb_enquiry_response(lapb); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 3927d9c3a..a8218d679 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -96,7 +96,7 @@ static void netlink_sock_destruct(struct sock *sk) #endif } -/* This lock without TASK_EXCLUSIVE is good on UP and it is _very_ bad on SMP. +/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on SMP. * Look, when several writers sleep and reader wakes them up, all but one * immediately hit write lock and grab all the cpus. Exclusive sleep solves * this, _but_ remember, it adds useless work on UP machines. @@ -111,7 +111,7 @@ static void netlink_table_grab(void) add_wait_queue_exclusive(&nl_table_wait, &wait); for(;;) { - set_current_state(TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE); + set_current_state(TASK_UNINTERRUPTIBLE); if (atomic_read(&nl_table_users) == 0) break; write_unlock_bh(&nl_table_lock); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 7603a9221..e48b8549a 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -8,7 +8,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Version: $Id: af_unix.c,v 1.107 2000/10/19 01:05:36 davem Exp $ + * Version: $Id: af_unix.c,v 1.108 2000/11/10 04:02:04 davem Exp $ * * Fixes: * Linus Torvalds : Assorted bug cures. @@ -832,7 +832,7 @@ static long unix_wait_for_peer(unix_socket *other, long timeo) int sched; DECLARE_WAITQUEUE(wait, current); - __set_current_state(TASK_INTERRUPTIBLE|TASK_EXCLUSIVE); + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue_exclusive(&other->protinfo.af_unix.peer_wait, &wait); sched = (!other->dead && -- 2.11.4.GIT