]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 30 Jun 2006 00:44:21 +0000 (17:44 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 30 Jun 2006 00:44:21 +0000 (17:44 -0700)
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
  ocfs2: remove redundant NULL checks in ocfs2_direct_IO_get_blocks()
  ocfs2: clean up some osb fields
  ocfs2: fix init of uuid_net_key
  ocfs2: silence a debug print
  ocfs2: silence ENOENT during lookup of broken links
  ocfs2: Cleanup message prints
  ocfs2: silence -EEXIST from ocfs2_extent_map_insert/lookup
  [PATCH] fs/ocfs2/dlm/dlmrecovery.c: make dlm_lockres_master_requery() static
  ocfs2: warn the user on a dead timeout mismatch
  ocfs2: OCFS2_FS must depend on SYSFS
  ocfs2: Compile-time disabling of ocfs2 debugging output.
  configfs: Clear up a few extra spaces where there should be TABs.
  configfs: Release memory in configfs_example.

329 files changed:
Documentation/Changes
Documentation/DocBook/kernel-api.tmpl
Documentation/README.DAC960
Documentation/feature-removal-schedule.txt
Documentation/filesystems/devfs/ChangeLog [deleted file]
Documentation/filesystems/devfs/README [deleted file]
Documentation/filesystems/devfs/ToDo [deleted file]
Documentation/filesystems/devfs/boot-options [deleted file]
Documentation/initrd.txt
Documentation/ioctl-number.txt
Documentation/kernel-parameters.txt
arch/cris/arch-v10/kernel/debugport.c
arch/cris/arch-v32/kernel/debugport.c
arch/i386/kernel/microcode.c
arch/ppc/4xx_io/serial_sicc.c
arch/sh/kernel/cpu/sh4/sq.c
arch/sparc/kernel/ioport.c
arch/sparc/kernel/of_device.c
arch/sparc/kernel/prom.c
arch/sparc/kernel/time.c
arch/sparc64/kernel/auxio.c
arch/sparc64/kernel/ebus.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/isa.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/power.c
arch/sparc64/kernel/prom.c
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/starfire.c
arch/sparc64/kernel/time.c
arch/sparc64/kernel/unaligned.c
arch/sparc64/solaris/socksys.c
arch/um/drivers/line.c
arch/um/drivers/ssl.c
arch/um/drivers/stdio_console.c
arch/um/drivers/ubd_kern.c
arch/um/include/line.h
arch/x86_64/kernel/functionlist
drivers/atm/he.c
drivers/atm/idt77105.c
drivers/atm/idt77105.h
drivers/atm/iphase.c
drivers/atm/suni.c
drivers/block/DAC960.c
drivers/block/acsi.c
drivers/block/acsi_slm.c
drivers/block/cciss.c
drivers/block/cpqarray.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/nbd.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/pktcdvd.c
drivers/block/ps2esdi.c
drivers/block/rd.c
drivers/block/swim3.c
drivers/block/sx8.c
drivers/block/ub.c
drivers/block/umem.c
drivers/block/viodasd.c
drivers/block/xd.c
drivers/block/z2ram.c
drivers/cdrom/aztcd.c
drivers/cdrom/cdu31a.c
drivers/cdrom/cm206.c
drivers/cdrom/gscd.c
drivers/cdrom/mcdx.c
drivers/cdrom/optcd.c
drivers/cdrom/sbpcd.c
drivers/cdrom/sjcd.c
drivers/cdrom/sonycd535.c
drivers/cdrom/viocd.c
drivers/char/agp/Kconfig
drivers/char/agp/amd64-agp.c
drivers/char/agp/ati-agp.c
drivers/char/agp/nvidia-agp.c
drivers/char/cyclades.c
drivers/char/dsp56k.c
drivers/char/dtlk.c
drivers/char/epca.c
drivers/char/esp.c
drivers/char/ftape/zftape/zftape-init.c
drivers/char/hvc_console.c
drivers/char/hvcs.c
drivers/char/hvsi.c
drivers/char/ip2/ip2main.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/mmtimer.c
drivers/char/moxa.c
drivers/char/ppdev.c
drivers/char/pty.c
drivers/char/raw.c
drivers/char/riscom8.c
drivers/char/rocket.c
drivers/char/serial167.c
drivers/char/stallion.c
drivers/char/tipar.c
drivers/char/tty_io.c
drivers/char/vc_screen.c
drivers/char/viocons.c
drivers/char/viotape.c
drivers/char/vme_scc.c
drivers/char/vt.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-floppy.c
drivers/ide/ide-probe.c
drivers/ide/ide-tape.c
drivers/ide/ide.c
drivers/input/serio/i8042-sparcio.h
drivers/input/serio/serio_raw.c
drivers/isdn/capi/capi.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/isdn/hardware/eicon/divamnt.c
drivers/isdn/hardware/eicon/divasi.c
drivers/isdn/hardware/eicon/divasmain.c
drivers/isdn/i4l/isdn_tty.c
drivers/macintosh/adb.c
drivers/md/dm-ioctl.c
drivers/md/dm.c
drivers/md/md.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/media/dvb/dvb-core/dvbdev.h
drivers/media/dvb/ttpci/av7110.h
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/radio/miropcm20-rds.c
drivers/media/video/arv.c
drivers/media/video/videodev.c
drivers/message/i2o/i2o_block.c
drivers/mmc/mmc_block.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/irda/Kconfig
drivers/net/irda/mcs7780.c
drivers/net/ppp_generic.c
drivers/net/sunhme.c
drivers/net/tun.c
drivers/net/wan/cosa.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_genhd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/xpram.c
drivers/s390/char/monreader.c
drivers/s390/char/tty3270.c
drivers/s390/crypto/z90main.c
drivers/sbus/char/bpp.c
drivers/sbus/char/vfc.h
drivers/sbus/char/vfc_dev.c
drivers/serial/21285.c
drivers/serial/8250.c
drivers/serial/at91_serial.c
drivers/serial/crisv10.c
drivers/serial/dz.c
drivers/serial/imx.c
drivers/serial/ip22zilog.c
drivers/serial/m32r_sio.c
drivers/serial/mcfserial.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mpsc.c
drivers/serial/pmac_zilog.c
drivers/serial/pxa.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/serial_core.c
drivers/serial/serial_txx9.c
drivers/serial/sh-sci.c
drivers/serial/sunhv.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/serial/v850e_uart.c
drivers/serial/vr41xx_siu.c
drivers/tc/zs.c
drivers/telephony/phonedev.c
drivers/usb/class/cdc-acm.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/gadget/serial.c
drivers/usb/serial/usb-serial.c
drivers/video/bw2.c
drivers/video/cg14.c
drivers/video/cg3.c
drivers/video/cg6.c
drivers/video/fbmem.c
drivers/video/ffb.c
drivers/video/leo.c
drivers/video/p9100.c
drivers/video/tcx.c
fs/Makefile
fs/block_dev.c
fs/char_dev.c
fs/coda/psdev.c
fs/compat_ioctl.c
fs/devfs/Makefile [deleted file]
fs/devfs/base.c [deleted file]
fs/devfs/util.c [deleted file]
fs/partitions/Makefile
fs/partitions/check.c
fs/partitions/devfs.c [deleted file]
fs/partitions/devfs.h [deleted file]
include/asm-alpha/socket.h
include/asm-arm/socket.h
include/asm-arm26/socket.h
include/asm-cris/socket.h
include/asm-frv/socket.h
include/asm-h8300/socket.h
include/asm-i386/socket.h
include/asm-ia64/socket.h
include/asm-m32r/socket.h
include/asm-m68k/socket.h
include/asm-mips/socket.h
include/asm-parisc/socket.h
include/asm-powerpc/socket.h
include/asm-ppc/ocp.h
include/asm-s390/socket.h
include/asm-sh/socket.h
include/asm-sparc/of_device.h
include/asm-sparc/prom.h
include/asm-sparc/socket.h
include/asm-sparc64/of_device.h
include/asm-sparc64/pbm.h
include/asm-sparc64/prom.h
include/asm-sparc64/sbus.h
include/asm-sparc64/socket.h
include/asm-sparc64/starfire.h
include/asm-v850/socket.h
include/asm-x86_64/socket.h
include/asm-xtensa/socket.h
include/linux/atmdev.h
include/linux/compat_ioctl.h
include/linux/devfs_fs.h [deleted file]
include/linux/devfs_fs_kernel.h [deleted file]
include/linux/fb.h
include/linux/genhd.h
include/linux/ide.h
include/linux/miscdevice.h
include/linux/net.h
include/linux/netdevice.h
include/linux/security.h
include/linux/serial_core.h
include/linux/skbuff.h
include/linux/tty_driver.h
include/media/v4l2-dev.h
include/net/af_unix.h
include/net/pkt_sched.h
include/net/protocol.h
include/net/scm.h
include/net/sock.h
include/net/tcp.h
include/net/tcp_ecn.h
init/Makefile
init/do_mounts.c
init/do_mounts.h
init/do_mounts_devfs.c [deleted file]
init/do_mounts_initrd.c
init/do_mounts_md.c
init/do_mounts_rd.c
init/main.c
kernel/audit.c
mm/shmem.c
mm/tiny-shmem.c
net/atm/Makefile
net/atm/atm_sysfs.c [new file with mode: 0644]
net/atm/common.c
net/atm/common.h
net/atm/resources.c
net/atm/resources.h
net/bluetooth/rfcomm/tty.c
net/bridge/br_device.c
net/bridge/br_if.c
net/core/dev.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/decnet/netfilter/dn_rtmsg.c
net/ipv4/af_inet.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/tcp.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/tcp_ipv6.c
net/irda/ircomm/ircomm_tty.c
net/irda/irlan/irlan_client.c
net/irda/irnet/irnet.h
net/netfilter/Kconfig
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_queue.c
net/netfilter/xt_sctp.c
net/netfilter/xt_tcpudp.c
net/netlink/genetlink.c
net/tipc/core.c
net/tipc/link.c
net/tipc/node.c
net/tipc/zone.h
net/unix/af_unix.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/commoncap.c
security/dummy.c
security/selinux/hooks.c
sound/core/info.c
sound/core/sound.c
sound/oss/soundcard.c
sound/sound_core.c

index b02f476c297302bced86ee62fe89afe2066d3c70..488272074c36f348753817c4c07484fe8035da91 100644 (file)
@@ -181,8 +181,8 @@ Intel IA32 microcode
 --------------------
 
 A driver has been added to allow updating of Intel IA32 microcode,
-accessible as both a devfs regular file and as a normal (misc)
-character device.  If you are not using devfs you may need to:
+accessible as a normal (misc) character device.  If you are not using
+udev you may need to:
 
 mkdir /dev/cpu
 mknod /dev/cpu/microcode c 10 184
@@ -201,7 +201,9 @@ with programs using shared memory.
 udev
 ----
 udev is a userspace application for populating /dev dynamically with
-only entries for devices actually present. udev replaces devfs.
+only entries for devices actually present.  udev replaces the basic
+functionality of devfs, while allowing persistant device naming for
+devices.
 
 FUSE
 ----
@@ -231,18 +233,13 @@ The PPP driver has been restructured to support multilink and to
 enable it to operate over diverse media layers.  If you use PPP,
 upgrade pppd to at least 2.4.0.
 
-If you are not using devfs, you must have the device file /dev/ppp
+If you are not using udev, you must have the device file /dev/ppp
 which can be made by:
 
 mknod /dev/ppp c 108 0
 
 as root.
 
-If you use devfsd and build ppp support as modules, you will need
-the following in your /etc/devfsd.conf file:
-
-LOOKUP PPP     MODLOAD
-
 Isdn4k-utils
 ------------
 
index 3630a0d7695f91f98dfa0844370ca7af3048620a..1ae4dc0fd8564db5801951997946603f0ce4a79d 100644 (file)
@@ -348,11 +348,6 @@ X!Earch/i386/kernel/mca.c
      </sect1>
   </chapter>
 
-  <chapter id="devfs">
-     <title>The Device File System</title>
-!Efs/devfs/base.c
-  </chapter>
-
   <chapter id="sysfs">
      <title>The Filesystem for Exporting Kernel Objects</title>
 !Efs/sysfs/file.c
index 98ea617a0dd6ea7b604610b786254db0f5fc7c44..0e8f618ab5344c3cbb6af186efcb4a0920a212db 100644 (file)
@@ -78,9 +78,9 @@ also known as "System Drives", and Drive Groups are also called "Packs".  Both
 terms are in use in the Mylex documentation; I have chosen to standardize on
 the more generic "Logical Drive" and "Drive Group".
 
-DAC960 RAID disk devices are named in the style of the Device File System
-(DEVFS).  The device corresponding to Logical Drive D on Controller C is
-referred to as /dev/rd/cCdD, and the partitions are called /dev/rd/cCdDp1
+DAC960 RAID disk devices are named in the style of the obsolete Device File
+System (DEVFS).  The device corresponding to Logical Drive D on Controller C
+is referred to as /dev/rd/cCdD, and the partitions are called /dev/rd/cCdDp1
 through /dev/rd/cCdDp7.  For example, partition 3 of Logical Drive 5 on
 Controller 2 is referred to as /dev/rd/c2d5p3.  Note that unlike with SCSI
 disks the device names will not change in the event of a disk drive failure.
index b1c6c7036c1c9a828711220c4a07c8a472fbd863..1cbbb8e28999fc0cc8d980700b2bc3e772790d5e 100644 (file)
@@ -6,17 +6,6 @@ be removed from this file.
 
 ---------------------------
 
-What:  devfs
-When:  July 2005
-Files: fs/devfs/*, include/linux/devfs_fs*.h and assorted devfs
-       function calls throughout the kernel tree
-Why:   It has been unmaintained for a number of years, has unfixable
-       races, contains a naming policy within the kernel that is
-       against the LSB, and can be replaced by using udev.
-Who:   Greg Kroah-Hartman <greg@kroah.com>
-
----------------------------
-
 What:  RAW driver (CONFIG_RAW_DRIVER)
 When:  December 2005
 Why:   declared obsolete since kernel 2.6.3
diff --git a/Documentation/filesystems/devfs/ChangeLog b/Documentation/filesystems/devfs/ChangeLog
deleted file mode 100644 (file)
index e5aba52..0000000
+++ /dev/null
@@ -1,1977 +0,0 @@
-/* -*- auto-fill -*-                                                         */
-===============================================================================
-Changes for patch v1
-
-- creation of devfs
-
-- modified miscellaneous character devices to support devfs
-===============================================================================
-Changes for patch v2
-
-- bug fix with manual inode creation
-===============================================================================
-Changes for patch v3
-
-- bugfixes
-
-- documentation improvements
-
-- created a couple of scripts (one to save&restore a devfs and the
-  other to set up compatibility symlinks)
-
-- devfs support for SCSI discs. New name format is: sd_hHcCiIlL
-===============================================================================
-Changes for patch v4
-
-- bugfix for the directory reading code
-
-- bugfix for compilation with kerneld
-
-- devfs support for generic hard discs
-
-- rationalisation of the various watchdog drivers
-===============================================================================
-Changes for patch v5
-
-- support for mounting directly from entries in the devfs (it doesn't
-  need to be mounted to do this), including the root filesystem.
-  Mounting of swap partitions also works. Hence, now if you set
-  CONFIG_DEVFS_ONLY to 'Y' then you won't be able to access your discs
-  via ordinary device nodes. Naturally, the default is 'N' so that you
-  can still use your old device nodes.  If you want to mount from devfs
-  entries, make sure you use: append = "root=/dev/sd_..." in your
-  lilo.conf. It seems LILO looks for the device number (major&minor)
-  and writes that into the kernel image :-( 
-
-- support for character memory devices (/dev/null, /dev/zero, /dev/full
-  and so on). Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-===============================================================================
-Changes for patch v6
-
-- support for subdirectories
-
-- support for symbolic links (created by devfs_mk_symlink(), no
-  support yet for creation via symlink(2))
-
-- SCSI disc naming now cast in stone, with the format:
-  /dev/sd/c0b1t2u3     controller=0, bus=1, ID=2, LUN=3, whole disc
-  /dev/sd/c0b1t2u3p4   controller=0, bus=1, ID=2, LUN=3, 4th partition
-
-- loop devices now appear in devfs
-
-- tty devices, console, serial ports, etc. now appear in devfs
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- bugs with mounting devfs-only devices now fixed
-===============================================================================
-Changes for patch v7
-
-- SCSI CD-ROMS, tapes and generic devices now appear in devfs
-===============================================================================
-Changes for patch v8
-
-- bugfix with no-rewind SCSI tapes
-
-- RAMDISCs now appear in devfs
-
-- better cleaning up of devfs entries created by various modules
-
-- interface change to <devfs_register>
-===============================================================================
-Changes for patch v9
-
-- the v8 patch was corrupted somehow, which would affect the patch for
-  linux/fs/filesystems.c
-  I've also fixed the v8 patch file on the WWW
-
-- MetaDevices (/dev/md*) should now appear in devfs
-===============================================================================
-Changes for patch v10
-
-- bugfix in meta device support for devfs
-
-- created this ChangeLog file
-
-- added devfs support to the floppy driver
-
-- added support for creating sockets in a devfs
-===============================================================================
-Changes for patch v11
-
-- added DEVFS_FL_HIDE_UNREG flag
-
-- incorporated better patch for ttyname() in libc 5.4.43 from H.J. Lu.
-
-- interface change to <devfs_mk_symlink>
-
-- support for creating symlinks with symlink(2)
-
-- parallel port printer (/dev/lp*) now appears in devfs
-===============================================================================
-Changes for patch v12
-
-- added inode check to <devfs_fill_file> function
-
-- improved devfs support when mounting from devfs
-
-- added call to <<release>> operation when removing swap areas on
-  devfs devices
-
-- increased NR_SUPER to 128 to support large numbers of devfs mounts
-  (for chroot(2) gaols)
-
-- fixed bug in SCSI disc support: was generating incorrect minors if
-  SCSI ID's did not start at 0 and increase by 1
-
-- support symlink traversal when mounting root
-===============================================================================
-Changes for patch v13
-
-- added devfs support to soundcard driver
-  Thanks to Eric Dumas <dumas@linux.eu.org> and
-  C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- added devfs support to the joystick driver
-
-- loop driver now has it's own subdirectory "/dev/loop/"
-
-- created <devfs_get_flags> and <devfs_set_flags> functions
-
-- fix problem with SCSI disc compatibility names (sd{a,b,c,d,e,f})
-  which assumes ID's start at 0 and increase by 1. Also only create
-  devfs entries for SCSI disc partitions which actually exist
-  Show new names in partition check
-  Thanks to Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
-===============================================================================
-Changes for patch v14
-
-- bug fix in floppy driver: would not compile without
-  CONFIG_DEVFS_FS='Y'
-  Thanks to Jurgen Botz <jbotz@nova.botz.org>
-
-- bug fix in loop driver
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- do not create devfs entries for printers not configured
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- do not create devfs entries for serial ports not present
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- ensure <tty_register_devfs> is exported from tty_io.c
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- allow unregistering of devfs symlink entries
-
-- fixed bug in SCSI disc naming introduced in last patch version
-===============================================================================
-Changes for patch v15
-
-- ported to kernel 2.1.81
-===============================================================================
-Changes for patch v16
-
-- created <devfs_set_symlink_destination> function
-
-- moved DEVFS_SUPER_MAGIC into header file
-
-- added DEVFS_FL_HIDE flag
-
-- created <devfs_get_maj_min>
-
-- created <devfs_get_handle_from_inode>
-
-- fixed bugs in searching by major&minor
-
-- changed interface to <devfs_unregister>, <devfs_fill_file> and
-  <devfs_find_handle>
-
-- fixed inode times when symlink created with symlink(2)
-
-- change tty driver to do auto-creation of devfs entries
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- fixed bug in genhd.c: whole disc (non-SCSI) was not registered to
-  devfs
-
-- updated libc 5.4.43 patch for ttyname()
-===============================================================================
-Changes for patch v17
-
-- added CONFIG_DEVFS_TTY_COMPAT
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- bugfix in devfs support for drivers/char/lp.c
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- clean up serial driver so that PCMCIA devices unregister correctly
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- fixed bug in genhd.c: whole disc (non-SCSI) was not registered to
-  devfs [was missing in patch v16]
-
-- updated libc 5.4.43 patch for ttyname() [was missing in patch v16]
-
-- all SCSI devices now registered in /dev/sg
-
-- support removal of devfs entries via unlink(2)
-===============================================================================
-Changes for patch v18
-
-- added floppy/?u720 floppy entry
-
-- fixed kerneld support for entries in devfs subdirectories
-
-- incorporated latest patch for ttyname() in libc 5.4.43 from H.J. Lu.
-===============================================================================
-Changes for patch v19
-
-- bug fix when looking up unregistered entries: kerneld was not called
-
-- fixes for kernel 2.1.86 (now requires 2.1.86)
-===============================================================================
-Changes for patch v20
-
-- only create available floppy entries
-  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
-
-- new IDE naming scheme following SCSI format (i.e. /dev/id/c0b0t0u0p1
-  instead of /dev/hda1)
-  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
-
-- new XT disc naming scheme following SCSI format (i.e. /dev/xd/c0t0p1
-  instead of /dev/xda1)
-  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
-
-- new non-standard CD-ROM names (i.e. /dev/sbp/c#t#)
-  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
-
-- allow symlink traversal when mounting the root filesystem
-
-- Create entries for MD devices at MD init
-  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
-===============================================================================
-Changes for patch v21
-
-- ported to kernel 2.1.91
-===============================================================================
-Changes for patch v22
-
-- SCSI host number patch ("scsihosts=" kernel option)
-  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
-===============================================================================
-Changes for patch v23
-
-- Fixed persistence bug with device numbers for manually created
-  device files
-
-- Fixed problem with recreating symlinks with different content
-
-- Added CONFIG_DEVFS_MOUNT (mount devfs on /dev at boot time)
-===============================================================================
-Changes for patch v24
-
-- Switched from CONFIG_KERNELD to CONFIG_KMOD: module autoloading
-  should now work again
-
-- Hide entries which are manually unlinked
-
-- Always invalidate devfs dentry cache when registering entries
-
-- Support removal of devfs directories via rmdir(2)
-
-- Ensure directories created by <devfs_mk_dir> are visible
-
-- Default no access for "other" for floppy device
-===============================================================================
-Changes for patch v25
-
-- Updates to CREDITS file and minor IDE numbering change
-  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
-
-- Invalidate devfs dentry cache when making directories
-
-- Invalidate devfs dentry cache when removing entries
-
-- More informative message if root FS mount fails when devfs
-  configured
-
-- Fixed persistence bug with fifos
-===============================================================================
-Changes for patch v26
-
-- ported to kernel 2.1.97
-
-- Changed serial directory from "/dev/serial" to "/dev/tts" and
-  "/dev/consoles" to "/dev/vc" to be more friendly to new procps
-===============================================================================
-Changes for patch v27
-
-- Added support for IDE4 and IDE5
-  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
-
-- Documented "scsihosts=" boot parameter
-
-- Print process command when debugging kerneld/kmod
-
-- Added debugging for register/unregister/change operations
-
-- Added "devfs=" boot options
-
-- Hide unregistered entries by default
-===============================================================================
-Changes for patch v28
-
-- No longer lock/unlock superblock in <devfs_put_super> (cope with
-  recent VFS interface change)
-
-- Do not automatically change ownership/protection of /dev/tty
-
-- Drop negative dentries when they are released
-
-- Manage dcache more efficiently
-===============================================================================
-Changes for patch v29
-
-- Added DEVFS_FL_AUTO_DEVNUM flag
-===============================================================================
-Changes for patch v30
-
-- No longer set unnecessary methods
-
-- Ported to kernel 2.1.99-pre3
-===============================================================================
-Changes for patch v31
-
-- Added PID display to <call_kerneld> debugging message
-
-- Added "diread" and "diwrite" options
-
-- Ported to kernel 2.1.102
-
-- Fixed persistence problem with permissions
-===============================================================================
-Changes for patch v32
-
-- Fixed devfs support in drivers/block/md.c
-===============================================================================
-Changes for patch v33
-
-- Support legacy device nodes
-
-- Fixed bug where recreated inodes were hidden
-
-- New IDE naming scheme: everything is under /dev/ide
-===============================================================================
-Changes for patch v34
-
-- Improved debugging in <get_vfs_inode>
-
-- Prevent duplicate calls to <devfs_mk_dir> in SCSI layer
-
-- No longer free old dentries in <devfs_mk_dir>
-
-- Free all dentries for a given entry when deleting inodes
-===============================================================================
-Changes for patch v35
-
-- Ported to kernel 2.1.105 (sound driver changes)
-===============================================================================
-Changes for patch v36
-
-- Fixed sound driver port
-===============================================================================
-Changes for patch v37
-
-- Minor documentation tweaks
-===============================================================================
-Changes for patch v38
-
-- More documentation tweaks
-
-- Fix for sound driver port
-
-- Removed ttyname-patch (grab libc 5.4.44 instead)
-
-- Ported to kernel 2.1.107-pre2 (loop driver fix)
-===============================================================================
-Changes for patch v39
-
-- Ported to kernel 2.1.107 (hd.c hunk broke due to spelling "fixes"). Sigh
-
-- Removed many #ifdef's, replaced with trickery in include/devfs_fs.h
-===============================================================================
-Changes for patch v40
-
-- Fix for sound driver port
-
-- Limit auto-device numbering to majors 128 to 239
-===============================================================================
-Changes for patch v41
-
-- Fixed inode times persistence problem
-===============================================================================
-Changes for patch v42
-
-- Ported to kernel 2.1.108 (drivers/scsi/hosts.c hunk broke)
-===============================================================================
-Changes for patch v43
-
-- Fixed spelling in <devfs_readlink> debug
-
-- Fixed bug in <devfs_setup> parsing "dilookup"
-
-- More #ifdef's removed
-
-- Supported Sparc keyboard (/dev/kbd)
-
-- Supported DSP56001 digital signal processor (/dev/dsp56k)
-
-- Supported Apple Desktop Bus (/dev/adb)
-
-- Supported Coda network file system (/dev/cfs*)
-===============================================================================
-Changes for patch v44
-
-- Fixed devfs inode leak when manually recreating inodes
-
-- Fixed permission persistence problem when recreating inodes
-===============================================================================
-Changes for patch v45
-
-- Ported to kernel 2.1.110
-===============================================================================
-Changes for patch v46
-
-- Ported to kernel 2.1.112-pre1
-
-- Removed harmless "unused variable" compiler warning
-
-- Fixed modes for manually recreated device nodes
-===============================================================================
-Changes for patch v47
-
-- Added NULL devfs inode warning in <devfs_read_inode>
-
-- Force all inode nlink values to 1
-===============================================================================
-Changes for patch v48
-
-- Added "dimknod" option
-
-- Set inode nlink to 0 when freeing dentries
-
-- Added support for virtual console capture devices (/dev/vcs*)
-  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
-
-- Fixed modes for manually recreated symlinks
-===============================================================================
-Changes for patch v49
-
-- Ported to kernel 2.1.113
-===============================================================================
-Changes for patch v50
-
-- Fixed bugs in recreated directories and symlinks
-===============================================================================
-Changes for patch v51
-
-- Improved robustness of rc.devfs script
-  Thanks to Roderich Schupp <rsch@experteam.de>
-
-- Fixed bugs in recreated device nodes
-
-- Fixed bug in currently unused <devfs_get_handle_from_inode>
-
-- Defined new <devfs_handle_t> type
-
-- Improved debugging when getting entries
-
-- Fixed bug where directories could be emptied
-
-- Ported to kernel 2.1.115
-===============================================================================
-Changes for patch v52
-
-- Replaced dummy .epoch inode with .devfsd character device
-
-- Modified rc.devfs to take account of above change
-
-- Removed spurious driver warning messages when CONFIG_DEVFS_FS=n
-
-- Implemented devfsd protocol revision 0
-===============================================================================
-Changes for patch v53
-
-- Ported to kernel 2.1.116 (kmod change broke hunk)
-
-- Updated Documentation/Configure.help
-
-- Test and tty pattern patch for rc.devfs script
-  Thanks to Roderich Schupp <rsch@experteam.de>
-
-- Added soothing message to warning in <devfs_d_iput>
-===============================================================================
-Changes for patch v54
-
-- Ported to kernel 2.1.117
-
-- Fixed default permissions in sound driver
-
-- Added support for frame buffer devices (/dev/fb*)
-===============================================================================
-Changes for patch v55
-
-- Ported to kernel 2.1.119
-
-- Use GCC extensions for structure initialisations
-
-- Implemented async open notification
-
-- Incremented devfsd protocol revision to 1
-===============================================================================
-Changes for patch v56
-
-- Ported to kernel 2.1.120-pre3
-
-- Moved async open notification to end of <devfs_open>
-===============================================================================
-Changes for patch v57
-
-- Ported to kernel 2.1.121
-
-- Prepended "/dev/" to module load request
-
-- Renamed <call_kerneld> to <call_kmod>
-
-- Created sample modules.conf file
-===============================================================================
-Changes for patch v58
-
-- Fixed typo "AYSNC" -> "ASYNC"
-===============================================================================
-Changes for patch v59
-
-- Added open flag for files
-===============================================================================
-Changes for patch v60
-
-- Ported to kernel 2.1.123-pre2
-===============================================================================
-Changes for patch v61
-
-- Set i_blocks=0 and i_blksize=1024 in <devfs_read_inode>
-===============================================================================
-Changes for patch v62
-
-- Ported to kernel 2.1.123
-===============================================================================
-Changes for patch v63
-
-- Ported to kernel 2.1.124-pre2
-===============================================================================
-Changes for patch v64
-
-- Fixed Unix98 pty support
-
-- Increased buffer size in <get_partition_list> to avoid crash and
-  burn
-===============================================================================
-Changes for patch v65
-
-- More Unix98 pty support fixes
-
-- Added test for empty <<name>> in <devfs_find_handle>
-
-- Renamed <generate_path> to <devfs_generate_path> and published
-
-- Created /dev/root symlink
-  Thanks to Roderich Schupp <rsch@ExperTeam.de>
-  with further modifications by me
-===============================================================================
-Changes for patch v66
-
-- Yet more Unix98 pty support fixes (now tested)
-
-- Created <devfs_get_fops>
-
-- Support media change checks when CONFIG_DEVFS_ONLY=y
-
-- Abolished Unix98-style PTY names for old PTY devices
-===============================================================================
-Changes for patch v67
-
-- Added inline declaration for dummy <devfs_generate_path>
-
-- Removed spurious "unable to register... in devfs" messages when
-  CONFIG_DEVFS_FS=n
-
-- Fixed misc. devices when CONFIG_DEVFS_FS=n
-
-- Limit auto-device numbering to majors 144 to 239
-===============================================================================
-Changes for patch v68
-
-- Hide unopened virtual consoles from directory listings
-
-- Added support for video capture devices
-
-- Ported to kernel 2.1.125
-===============================================================================
-Changes for patch v69
-
-- Fix for CONFIG_VT=n
-===============================================================================
-Changes for patch v70
-
-- Added support for non-OSS/Free sound cards
-===============================================================================
-Changes for patch v71
-
-- Ported to kernel 2.1.126-pre2
-===============================================================================
-Changes for patch v72
-
-- #ifdef's for CONFIG_DEVFS_DISABLE_OLD_NAMES removed
-===============================================================================
-Changes for patch v73
-
-- CONFIG_DEVFS_DISABLE_OLD_NAMES replaced with "nocompat" boot option
-
-- CONFIG_DEVFS_BOOT_OPTIONS removed: boot options always available
-===============================================================================
-Changes for patch v74
-
-- Removed CONFIG_DEVFS_MOUNT and "mount" boot option and replaced with
-  "nomount" boot option
-
-- Documentation updates
-
-- Updated sample modules.conf
-===============================================================================
-Changes for patch v75
-
-- Updated sample modules.conf
-
-- Remount devfs after initrd finishes
-
-- Ported to kernel 2.1.127
-
-- Added support for ISDN
-  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
-===============================================================================
-Changes for patch v76
-
-- Updated an email address in ChangeLog
-
-- CONFIG_DEVFS_ONLY replaced with "only" boot option
-===============================================================================
-Changes for patch v77
-
-- Added DEVFS_FL_REMOVABLE flag
-
-- Check for disc change when listing directories with removable media
-  devices
-
-- Use DEVFS_FL_REMOVABLE in sd.c
-
-- Ported to kernel 2.1.128
-===============================================================================
-Changes for patch v78
-
-- Only call <scan_dir_for_removable> on first call to <devfs_readdir>
-
-- Ported to kernel 2.1.129-pre5
-
-- ISDN support improvements
-  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
-===============================================================================
-Changes for patch v79
-
-- Ported to kernel 2.1.130
-
-- Renamed miscdevice "apm" to "apm_bios" to be consistent with
-  devices.txt
-===============================================================================
-Changes for patch v80
-
-- Ported to kernel 2.1.131
-
-- Updated <devfs_rmdir> for VFS change in 2.1.131
-===============================================================================
-Changes for patch v81
-
-- Fixed permissions on /dev/ptmx
-===============================================================================
-Changes for patch v82
-
-- Ported to kernel 2.1.132-pre4
-
-- Changed initial permissions on /dev/pts/*
-
-- Created <devfs_mk_compat>
-
-- Added "symlinks" boot option
-
-- Changed devfs_register_blkdev() back to register_blkdev() for IDE
-
-- Check for partitions on removable media in <devfs_lookup>
-===============================================================================
-Changes for patch v83
-
-- Fixed support for ramdisc when using string-based root FS name
-
-- Ported to kernel 2.2.0-pre1
-===============================================================================
-Changes for patch v84
-
-- Ported to kernel 2.2.0-pre7
-===============================================================================
-Changes for patch v85
-
-- Compile fixes for driver/sound/sound_common.c (non-module) and
-  drivers/isdn/isdn_common.c
-  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
-
-- Added support for registering regular files
-
-- Created <devfs_set_file_size>
-
-- Added /dev/cpu/mtrr as an alternative interface to /proc/mtrr
-
-- Update devfs inodes from entries if not changed through FS
-===============================================================================
-Changes for patch v86
-
-- Ported to kernel 2.2.0-pre9
-===============================================================================
-Changes for patch v87
-
-- Fixed bug when mounting non-devfs devices in a devfs
-===============================================================================
-Changes for patch v88
-
-- Fixed <devfs_fill_file> to only initialise temporary inodes
-
-- Trap for NULL fops in <devfs_register>
-
-- Return -ENODEV in <devfs_fill_file> for non-driver inodes
-
-- Fixed bug when unswapping non-devfs devices in a devfs
-===============================================================================
-Changes for patch v89
-
-- Switched to C data types in include/linux/devfs_fs.h
-
-- Switched from PATH_MAX to DEVFS_PATHLEN
-
-- Updated Documentation/filesystems/devfs/modules.conf to take account
-  of reverse scanning (!) by modprobe
-
-- Ported to kernel 2.2.0
-===============================================================================
-Changes for patch v90
-
-- CONFIG_DEVFS_DISABLE_OLD_TTY_NAMES replaced with "nottycompat" boot
-  option
-
-- CONFIG_DEVFS_TTY_COMPAT removed: existing "symlinks" boot option now
-  controls this. This means you must have libc 5.4.44 or later, or a
-  recent version of libc 6 if you use the "symlinks" option
-===============================================================================
-Changes for patch v91
-
-- Switch from <devfs_mk_symlink> to <devfs_mk_compat> in
-  drivers/char/vc_screen.c to fix problems with Midnight Commander
-===============================================================================
-Changes for patch v92
-
-- Ported to kernel 2.2.2-pre5
-===============================================================================
-Changes for patch v93
-
-- Modified <sd_name> in drivers/scsi/sd.c to cope with devices that
-  don't exist (which happens with new RAID autostart code printk()s)
-===============================================================================
-Changes for patch v94
-
-- Fixed bug in joystick driver: only first joystick was registered
-===============================================================================
-Changes for patch v95
-
-- Fixed another bug in joystick driver
-
-- Fixed <devfsd_read> to not overrun event buffer
-===============================================================================
-Changes for patch v96
-
-- Ported to kernel 2.2.5-2
-
-- Created <devfs_auto_unregister>
-
-- Fixed bugs: compatibility entries were not unregistered for:
-    loop driver
-    floppy driver
-    RAMDISC driver
-    IDE tape driver
-    SCSI CD-ROM driver
-    SCSI HDD driver
-===============================================================================
-Changes for patch v97
-
-- Fixed bugs: compatibility entries were not unregistered for:
-    ALSA sound driver
-    partitions in generic disc driver
-
-- Don't return unregistred entries in <devfs_find_handle>
-
-- Panic in <devfs_unregister> if entry unregistered
-
-- Don't panic in <devfs_auto_unregister> for duplicates
-===============================================================================
-Changes for patch v98
-
-- Don't unregister already unregistered entries in <unregister>
-
-- Register entry in <sd_detect>
-
-- Unregister entry in <sd_detach>
-
-- Changed to <devfs_*register_chrdev> in drivers/char/tty_io.c
-
-- Ported to kernel 2.2.7
-===============================================================================
-Changes for patch v99
-
-- Ported to kernel 2.2.8
-
-- Fixed bug in drivers/scsi/sd.c when >16 SCSI discs
-
-- Disable warning messages when unable to read partition table for
-  removable media
-===============================================================================
-Changes for patch v100
-
-- Ported to kernel 2.3.1-pre5
-
-- Added "oops-on-panic" boot option
-
-- Improved debugging in <devfs_register> and <devfs_unregister>
-
-- Register entry in <sr_detect>
-
-- Unregister entry in <sr_detach>
-
-- Register entry in <sg_detect>
-
-- Unregister entry in <sg_detach>
-
-- Added support for ALSA drivers
-===============================================================================
-Changes for patch v101
-
-- Ported to kernel 2.3.2
-===============================================================================
-Changes for patch v102
-
-- Update serial driver to register PCMCIA entries
-  Thanks to Roch-Alexandre Nomine-Beguin <roch@samarkand.infini.fr>
-
-- Updated an email address in ChangeLog
-
-- Hide virtual console capture entries from directory listings when
-  corresponding console device is not open
-===============================================================================
-Changes for patch v103
-
-- Ported to kernel 2.3.3
-===============================================================================
-Changes for patch v104
-
-- Added documentation for some functions
-
-- Added "doc" target to fs/devfs/Makefile
-
-- Added "v4l" directory for video4linux devices
-
-- Replaced call to <devfs_unregister> in <sd_detach> with call to
-  <devfs_register_partitions>
-
-- Moved registration for sr and sg drivers from detect() to attach()
-  methods
-
-- Register entries in <st_attach> and unregister in <st_detach>
-
-- Work around IDE driver treating CD-ROM as gendisk
-
-- Use <sed> instead of <tr> in rc.devfs
-
-- Updated ToDo list
-
-- Removed "oops-on-panic" boot option: now always Oops
-===============================================================================
-Changes for patch v105
-
-- Unregister SCSI host from <scsi_host_no_list> in <scsi_unregister>
-  Thanks to Zoltán Böszörményi <zboszor@mail.externet.hu>
-
-- Don't save /dev/log in rc.devfs
-
-- Ported to kernel 2.3.4-pre1
-===============================================================================
-Changes for patch v106
-
-- Fixed silly typo in drivers/scsi/st.c
-
-- Improved debugging in <devfs_register>
-===============================================================================
-Changes for patch v107
-
-- Added "diunlink" and "nokmod" boot options
-
-- Removed superfluous warning message in <devfs_d_iput>
-===============================================================================
-Changes for patch v108
-
-- Remove entries when unloading sound module
-===============================================================================
-Changes for patch v109
-
-- Ported to kernel 2.3.6-pre2
-===============================================================================
-Changes for patch v110
-
-- Took account of change to <d_alloc_root>
-===============================================================================
-Changes for patch v111
-
-- Created separate event queue for each mounted devfs
-
-- Removed <devfs_invalidate_dcache>
-
-- Created new ioctl()s for devfsd
-
-- Incremented devfsd protocol revision to 3
-
-- Fixed bug when re-creating directories: contents were lost
-
-- Block access to inodes until devfsd updates permissions
-===============================================================================
-Changes for patch v112
-
-- Modified patch so it applies against 2.3.5 and 2.3.6
-
-- Updated an email address in ChangeLog
-
-- Do not automatically change ownership/protection of /dev/tty<n>
-
-- Updated sample modules.conf
-
-- Switched to sending process uid/gid to devfsd
-
-- Renamed <call_kmod> to <try_modload>
-
-- Added DEVFSD_NOTIFY_LOOKUP event
-
-- Added DEVFSD_NOTIFY_CHANGE event
-
-- Added DEVFSD_NOTIFY_CREATE event
-
-- Incremented devfsd protocol revision to 4
-
-- Moved kernel-specific stuff to include/linux/devfs_fs_kernel.h
-===============================================================================
-Changes for patch v113
-
-- Ported to kernel 2.3.9
-
-- Restricted permissions on some block devices
-===============================================================================
-Changes for patch v114
-
-- Added support for /dev/netlink
-  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
-
-- Return EISDIR rather than EINVAL for read(2) on directories
-
-- Ported to kernel 2.3.10
-===============================================================================
-Changes for patch v115
-
-- Added support for all remaining character devices
-  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
-
-- Cleaned up netlink support
-===============================================================================
-Changes for patch v116
-
-- Added support for /dev/parport%d
-  Thanks to Tim Waugh <tim@cyberelk.demon.co.uk>
-
-- Fixed parallel port ATAPI tape driver
-
-- Fixed Atari SLM laser printer driver
-===============================================================================
-Changes for patch v117
-
-- Added support for COSA card
-  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
-
-- Fixed drivers/char/ppdev.c: missing #include <linux/init.h>
-
-- Fixed drivers/char/ftape/zftape/zftape-init.c
-  Thanks to Vladimir Popov <mashgrad@usa.net>
-===============================================================================
-Changes for patch v118
-
-- Ported to kernel 2.3.15-pre3
-
-- Fixed bug in loop driver
-
-- Unregister /dev/lp%d entries in drivers/char/lp.c
-  Thanks to Maciej W. Rozycki <macro@ds2.pg.gda.pl>
-===============================================================================
-Changes for patch v119
-
-- Ported to kernel 2.3.16
-===============================================================================
-Changes for patch v120
-
-- Fixed bug in drivers/scsi/scsi.c
-
-- Added /dev/ppp
-  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
-
-- Ported to kernel 2.3.17
-===============================================================================
-Changes for patch v121
-
-- Fixed bug in drivers/block/loop.c
-
-- Ported to kernel 2.3.18
-===============================================================================
-Changes for patch v122
-
-- Ported to kernel 2.3.19
-===============================================================================
-Changes for patch v123
-
-- Ported to kernel 2.3.20
-===============================================================================
-Changes for patch v124
-
-- Ported to kernel 2.3.21
-===============================================================================
-Changes for patch v125
-
-- Created <devfs_get_info>, <devfs_set_info>,
-  <devfs_get_first_child> and <devfs_get_next_sibling>
-  Added <<dir>> parameter to <devfs_register>, <devfs_mk_compat>,
-  <devfs_mk_dir> and <devfs_find_handle>
-  Work sponsored by SGI
-
-- Fixed apparent bug in COSA driver
-
-- Re-instated "scsihosts=" boot option
-===============================================================================
-Changes for patch v126
-
-- Always create /dev/pts if CONFIG_UNIX98_PTYS=y
-
-- Fixed call to <devfs_mk_dir> in drivers/block/ide-disk.c
-  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
-
-- Allow multiple unregistrations
-
-- Created /dev/scsi hierarchy
-  Work sponsored by SGI
-===============================================================================
-Changes for patch v127
-
-Work sponsored by SGI
-
-- No longer disable devpts if devfs enabled (caveat emptor)
-
-- Added flags array to struct gendisk and removed code from
-  drivers/scsi/sd.c
-
-- Created /dev/discs hierarchy
-===============================================================================
-Changes for patch v128
-
-Work sponsored by SGI
-
-- Created /dev/cdroms hierarchy
-===============================================================================
-Changes for patch v129
-
-Work sponsored by SGI
-
-- Removed compatibility entries for sound devices
-
-- Removed compatibility entries for printer devices
-
-- Removed compatibility entries for video4linux devices
-
-- Removed compatibility entries for parallel port devices
-
-- Removed compatibility entries for frame buffer devices
-===============================================================================
-Changes for patch v130
-
-Work sponsored by SGI
-
-- Added major and minor number to devfsd protocol
-
-- Incremented devfsd protocol revision to 5
-
-- Removed compatibility entries for SoundBlaster CD-ROMs
-
-- Removed compatibility entries for netlink devices
-
-- Removed compatibility entries for SCSI generic devices
-
-- Removed compatibility entries for SCSI tape devices
-===============================================================================
-Changes for patch v131
-
-Work sponsored by SGI
-
-- Support info pointer for all devfs entry types
-
-- Added <<info>> parameter to <devfs_mk_dir> and <devfs_mk_symlink>
-
-- Removed /dev/st hierarchy
-
-- Removed /dev/sg hierarchy
-
-- Removed compatibility entries for loop devices
-
-- Removed compatibility entries for IDE tape devices
-
-- Removed compatibility entries for SCSI CD-ROMs
-
-- Removed /dev/sr hierarchy
-===============================================================================
-Changes for patch v132
-
-Work sponsored by SGI
-
-- Removed compatibility entries for floppy devices
-
-- Removed compatibility entries for RAMDISCs
-
-- Removed compatibility entries for meta-devices
-
-- Removed compatibility entries for SCSI discs
-
-- Created <devfs_make_root>
-
-- Removed /dev/sd hierarchy
-
-- Support "../" when searching devfs namespace
-
-- Created /dev/ide/host* hierarchy
-
-- Supported IDE hard discs in /dev/ide/host* hierarchy
-
-- Removed compatibility entries for IDE discs
-
-- Removed /dev/ide/hd hierarchy
-
-- Supported IDE CD-ROMs in /dev/ide/host* hierarchy
-
-- Removed compatibility entries for IDE CD-ROMs
-
-- Removed /dev/ide/cd hierarchy
-===============================================================================
-Changes for patch v133
-
-Work sponsored by SGI
-
-- Created <devfs_get_unregister_slave>
-
-- Fixed bug in fs/partitions/check.c when rescanning
-===============================================================================
-Changes for patch v134
-
-Work sponsored by SGI
-
-- Removed /dev/sd, /dev/sr, /dev/st and /dev/sg directories
-
-- Removed /dev/ide/hd directory
-
-- Exported <devfs_get_parent>
-
-- Created <devfs_register_tape> and /dev/tapes hierarchy
-
-- Removed /dev/ide/mt hierarchy
-
-- Removed /dev/ide/fd hierarchy
-
-- Ported to kernel 2.3.25
-===============================================================================
-Changes for patch v135
-
-Work sponsored by SGI
-
-- Removed compatibility entries for virtual console capture devices
-
-- Removed unused <devfs_set_symlink_destination>
-
-- Removed compatibility entries for serial devices
-
-- Removed compatibility entries for console devices
-
-- Do not hide entries from devfsd or children
-
-- Removed DEVFS_FL_TTY_COMPAT flag
-
-- Removed "nottycompat" boot option
-
-- Removed <devfs_mk_compat>
-===============================================================================
-Changes for patch v136
-
-Work sponsored by SGI
-
-- Moved BSD pty devices to /dev/pty
-
-- Added DEVFS_FL_WAIT flag
-===============================================================================
-Changes for patch v137
-
-Work sponsored by SGI
-
-- Really fixed bug in fs/partitions/check.c when rescanning
-
-- Support new "disc" naming scheme in <get_removable_partition>
-
-- Allow NULL fops in <devfs_register>
-
-- Removed redundant name functions in SCSI disc and IDE drivers
-===============================================================================
-Changes for patch v138
-
-Work sponsored by SGI
-
-- Fixed old bugs in drivers/block/paride/pt.c, drivers/char/tpqic02.c,
-  drivers/net/wan/cosa.c and drivers/scsi/scsi.c
-  Thanks to Sergey Kubushin <ksi@ksi-linux.com>
-
-- Fall back to major table if NULL fops given to <devfs_register>
-===============================================================================
-Changes for patch v139
-
-Work sponsored by SGI
-
-- Corrected and moved <get_blkfops> and <get_chrfops> declarations
-  from arch/alpha/kernel/osf_sys.c to include/linux/fs.h
-
-- Removed name function from struct gendisk
-
-- Updated devfs FAQ
-===============================================================================
-Changes for patch v140
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.27
-===============================================================================
-Changes for patch v141
-
-Work sponsored by SGI
-
-- Bug fix in arch/m68k/atari/joystick.c
-
-- Moved ISDN and capi devices to /dev/isdn
-===============================================================================
-Changes for patch v142
-
-Work sponsored by SGI
-
-- Bug fix in drivers/block/ide-probe.c (patch confusion)
-===============================================================================
-Changes for patch v143
-
-Work sponsored by SGI
-
-- Bug fix in drivers/block/blkpg.c:partition_name()
-===============================================================================
-Changes for patch v144
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.29
-
-- Removed calls to <devfs_register> from cdu31a, cm206, mcd and mcdx
-  CD-ROM drivers: generic driver handles this now
-
-- Moved joystick devices to /dev/joysticks
-===============================================================================
-Changes for patch v145
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.30-pre3
-
-- Register whole-disc entry even for invalid partition tables
-
-- Fixed bug in mounting root FS when initrd enabled
-
-- Fixed device entry leak with IDE CD-ROMs
-
-- Fixed compile problem with drivers/isdn/isdn_common.c
-
-- Moved COSA devices to /dev/cosa
-
-- Support fifos when unregistering
-
-- Created <devfs_register_series> and used in many drivers
-
-- Moved Coda devices to /dev/coda
-
-- Moved parallel port IDE tapes to /dev/pt
-
-- Moved parallel port IDE generic devices to /dev/pg
-===============================================================================
-Changes for patch v146
-
-Work sponsored by SGI
-
-- Removed obsolete DEVFS_FL_COMPAT and DEVFS_FL_TOLERANT flags
-
-- Fixed compile problem with fs/coda/psdev.c
-
-- Reinstate change to <devfs_register_blkdev> in
-  drivers/block/ide-probe.c now that fs/isofs/inode.c is fixed
-
-- Switched to <devfs_register_blkdev> in drivers/block/floppy.c,
-  drivers/scsi/sr.c and drivers/block/md.c
-
-- Moved DAC960 devices to /dev/dac960
-===============================================================================
-Changes for patch v147
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.32-pre4
-===============================================================================
-Changes for patch v148
-
-Work sponsored by SGI
-
-- Removed kmod support: use devfsd instead
-
-- Moved miscellaneous character devices to /dev/misc
-===============================================================================
-Changes for patch v149
-
-Work sponsored by SGI
-
-- Ensure include/linux/joystick.h is OK for user-space
-
-- Improved debugging in <get_vfs_inode>
-
-- Ensure dentries created by devfsd will be cleaned up
-===============================================================================
-Changes for patch v150
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.34
-===============================================================================
-Changes for patch v151
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.35-pre1
-
-- Created <devfs_get_name>
-===============================================================================
-Changes for patch v152
-
-Work sponsored by SGI
-
-- Updated sample modules.conf
-
-- Ported to kernel 2.3.36-pre1
-===============================================================================
-Changes for patch v153
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.42
-
-- Removed <devfs_fill_file>
-===============================================================================
-Changes for patch v154
-
-Work sponsored by SGI
-
-- Took account of device number changes for /dev/fb*
-===============================================================================
-Changes for patch v155
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.43-pre8
-
-- Moved /dev/tty0 to /dev/vc/0
-
-- Moved sequence number formatting from <_tty_make_name> to drivers
-===============================================================================
-Changes for patch v156
-
-Work sponsored by SGI
-
-- Fixed breakage in drivers/scsi/sd.c due to recent SCSI changes
-===============================================================================
-Changes for patch v157
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.45
-===============================================================================
-Changes for patch v158
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.46-pre2
-===============================================================================
-Changes for patch v159
-
-Work sponsored by SGI
-
-- Fixed drivers/block/md.c
-  Thanks to Mike Galbraith <mikeg@weiden.de>
-
-- Documentation fixes
-
-- Moved device registration from <lp_init> to <lp_register>
-  Thanks to Tim Waugh <twaugh@redhat.com>
-===============================================================================
-Changes for patch v160
-
-Work sponsored by SGI
-
-- Fixed drivers/char/joystick/joystick.c
-  Thanks to Vojtech Pavlik <vojtech@suse.cz>
-
-- Documentation updates
-
-- Fixed arch/i386/kernel/mtrr.c if procfs and devfs not enabled
-
-- Fixed drivers/char/stallion.c
-===============================================================================
-Changes for patch v161
-
-Work sponsored by SGI
-
-- Remove /dev/ide when ide-mod is unloaded
-
-- Fixed bug in drivers/block/ide-probe.c when secondary but no primary
-
-- Added DEVFS_FL_NO_PERSISTENCE flag
-
-- Used new DEVFS_FL_NO_PERSISTENCE flag for Unix98 pty slaves
-
-- Removed unnecessary call to <update_devfs_inode_from_entry> in
-  <devfs_readdir>
-
-- Only set auto-ownership for /dev/pty/s*
-===============================================================================
-Changes for patch v162
-
-Work sponsored by SGI
-
-- Set inode->i_size to correct size for symlinks
-  Thanks to Jeremy Fitzhardinge <jeremy@goop.org>
-
-- Only give lookup() method to directories to comply with new VFS
-  assumptions
-
-- Remove unnecessary tests in symlink methods
-
-- Don't kill existing block ops in <devfs_read_inode>
-
-- Restore auto-ownership for /dev/pty/m*
-===============================================================================
-Changes for patch v163
-
-Work sponsored by SGI
-
-- Don't create missing directories in <devfs_find_handle>
-
-- Removed Documentation/filesystems/devfs/mk-devlinks
-
-- Updated Documentation/filesystems/devfs/README
-===============================================================================
-Changes for patch v164
-
-Work sponsored by SGI
-
-- Fixed CONFIG_DEVFS breakage in drivers/char/serial.c introduced in
-  linux-2.3.99-pre6-7
-===============================================================================
-Changes for patch v165
-
-Work sponsored by SGI
-
-- Ported to kernel 2.3.99-pre6
-===============================================================================
-Changes for patch v166
-
-Work sponsored by SGI
-
-- Added CONFIG_DEVFS_MOUNT
-===============================================================================
-Changes for patch v167
-
-Work sponsored by SGI
-
-- Updated Documentation/filesystems/devfs/README
-
-- Updated sample modules.conf
-===============================================================================
-Changes for patch v168
-
-Work sponsored by SGI
-
-- Disabled multi-mount capability (use VFS bindings instead)
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v169
-
-Work sponsored by SGI
-
-- Removed multi-mount code
-
-- Removed compatibility macros: VFS has changed too much
-===============================================================================
-Changes for patch v170
-
-Work sponsored by SGI
-
-- Updated README from master HTML file
-
-- Merged devfs inode into devfs entry
-===============================================================================
-Changes for patch v171
-
-Work sponsored by SGI
-
-- Updated sample modules.conf
-
-- Removed dead code in <devfs_register> which used to call
-  <free_dentries>
-
-- Ported to kernel 2.4.0-test2-pre3
-===============================================================================
-Changes for patch v172
-
-Work sponsored by SGI
-
-- Changed interface to <devfs_register>
-
-- Changed interface to <devfs_register_series>
-===============================================================================
-Changes for patch v173
-
-Work sponsored by SGI
-
-- Simplified interface to <devfs_mk_symlink>
-
-- Simplified interface to <devfs_mk_dir>
-
-- Simplified interface to <devfs_find_handle>
-===============================================================================
-Changes for patch v174
-
-Work sponsored by SGI
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v175
-
-Work sponsored by SGI
-
-- DocBook update for fs/devfs/base.c
-  Thanks to Tim Waugh <twaugh@redhat.com>
-
-- Removed stale fs/tunnel.c (was never used or completed)
-===============================================================================
-Changes for patch v176
-
-Work sponsored by SGI
-
-- Updated ToDo list
-
-- Removed sample modules.conf: now distributed with devfsd
-
-- Updated README from master HTML file
-
-- Ported to kernel 2.4.0-test3-pre4 (which had devfs-patch-v174)
-===============================================================================
-Changes for patch v177
-
-- Updated README from master HTML file
-
-- Documentation cleanups
-
-- Ensure <devfs_generate_path> terminates string for root entry
-  Thanks to Tim Jansen <tim@tjansen.de>
-
-- Exported <devfs_get_name> to modules
-
-- Make <devfs_mk_symlink> send events to devfsd
-
-- Cleaned up option processing in <devfs_setup>
-
-- Fixed bugs in handling symlinks: could leak or cause Oops
-
-- Cleaned up directory handling by separating fops
-  Thanks to Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk>
-===============================================================================
-Changes for patch v178
-
-- Fixed handling of inverted options in <devfs_setup>
-===============================================================================
-Changes for patch v179
-
-- Adjusted <try_modload> to account for <devfs_generate_path> fix
-===============================================================================
-Changes for patch v180
-
-- Fixed !CONFIG_DEVFS_FS stub declaration of <devfs_get_info>
-===============================================================================
-Changes for patch v181
-
-- Answered question posed by Al Viro and removed his comments from <devfs_open>
-
-- Moved setting of registered flag after other fields are changed
-
-- Fixed race between <devfsd_close> and <devfsd_notify_one>
-
-- Global VFS changes added bogus BKL to devfsd_close(): removed
-
-- Widened locking in <devfs_readlink> and <devfs_follow_link>
-
-- Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc
-
-- Simplified locking in <devfsd_ioctl> and fixed memory leak
-===============================================================================
-Changes for patch v182
-
-- Created <devfs_*alloc_major> and <devfs_*alloc_devnum>
-
-- Removed broken devnum allocation and use <devfs_alloc_devnum>
-
-- Fixed old devnum leak by calling new <devfs_dealloc_devnum>
-
-- Created <devfs_*alloc_unique_number>
-
-- Fixed number leak for /dev/cdroms/cdrom%d
-
-- Fixed number leak for /dev/discs/disc%d
-===============================================================================
-Changes for patch v183
-
-- Fixed bug in <devfs_setup> which could hang boot process
-===============================================================================
-Changes for patch v184
-
-- Documentation typo fix for fs/devfs/util.c
-
-- Fixed drivers/char/stallion.c for devfs
-
-- Added DEVFSD_NOTIFY_DELETE event
-
-- Updated README from master HTML file
-
-- Removed #include <asm/segment.h> from fs/devfs/base.c
-===============================================================================
-Changes for patch v185
-
-- Made <block_semaphore> and <char_semaphore> in fs/devfs/util.c
-  private
-
-- Fixed inode table races by removing it and using inode->u.generic_ip
-  instead
-
-- Moved <devfs_read_inode> into <get_vfs_inode>
-
-- Moved <devfs_write_inode> into <devfs_notify_change>
-===============================================================================
-Changes for patch v186
-
-- Fixed race in <devfs_do_symlink> for uni-processor
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v187
-
-- Fixed drivers/char/stallion.c for devfs
-
-- Fixed drivers/char/rocket.c for devfs
-
-- Fixed bug in <devfs_alloc_unique_number>: limited to 128 numbers
-===============================================================================
-Changes for patch v188
-
-- Updated major masks in fs/devfs/util.c up to Linus' "no new majors"
-  proclamation. Block: were 126 now 122 free, char: were 26 now 19 free
-
-- Updated README from master HTML file
-
-- Removed remnant of multi-mount support in <devfs_mknod>
-
-- Removed unused DEVFS_FL_SHOW_UNREG flag
-===============================================================================
-Changes for patch v189
-
-- Removed nlink field from struct devfs_inode
-
-- Removed auto-ownership for /dev/pty/* (BSD ptys) and used
-  DEVFS_FL_CURRENT_OWNER|DEVFS_FL_NO_PERSISTENCE for /dev/pty/s* (just
-  like Unix98 pty slaves) and made /dev/pty/m* rw-rw-rw- access
-===============================================================================
-Changes for patch v190
-
-- Updated README from master HTML file
-
-- Replaced BKL with global rwsem to protect symlink data (quick and
-  dirty hack)
-===============================================================================
-Changes for patch v191
-
-- Replaced global rwsem for symlink with per-link refcount
-===============================================================================
-Changes for patch v192
-
-- Removed unnecessary #ifdef CONFIG_DEVFS_FS from arch/i386/kernel/mtrr.c
-
-- Ported to kernel 2.4.10-pre11
-
-- Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>
-===============================================================================
-Changes for patch v193
-
-- Went back to global rwsem for symlinks (refcount scheme no good)
-===============================================================================
-Changes for patch v194
-
-- Fixed overrun in <devfs_link> by removing function (not needed)
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v195
-
-- Fixed buffer underrun in <try_modload>
-
-- Moved down_read() from <search_for_entry_in_dir> to <find_entry>
-===============================================================================
-Changes for patch v196
-
-- Fixed race in <devfsd_ioctl> when setting event mask
-  Thanks to Kari Hurtta <hurtta@leija.mh.fmi.fi>
-
-- Avoid deadlock in <devfs_follow_link> by using temporary buffer
-===============================================================================
-Changes for patch v197
-
-- First release of new locking code for devfs core (v1.0)
-
-- Fixed bug in drivers/cdrom/cdrom.c
-===============================================================================
-Changes for patch v198
-
-- Discard temporary buffer, now use "%s" for dentry names
-
-- Don't generate path in <try_modload>: use fake entry instead
-
-- Use "existing" directory in <_devfs_make_parent_for_leaf>
-
-- Use slab cache rather than fixed buffer for devfsd events
-===============================================================================
-Changes for patch v199
-
-- Removed obsolete usage of DEVFS_FL_NO_PERSISTENCE
-
-- Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>
-
-- Fixed locking bug in <devfs_d_revalidate_wait> due to typo
-
-- Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from devfsd
-  or children
-===============================================================================
-Changes for patch v200
-
-- Ported to kernel 2.5.1-pre2
-===============================================================================
-Changes for patch v201
-
-- Fixed bug in <devfsd_read>: was dereferencing freed pointer
-===============================================================================
-Changes for patch v202
-
-- Fixed bug in <devfsd_close>: was dereferencing freed pointer
-
-- Added process group check for devfsd privileges
-===============================================================================
-Changes for patch v203
-
-- Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>
-===============================================================================
-Changes for patch v204
-
-- Removed long obsolete rc.devfs
-
-- Return old entry in <devfs_mk_dir> for 2.4.x kernels
-
-- Updated README from master HTML file
-
-- Increment refcount on module in <check_disc_changed>
-
-- Created <devfs_get_handle> and exported <devfs_put>
-
-- Increment refcount on module in <devfs_get_ops>
-
-- Created <devfs_put_ops> and used where needed to fix races
-
-- Added clarifying comments in response to preliminary EMC code review
-
-- Added poisoning to <devfs_put>
-
-- Improved debugging messages
-
-- Fixed unregister bugs in drivers/md/lvm-fs.c
-===============================================================================
-Changes for patch v205
-
-- Corrected (made useful) debugging message in <unregister>
-
-- Moved <kmem_cache_create> in <mount_devfs_fs> to <init_devfs_fs>
-
-- Fixed drivers/md/lvm-fs.c to create "lvm" entry
-
-- Added magic number to guard against scribbling drivers
-
-- Only return old entry in <devfs_mk_dir> if a directory
-
-- Defined macros for error and debug messages
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v206
-
-- Added support for multiple Compaq cpqarray controllers
-
-- Fixed (rare, old) race in <devfs_lookup>
-===============================================================================
-Changes for patch v207
-
-- Fixed deadlock bug in <devfs_d_revalidate_wait>
-
-- Tag VFS deletable in <devfs_mk_symlink> if handle ignored
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v208
-
-- Added KERN_* to remaining messages
-
-- Cleaned up declaration of <stat_read>
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v209
-
-- Updated README from master HTML file
-
-- Removed silently introduced calls to lock_kernel() and
-  unlock_kernel() due to recent VFS locking changes. BKL isn't
-  required in devfs 
-
-- Changed <devfs_rmdir> to allow later additions if not yet empty
-
-- Added calls to <devfs_register_partitions> in drivers/block/blkpc.c
-  <add_partition> and <del_partition>
-
-- Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
-  bitfield
-
-- Fixed bitfield data type for <devfs_*alloc_devnum>
-
-- Made major bitfield type and initialiser 64 bit safe
-===============================================================================
-Changes for patch v210
-
-- Updated fs/devfs/util.c to fix shift warning on 64 bit machines
-  Thanks to Anton Blanchard <anton@samba.org>
-
-- Updated README from master HTML file
-===============================================================================
-Changes for patch v211
-
-- Do not put miscellaneous character devices in /dev/misc if they
-  specify their own directory (i.e. contain a '/' character)
-
-- Copied macro for error messages from fs/devfs/base.c to
-  fs/devfs/util.c and made use of this macro
-
-- Removed 2.4.x compatibility code from fs/devfs/base.c
-===============================================================================
-Changes for patch v212
-
-- Added BKL to <devfs_open> because drivers still need it
-===============================================================================
-Changes for patch v213
-
-- Protected <scan_dir_for_removable> and <get_removable_partition>
-  from changing directory contents
-===============================================================================
-Changes for patch v214
-
-- Switched to ISO C structure field initialisers
-
-- Switch to set_current_state() and move before add_wait_queue()
-
-- Updated README from master HTML file
-
-- Fixed devfs entry leak in <devfs_readdir> when *readdir fails
-===============================================================================
-Changes for patch v215
-
-- Created <devfs_find_and_unregister>
-
-- Switched many functions from <devfs_find_handle> to
-  <devfs_find_and_unregister>
-
-- Switched many functions from <devfs_find_handle> to <devfs_get_handle>
-===============================================================================
-Changes for patch v216
-
-- Switched arch/ia64/sn/io/hcl.c from <devfs_find_handle> to
-  <devfs_get_handle>
-
-- Removed deprecated <devfs_find_handle>
-===============================================================================
-Changes for patch v217
-
-- Exported <devfs_find_and_unregister> and <devfs_only> to modules
-
-- Updated README from master HTML file
-
-- Fixed module unload race in <devfs_open>
-===============================================================================
-Changes for patch v218
-
-- Removed DEVFS_FL_AUTO_OWNER flag
-
-- Switched lingering structure field initialiser to ISO C
-
-- Added locking when setting/clearing flags
-
-- Documentation fix in fs/devfs/util.c
diff --git a/Documentation/filesystems/devfs/README b/Documentation/filesystems/devfs/README
deleted file mode 100644 (file)
index aabfba2..0000000
+++ /dev/null
@@ -1,1959 +0,0 @@
-Devfs (Device File System) FAQ
-
-
-Linux Devfs (Device File System) FAQ
-Richard Gooch
-20-AUG-2002
-
-
-Document languages:
-
-
-
-
-
-
-
------------------------------------------------------------------------------
-
-NOTE: the master copy of this document is available online at:
-
-http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html
-and looks much better than the text version distributed with the
-kernel sources. A mirror site is available at:
-
-http://www.ras.ucalgary.ca/~rgooch/linux/docs/devfs.html
-
-There is also an optional daemon that may be used with devfs. You can
-find out more about it at:
-
-http://www.atnf.csiro.au/~rgooch/linux/
-
-A mailing list is available which you may subscribe to. Send
-email
-to majordomo@oss.sgi.com with the following line in the
-body of the message:
-subscribe devfs
-To unsubscribe, send the message body:
-unsubscribe devfs
-instead. The list is archived at
-
-http://oss.sgi.com/projects/devfs/archive/.
-
------------------------------------------------------------------------------
-
-Contents
-
-
-What is it?
-
-Why do it?
-
-Who else does it?
-
-How it works
-
-Operational issues (essential reading)
-
-Instructions for the impatient
-Permissions persistence across reboots
-Dealing with drivers without devfs support
-All the way with Devfs
-Other Issues
-Kernel Naming Scheme
-Devfsd Naming Scheme
-Old Compatibility Names
-SCSI Host Probing Issues
-
-
-
-Device drivers currently ported
-
-Allocation of Device Numbers
-
-Questions and Answers
-
-Making things work
-Alternatives to devfs
-What I don't like about devfs
-How to report bugs
-Strange kernel messages
-Compilation problems with devfsd
-
-
-Other resources
-
-Translations of this document
-
-
------------------------------------------------------------------------------
-
-
-What is it?
-
-Devfs is an alternative to "real" character and block special devices
-on your root filesystem. Kernel device drivers can register devices by
-name rather than major and minor numbers. These devices will appear in
-devfs automatically, with whatever default ownership and
-protection the driver specified. A daemon (devfsd) can be used to
-override these defaults. Devfs has been in the kernel since 2.3.46.
-
-NOTE that devfs is entirely optional. If you prefer the old
-disc-based device nodes, then simply leave CONFIG_DEVFS_FS=n (the
-default). In this case, nothing will change.  ALSO NOTE that if you do
-enable devfs, the defaults are such that full compatibility is
-maintained with the old devices names.
-
-There are two aspects to devfs: one is the underlying device
-namespace, which is a namespace just like any mounted filesystem. The
-other aspect is the filesystem code which provides a view of the
-device namespace. The reason I make a distinction is because devfs
-can be mounted many times, with each mount showing the same device
-namespace. Changes made are global to all mounted devfs filesystems.
-Also, because the devfs namespace exists without any devfs mounts, you
-can easily mount the root filesystem by referring to an entry in the
-devfs namespace.
-
-
-The cost of devfs is a small increase in kernel code size and memory
-usage. About 7 pages of code (some of that in __init sections) and 72
-bytes for each entry in the namespace. A modest system has only a
-couple of hundred device entries, so this costs a few more
-pages. Compare this with the suggestion to put /dev on a <a
-href="#why-faq-ramdisc">ramdisc.
-
-On a typical machine, the cost is under 0.2 percent. On a modest
-system with 64 MBytes of RAM, the cost is under 0.1 percent.  The
-accusations of "bloatware" levelled at devfs are not justified.
-
------------------------------------------------------------------------------
-
-
-Why do it?
-
-There are several problems that devfs addresses. Some of these
-problems are more serious than others (depending on your point of
-view), and some can be solved without devfs. However, the totality of
-these problems really calls out for devfs.
-
-The choice is a patchwork of inefficient user space solutions, which
-are complex and likely to be fragile, or to use a simple and efficient
-devfs which is robust.
-
-There have been many counter-proposals to devfs, all seeking to
-provide some of the benefits without actually implementing devfs. So
-far there has been an absence of code and no proposed alternative has
-been able to provide all the features that devfs does. Further,
-alternative proposals require far more complexity in user-space (and
-still deliver less functionality than devfs). Some people have the
-mantra of reducing "kernel bloat", but don't consider the effects on
-user-space.
-
-A good solution limits the total complexity of kernel-space and
-user-space.
-
-
-Major&minor allocation
-
-The existing scheme requires the allocation of major and minor device
-numbers for each and every device. This means that a central
-co-ordinating authority is required to issue these device numbers
-(unless you're developing a "private" device driver), in order to
-preserve uniqueness. Devfs shifts the burden to a namespace. This may
-not seem like a huge benefit, but actually it is. Since driver authors
-will naturally choose a device name which reflects the functionality
-of the device, there is far less potential for namespace conflict.
-Solving this requires a kernel change.
-
-/dev management
-
-Because you currently access devices through device nodes, these must
-be created by the system administrator. For standard devices you can
-usually find a MAKEDEV programme which creates all these (hundreds!)
-of nodes. This means that changes in the kernel must be reflected by
-changes in the MAKEDEV programme, or else the system administrator
-creates device nodes by hand.
-
-The basic problem is that there are two separate databases of
-major and minor numbers. One is in the kernel and one is in /dev (or
-in a MAKEDEV programme, if you want to look at it that way). This is
-duplication of information, which is not good practice.
-Solving this requires a kernel change.
-
-/dev growth
-
-A typical /dev has over 1200 nodes! Most of these devices simply don't
-exist because the hardware is not available. A huge /dev increases the
-time to access devices (I'm just referring to the dentry lookup times
-and the time taken to read inodes off disc: the next subsection shows
-some more horrors).
-
-An example of how big /dev can grow is if we consider SCSI devices:
-
-host           6  bits  (say up to 64 hosts on a really big machine)
-channel        4  bits  (say up to 16 SCSI buses per host)
-id             4  bits
-lun            3  bits
-partition      6  bits
-TOTAL          23 bits
-
-
-This requires 8 Mega (1024*1024) inodes if we want to store all
-possible device nodes. Even if we scrap everything but id,partition
-and assume a single host adapter with a single SCSI bus and only one
-logical unit per SCSI target (id), that's still 10 bits or 1024
-inodes. Each VFS inode takes around 256 bytes (kernel 2.1.78), so
-that's 256 kBytes of inode storage on disc (assuming real inodes take
-a similar amount of space as VFS inodes). This is actually not so bad,
-because disc is cheap these days. Embedded systems would care about
-256 kBytes of /dev inodes, but you could argue that embedded systems
-would have hand-tuned /dev directories. I've had to do just that on my
-embedded systems, but I would rather just leave it to devfs.
-
-Another issue is the time taken to lookup an inode when first
-referenced. Not only does this take time in scanning through a list in
-memory, but also the seek times to read the inodes off disc.
-This could be solved in user-space using a clever programme which
-scanned the kernel logs and deleted /dev entries which are not
-available and created them when they were available. This programme
-would need to be run every time a new module was loaded, which would
-slow things down a lot.
-
-There is an existing programme called scsidev which will automatically
-create device nodes for SCSI devices. It can do this by scanning files
-in /proc/scsi. Unfortunately, to extend this idea to other device
-nodes would require significant modifications to existing drivers (so
-they too would provide information in /proc). This is a non-trivial
-change (I should know: devfs has had to do something similar). Once
-you go to this much effort, you may as well use devfs itself (which
-also provides this information).  Furthermore, such a system would
-likely be implemented in an ad-hoc fashion, as different drivers will
-provide their information in different ways.
-
-Devfs is much cleaner, because it (naturally) has a uniform mechanism
-to provide this information: the device nodes themselves!
-
-
-Node to driver file_operations translation
-
-There is an important difference between the way disc-based character
-and block nodes and devfs entries make the connection between an entry
-in /dev and the actual device driver.
-
-With the current 8 bit major and minor numbers the connection between
-disc-based c&b nodes and per-major drivers is done through a
-fixed-length table of 128 entries. The various filesystem types set
-the inode operations for c&b nodes to {chr,blk}dev_inode_operations,
-so when a device is opened a few quick levels of indirection bring us
-to the driver file_operations.
-
-For miscellaneous character devices a second step is required: there
-is a scan for the driver entry with the same minor number as the file
-that was opened, and the appropriate minor open method is called. This
-scanning is done *every time* you open a device node. Potentially, you
-may be searching through dozens of misc. entries before you find your
-open method. While not an enormous performance overhead, this does
-seem pointless.
-
-Linux *must* move beyond the 8 bit major and minor barrier,
-somehow. If we simply increase each to 16 bits, then the indexing
-scheme used for major driver lookup becomes untenable, because the
-major tables (one each for character and block devices) would need to
-be 64 k entries long (512 kBytes on x86, 1 MByte for 64 bit
-systems). So we would have to use a scheme like that used for
-miscellaneous character devices, which means the search time goes up
-linearly with the average number of major device drivers on your
-system. Not all "devices" are hardware, some are higher-level drivers
-like KGI, so you can get more "devices" without adding hardware
-You can improve this by creating an ordered (balanced:-)
-binary tree, in which case your search time becomes log(N).
-Alternatively, you can use hashing to speed up the search.
-But why do that search at all if you don't have to? Once again, it
-seems pointless.
-
-Note that devfs doesn't use the major&minor system. For devfs
-entries, the connection is done when you lookup the /dev entry. When
-devfs_register() is called, an internal table is appended which has
-the entry name and the file_operations. If the dentry cache doesn't
-have the /dev entry already, this internal table is scanned to get the
-file_operations, and an inode is created. If the dentry cache already
-has the entry, there is *no lookup time* (other than the dentry scan
-itself, but we can't avoid that anyway, and besides Linux dentries
-cream other OS's which don't have them:-). Furthermore, the number of
-node entries in a devfs is only the number of available device
-entries, not the number of *conceivable* entries. Even if you remove
-unnecessary entries in a disc-based /dev, the number of conceivable
-entries remains the same: you just limit yourself in order to save
-space.
-
-Devfs provides a fast connection between a VFS node and the device
-driver, in a scalable way.
-
-/dev as a system administration tool
-
-Right now /dev contains a list of conceivable devices, most of which I
-don't have. Devfs only shows those devices available on my
-system. This means that listing /dev is a handy way of checking what
-devices are available.
-
-Major&minor size
-
-Existing major and minor numbers are limited to 8 bits each. This is
-now a limiting factor for some drivers, particularly the SCSI disc
-driver, which consumes a single major number. Only 16 discs are
-supported, and each disc may have only 15 partitions. Maybe this isn't
-a problem for you, but some of us are building huge Linux systems with
-disc arrays. With devfs an arbitrary pointer can be associated with
-each device entry, which can be used to give an effective 32 bit
-device identifier (i.e. that's like having a 32 bit minor
-number). Since this is private to the kernel, there are no C library
-compatibility issues which you would have with increasing major and
-minor number sizes. See the section on "Allocation of Device Numbers"
-for details on maintaining compatibility with userspace.
-
-Solving this requires a kernel change.
-
-Since writing this, the kernel has been modified so that the SCSI disc
-driver has more major numbers allocated to it and now supports up to
-128 discs. Since these major numbers are non-contiguous (a result of
-unplanned expansion), the implementation is a little more cumbersome
-than originally.
-
-Just like the changes to IPv4 to fix impending limitations in the
-address space, people find ways around the limitations. In the long
-run, however, solutions like IPv6 or devfs can't be put off forever.
-
-Read-only root filesystem
-
-Having your device nodes on the root filesystem means that you can't
-operate properly with a read-only root filesystem. This is because you
-want to change ownerships and protections of tty devices. Existing
-practice prevents you using a CD-ROM as your root filesystem for a
-*real* system. Sure, you can boot off a CD-ROM, but you can't change
-tty ownerships, so it's only good for installing.
-
-Also, you can't use a shared NFS root filesystem for a cluster of
-discless Linux machines (having tty ownerships changed on a common
-/dev is not good). Nor can you embed your root filesystem in a
-ROM-FS.
-
-You can get around this by creating a RAMDISC at boot time, making
-an ext2 filesystem in it, mounting it somewhere and copying the
-contents of /dev into it, then unmounting it and mounting it over
-/dev.
-
-A devfs is a cleaner way of solving this.
-
-Non-Unix root filesystem
-
-Non-Unix filesystems (such as NTFS) can't be used for a root
-filesystem because they variously don't support character and block
-special files or symbolic links. You can't have a separate disc-based
-or RAMDISC-based filesystem mounted on /dev because you need device
-nodes before you can mount these. Devfs can be mounted without any
-device nodes. Devlinks won't work because symlinks aren't supported.
-An alternative solution is to use initrd to mount a RAMDISC initial
-root filesystem (which is populated with a minimal set of device
-nodes), and then construct a new /dev in another RAMDISC, and finally
-switch to your non-Unix root filesystem. This requires clever boot
-scripts and a fragile and conceptually complex boot procedure.
-
-Devfs solves this in a robust and conceptually simple way.
-
-PTY security
-
-Current pseudo-tty (pty) devices are owned by root and read-writable
-by everyone. The user of a pty-pair cannot change
-ownership/protections without being suid-root.
-
-This could be solved with a secure user-space daemon which runs as
-root and does the actual creation of pty-pairs. Such a daemon would
-require modification to *every* programme that wants to use this new
-mechanism. It also slows down creation of pty-pairs.
-
-An alternative is to create a new open_pty() syscall which does much
-the same thing as the user-space daemon. Once again, this requires
-modifications to pty-handling programmes.
-
-The devfs solution allows a device driver to "tag" certain device
-files so that when an unopened device is opened, the ownerships are
-changed to the current euid and egid of the opening process, and the
-protections are changed to the default registered by the driver. When
-the device is closed ownership is set back to root and protections are
-set back to read-write for everybody. No programme need be changed.
-The devpts filesystem provides this auto-ownership feature for Unix98
-ptys. It doesn't support old-style pty devices, nor does it have all
-the other features of devfs.
-
-Intelligent device management
-
-Devfs implements a simple yet powerful protocol for communication with
-a device management daemon (devfsd) which runs in user space. It is
-possible to send a message (either synchronously or asynchronously) to
-devfsd on any event, such as registration/unregistration of device
-entries, opening and closing devices, looking up inodes, scanning
-directories and more. This has many possibilities. Some of these are
-already implemented. See:
-
-
-http://www.atnf.csiro.au/~rgooch/linux/
-
-Device entry registration events can be used by devfsd to change
-permissions of newly-created device nodes. This is one mechanism to
-control device permissions.
-
-Device entry registration/unregistration events can be used to run
-programmes or scripts. This can be used to provide automatic mounting
-of filesystems when a new block device media is inserted into the
-drive.
-
-Asynchronous device open and close events can be used to implement
-clever permissions management. For example, the default permissions on
-/dev/dsp do not allow everybody to read from the device. This is
-sensible, as you don't want some remote user recording what you say at
-your console. However, the console user is also prevented from
-recording. This behaviour is not desirable. With asynchronous device
-open and close events, you can have devfsd run a programme or script
-when console devices are opened to change the ownerships for *other*
-device nodes (such as /dev/dsp). On closure, you can run a different
-script to restore permissions. An advantage of this scheme over
-modifying the C library tty handling is that this works even if your
-programme crashes (how many times have you seen the utmp database with
-lingering entries for non-existent logins?).
-
-Synchronous device open events can be used to perform intelligent
-device access protections. Before the device driver open() method is
-called, the daemon must first validate the open attempt, by running an
-external programme or script. This is far more flexible than access
-control lists, as access can be determined on the basis of other
-system conditions instead of just the UID and GID.
-
-Inode lookup events can be used to authenticate module autoload
-requests. Instead of using kmod directly, the event is sent to
-devfsd which can implement an arbitrary authentication before loading
-the module itself.
-
-Inode lookup events can also be used to construct arbitrary
-namespaces, without having to resort to populating devfs with symlinks
-to devices that don't exist.
-
-Speculative Device Scanning
-
-Consider an application (like cdparanoia) that wants to find all
-CD-ROM devices on the system (SCSI, IDE and other types), whether or
-not their respective modules are loaded. The application must
-speculatively open certain device nodes (such as /dev/sr0 for the SCSI
-CD-ROMs) in order to make sure the module is loaded. This requires
-that all Linux distributions follow the standard device naming scheme
-(last time I looked RedHat did things differently). Devfs solves the
-naming problem.
-
-The same application also wants to see which devices are actually
-available on the system. With the existing system it needs to read the
-/dev directory and speculatively open each /dev/sr* device to
-determine if the device exists or not. With a large /dev this is an
-inefficient operation, especially if there are many /dev/sr* nodes. A
-solution like scsidev could reduce the number of /dev/sr* entries (but
-of course that also requires all that inefficient directory scanning).
-
-With devfs, the application can open the /dev/sr directory
-(which triggers the module autoloading if required), and proceed to
-read /dev/sr. Since only the available devices will have
-entries, there are no inefficencies in directory scanning or device
-openings.
-
------------------------------------------------------------------------------
-
-Who else does it?
-
-FreeBSD has a devfs implementation. Solaris and AIX each have a
-pseudo-devfs (something akin to scsidev but for all devices, with some
-unspecified kernel support). BeOS, Plan9 and QNX also have it. SGI's
-IRIX 6.4 and above also have a device filesystem.
-
-While we shouldn't just automatically do something because others do
-it, we should not ignore the work of others either. FreeBSD has a lot
-of competent people working on it, so their opinion should not be
-blithely ignored.
-
------------------------------------------------------------------------------
-
-
-How it works
-
-Registering device entries
-
-For every entry (device node) in a devfs-based /dev a driver must call
-devfs_register(). This adds the name of the device entry, the
-file_operations structure pointer and a few other things to an
-internal table. Device entries may be added and removed at any
-time. When a device entry is registered, it automagically appears in
-any mounted devfs'.
-
-Inode lookup
-
-When a lookup operation on an entry is performed and if there is no
-driver information for that entry devfs will attempt to call
-devfsd. If still no driver information can be found then a negative
-dentry is yielded and the next stage operation will be called by the
-VFS (such as create() or mknod() inode methods). If driver information
-can be found, an inode is created (if one does not exist already) and
-all is well.
-
-Manually creating device nodes
-
-The mknod() method allows you to create an ordinary named pipe in the
-devfs, or you can create a character or block special inode if one
-does not already exist. You may wish to create a character or block
-special inode so that you can set permissions and ownership. Later, if
-a device driver registers an entry with the same name, the
-permissions, ownership and times are retained. This is how you can set
-the protections on a device even before the driver is loaded. Once you
-create an inode it appears in the directory listing.
-
-Unregistering device entries
-
-A device driver calls devfs_unregister() to unregister an entry.
-
-Chroot() gaols
-
-2.2.x kernels
-
-The semantics of inode creation are different when devfs is mounted
-with the "explicit" option. Now, when a device entry is registered, it
-will not appear until you use mknod() to create the device. It doesn't
-matter if you mknod() before or after the device is registered with
-devfs_register(). The purpose of this behaviour is to support
-chroot(2) gaols, where you want to mount a minimal devfs inside the
-gaol. Only the devices you specifically want to be available (through
-your mknod() setup) will be accessible.
-
-2.4.x kernels
-
-As of kernel 2.3.99, the VFS has had the ability to rebind parts of
-the global filesystem namespace into another part of the namespace.
-This now works even at the leaf-node level, which means that
-individual files and device nodes may be bound into other parts of the
-namespace. This is like making links, but better, because it works
-across filesystems (unlike hard links) and works through chroot()
-gaols (unlike symbolic links).
-
-Because of these improvements to the VFS, the multi-mount capability
-in devfs is no longer needed. The administrator may create a minimal
-device tree inside a chroot(2) gaol by using VFS bindings. As this
-provides most of the features of the devfs multi-mount capability, I
-removed the multi-mount support code (after issuing an RFC). This
-yielded code size reductions and simplifications.
-
-If you want to construct a minimal chroot() gaol, the following
-command should suffice:
-
-mount --bind /dev/null /gaol/dev/null
-
-
-Repeat for other device nodes you want to expose. Simple!
-
------------------------------------------------------------------------------
-
-
-Operational issues
-
-
-Instructions for the impatient
-
-Nobody likes reading documentation. People just want to get in there
-and play. So this section tells you quickly the steps you need to take
-to run with devfs mounted over /dev. Skip these steps and you will end
-up with a nearly unbootable system. Subsequent sections describe the
-issues in more detail, and discuss non-essential configuration
-options.
-
-Devfsd
-OK, if you're reading this, I assume you want to play with
-devfs. First you should ensure that /usr/src/linux contains a
-recent kernel source tree. Then you need to compile devfsd, the device
-management daemon, available at
-
-http://www.atnf.csiro.au/~rgooch/linux/.
-Because the kernel has a naming scheme
-which is quite different from the old naming scheme, you need to
-install devfsd so that software and configuration files that use the
-old naming scheme will not break.
-
-Compile and install devfsd. You will be provided with a default
-configuration file /etc/devfsd.conf which will provide
-compatibility symlinks for the old naming scheme. Don't change this
-config file unless you know what you're doing. Even if you think you
-do know what you're doing, don't change it until you've followed all
-the steps below and booted a devfs-enabled system and verified that it
-works.
-
-Now edit your main system boot script so that devfsd is started at the
-very beginning (before any filesystem
-checks). /etc/rc.d/rc.sysinit is often the main boot script
-on systems with SysV-style boot scripts. On systems with BSD-style
-boot scripts it is often /etc/rc. Also check
-/sbin/rc.
-
-NOTE that the line you put into the boot
-script should be exactly:
-
-/sbin/devfsd /dev
-
-DO NOT use some special daemon-launching
-programme, otherwise the boot script may not wait for devfsd to finish
-initialising.
-
-System Libraries
-There may still be some problems because of broken software making
-assumptions about device names. In particular, some software does not
-handle devices which are symbolic links. If you are running a libc 5
-based system, install libc 5.4.44 (if you have libc 5.4.46, go back to
-libc 5.4.44, which is actually correct). If you are running a glibc
-based system, make sure you have glibc 2.1.3 or later.
-
-/etc/securetty
-PAM (Pluggable Authentication Modules) is supposed to be a flexible
-mechanism for providing better user authentication and access to
-services. Unfortunately, it's also fragile, complex and undocumented
-(check out RedHat 6.1, and probably other distributions as well). PAM
-has problems with symbolic links. Append the following lines to your
-/etc/securetty file:
-
-vc/1
-vc/2
-vc/3
-vc/4
-vc/5
-vc/6
-vc/7
-vc/8
-
-This will not weaken security. If you have a version of util-linux
-earlier than 2.10.h, please upgrade to 2.10.h or later. If you
-absolutely cannot upgrade, then also append the following lines to
-your /etc/securetty file:
-
-1
-2
-3
-4
-5
-6
-7
-8
-
-This may potentially weaken security by allowing root logins over the
-network (a password is still required, though). However, since there
-are problems with dealing with symlinks, I'm suspicious of the level
-of security offered in any case.
-
-XFree86
-While not essential, it's probably a good idea to upgrade to XFree86
-4.0, as patches went in to make it more devfs-friendly. If you don't,
-you'll probably need to apply the following patch to
-/etc/security/console.perms so that ordinary users can run
-startx. Note that not all distributions have this file (e.g. Debian),
-so if it's not present, don't worry about it.
-
---- /etc/security/console.perms.orig    Sat Apr 17 16:26:47 1999 
-+++ /etc/security/console.perms Fri Feb 25 23:53:55 2000 
-@@ -14,7 +14,7 @@ 
- # man 5 console.perms 
-
- # file classes -- these are regular expressions 
--<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
-+<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
-
- # device classes -- these are shell-style globs 
- <floppy>=/dev/fd[0-1]* 
-
-If the patch does not apply, then change the line:
-
-<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
-
-with:
-
-<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
-
-
-Disable devpts
-I've had a report of devpts mounted on /dev/pts not working
-correctly. Since devfs will also manage /dev/pts, there is no
-need to mount devpts as well. You should either edit your
-/etc/fstab so devpts is not mounted, or disable devpts from
-your kernel configuration.
-
-Unsupported drivers
-Not all drivers have devfs support. If you depend on one of these
-drivers, you will need to create a script or tarfile that you can use
-at boot time to create device nodes as appropriate. There is a
-section which describes this. Another
-section lists the drivers which have
-devfs support.
-
-/dev/mouse
-
-Many disributions configure /dev/mouse to be the mouse device
-for XFree86 and GPM. I actually think this is a bad idea, because it
-adds another level of indirection. When looking at a config file, if
-you see /dev/mouse you're left wondering which mouse
-is being referred to. Hence I recommend putting the actual mouse
-device (for example /dev/psaux) into your
-/etc/X11/XF86Config file (and similarly for the GPM
-configuration file).
-
-Alternatively, use the same technique used for unsupported drivers
-described above.
-
-The Kernel
-Finally, you need to make sure devfs is compiled into your kernel. Set
-CONFIG_EXPERIMENTAL=y, CONFIG_DEVFS_FS=y and CONFIG_DEVFS_MOUNT=y by
-using favourite configuration tool (i.e. make config or
-make xconfig) and then make clean and then recompile your kernel and 
-modules. At boot, devfs will be mounted onto /dev.
-
-If you encounter problems booting (for example if you forgot a
-configuration step), you can pass devfs=nomount at the kernel
-boot command line. This will prevent the kernel from mounting devfs at
-boot time onto /dev.
-
-In general, a kernel built with CONFIG_DEVFS_FS=y but without mounting
-devfs onto /dev is completely safe, and requires no
-configuration changes. One exception to take note of is when
-LABEL= directives are used in /etc/fstab. In this
-case you will be unable to boot properly. This is because the
-mount(8) programme uses /proc/partitions as part of
-the volume label search process, and the device names it finds are not
-available, because setting CONFIG_DEVFS_FS=y changes the names in
-/proc/partitions, irrespective of whether devfs is mounted.
-
-Now you've finished all the steps required. You're now ready to boot
-your shiny new kernel. Enjoy.
-
-Changing the configuration
-
-OK, you've now booted a devfs-enabled system, and everything works.
-Now you may feel like changing the configuration (common targets are
-/etc/fstab and /etc/devfsd.conf). Since you have a
-system that works, if you make any changes and it doesn't work, you
-now know that you only have to restore your configuration files to the
-default and it will work again.
-
-
-Permissions persistence across reboots
-
-If you don't use mknod(2) to create a device file, nor use chmod(2) or
-chown(2) to change the ownerships/permissions, the inode ctime will
-remain at 0 (the epoch, 12 am, 1-JAN-1970, GMT). Anything with a ctime
-later than this has had it's ownership/permissions changed. Hence, a
-simple script or programme may be used to tar up all changed inodes,
-prior to shutdown. Although effective, many consider this approach a
-kludge.
-
-A much better approach is to use devfsd to save and restore
-permissions. It may be configured to record changes in permissions and
-will save them in a database (in fact a directory tree), and restore
-these upon boot. This is an efficient method and results in immediate
-saving of current permissions (unlike the tar approach, which saves
-permissions at some unspecified future time).
-
-The default configuration file supplied with devfsd has config entries
-which you may uncomment to enable persistence management.
-
-If you decide to use the tar approach anyway, be aware that tar will
-first unlink(2) an inode before creating a new device node. The
-unlink(2) has the effect of breaking the connection between a devfs
-entry and the device driver. If you use the "devfs=only" boot option,
-you lose access to the device driver, requiring you to reload the
-module. I consider this a bug in tar (there is no real need to
-unlink(2) the inode first).
-
-Alternatively, you can use devfsd to provide more sophisticated
-management of device permissions. You can use devfsd to store
-permissions for whole groups of devices with a single configuration
-entry, rather than the conventional single entry per device entry.
-
-Permissions database stored in mounted-over /dev
-
-If you wish to save and restore your device permissions into the
-disc-based /dev while still mounting devfs onto /dev
-you may do so. This requires a 2.4.x kernel (in fact, 2.3.99 or
-later), which has the VFS binding facility. You need to do the
-following to set this up:
-
-
-
-make sure the kernel does not mount devfs at boot time
-
-
-make sure you have a correct /dev/console entry in your
-root file-system (where your disc-based /dev lives)
-
-create the /dev-state directory
-
-
-add the following lines near the very beginning of your boot
-scripts:
-
-mount --bind /dev /dev-state
-mount -t devfs none /dev
-devfsd /dev
-
-
-
-
-add the following lines to your /etc/devfsd.conf file:
-
-REGISTER       ^pt[sy]         IGNORE
-CREATE         ^pt[sy]         IGNORE
-CHANGE         ^pt[sy]         IGNORE
-DELETE         ^pt[sy]         IGNORE
-REGISTER       .*              COPY    /dev-state/$devname $devpath
-CREATE         .*              COPY    $devpath /dev-state/$devname
-CHANGE         .*              COPY    $devpath /dev-state/$devname
-DELETE         .*              CFUNCTION GLOBAL unlink /dev-state/$devname
-RESTORE                /dev-state
-
-Note that the sample devfsd.conf file contains these lines,
-as well as other sample configurations you may find useful. See the
-devfsd distribution
-
-
-reboot.
-
-
-
-
-Permissions database stored in normal directory
-
-If you are using an older kernel which doesn't support VFS binding,
-then you won't be able to have the permissions database in a
-mounted-over /dev. However, you can still use a regular
-directory to store the database. The sample /etc/devfsd.conf
-file above may still be used. You will need to create the
-/dev-state directory prior to installing devfsd. If you have
-old permissions in /dev, then just copy (or move) the device
-nodes over to the new directory.
-
-Which method is better?
-
-The best method is to have the permissions database stored in the
-mounted-over /dev. This is because you will not need to copy
-device nodes over to /dev-state, and because it allows you to
-switch between devfs and non-devfs kernels, without requiring you to
-copy permissions between /dev-state (for devfs) and
-/dev (for non-devfs).
-
-
-Dealing with drivers without devfs support
-
-Currently, not all device drivers in the kernel have been modified to
-use devfs. Device drivers which do not yet have devfs support will not
-automagically appear in devfs. The simplest way to create device nodes
-for these drivers is to unpack a tarfile containing the required
-device nodes. You can do this in your boot scripts. All your drivers
-will now work as before.
-
-Hopefully for most people devfs will have enough support so that they
-can mount devfs directly over /dev without losing most functionality
-(i.e. losing access to various devices). As of 22-JAN-1998 (devfs
-patch version 10) I am now running this way. All the devices I have
-are available in devfs, so I don't lose anything.
-
-WARNING: if your configuration requires the old-style device names
-(i.e. /dev/hda1 or /dev/sda1), you must install devfsd and configure
-it to maintain compatibility entries. It is almost certain that you
-will require this. Note that the kernel creates a compatibility entry
-for the root device, so you don't need initrd.
-
-Note that you no longer need to mount devpts if you use Unix98 PTYs,
-as devfs can manage /dev/pts itself. This saves you some RAM, as you
-don't need to compile and install devpts. Note that some versions of
-glibc have a bug with Unix98 pty handling on devfs systems. Contact
-the glibc maintainers for a fix. Glibc 2.1.3 has the fix.
-
-Note also that apart from editing /etc/fstab, other things will need
-to be changed if you *don't* install devfsd. Some software (like the X
-server) hard-wire device names in their source. It really is much
-easier to install devfsd so that compatibility entries are created.
-You can then slowly migrate your system to using the new device names
-(for example, by starting with /etc/fstab), and then limiting the
-compatibility entries that devfsd creates.
-
-IF YOU CONFIGURE TO MOUNT DEVFS AT BOOT, MAKE SURE YOU INSTALL DEVFSD
-BEFORE YOU BOOT A DEVFS-ENABLED KERNEL!
-
-Now that devfs has gone into the 2.3.46 kernel, I'm getting a lot of
-reports back. Many of these are because people are trying to run
-without devfsd, and hence some things break. Please just run devfsd if
-things break. I want to concentrate on real bugs rather than
-misconfiguration problems at the moment. If people are willing to fix
-bugs/false assumptions in other code (i.e. glibc, X server) and submit
-that to the respective maintainers, that would be great.
-
-
-All the way with Devfs
-
-The devfs kernel patch creates a rationalised device tree. As stated
-above, if you want to keep using the old /dev naming scheme,
-you just need to configure devfsd appopriately (see the man
-page). People who prefer the old names can ignore this section. For
-those of us who like the rationalised names and an uncluttered
-/dev, read on.
-
-If you don't run devfsd, or don't enable compatibility entry
-management, then you will have to configure your system to use the new
-names. For example, you will then need to edit your
-/etc/fstab to use the new disc naming scheme. If you want to
-be able to boot non-devfs kernels, you will need compatibility
-symlinks in the underlying disc-based /dev pointing back to
-the old-style names for when you boot a kernel without devfs.
-
-You can selectively decide which devices you want compatibility
-entries for. For example, you may only want compatibility entries for
-BSD pseudo-terminal devices (otherwise you'll have to patch you C
-library or use Unix98 ptys instead). It's just a matter of putting in
-the correct regular expression into /dev/devfsd.conf.
-
-There are other choices of naming schemes that you may prefer. For
-example, I don't use the kernel-supplied
-names, because they are too verbose. A common misconception is
-that the kernel-supplied names are meant to be used directly in
-configuration files. This is not the case. They are designed to
-reflect the layout of the devices attached and to provide easy
-classification.
-
-If you like the kernel-supplied names, that's fine. If you don't then
-you should be using devfsd to construct a namespace more to your
-liking. Devfsd has built-in code to construct a
-namespace that is both logical and easy to
-manage. In essence, it creates a convenient abbreviation of the
-kernel-supplied namespace.
-
-You are of course free to build your own namespace. Devfsd has all the
-infrastructure required to make this easy for you. All you need do is
-write a script. You can even write some C code and devfsd can load the
-shared object as a callable extension.
-
-
-Other Issues
-
-The init programme
-Another thing to take note of is whether your init programme
-creates a Unix socket /dev/telinit. Some versions of init
-create /dev/telinit so that the telinit programme can
-communicate with the init process. If you have such a system you need
-to make sure that devfs is mounted over /dev *before* init
-starts. In other words, you can't leave the mounting of devfs to
-/etc/rc, since this is executed after init. Other
-versions of init require a named pipe /dev/initctl
-which must exist *before* init starts. Once again, you need to
-mount devfs and then create the named pipe *before* init
-starts.
-
-The default behaviour now is not to mount devfs onto /dev at
-boot time for 2.3.x and later kernels. You can correct this with the
-"devfs=mount" boot option. This solves any problems with init,
-and also prevents the dreaded:
-
-Cannot open initial console
-
-message. For 2.2.x kernels where you need to apply the devfs patch,
-the default is to mount.
-
-If you have automatic mounting of devfs onto /dev then you
-may need to create /dev/initctl in your boot scripts. The
-following lines should suffice:
-
-mknod /dev/initctl p
-kill -SIGUSR1 1       # tell init that /dev/initctl now exists
-
-Alternatively, if you don't want the kernel to mount devfs onto
-/dev then you could use the following procedure is a
-guideline for how to get around /dev/initctl problems:
-
-# cd /sbin
-# mv init init.real
-# cat > init
-#! /bin/sh
-mount -n -t devfs none /dev
-mknod /dev/initctl p
-exec /sbin/init.real $*
-[control-D]
-# chmod a+x init
-
-Note that newer versions of init create /dev/initctl
-automatically, so you don't have to worry about this.
-
-Module autoloading
-You will need to configure devfsd to enable module
-autoloading. The following lines should be placed in your
-/etc/devfsd.conf file:
-
-LOOKUP .*              MODLOAD
-
-
-As of devfsd-v1.3.10, a generic /etc/modules.devfs
-configuration file is installed, which is used by the MODLOAD
-action. This should be sufficient for most configurations. If you
-require further configuration, edit your /etc/modules.conf
-file. The way module autoloading work with devfs is:
-
-
-a process attempts to lookup a device node (e.g. /dev/fred)
-
-
-if that device node does not exist, the full pathname is passed to
-devfsd as a string
-
-
-devfsd will pass the string to the modprobe programme (provided the
-configuration line shown above is present), and specifies that
-/etc/modules.devfs is the configuration file
-
-
-/etc/modules.devfs includes /etc/modules.conf to
-access local configurations
-
-modprobe will search it's configuration files, looking for an alias
-that translates the pathname into a module name
-
-
-the translated pathname is then used to load the module.
-
-
-If you wanted a lookup of /dev/fred to load the
-mymod module, you would require the following configuration
-line in /etc/modules.conf:
-
-alias    /dev/fred    mymod
-
-The /etc/modules.devfs configuration file provides many such
-aliases for standard device names. If you look closely at this file,
-you will note that some modules require multiple alias configuration
-lines. This is required to support module autoloading for old and new
-device names.
-
-Mounting root off a devfs device
-If you wish to mount root off a devfs device when you pass the
-"devfs=only" boot option, then you need to pass in the
-"root=<device>" option to the kernel when booting. If you use
-LILO, then you must have this in lilo.conf:
-
-append = "root=<device>"
-
-Surprised? Yep, so was I. It turns out if you have (as most people
-do):
-
-root = <device>
-
-
-then LILO will determine the device number of <device> and will
-write that device number into a special place in the kernel image
-before starting the kernel, and the kernel will use that device number
-to mount the root filesystem. So, using the "append" variety ensures
-that LILO passes the root filesystem device as a string, which devfs
-can then use.
-
-Note that this isn't an issue if you don't pass "devfs=only".
-
-TTY issues
-The ttyname(3) function in some versions of the C library makes
-false assumptions about device entries which are symbolic links.  The
-tty(1) programme is one that depends on this function.  I've
-written a patch to libc 5.4.43 which fixes this. This has been
-included in libc 5.4.44 and a similar fix is in glibc 2.1.3.
-
-
-Kernel Naming Scheme
-
-The kernel provides a default naming scheme. This scheme is designed
-to make it easy to search for specific devices or device types, and to
-view the available devices. Some device types (such as hard discs),
-have a directory of entries, making it easy to see what devices of
-that class are available. Often, the entries are symbolic links into a
-directory tree that reflects the topology of available devices. The
-topological tree is useful for finding how your devices are arranged.
-
-Below is a list of the naming schemes for the most common drivers. A
-list of reserved device names is
-available for reference. Please send email to
-rgooch@atnf.csiro.au to obtain an allocation. Please be
-patient (the maintainer is busy). An alternative name may be allocated
-instead of the requested name, at the discretion of the maintainer.
-
-Disc Devices
-
-All discs, whether SCSI, IDE or whatever, are placed under the
-/dev/discs hierarchy:
-
-       /dev/discs/disc0        first disc
-       /dev/discs/disc1        second disc
-
-
-Each of these entries is a symbolic link to the directory for that
-device. The device directory contains:
-
-       disc    for the whole disc
-       part*   for individual partitions
-
-
-CD-ROM Devices
-
-All CD-ROMs, whether SCSI, IDE or whatever, are placed under the
-/dev/cdroms hierarchy:
-
-       /dev/cdroms/cdrom0      first CD-ROM
-       /dev/cdroms/cdrom1      second CD-ROM
-
-
-Each of these entries is a symbolic link to the real device entry for
-that device.
-
-Tape Devices
-
-All tapes, whether SCSI, IDE or whatever, are placed under the
-/dev/tapes hierarchy:
-
-       /dev/tapes/tape0        first tape
-       /dev/tapes/tape1        second tape
-
-
-Each of these entries is a symbolic link to the directory for that
-device. The device directory contains:
-
-       mt                      for mode 0
-       mtl                     for mode 1
-       mtm                     for mode 2
-       mta                     for mode 3
-       mtn                     for mode 0, no rewind
-       mtln                    for mode 1, no rewind
-       mtmn                    for mode 2, no rewind
-       mtan                    for mode 3, no rewind
-
-
-SCSI Devices
-
-To uniquely identify any SCSI device requires the following
-information:
-
-  controller   (host adapter)
-  bus          (SCSI channel)
-  target       (SCSI ID)
-  unit         (Logical Unit Number)
-
-
-All SCSI devices are placed under /dev/scsi (assuming devfs
-is mounted on /dev). Hence, a SCSI device with the following
-parameters: c=1,b=2,t=3,u=4 would appear as:
-
-       /dev/scsi/host1/bus2/target3/lun4       device directory
-
-
-Inside this directory, a number of device entries may be created,
-depending on which SCSI device-type drivers were installed.
-
-See the section on the disc naming scheme to see what entries the SCSI
-disc driver creates.
-
-See the section on the tape naming scheme to see what entries the SCSI
-tape driver creates.
-
-The SCSI CD-ROM driver creates:
-
-       cd
-
-
-The SCSI generic driver creates:
-
-       generic
-
-
-IDE Devices
-
-To uniquely identify any IDE device requires the following
-information:
-
-  controller
-  bus          (aka. primary/secondary)
-  target       (aka. master/slave)
-  unit
-
-
-All IDE devices are placed under /dev/ide, and uses a similar
-naming scheme to the SCSI subsystem.
-
-XT Hard Discs
-
-All XT discs are placed under /dev/xd. The first XT disc has
-the directory /dev/xd/disc0.
-
-TTY devices
-
-The tty devices now appear as:
-
-  New name                   Old-name                   Device Type
-  --------                   --------                   -----------
-  /dev/tts/{0,1,...}         /dev/ttyS{0,1,...}         Serial ports
-  /dev/cua/{0,1,...}         /dev/cua{0,1,...}          Call out devices
-  /dev/vc/0                  /dev/tty                   Current virtual console
-  /dev/vc/{1,2,...}          /dev/tty{1...63}           Virtual consoles
-  /dev/vcc/{0,1,...}         /dev/vcs{1...63}           Virtual consoles
-  /dev/pty/m{0,1,...}        /dev/ptyp??                PTY masters
-  /dev/pty/s{0,1,...}        /dev/ttyp??                PTY slaves
-
-
-RAMDISCS
-
-The RAMDISCS are placed in their own directory, and are named thus:
-
-  /dev/rd/{0,1,2,...}
-
-
-Meta Devices
-
-The meta devices are placed in their own directory, and are named
-thus:
-
-  /dev/md/{0,1,2,...}
-
-
-Floppy discs
-
-Floppy discs are placed in the /dev/floppy directory.
-
-Loop devices
-
-Loop devices are placed in the /dev/loop directory.
-
-Sound devices
-
-Sound devices are placed in the /dev/sound directory
-(audio, sequencer, ...).
-
-
-Devfsd Naming Scheme
-
-Devfsd provides a naming scheme which is a convenient abbreviation of
-the kernel-supplied namespace. In some
-cases, the kernel-supplied naming scheme is quite convenient, so
-devfsd does not provide another naming scheme. The convenience names
-that devfsd creates are in fact the same names as the original devfs
-kernel patch created (before Linus mandated the Big Name
-Change). These are referred to as "new compatibility entries".
-
-In order to configure devfsd to create these convenience names, the
-following lines should be placed in your /etc/devfsd.conf:
-
-REGISTER       .*              MKNEWCOMPAT
-UNREGISTER     .*              RMNEWCOMPAT
-
-This will cause devfsd to create (and destroy) symbolic links which
-point to the kernel-supplied names.
-
-SCSI Hard Discs
-
-All SCSI discs are placed under /dev/sd (assuming devfs is
-mounted on /dev). Hence, a SCSI disc with the following
-parameters: c=1,b=2,t=3,u=4 would appear as:
-
-       /dev/sd/c1b2t3u4        for the whole disc
-       /dev/sd/c1b2t3u4p5      for the 5th partition
-       /dev/sd/c1b2t3u4p5s6    for the 6th slice in the 5th partition
-
-
-SCSI Tapes
-
-All SCSI tapes are placed under /dev/st. A similar naming
-scheme is used as for SCSI discs. A SCSI tape with the
-parameters:c=1,b=2,t=3,u=4 would appear as:
-
-       /dev/st/c1b2t3u4m0      for mode 0
-       /dev/st/c1b2t3u4m1      for mode 1
-       /dev/st/c1b2t3u4m2      for mode 2
-       /dev/st/c1b2t3u4m3      for mode 3
-       /dev/st/c1b2t3u4m0n     for mode 0, no rewind
-       /dev/st/c1b2t3u4m1n     for mode 1, no rewind
-       /dev/st/c1b2t3u4m2n     for mode 2, no rewind
-       /dev/st/c1b2t3u4m3n     for mode 3, no rewind
-
-
-SCSI CD-ROMs
-
-All SCSI CD-ROMs are placed under /dev/sr. A similar naming
-scheme is used as for SCSI discs. A SCSI CD-ROM with the
-parameters:c=1,b=2,t=3,u=4 would appear as:
-
-       /dev/sr/c1b2t3u4
-
-
-SCSI Generic Devices
-
-The generic (aka. raw) interface for all SCSI devices are placed under
-/dev/sg. A similar naming scheme is used as for SCSI discs. A
-SCSI generic device with the parameters:c=1,b=2,t=3,u=4 would appear
-as:
-
-       /dev/sg/c1b2t3u4
-
-
-IDE Hard Discs
-
-All IDE discs are placed under /dev/ide/hd, using a similar
-convention to SCSI discs. The following mappings exist between the new
-and the old names:
-
-       /dev/hda        /dev/ide/hd/c0b0t0u0
-       /dev/hdb        /dev/ide/hd/c0b0t1u0
-       /dev/hdc        /dev/ide/hd/c0b1t0u0
-       /dev/hdd        /dev/ide/hd/c0b1t1u0
-
-
-IDE Tapes
-
-A similar naming scheme is used as for IDE discs. The entries will
-appear in the /dev/ide/mt directory.
-
-IDE CD-ROM
-
-A similar naming scheme is used as for IDE discs. The entries will
-appear in the /dev/ide/cd directory.
-
-IDE Floppies
-
-A similar naming scheme is used as for IDE discs. The entries will
-appear in the /dev/ide/fd directory.
-
-XT Hard Discs
-
-All XT discs are placed under /dev/xd. The first XT disc
-would appear as /dev/xd/c0t0.
-
-
-Old Compatibility Names
-
-The old compatibility names are the legacy device names, such as
-/dev/hda, /dev/sda, /dev/rtc and so on.
-Devfsd can be configured to create compatibility symlinks so that you
-may continue to use the old names in your configuration files and so
-that old applications will continue to function correctly.
-
-In order to configure devfsd to create these legacy names, the
-following lines should be placed in your /etc/devfsd.conf:
-
-REGISTER       .*              MKOLDCOMPAT
-UNREGISTER     .*              RMOLDCOMPAT
-
-This will cause devfsd to create (and destroy) symbolic links which
-point to the kernel-supplied names.
-
-
------------------------------------------------------------------------------
-
-
-Device drivers currently ported
-
-- All miscellaneous character devices support devfs (this is done
-  transparently through misc_register())
-
-- SCSI discs and generic hard discs
-
-- Character memory devices (null, zero, full and so on)
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- Loop devices (/dev/loop?)
-- TTY devices (console, serial ports, terminals and pseudo-terminals)
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- SCSI tapes (/dev/scsi and /dev/tapes)
-
-- SCSI CD-ROMs (/dev/scsi and /dev/cdroms)
-
-- SCSI generic devices (/dev/scsi)
-
-- RAMDISCS (/dev/ram?)
-
-- Meta Devices (/dev/md*)
-
-- Floppy discs (/dev/floppy)
-
-- Parallel port printers (/dev/printers)
-
-- Sound devices (/dev/sound)
-  Thanks to Eric Dumas <dumas@linux.eu.org> and
-  C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- Joysticks (/dev/joysticks)
-
-- Sparc keyboard (/dev/kbd)
-
-- DSP56001 digital signal processor (/dev/dsp56k)
-
-- Apple Desktop Bus (/dev/adb)
-
-- Coda network file system (/dev/cfs*)
-
-- Virtual console capture devices (/dev/vcc)
-  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
-
-- Frame buffer devices (/dev/fb)
-
-- Video capture devices (/dev/v4l)
-
-
------------------------------------------------------------------------------
-
-
-Allocation of Device Numbers
-
-Devfs allows you to write a driver which doesn't need to allocate a
-device number (major&minor numbers) for the internal operation of the
-kernel. However, there are a number of userspace programmes that use
-the device number as a unique handle for a device. An example is the
-find programme, which uses device numbers to determine whether
-an inode is on a different filesystem than another inode. The device
-number used is the one for the block device which a filesystem is
-using. To preserve compatibility with userspace programmes, block
-devices using devfs need to have unique device numbers allocated to
-them. Furthermore, POSIX specifies device numbers, so some kind of
-device number needs to be presented to userspace.
-
-The simplest option (especially when porting drivers to devfs) is to
-keep using the old major and minor numbers. Devfs will take whatever
-values are given for major&minor and pass them onto userspace.
-
-This device number is a 16 bit number, so this leaves plenty of space
-for large numbers of discs and partitions. This scheme can also be
-used for character devices, in particular the tty devices, which are
-currently limited to 256 pseudo-ttys (this limits the total number of
-simultaneous xterms and remote logins).  Note that the device number
-is limited to the range 36864-61439 (majors 144-239), in order to
-avoid any possible conflicts with existing official allocations.
-
-Please note that using dynamically allocated block device numbers may
-break the NFS daemons (both user and kernel mode), which expect dev_t
-for a given device to be constant over the lifetime of remote mounts.
-
-A final note on this scheme: since it doesn't increase the size of
-device numbers, there are no compatibility issues with userspace.
-
------------------------------------------------------------------------------
-
-
-Questions and Answers
-
-
-Making things work
-Alternatives to devfs
-What I don't like about devfs
-How to report bugs
-Strange kernel messages
-Compilation problems with devfsd
-
-
-
-Making things work
-
-Here are some common questions and answers.
-
-
-
-Devfsd doesn't start
-
-Make sure you have compiled and installed devfsd
-Make sure devfsd is being started from your boot
-scripts
-Make sure you have configured your kernel to enable devfs (see
-below)
-Make sure devfs is mounted (see below)
-
-
-Devfsd is not managing all my permissions
-
-Make sure you are capturing the appropriate events. For example,
-device entries created by the kernel generate REGISTER events,
-but those created by devfsd generate CREATE events.
-
-
-Devfsd is not capturing all REGISTER events
-
-See the previous entry: you may need to capture CREATE events.
-
-
-X will not start
-
-Make sure you followed the steps 
-outlined above.
-
-
-Why don't my network devices appear in devfs?
-
-This is not a bug. Network devices have their own, completely separate
-namespace. They are accessed via socket(2) and
-setsockopt(2) calls, and thus require no device nodes. I have
-raised the possibilty of moving network devices into the device
-namespace, but have had no response.
-
-
-How can I test if I have devfs compiled into my kernel?
-
-All filesystems built-in or currently loaded are listed in
-/proc/filesystems. If you see a devfs entry, then
-you know that devfs was compiled into your kernel. If you have
-correctly configured and rebuilt your kernel, then devfs will be
-built-in. If you think you've configured it in, but
-/proc/filesystems doesn't show it, you've made a mistake.
-Common mistakes include:
-
-Using a 2.2.x kernel without applying the devfs patch (if you
-don't know how to patch your kernel, use 2.4.x instead, don't bother
-asking me how to patch)
-Forgetting to set CONFIG_EXPERIMENTAL=y
-Forgetting to set CONFIG_DEVFS_FS=y
-Forgetting to set CONFIG_DEVFS_MOUNT=y (if you want devfs
-to be automatically mounted at boot)
-Editing your .config manually, instead of using make
-config or make xconfig
-Forgetting to run make dep; make clean after changing the
-configuration and before compiling
-Forgetting to compile your kernel and modules
-Forgetting to install your kernel
-Forgetting to install your modules
-
-Please check twice that you've done all these steps before sending in
-a bug report.
-
-
-
-How can I test if devfs is mounted on /dev?
-
-The device filesystem will always create an entry called
-".devfsd", which is used to communicate with the daemon. Even
-if the daemon is not running, this entry will exist. Testing for the
-existence of this entry is the approved method of determining if devfs
-is mounted or not. Note that the type of entry (i.e. regular file,
-character device, named pipe, etc.) may change without notice. Only
-the existence of the entry should be relied upon.
-
-
-When I start devfsd, I see the error:
-Error opening file: ".devfsd"   No such file or directory?
-
-This means that devfs is not mounted. Make sure you have devfs mounted.
-
-
-How do I mount devfs?
-
-First make sure you have devfs compiled into your kernel (see
-above). Then you will either need to:
-
-set CONFIG_DEVFS_MOUNT=y in your kernel config
-pass devfs=mount to your boot loader
-mount devfs manually in your boot scripts with:
-mount -t none devfs /dev
-
-
-
-Mount by volume LABEL=<label> doesn't work with
-devfs
-
-Most probably you are not mounting devfs onto /dev. What
-happens is that if your kernel config has CONFIG_DEVFS_FS=y
-then the contents of /proc/partitions will have the devfs
-names (such as scsi/host0/bus0/target0/lun0/part1). The
-contents of /proc/partitions are used by mount(8) when
-mounting by volume label. If devfs is not mounted on /dev,
-then mount(8) will fail to find devices. The solution is to
-make sure that devfs is mounted on /dev. See above for how to
-do that.
-
-
-I have extra or incorrect entries in /dev
-
-You may have stale entries in your dev-state area. Check for a
-RESTORE configuration line in your devfsd configuration
-(typically /etc/devfsd.conf). If you have this line, check
-the contents of the specified directory for stale entries. Remove
-any entries which are incorrect, then reboot.
-
-
-I get "Unable to open initial console" messages at boot
-
-This usually happens when you don't have devfs automounted onto
-/dev at boot time, and there is no valid
-/dev/console entry on your root file-system. Create a valid
-/dev/console device node.
-
-
-
-
-
-Alternatives to devfs
-
-I've attempted to collate all the anti-devfs proposals and explain
-their limitations. Under construction.
-
-
-Why not just pass device create/remove events to a daemon?
-
-Here the suggestion is to develop an API in the kernel so that devices
-can register create and remove events, and a daemon listens for those
-events. The daemon would then populate/depopulate /dev (which
-resides on disc).
-
-This has several limitations:
-
-
-it only works for modules loaded and unloaded (or devices inserted
-and removed) after the kernel has finished booting. Without a database
-of events, there is no way the daemon could fully populate
-/dev
-
-
-if you add a database to this scheme, the question is then how to
-present that database to user-space. If you make it a list of strings
-with embedded event codes which are passed through a pipe to the
-daemon, then this is only of use to the daemon. I would argue that the
-natural way to present this data is via a filesystem (since many of
-the events will be of a hierarchical nature), such as devfs.
-Presenting the data as a filesystem makes it easy for the user to see
-what is available and also makes it easy to write scripts to scan the
-"database"
-
-
-the tight binding between device nodes and drivers is no longer
-possible (requiring the otherwise perfectly avoidable
-table lookups)
-
-
-you cannot catch inode lookup events on /dev which means
-that module autoloading requires device nodes to be created. This is a
-problem, particularly for drivers where only a few inodes are created
-from a potentially large set
-
-
-this technique can't be used when the root FS is mounted
-read-only
-
-
-
-
-Just implement a better scsidev
-
-This suggestion involves taking the scsidev programme and
-extending it to scan for all devices, not just SCSI devices. The
-scsidev programme works by scanning /proc/scsi
-
-Problems:
-
-
-the kernel does not currently provide a list of all devices
-available. Not all drivers register entries in /proc or
-generate kernel messages
-
-
-there is no uniform mechanism to register devices other than the
-devfs API
-
-
-implementing such an API is then the same as the
-proposal above
-
-
-
-
-Put /dev on a ramdisc
-
-This suggestion involves creating a ramdisc and populating it with
-device nodes and then mounting it over /dev.
-
-Problems:
-
-
-
-this doesn't help when mounting the root filesystem, since you
-still need a device node to do that
-
-
-if you want to use this technique for the root device node as
-well, you need to use initrd. This complicates the booting sequence
-and makes it significantly harder to administer and configure. The
-initrd is essentially opaque, robbing the system administrator of easy
-configuration
-
-
-insufficient information is available to correctly populate the
-ramdisc. So we come back to the
-proposal above to "solve" this
-
-
-a ramdisc-based solution would take more kernel memory, since the
-backing store would be (at best) normal VFS inodes and dentries, which
-take 284 bytes and 112 bytes, respectively, for each entry. Compare
-that to 72 bytes for devfs
-
-
-
-
-Do nothing: there's no problem
-
-Sometimes people can be heard to claim that the existing scheme is
-fine. This is what they're ignoring:
-
-
-device number size (8 bits each for major and minor) is a real
-limitation, and must be fixed somehow. Systems with large numbers of
-SCSI devices, for example, will continue to consume the remaining
-unallocated major numbers. USB will also need to push beyond the 8 bit
-minor limitation
-
-
-simply increasing the device number size is insufficient. Apart
-from causing a lot of pain, it doesn't solve the management issues
-of a /dev with thousands or more device nodes
-
-
-ignoring the problem of a huge /dev will not make it go
-away, and dismisses the legitimacy of a large number of people who
-want a dynamic /dev
-
-
-the standard response then becomes: "write a device management
-daemon", which brings us back to the
-proposal above
-
-
-
-
-What I don't like about devfs
-
-Here are some common complaints about devfs, and some suggestions and
-solutions that may make it more palatable for you. I can't please
-everybody, but I do try :-)
-
-I hate the naming scheme
-
-First, remember that no naming scheme will please everybody. You hate
-the scheme, others love it. Who's to say who's right and who's wrong?
-Ultimately, the person who writes the code gets to choose, and what
-exists now is a combination of the choices made by the
-devfs author and the
-kernel maintainer (Linus).
-
-However, not all is lost. If you want to create your own naming
-scheme, it is a simple matter to write a standalone script, hack
-devfsd, or write a script called by devfsd. You can create whatever
-naming scheme you like.
-
-Further, if you want to remove all traces of the devfs naming scheme
-from /dev, you can mount devfs elsewhere (say
-/devfs) and populate /dev with links into
-/devfs. This population can be automated using devfsd if you
-wish.
-
-You can even use the VFS binding facility to make the links, rather
-than using symbolic links. This way, you don't even have to see the
-"destination" of these symbolic links.
-
-Devfs puts policy into the kernel
-
-There's already policy in the kernel. Device numbers are in fact
-policy (why should the kernel dictate what device numbers I use?).
-Face it, some policy has to be in the kernel. The real difference
-between device names as policy and device numbers as policy is that
-no one will use device numbers directly, because device
-numbers are devoid of meaning to humans and are ugly. At least with
-the devfs device names, (even though you can add your own naming
-scheme) some people will use the devfs-supplied names directly. This
-offends some people :-)
-
-Devfs is bloatware
-
-This is not even remotely true. As shown above,
-both code and data size are quite modest.
-
-
-How to report bugs
-
-If you have (or think you have) a bug with devfs, please follow the
-steps below:
-
-
-
-make sure you have enabled debugging output when configuring your
-kernel. You will need to set (at least) the following config options:
-
-CONFIG_DEVFS_DEBUG=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SLAB=y
-
-
-
-please make sure you have the latest devfs patches applied. The
-latest kernel version might not have the latest devfs patches applied
-yet (Linus is very busy)
-
-
-save a copy of your complete kernel logs (preferably by
-using the dmesg programme) for later inclusion in your bug
-report. You may need to use the -s switch to increase the
-internal buffer size so you can capture all the boot messages.
-Don't edit or trim the dmesg output
-
-
-
-
-try booting with devfs=dall passed to the kernel boot
-command line (read the documentation on your bootloader on how to do
-this), and save the result to a file. This may be quite verbose, and
-it may overflow the messages buffer, but try to get as much of it as
-you can
-
-
-send a copy of your devfsd configuration file(s)
-
-send the bug report to me first.
-Don't expect that I will see it if you post it to the linux-kernel
-mailing list. Include all the information listed above, plus
-anything else that you think might be relevant. Put the string
-devfs somewhere in the subject line, so my mail filters mark
-it as urgent
-
-
-
-
-Here is a general guide on how to ask questions in a way that greatly
-improves your chances of getting a reply:
-
-http://www.tuxedo.org/~esr/faqs/smart-questions.html. If you have
-a bug to report, you should also read
-
-http://www.chiark.greenend.org.uk/~sgtatham/bugs.html.
-
-
-Strange kernel messages
-
-You may see devfs-related messages in your kernel logs. Below are some
-messages and what they mean (and what you should do about them, if
-anything).
-
-
-
-devfs_register(fred): could not append to parent, err: -17
-
-You need to check what the error code means, but usually 17 means
-EEXIST. This means that a driver attempted to create an entry
-fred in a directory, but there already was an entry with that
-name. This is often caused by flawed boot scripts which untar a bunch
-of inodes into /dev, as a way to restore permissions. This
-message is harmless, as the device nodes will still
-provide access to the driver (unless you use the devfs=only
-boot option, which is only for dedicated souls:-). If you want to get
-rid of these annoying messages, upgrade to devfsd-v1.3.20 and use the
-recommended RESTORE directive to restore permissions.
-
-
-devfs_mk_dir(bill): using old entry in dir: c1808724 ""
-
-This is similar to the message above, except that a driver attempted
-to create a directory named bill, and the parent directory
-has an entry with the same name. In this case, to ensure that drivers
-continue to work properly, the old entry is re-used and given to the
-driver. In 2.5 kernels, the driver is given a NULL entry, and thus,
-under rare circumstances, may not create the require device nodes.
-The solution is the same as above.
-
-
-
-
-
-Compilation problems with devfsd
-
-Usually, you can compile devfsd just by typing in
-make in the source directory, followed by a make
-install (as root). Sometimes, you may have problems, particularly
-on broken configurations.
-
-
-
-error messages relating to DEVFSD_NOTIFY_DELETE
-
-This happened because you have an ancient set of kernel headers
-installed in /usr/include/linux or /usr/src/linux.
-Install kernel 2.4.10 or later. You may need to pass the
-KERNEL_DIR variable to make (if you did not install
-the new kernel sources as /usr/src/linux), or you may copy
-the devfs_fs.h file in the kernel source tree into
-/usr/include/linux.
-
-
-
-
------------------------------------------------------------------------------
-
-
-Other resources
-
-
-
-Douglas Gilbert has written a useful document at
-
-http://www.torque.net/sg/devfs_scsi.html which
-explores the SCSI subsystem and how it interacts with devfs
-
-
-Douglas Gilbert has written another useful document at
-
-http://www.torque.net/scsi/SCSI-2.4-HOWTO/ which
-discusses the Linux SCSI subsystem in 2.4.
-
-
-Johannes Erdfelt has started a discussion paper on Linux and
-hot-swap devices, describing what the requirements are for a scalable
-solution and how and why he's used devfs+devfsd. Note that this is an
-early draft only, available in plain text form at:
-
-http://johannes.erdfelt.com/hotswap.txt.
-Johannes has promised a HTML version will follow.
-
-
-I presented an invited 
-paper
-at the
-
-2nd Annual Storage Management Workshop held in Miamia, Florida,
-U.S.A. in October 2000.
-
-
-
-
------------------------------------------------------------------------------
-
-
-Translations of this document
-
-This document has been translated into other languages.
-
-
-
-
-The document master (in English) by rgooch@atnf.csiro.au is
-available at
-
-http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html
-
-
-
-A Korean translation by viatoris@nownuri.net is available at
-
-http://your.destiny.pe.kr/devfs/devfs.html
-
-
-
-
------------------------------------------------------------------------------
-Most flags courtesy of ITA's 
-Flags of All Countries
-used with permission. 
diff --git a/Documentation/filesystems/devfs/ToDo b/Documentation/filesystems/devfs/ToDo
deleted file mode 100644 (file)
index afd5a8f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-               Device File System (devfs) ToDo List
-
-               Richard Gooch <rgooch@atnf.csiro.au>
-
-                             3-JUL-2000
-
-This is a list of things to be done for better devfs support in the
-Linux kernel. If you'd like to contribute to the devfs, please have a
-look at this list for anything that is unallocated. Also, if there are
-items missing (surely), please contact me so I can add them to the
-list (preferably with your name attached to them:-).
-
-
-- >256 ptys
-  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
-
-- Amiga floppy driver (drivers/block/amiflop.c)
-
-- Atari floppy driver (drivers/block/ataflop.c)
-
-- SWIM3 (Super Woz Integrated Machine 3) floppy driver (drivers/block/swim3.c)
-
-- Amiga ZorroII ramdisc driver (drivers/block/z2ram.c)
-
-- Parallel port ATAPI CD-ROM (drivers/block/paride/pcd.c)
-
-- Parallel port ATAPI floppy (drivers/block/paride/pf.c)
-
-- AP1000 block driver (drivers/ap1000/ap.c, drivers/ap1000/ddv.c)
-
-- Archimedes floppy (drivers/acorn/block/fd1772.c)
-
-- MFM hard drive (drivers/acorn/block/mfmhd.c)
-
-- I2O block device (drivers/message/i2o/i2o_block.c)
-
-- ST-RAM device (arch/m68k/atari/stram.c)
-
-- Raw devices
-
diff --git a/Documentation/filesystems/devfs/boot-options b/Documentation/filesystems/devfs/boot-options
deleted file mode 100644 (file)
index df3d33b..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- auto-fill -*-                                                         */
-
-               Device File System (devfs) Boot Options
-
-               Richard Gooch <rgooch@atnf.csiro.au>
-
-                             18-AUG-2001
-
-
-When CONFIG_DEVFS_DEBUG is enabled, you can pass several boot options
-to the kernel to debug devfs. The boot options are prefixed by
-"devfs=", and are separated by commas. Spaces are not allowed. The
-syntax looks like this:
-
-devfs=<option1>,<option2>,<option3>
-
-and so on. For example, if you wanted to turn on debugging for module
-load requests and device registration, you would do:
-
-devfs=dmod,dreg
-
-You may prefix "no" to any option. This will invert the option.
-
-
-Debugging Options
-=================
-
-These requires CONFIG_DEVFS_DEBUG to be enabled.
-Note that all debugging options have 'd' as the first character. By
-default all options are off. All debugging output is sent to the
-kernel logs. The debugging options do not take effect until the devfs
-version message appears (just prior to the root filesystem being
-mounted).
-
-These are the options:
-
-dmod           print module load requests to <request_module>
-
-dreg           print device register requests to <devfs_register>
-
-dunreg         print device unregister requests to <devfs_unregister>
-
-dchange                print device change requests to <devfs_set_flags>
-
-dilookup       print inode lookup requests
-
-diget          print VFS inode allocations
-
-diunlink       print inode unlinks
-
-dichange       print inode changes
-
-dimknod                print calls to mknod(2)
-
-dall           some debugging turned on
-
-
-Other Options
-=============
-
-These control the default behaviour of devfs. The options are:
-
-mount          mount devfs onto /dev at boot time
-
-only           disable non-devfs device nodes for devfs-capable drivers
index 7de1c80cd719fb69446b464f6dfe310e4024788c..b1b6440237a6ef82fa367fdc4560e7b6d3590eb2 100644 (file)
@@ -67,8 +67,7 @@ initrd adds the following new options:
     as the last process has closed it, all data is freed and /dev/initrd
     can't be opened anymore.
 
-  root=/dev/ram0   (without devfs)
-  root=/dev/rd/0   (with devfs)
+  root=/dev/ram0
 
     initrd is mounted as root, and the normal boot procedure is followed,
     with the RAM disk still mounted as root.
@@ -90,8 +89,7 @@ you're building an install floppy), the root file system creation
 procedure should create the /initrd directory.
 
 If initrd will not be mounted in some cases, its content is still
-accessible if the following device has been created (note that this
-does not work if using devfs):
+accessible if the following device has been created:
 
 # mknod /dev/initrd b 1 250 
 # chmod 400 /dev/initrd
@@ -119,8 +117,7 @@ We'll describe the loopback device method:
     (if space is critical, you may want to use the Minix FS instead of Ext2)
  3) mount the file system, e.g.
     # mount -t ext2 -o loop initrd /mnt
- 4) create the console device (not necessary if using devfs, but it can't
-    hurt to do it anyway):
+ 4) create the console device:
     # mkdir /mnt/dev
     # mknod /mnt/dev/console c 5 1
  5) copy all the files that are needed to properly use the initrd
@@ -152,12 +149,7 @@ have to be given:
 
   root=/dev/ram0 init=/linuxrc rw
 
-if not using devfs, or
-
-  root=/dev/rd/0 init=/linuxrc rw
-
-if using devfs. (rw is only necessary if writing to the initrd file
-system.)
+(rw is only necessary if writing to the initrd file system.)
 
 With LOADLIN, you simply execute
 
@@ -217,9 +209,9 @@ following command:
 # exec chroot . what-follows <dev/console >dev/console 2>&1
 
 Where what-follows is a program under the new root, e.g. /sbin/init
-If the new root file system will be used with devfs and has no valid
-/dev directory, devfs must be mounted before invoking chroot in order to
-provide /dev/console.
+If the new root file system will be used with udev and has no valid
+/dev directory, udev must be initialized before invoking chroot in order
+to provide /dev/console.
 
 Note: implementation details of pivot_root may change with time. In order
 to ensure compatibility, the following points should be observed:
@@ -236,7 +228,7 @@ Now, the initrd can be unmounted and the memory allocated by the RAM
 disk can be freed:
 
 # umount /initrd
-# blockdev --flushbufs /dev/ram0    # /dev/rd/0 if using devfs
+# blockdev --flushbufs /dev/ram0
 
 It is also possible to use initrd with an NFS-mounted root, see the
 pivot_root(8) man page for details.
index 1543802ef53ec8f5ee434fe6c6a63b443e741103..edc04d74ae239e35308081415ea19cd7de9304bf 100644 (file)
@@ -119,7 +119,6 @@ Code        Seq#    Include File            Comments
 'c'    00-7F   linux/comstats.h        conflict!
 'c'    00-7F   linux/coda.h            conflict!
 'd'    00-FF   linux/char/drm/drm/h    conflict!
-'d'    00-1F   linux/devfs_fs.h        conflict!
 'd'    00-DF   linux/video_decoder.h   conflict!
 'd'    F0-FF   linux/digi1.h
 'e'    all     linux/digi1.h           conflict!
index 25f8d20dac534f07a0bf285feb35de115e2ac514..86e9282d1c20053058ef1525b259d2645dd99ad3 100644 (file)
@@ -35,7 +35,6 @@ parameter is applicable:
        APM     Advanced Power Management support is enabled.
        AX25    Appropriate AX.25 support is enabled.
        CD      Appropriate CD support is enabled.
-       DEVFS   devfs support is enabled.
        DRM     Direct Rendering Management support is enabled.
        EDD     BIOS Enhanced Disk Drive Services (EDD) is enabled
        EFI     EFI Partitioning (GPT) is enabled
@@ -440,9 +439,6 @@ running once the system is up.
                        Format: <area>[,<node>]
                        See also Documentation/networking/decnet.txt.
 
-       devfs=          [DEVFS]
-                       See Documentation/filesystems/devfs/boot-options.
-
        dhash_entries=  [KNL]
                        Set number of hash buckets for dentry cache.
 
index f3a85b77c17e1c5b68596cf47d6e77587bfaa1bd..dde813e16294ddedf7b1a25264a3f2001c0c8834 100644 (file)
@@ -541,7 +541,7 @@ init_dummy_console(void)
        dummy_driver.init_termios = tty_std_termios;
        dummy_driver.init_termios.c_cflag =
                B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
-       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 
        dummy_driver.open = dummy_open;
        dummy_driver.close = dummy_close;
index ffc1ebf2dfee30b4a3b4ceb039236e4fea58d079..3dc587e6201aee865c762fa71a1807f5dffcd3d3 100644 (file)
@@ -353,7 +353,7 @@ init_dummy_console(void)
        dummy_driver.init_termios = tty_std_termios;
        dummy_driver.init_termios.c_cflag =
                B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
-       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 
        dummy_driver.open = dummy_open;
        dummy_driver.close = dummy_close;
index 0a865889b2a993ccfe409dbfd219a262a295dffc..40b44cc0d14b048523f8bbf0c6935342a6067e3e 100644 (file)
@@ -493,7 +493,6 @@ static struct file_operations microcode_fops = {
 static struct miscdevice microcode_dev = {
        .minor          = MICROCODE_MINOR,
        .name           = "microcode",
-       .devfs_name     = "cpu/microcode",
        .fops           = &microcode_fops,
 };
 
index 98b25fa0049a2cbf561bee7400046f23b7976c1a..1e113d0f59b8e3cbfa760f1aec1734c4b530c313 100644 (file)
@@ -1758,7 +1758,7 @@ int __init siccuart_init(void)
     siccnormal_driver->subtype = SERIAL_TYPE_NORMAL;
     siccnormal_driver->init_termios = tty_std_termios;
     siccnormal_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-    siccnormal_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+    siccnormal_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
     tty_set_operations(siccnormal_driver, &sicc_ops);
 
     if (tty_register_driver(siccnormal_driver))
index 8437ea7430fe061cec70510f9f0f0bb66d2e5fb1..83a4f91bce5aefab58cfdbd06e6c27f438ac2161 100644 (file)
@@ -417,7 +417,6 @@ static struct file_operations sq_fops = {
 static struct miscdevice sq_dev = {
        .minor          = STORE_QUEUE_MINOR,
        .name           = "sq",
-       .devfs_name     = "cpu/sq",
        .fops           = &sq_fops,
 };
 
index 79d177149fdb351825c750559a05a0f4b92b4094..8654b446ac9ede55439c4639158d296213ae3c2e 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -40,6 +41,7 @@
 #include <asm/vaddrs.h>
 #include <asm/oplib.h>
 #include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/sbus.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
@@ -143,6 +145,21 @@ void __iomem *sbus_ioremap(struct resource *phyres, unsigned long offset,
            phyres->start + offset, size, name);
 }
 
+void __iomem *of_ioremap(struct resource *res, unsigned long offset,
+                        unsigned long size, char *name)
+{
+       return _sparc_alloc_io(res->flags & 0xF,
+                              res->start + offset,
+                              size, name);
+}
+EXPORT_SYMBOL(of_ioremap);
+
+void of_iounmap(void __iomem *base, unsigned long size)
+{
+       iounmap(base);
+}
+EXPORT_SYMBOL(of_iounmap);
+
 /*
  */
 void sbus_iounmap(volatile void __iomem *addr, unsigned long size)
index 80a809478781845ecba6962b7f7b1ce534b8d0c2..bc956c5303764ccc1d4bdd87d271d4044aedff77 100644 (file)
@@ -129,6 +129,26 @@ static int of_device_resume(struct device * dev)
        return error;
 }
 
+static int node_match(struct device *dev, void *data)
+{
+       struct of_device *op = to_of_device(dev);
+       struct device_node *dp = data;
+
+       return (op->node == dp);
+}
+
+struct of_device *of_find_device_by_node(struct device_node *dp)
+{
+       struct device *dev = bus_find_device(&of_bus_type, NULL,
+                                            dp, node_match);
+
+       if (dev)
+               return to_of_device(dev);
+
+       return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
 #ifdef CONFIG_PCI
 struct bus_type ebus_bus_type = {
        .name   = "ebus",
@@ -153,10 +173,459 @@ struct bus_type sbus_bus_type = {
 EXPORT_SYMBOL(sbus_bus_type);
 #endif
 
+struct bus_type of_bus_type = {
+       .name   = "of",
+       .match  = of_platform_bus_match,
+       .probe  = of_device_probe,
+       .remove = of_device_remove,
+       .suspend        = of_device_suspend,
+       .resume = of_device_resume,
+};
+EXPORT_SYMBOL(of_bus_type);
+
+static inline u64 of_read_addr(u32 *cell, int size)
+{
+       u64 r = 0;
+       while (size--)
+               r = (r << 32) | *(cell++);
+       return r;
+}
+
+static void __init get_cells(struct device_node *dp,
+                            int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = of_n_addr_cells(dp);
+       if (sizec)
+               *sizec = of_n_size_cells(dp);
+}
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS      4
+
+struct of_bus {
+       const char      *name;
+       const char      *addr_prop_name;
+       int             (*match)(struct device_node *parent);
+       void            (*count_cells)(struct device_node *child,
+                                      int *addrc, int *sizec);
+       u64             (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
+       int             (*translate)(u32 *addr, u64 offset, int na);
+       unsigned int    (*get_flags)(u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+                                      int *addrc, int *sizec)
+{
+       get_cells(dev, addrc, sizec);
+}
+
+static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       cp = of_read_addr(range, na);
+       s  = of_read_addr(range + na + pna, ns);
+       da = of_read_addr(addr, na);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+       u64 a = of_read_addr(addr, na);
+       memset(addr, 0, na * 4);
+       a += offset;
+       if (na > 1)
+               addr[na - 2] = a >> 32;
+       addr[na - 1] = a & 0xffffffffu;
+
+       return 0;
+}
+
+static unsigned int of_bus_default_get_flags(u32 *addr)
+{
+       return IORESOURCE_MEM;
+}
+
+
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+       return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 3;
+       if (sizec)
+               *sizec = 2;
+}
+
+static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       /* Check address type match */
+       if ((addr[0] ^ range[0]) & 0x03000000)
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_addr(range + 1, na - 1);
+       s  = of_read_addr(range + na + pna, ns);
+       da = of_read_addr(addr + 1, na - 1);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_pci_get_flags(u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       switch((w >> 24) & 0x03) {
+       case 0x01:
+               flags |= IORESOURCE_IO;
+       case 0x02: /* 32 bits */
+       case 0x03: /* 64 bits */
+               flags |= IORESOURCE_MEM;
+       }
+       if (w & 0x40000000)
+               flags |= IORESOURCE_PREFETCH;
+       return flags;
+}
+
+/*
+ * SBUS bus specific translator
+ */
+
+static int of_bus_sbus_match(struct device_node *np)
+{
+       return !strcmp(np->name, "sbus") ||
+               !strcmp(np->name, "sbi");
+}
+
+static void of_bus_sbus_count_cells(struct device_node *child,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 2;
+       if (sizec)
+               *sizec = 1;
+}
+
+static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+       return of_bus_default_map(addr, range, na, ns, pna);
+}
+
+static int of_bus_sbus_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr, offset, na);
+}
+
+static unsigned int of_bus_sbus_get_flags(u32 *addr)
+{
+       return IORESOURCE_MEM;
+}
+
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+       /* PCI */
+       {
+               .name = "pci",
+               .addr_prop_name = "assigned-addresses",
+               .match = of_bus_pci_match,
+               .count_cells = of_bus_pci_count_cells,
+               .map = of_bus_pci_map,
+               .translate = of_bus_pci_translate,
+               .get_flags = of_bus_pci_get_flags,
+       },
+       /* SBUS */
+       {
+               .name = "sbus",
+               .addr_prop_name = "reg",
+               .match = of_bus_sbus_match,
+               .count_cells = of_bus_sbus_count_cells,
+               .map = of_bus_sbus_map,
+               .translate = of_bus_sbus_translate,
+               .get_flags = of_bus_sbus_get_flags,
+       },
+       /* Default */
+       {
+               .name = "default",
+               .addr_prop_name = "reg",
+               .match = NULL,
+               .count_cells = of_bus_default_count_cells,
+               .map = of_bus_default_map,
+               .translate = of_bus_default_translate,
+               .get_flags = of_bus_default_get_flags,
+       },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
+               if (!of_busses[i].match || of_busses[i].match(np))
+                       return &of_busses[i];
+       BUG();
+       return NULL;
+}
+
+static int __init build_one_resource(struct device_node *parent,
+                                    struct of_bus *bus,
+                                    struct of_bus *pbus,
+                                    u32 *addr,
+                                    int na, int ns, int pna)
+{
+       u32 *ranges;
+       unsigned int rlen;
+       int rone;
+       u64 offset = OF_BAD_ADDR;
+
+       ranges = of_get_property(parent, "ranges", &rlen);
+       if (ranges == NULL || rlen == 0) {
+               offset = of_read_addr(addr, na);
+               memset(addr, 0, pna * 4);
+               goto finish;
+       }
+
+       /* Now walk through the ranges */
+       rlen /= 4;
+       rone = na + pna + ns;
+       for (; rlen >= rone; rlen -= rone, ranges += rone) {
+               offset = bus->map(addr, ranges, na, ns, pna);
+               if (offset != OF_BAD_ADDR)
+                       break;
+       }
+       if (offset == OF_BAD_ADDR)
+               return 1;
+
+       memcpy(addr, ranges + na, 4 * pna);
+
+finish:
+       /* Translate it into parent bus space */
+       return pbus->translate(addr, offset, pna);
+}
+
+static void __init build_device_resources(struct of_device *op,
+                                         struct device *parent)
+{
+       struct of_device *p_op;
+       struct of_bus *bus;
+       int na, ns;
+       int index, num_reg;
+       void *preg;
+
+       if (!parent)
+               return;
+
+       p_op = to_of_device(parent);
+       bus = of_match_bus(p_op->node);
+       bus->count_cells(op->node, &na, &ns);
+
+       preg = of_get_property(op->node, bus->addr_prop_name, &num_reg);
+       if (!preg || num_reg == 0)
+               return;
+
+       /* Convert to num-cells.  */
+       num_reg /= 4;
+
+       /* Conver to num-entries.  */
+       num_reg /= na + ns;
+
+       for (index = 0; index < num_reg; index++) {
+               struct resource *r = &op->resource[index];
+               u32 addr[OF_MAX_ADDR_CELLS];
+               u32 *reg = (preg + (index * ((na + ns) * 4)));
+               struct device_node *dp = op->node;
+               struct device_node *pp = p_op->node;
+               struct of_bus *pbus;
+               u64 size, result = OF_BAD_ADDR;
+               unsigned long flags;
+               int dna, dns;
+               int pna, pns;
+
+               size = of_read_addr(reg + na, ns);
+               flags = bus->get_flags(reg);
+
+               memcpy(addr, reg, na * 4);
+
+               /* If the immediate parent has no ranges property to apply,
+                * just use a 1<->1 mapping.
+                */
+               if (of_find_property(pp, "ranges", NULL) == NULL) {
+                       result = of_read_addr(addr, na);
+                       goto build_res;
+               }
+
+               dna = na;
+               dns = ns;
+
+               while (1) {
+                       dp = pp;
+                       pp = dp->parent;
+                       if (!pp) {
+                               result = of_read_addr(addr, dna);
+                               break;
+                       }
+
+                       pbus = of_match_bus(pp);
+                       pbus->count_cells(dp, &pna, &pns);
+
+                       if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna))
+                               break;
+
+                       dna = pna;
+                       dns = pns;
+                       bus = pbus;
+               }
+
+       build_res:
+               memset(r, 0, sizeof(*r));
+               if (result != OF_BAD_ADDR) {
+                       r->start = result & 0xffffffff;
+                       r->end = result + size - 1;
+                       r->flags = flags | ((result >> 32ULL) & 0xffUL);
+               } else {
+                       r->start = ~0UL;
+                       r->end = ~0UL;
+               }
+               r->name = op->node->name;
+       }
+}
+
+static struct of_device * __init scan_one_device(struct device_node *dp,
+                                                struct device *parent)
+{
+       struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
+       struct linux_prom_irqs *intr;
+       int len, i;
+
+       if (!op)
+               return NULL;
+
+       op->node = dp;
+
+       op->clock_freq = of_getintprop_default(dp, "clock-frequency",
+                                              (25*1000*1000));
+       op->portid = of_getintprop_default(dp, "upa-portid", -1);
+       if (op->portid == -1)
+               op->portid = of_getintprop_default(dp, "portid", -1);
+
+       intr = of_get_property(dp, "intr", &len);
+       if (intr) {
+               op->num_irqs = len / sizeof(struct linux_prom_irqs);
+               for (i = 0; i < op->num_irqs; i++)
+                       op->irqs[i] = intr[i].pri;
+       } else {
+               unsigned int *irq = of_get_property(dp, "interrupts", &len);
+
+               if (irq) {
+                       op->num_irqs = len / sizeof(unsigned int);
+                       for (i = 0; i < op->num_irqs; i++)
+                               op->irqs[i] = irq[i];
+               } else {
+                       op->num_irqs = 0;
+               }
+       }
+       if (sparc_cpu_model == sun4d) {
+               static int pil_to_sbus[] = {
+                       0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
+               };
+               struct device_node *busp = dp->parent;
+               struct linux_prom_registers *regs;
+               int board = of_getintprop_default(busp, "board#", 0);
+               int slot;
+
+               regs = of_get_property(dp, "reg", NULL);
+               slot = regs->which_io;
+
+               for (i = 0; i < op->num_irqs; i++) {
+                       int this_irq = op->irqs[i];
+                       int sbusl = pil_to_sbus[this_irq];
+
+                       if (sbusl)
+                               this_irq = (((board + 1) << 5) +
+                                           (sbusl << 2) +
+                                           slot);
+
+                       op->irqs[i] = this_irq;
+               }
+       }
+
+       build_device_resources(op, parent);
+
+       op->dev.parent = parent;
+       op->dev.bus = &of_bus_type;
+       if (!parent)
+               strcpy(op->dev.bus_id, "root");
+       else
+               strcpy(op->dev.bus_id, dp->path_component_name);
+
+       if (of_device_register(op)) {
+               printk("%s: Could not register of device.\n",
+                      dp->full_name);
+               kfree(op);
+               op = NULL;
+       }
+
+       return op;
+}
+
+static void __init scan_tree(struct device_node *dp, struct device *parent)
+{
+       while (dp) {
+               struct of_device *op = scan_one_device(dp, parent);
+
+               if (op)
+                       scan_tree(dp->child, &op->dev);
+
+               dp = dp->sibling;
+       }
+}
+
+static void __init scan_of_devices(void)
+{
+       struct device_node *root = of_find_node_by_path("/");
+       struct of_device *parent;
+
+       parent = scan_one_device(root, NULL);
+       if (!parent)
+               return;
+
+       scan_tree(root->child, &parent->dev);
+}
+
 static int __init of_bus_driver_init(void)
 {
-       int err = 0;
+       int err;
 
+       err = bus_register(&of_bus_type);
 #ifdef CONFIG_PCI
        if (!err)
                err = bus_register(&ebus_bus_type);
@@ -165,7 +634,11 @@ static int __init of_bus_driver_init(void)
        if (!err)
                err = bus_register(&sbus_bus_type);
 #endif
-       return 0;
+
+       if (!err)
+               scan_of_devices();
+
+       return err;
 }
 
 postcore_initcall(of_bus_driver_init);
index 946ce6d15819ae12448e2d4bc2bf86df0d2f7dc3..4b06dcb00ebde6212caafa0ff47989f86ce57f7e 100644 (file)
@@ -190,6 +190,36 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
 }
 EXPORT_SYMBOL(of_getintprop_default);
 
+int of_n_addr_cells(struct device_node *np)
+{
+       int* ip;
+       do {
+               if (np->parent)
+                       np = np->parent;
+               ip = of_get_property(np, "#address-cells", NULL);
+               if (ip != NULL)
+                       return *ip;
+       } while (np->parent);
+       /* No #address-cells property for the root node, default to 2 */
+       return 2;
+}
+EXPORT_SYMBOL(of_n_addr_cells);
+
+int of_n_size_cells(struct device_node *np)
+{
+       int* ip;
+       do {
+               if (np->parent)
+                       np = np->parent;
+               ip = of_get_property(np, "#size-cells", NULL);
+               if (ip != NULL)
+                       return *ip;
+       } while (np->parent);
+       /* No #size-cells property for the root node, default to 1 */
+       return 1;
+}
+EXPORT_SYMBOL(of_n_size_cells);
+
 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
 {
        struct property **prevp;
index 7dadcdb4ca42540b6dfef30afef9d3957bdec44d..9631e8f4ae60cc669e47b21451dfbf195259ec13 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/sun4paddr.h>
 #include <asm/page.h>
 #include <asm/pcic.h>
+#include <asm/of_device.h>
 
 extern unsigned long wall_jiffies;
 
@@ -273,83 +274,31 @@ static __inline__ void sun4_clock_probe(void)
 #endif
 }
 
-/* Probe for the mostek real time clock chip. */
-static __inline__ void clock_probe(void)
+static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct linux_prom_registers clk_reg[2];
-       char model[128];
-       register int node, cpuunit, bootbus;
-       struct resource r;
-
-       cpuunit = bootbus = 0;
-       memset(&r, 0, sizeof(r));
-
-       /* Determine the correct starting PROM node for the probe. */
-       node = prom_getchild(prom_root_node);
-       switch (sparc_cpu_model) {
-       case sun4c:
-               break;
-       case sun4m:
-               node = prom_getchild(prom_searchsiblings(node, "obio"));
-               break;
-       case sun4d:
-               node = prom_getchild(bootbus = prom_searchsiblings(prom_getchild(cpuunit = prom_searchsiblings(node, "cpu-unit")), "bootbus"));
-               break;
-       default:
-               prom_printf("CLOCK: Unsupported architecture!\n");
-               prom_halt();
-       }
+       struct device_node *dp = op->node;
+       char *model = of_get_property(dp, "model", NULL);
 
-       /* Find the PROM node describing the real time clock. */
-       sp_clock_typ = MSTK_INVALID;
-       node = prom_searchsiblings(node,"eeprom");
-       if (!node) {
-               prom_printf("CLOCK: No clock found!\n");
-               prom_halt();
-       }
+       if (!model)
+               return -ENODEV;
 
-       /* Get the model name and setup everything up. */
-       model[0] = '\0';
-       prom_getstring(node, "model", model, sizeof(model));
-       if (strcmp(model, "mk48t02") == 0) {
+       if (!strcmp(model, "mk48t02")) {
                sp_clock_typ = MSTK48T02;
-               if (prom_getproperty(node, "reg", (char *) clk_reg, sizeof(clk_reg)) == -1) {
-                       prom_printf("clock_probe: FAILED!\n");
-                       prom_halt();
-               }
-               if (sparc_cpu_model == sun4d)
-                       prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
-               else
-                       prom_apply_obio_ranges(clk_reg, 1);
+
                /* Map the clock register io area read-only */
-               r.flags = clk_reg[0].which_io;
-               r.start = clk_reg[0].phys_addr;
-               mstk48t02_regs = sbus_ioremap(&r, 0,
-                   sizeof(struct mostek48t02), "mk48t02");
+               mstk48t02_regs = of_ioremap(&op->resource[0], 0,
+                                           sizeof(struct mostek48t02),
+                                           "mk48t02");
                mstk48t08_regs = NULL;  /* To catch weirdness */
-       } else if (strcmp(model, "mk48t08") == 0) {
+       } else if (!strcmp(model, "mk48t08")) {
                sp_clock_typ = MSTK48T08;
-               if(prom_getproperty(node, "reg", (char *) clk_reg,
-                                   sizeof(clk_reg)) == -1) {
-                       prom_printf("clock_probe: FAILED!\n");
-                       prom_halt();
-               }
-               if (sparc_cpu_model == sun4d)
-                       prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1);
-               else
-                       prom_apply_obio_ranges(clk_reg, 1);
-               /* Map the clock register io area read-only */
-               /* XXX r/o attribute is somewhere in r.flags */
-               r.flags = clk_reg[0].which_io;
-               r.start = clk_reg[0].phys_addr;
-               mstk48t08_regs = sbus_ioremap(&r, 0,
-                   sizeof(struct mostek48t08), "mk48t08");
+               mstk48t08_regs = of_ioremap(&op->resource[0], 0,
+                                           sizeof(struct mostek48t08),
+                                           "mk48t08");
 
                mstk48t02_regs = &mstk48t08_regs->regs;
-       } else {
-               prom_printf("CLOCK: Unknown model name '%s'\n",model);
-               prom_halt();
-       }
+       } else
+               return -ENODEV;
 
        /* Report a low battery voltage condition. */
        if (has_low_battery())
@@ -358,6 +307,28 @@ static __inline__ void clock_probe(void)
        /* Kick start the clock if it is completely stopped. */
        if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
                kick_start_clock();
+
+       return 0;
+}
+
+static struct of_device_id clock_match[] = {
+       {
+               .name = "eeprom",
+       },
+       {},
+};
+
+static struct of_platform_driver clock_driver = {
+       .name           = "clock",
+       .match_table    = clock_match,
+       .probe          = clock_probe,
+};
+
+
+/* Probe for the mostek real time clock chip. */
+static void clock_init(void)
+{
+       of_register_driver(&clock_driver, &of_bus_type);
 }
 
 void __init sbus_time_init(void)
@@ -376,7 +347,7 @@ void __init sbus_time_init(void)
        if (ARCH_SUN4)
                sun4_clock_probe();
        else
-               clock_probe();
+               clock_init();
 
        sparc_init_timers(timer_interrupt);
        
index c2c69c167d182456ec4ae1d93c6c3a6fed0b35c0..718350aba1ecae75a009f789f0a08b8c5e54869d 100644 (file)
 #include <linux/init.h>
 #include <linux/ioport.h>
 
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/ebus.h>
 #include <asm/auxio.h>
 
 void __iomem *auxio_register = NULL;
@@ -111,12 +110,6 @@ void auxio_set_lte(int on)
        }
 }
 
-static void __devinit auxio_report_dev(struct device_node *dp)
-{
-       printk(KERN_INFO "AUXIO: Found device at %s\n",
-              dp->full_name);
-}
-
 static struct of_device_id auxio_match[] = {
        {
                .name = "auxio",
@@ -126,67 +119,48 @@ static struct of_device_id auxio_match[] = {
 
 MODULE_DEVICE_TABLE(of, auxio_match);
 
-#ifdef CONFIG_SBUS
-static int __devinit auxio_sbus_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-
-       auxio_devtype  = AUXIO_TYPE_SBUS;
-       auxio_register = sbus_ioremap(&sdev->resource[0], 0,
-                                     sdev->reg_addrs[0].reg_size,
-                                     "auxiliaryIO");
-       if (!auxio_register)
+       struct device_node *dp = dev->node;
+       unsigned long size;
+
+       if (!strcmp(dp->parent->name, "ebus")) {
+               auxio_devtype = AUXIO_TYPE_EBUS;
+               size = sizeof(u32);
+       } else if (!strcmp(dp->parent->name, "sbus")) {
+               auxio_devtype = AUXIO_TYPE_SBUS;
+               size = 1;
+       } else {
+               printk("auxio: Unknown parent bus type [%s]\n",
+                      dp->parent->name);
                return -ENODEV;
-
-       auxio_report_dev(dev->node);
-       return 0;
-}
-
-static struct of_platform_driver auxio_sbus_driver = {
-       .name           = "auxio",
-       .match_table    = auxio_match,
-       .probe          = auxio_sbus_probe,
-};
-#endif
-
-#ifdef CONFIG_PCI
-static int __devinit auxio_ebus_probe(struct of_device *dev, const struct of_device_id *match)
-{
-       struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
-
-       auxio_devtype  = AUXIO_TYPE_EBUS;
-       auxio_register = ioremap(edev->resource[0].start, sizeof(u32));
+       }
+       auxio_register = of_ioremap(&dev->resource[0], 0, size, "auxio");
        if (!auxio_register)
                return -ENODEV;
 
-       auxio_report_dev(dev->node);
+       printk(KERN_INFO "AUXIO: Found device at %s\n",
+              dp->full_name);
 
-       auxio_set_led(AUXIO_LED_ON);
+       if (auxio_devtype == AUXIO_TYPE_EBUS)
+               auxio_set_led(AUXIO_LED_ON);
 
        return 0;
 }
 
-static struct of_platform_driver auxio_ebus_driver = {
+static struct of_platform_driver auxio_driver = {
        .name           = "auxio",
        .match_table    = auxio_match,
-       .probe          = auxio_ebus_probe,
+       .probe          = auxio_probe,
 };
-#endif
 
-static int __init auxio_probe(void)
+static int __init auxio_init(void)
 {
-#ifdef CONFIG_SBUS
-       of_register_driver(&auxio_sbus_driver, &sbus_bus_type);
-#endif
-#ifdef CONFIG_PCI
-       of_register_driver(&auxio_ebus_driver, &ebus_bus_type);
-#endif
-
-       return 0;
+       return of_register_driver(&auxio_driver, &of_bus_type);
 }
 
 /* Must be after subsys_initcall() so that busses are probed.  Must
  * be before device_initcall() because things like the floppy driver
  * need to use the AUXIO register.
  */
-fs_initcall(auxio_probe);
+fs_initcall(auxio_init);
index 98e0a8cbeecdcf1e1beb40c66e95b657b863bca2..aac014d15ad3e6e9030c8050ee63363d38e3767f 100644 (file)
@@ -20,6 +20,8 @@
 #include <asm/pbm.h>
 #include <asm/ebus.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/bpp.h>
 #include <asm/irq.h>
 
@@ -279,45 +281,12 @@ static inline void *ebus_alloc(size_t size)
        return mem;
 }
 
-int __init ebus_intmap_match(struct linux_ebus *ebus,
-                            struct linux_prom_registers *reg,
-                            int *interrupt)
-{
-       struct linux_prom_ebus_intmap *imap;
-       struct linux_prom_ebus_intmask *imask;
-       unsigned int hi, lo, irq;
-       int i, len, n_imap;
-
-       imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
-       if (!imap)
-               return 0;
-       n_imap = len / sizeof(imap[0]);
-
-       imask = of_get_property(ebus->prom_node, "interrupt-map-mask", NULL);
-       if (!imask)
-               return 0;
-
-       hi = reg->which_io & imask->phys_hi;
-       lo = reg->phys_addr & imask->phys_lo;
-       irq = *interrupt & imask->interrupt;
-       for (i = 0; i < n_imap; i++) {
-               if ((imap[i].phys_hi == hi) &&
-                   (imap[i].phys_lo == lo) &&
-                   (imap[i].interrupt == irq)) {
-                       *interrupt = imap[i].cinterrupt;
-                       return 0;
-               }
-       }
-       return -1;
-}
-
-void __init fill_ebus_child(struct device_node *dp,
-                           struct linux_prom_registers *preg,
-                           struct linux_ebus_child *dev,
-                           int non_standard_regs)
+static void __init fill_ebus_child(struct device_node *dp,
+                                  struct linux_ebus_child *dev,
+                                  int non_standard_regs)
 {
+       struct of_device *op;
        int *regs;
-       int *irqs;
        int i, len;
 
        dev->prom_node = dp;
@@ -354,12 +323,16 @@ void __init fill_ebus_child(struct device_node *dp,
                }
        }
 
-       for (i = 0; i < PROMINTR_MAX; i++)
-               dev->irqs[i] = PCI_IRQ_NONE;
-
-       irqs = of_get_property(dp, "interrupts", &len);
-       if (!irqs) {
+       op = of_find_device_by_node(dp);
+       if (!op) {
                dev->num_irqs = 0;
+       } else {
+               dev->num_irqs = op->num_irqs;
+               for (i = 0; i < dev->num_irqs; i++)
+                       dev->irqs[i] = op->irqs[i];
+       }
+
+       if (!dev->num_irqs) {
                /*
                 * Oh, well, some PROMs don't export interrupts
                 * property to children of EBus devices...
@@ -375,23 +348,6 @@ void __init fill_ebus_child(struct device_node *dp,
                                dev->irqs[0] = dev->parent->irqs[1];
                        }
                }
-       } else {
-               dev->num_irqs = len / sizeof(irqs[0]);
-               for (i = 0; i < dev->num_irqs; i++) {
-                       struct pci_pbm_info *pbm = dev->bus->parent;
-                       struct pci_controller_info *p = pbm->parent;
-
-                       if (ebus_intmap_match(dev->bus, preg, &irqs[i]) != -1) {
-                               dev->irqs[i] = p->irq_build(pbm,
-                                                           dev->bus->self,
-                                                           irqs[i]);
-                       } else {
-                               /* If we get a bogus interrupt property, just
-                                * record the raw value instead of punting.
-                                */
-                               dev->irqs[i] = irqs[i];
-                       }
-               }
        }
 }
 
@@ -403,72 +359,32 @@ static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
        return 0;
 }
 
-void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
+static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
 {
-       struct linux_prom_registers *regs;
        struct linux_ebus_child *child;
-       int *irqs;
-       int i, n, len;
+       struct of_device *op;
+       int i, len;
 
        dev->prom_node = dp;
 
        printk(" [%s", dp->name);
 
-       regs = of_get_property(dp, "reg", &len);
-       if (!regs) {
+       op = of_find_device_by_node(dp);
+       if (!op) {
                dev->num_addrs = 0;
-               goto probe_interrupts;
-       }
-
-       if (len % sizeof(struct linux_prom_registers)) {
-               prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
-                           dev->prom_node->name, len,
-                           (int)sizeof(struct linux_prom_registers));
-               prom_halt();
-       }
-       dev->num_addrs = len / sizeof(struct linux_prom_registers);
-
-       for (i = 0; i < dev->num_addrs; i++) {
-               /* XXX Learn how to interpret ebus ranges... -DaveM */
-               if (regs[i].which_io >= 0x10)
-                       n = (regs[i].which_io - 0x10) >> 2;
-               else
-                       n = regs[i].which_io;
-
-               dev->resource[i].start  = dev->bus->self->resource[n].start;
-               dev->resource[i].start += (unsigned long)regs[i].phys_addr;
-               dev->resource[i].end    =
-                       (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
-               dev->resource[i].flags  = IORESOURCE_MEM;
-               dev->resource[i].name   = dev->prom_node->name;
-               request_resource(&dev->bus->self->resource[n],
-                                &dev->resource[i]);
-       }
-
-probe_interrupts:
-       for (i = 0; i < PROMINTR_MAX; i++)
-               dev->irqs[i] = PCI_IRQ_NONE;
-
-       irqs = of_get_property(dp, "interrupts", &len);
-       if (!irqs) {
                dev->num_irqs = 0;
        } else {
-               dev->num_irqs = len / sizeof(irqs[0]);
-               for (i = 0; i < dev->num_irqs; i++) {
-                       struct pci_pbm_info *pbm = dev->bus->parent;
-                       struct pci_controller_info *p = pbm->parent;
-
-                       if (ebus_intmap_match(dev->bus, &regs[0], &irqs[i]) != -1) {
-                               dev->irqs[i] = p->irq_build(pbm,
-                                                           dev->bus->self,
-                                                           irqs[i]);
-                       } else {
-                               /* If we get a bogus interrupt property, just
-                                * record the raw value instead of punting.
-                                */
-                               dev->irqs[i] = irqs[i];
-                       }
-               }
+               (void) of_get_property(dp, "reg", &len);
+               dev->num_addrs = len / sizeof(struct linux_prom_registers);
+
+               for (i = 0; i < dev->num_addrs; i++)
+                       memcpy(&dev->resource[i],
+                              &op->resource[i],
+                              sizeof(struct resource));
+
+               dev->num_irqs = op->num_irqs;
+               for (i = 0; i < dev->num_irqs; i++)
+                       dev->irqs[i] = op->irqs[i];
        }
 
        dev->ofdev.node = dp;
@@ -490,7 +406,7 @@ probe_interrupts:
                child->next = NULL;
                child->parent = dev;
                child->bus = dev->bus;
-               fill_ebus_child(dp, regs, child,
+               fill_ebus_child(dp, child,
                                child_regs_nonstandard(dev));
 
                while ((dp = dp->sibling) != NULL) {
@@ -500,7 +416,7 @@ probe_interrupts:
                        child->next = NULL;
                        child->parent = dev;
                        child->bus = dev->bus;
-                       fill_ebus_child(dp, regs, child,
+                       fill_ebus_child(dp, child,
                                        child_regs_nonstandard(dev));
                }
        }
index ab9e640df22820a5ffd9084b73258ea09042c41e..eebe02f3f4cb30a672bb8079ad3fd2dcf86f5aa6 100644 (file)
@@ -414,6 +414,10 @@ void irq_install_pre_handler(int virt_irq,
        data->pre_handler_arg1 = arg1;
        data->pre_handler_arg2 = arg2;
 
+       if (desc->chip == &sun4u_irq_ack ||
+           desc->chip == &sun4v_irq_ack)
+               return;
+
        desc->chip = (desc->chip == &sun4u_irq ?
                      &sun4u_irq_ack : &sun4v_irq_ack);
 }
index 6f16dee280a89ef2c457b5e2714d962cf10bb8ca..0f3aec72ef5fc3161530997853502f4d985e5052 100644 (file)
@@ -3,6 +3,8 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/isa.h>
 
 struct sparc_isa_bridge *isa_chain;
@@ -46,107 +48,16 @@ isa_dev_get_resource(struct sparc_isa_device *isa_dev)
        return pregs;
 }
 
-/* I can't believe they didn't put a real INO in the isa device
- * interrupts property.  The whole point of the OBP properties
- * is to shield the kernel from IRQ routing details.
- *
- * The P1275 standard for ISA devices seems to also have been
- * totally ignored.
- *
- * On later systems, an interrupt-map and interrupt-map-mask scheme
- * akin to EBUS is used.
- */
-static struct {
-       int     obp_irq;
-       int     pci_ino;
-} grover_irq_table[] = {
-       { 1, 0x00 },    /* dma, unknown ino at this point */
-       { 2, 0x27 },    /* floppy */
-       { 3, 0x22 },    /* parallel */
-       { 4, 0x2b },    /* serial */
-       { 5, 0x25 },    /* acpi power management */
-
-       { 0, 0x00 }     /* end of table */
-};
-
-static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev,
-                                            struct sparc_isa_bridge *isa_br,
-                                            int *interrupt,
-                                            struct linux_prom_registers *reg)
-{
-       struct linux_prom_ebus_intmap *imap;
-       struct linux_prom_ebus_intmap *imask;
-       unsigned int hi, lo, irq;
-       int i, len, n_imap;
-
-       imap = of_get_property(isa_br->prom_node, "interrupt-map", &len);
-       if (!imap)
-               return 0;
-       n_imap = len / sizeof(imap[0]);
-
-       imask = of_get_property(isa_br->prom_node, "interrupt-map-mask", NULL);
-       if (!imask)
-               return 0;
-
-       hi = reg->which_io & imask->phys_hi;
-       lo = reg->phys_addr & imask->phys_lo;
-       irq = *interrupt & imask->interrupt;
-       for (i = 0; i < n_imap; i++) {
-               if ((imap[i].phys_hi == hi) &&
-                   (imap[i].phys_lo == lo) &&
-                   (imap[i].interrupt == irq)) {
-                       *interrupt = imap[i].cinterrupt;
-                       return 0;
-               }
-       }
-       return -1;
-}
-
 static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
                                   struct linux_prom_registers *pregs)
 {
-       int irq_prop;
+       struct of_device *op = of_find_device_by_node(isa_dev->prom_node);
 
-       irq_prop = of_getintprop_default(isa_dev->prom_node,
-                                        "interrupts", -1);
-       if (irq_prop <= 0) {
-               goto no_irq;
+       if (!op || !op->num_irqs) {
+               isa_dev->irq = PCI_IRQ_NONE;
        } else {
-               struct pci_controller_info *pcic;
-               struct pci_pbm_info *pbm;
-               int i;
-
-               if (of_find_property(isa_dev->bus->prom_node,
-                                    "interrupt-map", NULL)) {
-                       if (!isa_dev_get_irq_using_imap(isa_dev,
-                                                       isa_dev->bus,
-                                                       &irq_prop,
-                                                       pregs))
-                               goto route_irq;
-               }
-
-               for (i = 0; grover_irq_table[i].obp_irq != 0; i++) {
-                       if (grover_irq_table[i].obp_irq == irq_prop) {
-                               int ino = grover_irq_table[i].pci_ino;
-
-                               if (ino == 0)
-                                       goto no_irq;
-                               irq_prop = ino;
-                               goto route_irq;
-                       }
-               }
-               goto no_irq;
-
-route_irq:
-               pbm = isa_dev->bus->parent;
-               pcic = pbm->parent;
-               isa_dev->irq = pcic->irq_build(pbm, NULL, irq_prop);
-               return;
+               isa_dev->irq = op->irqs[0];
        }
-
-no_irq:
-       isa_dev->irq = PCI_IRQ_NONE;
 }
 
 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
index 768475bbce82f24c8a6e5a87a2ce7c7ec467694b..3670dc8a7d5f2eace36735f87c1a6e181b62207a 100644 (file)
@@ -129,6 +129,43 @@ static int of_device_resume(struct device * dev)
        return error;
 }
 
+void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name)
+{
+       unsigned long ret = res->start + offset;
+
+       if (!request_region(ret, size, name))
+               ret = 0;
+
+       return (void __iomem *) ret;
+}
+EXPORT_SYMBOL(of_ioremap);
+
+void of_iounmap(void __iomem *base, unsigned long size)
+{
+       release_region((unsigned long) base, size);
+}
+EXPORT_SYMBOL(of_iounmap);
+
+static int node_match(struct device *dev, void *data)
+{
+       struct of_device *op = to_of_device(dev);
+       struct device_node *dp = data;
+
+       return (op->node == dp);
+}
+
+struct of_device *of_find_device_by_node(struct device_node *dp)
+{
+       struct device *dev = bus_find_device(&of_bus_type, NULL,
+                                            dp, node_match);
+
+       if (dev)
+               return to_of_device(dev);
+
+       return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
 #ifdef CONFIG_PCI
 struct bus_type isa_bus_type = {
        .name   = "isa",
@@ -163,10 +200,654 @@ struct bus_type sbus_bus_type = {
 EXPORT_SYMBOL(sbus_bus_type);
 #endif
 
+struct bus_type of_bus_type = {
+       .name   = "of",
+       .match  = of_platform_bus_match,
+       .probe  = of_device_probe,
+       .remove = of_device_remove,
+       .suspend        = of_device_suspend,
+       .resume = of_device_resume,
+};
+EXPORT_SYMBOL(of_bus_type);
+
+static inline u64 of_read_addr(u32 *cell, int size)
+{
+       u64 r = 0;
+       while (size--)
+               r = (r << 32) | *(cell++);
+       return r;
+}
+
+static void __init get_cells(struct device_node *dp,
+                            int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = of_n_addr_cells(dp);
+       if (sizec)
+               *sizec = of_n_size_cells(dp);
+}
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS      4
+
+struct of_bus {
+       const char      *name;
+       const char      *addr_prop_name;
+       int             (*match)(struct device_node *parent);
+       void            (*count_cells)(struct device_node *child,
+                                      int *addrc, int *sizec);
+       u64             (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
+       int             (*translate)(u32 *addr, u64 offset, int na);
+       unsigned int    (*get_flags)(u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+                                      int *addrc, int *sizec)
+{
+       get_cells(dev, addrc, sizec);
+}
+
+static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       cp = of_read_addr(range, na);
+       s  = of_read_addr(range + na + pna, ns);
+       da = of_read_addr(addr, na);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+       u64 a = of_read_addr(addr, na);
+       memset(addr, 0, na * 4);
+       a += offset;
+       if (na > 1)
+               addr[na - 2] = a >> 32;
+       addr[na - 1] = a & 0xffffffffu;
+
+       return 0;
+}
+
+static unsigned int of_bus_default_get_flags(u32 *addr)
+{
+       return IORESOURCE_MEM;
+}
+
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+       return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 3;
+       if (sizec)
+               *sizec = 2;
+}
+
+static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       /* Check address type match */
+       if ((addr[0] ^ range[0]) & 0x03000000)
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_addr(range + 1, na - 1);
+       s  = of_read_addr(range + na + pna, ns);
+       da = of_read_addr(addr + 1, na - 1);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_pci_get_flags(u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       switch((w >> 24) & 0x03) {
+       case 0x01:
+               flags |= IORESOURCE_IO;
+       case 0x02: /* 32 bits */
+       case 0x03: /* 64 bits */
+               flags |= IORESOURCE_MEM;
+       }
+       if (w & 0x40000000)
+               flags |= IORESOURCE_PREFETCH;
+       return flags;
+}
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+       return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 2;
+       if (sizec)
+               *sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       /* Check address type match */
+       if ((addr[0] ^ range[0]) & 0x00000001)
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_addr(range + 1, na - 1);
+       s  = of_read_addr(range + na + pna, ns);
+       da = of_read_addr(addr + 1, na - 1);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_isa_get_flags(u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       if (w & 1)
+               flags |= IORESOURCE_IO;
+       else
+               flags |= IORESOURCE_MEM;
+       return flags;
+}
+
+/*
+ * SBUS bus specific translator
+ */
+
+static int of_bus_sbus_match(struct device_node *np)
+{
+       return !strcmp(np->name, "sbus") ||
+               !strcmp(np->name, "sbi");
+}
+
+static void of_bus_sbus_count_cells(struct device_node *child,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 2;
+       if (sizec)
+               *sizec = 1;
+}
+
+static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+       return of_bus_default_map(addr, range, na, ns, pna);
+}
+
+static int of_bus_sbus_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr, offset, na);
+}
+
+static unsigned int of_bus_sbus_get_flags(u32 *addr)
+{
+       return IORESOURCE_MEM;
+}
+
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+       /* PCI */
+       {
+               .name = "pci",
+               .addr_prop_name = "assigned-addresses",
+               .match = of_bus_pci_match,
+               .count_cells = of_bus_pci_count_cells,
+               .map = of_bus_pci_map,
+               .translate = of_bus_pci_translate,
+               .get_flags = of_bus_pci_get_flags,
+       },
+       /* ISA */
+       {
+               .name = "isa",
+               .addr_prop_name = "reg",
+               .match = of_bus_isa_match,
+               .count_cells = of_bus_isa_count_cells,
+               .map = of_bus_isa_map,
+               .translate = of_bus_isa_translate,
+               .get_flags = of_bus_isa_get_flags,
+       },
+       /* SBUS */
+       {
+               .name = "sbus",
+               .addr_prop_name = "reg",
+               .match = of_bus_sbus_match,
+               .count_cells = of_bus_sbus_count_cells,
+               .map = of_bus_sbus_map,
+               .translate = of_bus_sbus_translate,
+               .get_flags = of_bus_sbus_get_flags,
+       },
+       /* Default */
+       {
+               .name = "default",
+               .addr_prop_name = "reg",
+               .match = NULL,
+               .count_cells = of_bus_default_count_cells,
+               .map = of_bus_default_map,
+               .translate = of_bus_default_translate,
+               .get_flags = of_bus_default_get_flags,
+       },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
+               if (!of_busses[i].match || of_busses[i].match(np))
+                       return &of_busses[i];
+       BUG();
+       return NULL;
+}
+
+static int __init build_one_resource(struct device_node *parent,
+                                    struct of_bus *bus,
+                                    struct of_bus *pbus,
+                                    u32 *addr,
+                                    int na, int ns, int pna)
+{
+       u32 *ranges;
+       unsigned int rlen;
+       int rone;
+       u64 offset = OF_BAD_ADDR;
+
+       ranges = of_get_property(parent, "ranges", &rlen);
+       if (ranges == NULL || rlen == 0) {
+               offset = of_read_addr(addr, na);
+               memset(addr, 0, pna * 4);
+               goto finish;
+       }
+
+       /* Now walk through the ranges */
+       rlen /= 4;
+       rone = na + pna + ns;
+       for (; rlen >= rone; rlen -= rone, ranges += rone) {
+               offset = bus->map(addr, ranges, na, ns, pna);
+               if (offset != OF_BAD_ADDR)
+                       break;
+       }
+       if (offset == OF_BAD_ADDR)
+               return 1;
+
+       memcpy(addr, ranges + na, 4 * pna);
+
+finish:
+       /* Translate it into parent bus space */
+       return pbus->translate(addr, offset, pna);
+}
+
+static void __init build_device_resources(struct of_device *op,
+                                         struct device *parent)
+{
+       struct of_device *p_op;
+       struct of_bus *bus;
+       int na, ns;
+       int index, num_reg;
+       void *preg;
+
+       if (!parent)
+               return;
+
+       p_op = to_of_device(parent);
+       bus = of_match_bus(p_op->node);
+       bus->count_cells(op->node, &na, &ns);
+
+       preg = of_get_property(op->node, bus->addr_prop_name, &num_reg);
+       if (!preg || num_reg == 0)
+               return;
+
+       /* Convert to num-cells.  */
+       num_reg /= 4;
+
+       /* Conver to num-entries.  */
+       num_reg /= na + ns;
+
+       for (index = 0; index < num_reg; index++) {
+               struct resource *r = &op->resource[index];
+               u32 addr[OF_MAX_ADDR_CELLS];
+               u32 *reg = (preg + (index * ((na + ns) * 4)));
+               struct device_node *dp = op->node;
+               struct device_node *pp = p_op->node;
+               struct of_bus *pbus;
+               u64 size, result = OF_BAD_ADDR;
+               unsigned long flags;
+               int dna, dns;
+               int pna, pns;
+
+               size = of_read_addr(reg + na, ns);
+               flags = bus->get_flags(reg);
+
+               memcpy(addr, reg, na * 4);
+
+               /* If the immediate parent has no ranges property to apply,
+                * just use a 1<->1 mapping.  Unless it is the 'dma' child
+                * of an isa bus, which must be passed up towards the root.
+                *
+                * Also, don't try to translate PMU bus device registers.
+                */
+               if ((of_find_property(pp, "ranges", NULL) == NULL &&
+                    strcmp(pp->name, "dma") != 0) ||
+                   !strcmp(pp->name, "pmu")) {
+                       result = of_read_addr(addr, na);
+                       goto build_res;
+               }
+
+               dna = na;
+               dns = ns;
+
+               while (1) {
+                       dp = pp;
+                       pp = dp->parent;
+                       if (!pp) {
+                               result = of_read_addr(addr, dna);
+                               break;
+                       }
+
+                       pbus = of_match_bus(pp);
+                       pbus->count_cells(dp, &pna, &pns);
+
+                       if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna))
+                               break;
+
+                       dna = pna;
+                       dns = pns;
+                       bus = pbus;
+               }
+
+       build_res:
+               memset(r, 0, sizeof(*r));
+               if (result != OF_BAD_ADDR) {
+                       r->start = result;
+                       r->end = result + size - 1;
+                       r->flags = flags;
+               } else {
+                       r->start = ~0UL;
+                       r->end = ~0UL;
+               }
+               r->name = op->node->name;
+       }
+}
+
+static struct device_node * __init
+apply_interrupt_map(struct device_node *dp, struct device_node *pp,
+                   u32 *imap, int imlen, u32 *imask,
+                   unsigned int *irq_p)
+{
+       struct device_node *cp;
+       unsigned int irq = *irq_p;
+       struct of_bus *bus;
+       phandle handle;
+       u32 *reg;
+       int na, num_reg, i;
+
+       bus = of_match_bus(pp);
+       bus->count_cells(dp, &na, NULL);
+
+       reg = of_get_property(dp, "reg", &num_reg);
+       if (!reg || !num_reg)
+               return NULL;
+
+       imlen /= ((na + 3) * 4);
+       handle = 0;
+       for (i = 0; i < imlen; i++) {
+               int j;
+
+               for (j = 0; j < na; j++) {
+                       if ((reg[j] & imask[j]) != imap[j])
+                               goto next;
+               }
+               if (imap[na] == irq) {
+                       handle = imap[na + 1];
+                       irq = imap[na + 2];
+                       break;
+               }
+
+       next:
+               imap += (na + 3);
+       }
+       if (i == imlen)
+               return NULL;
+
+       *irq_p = irq;
+       cp = of_find_node_by_phandle(handle);
+
+       return cp;
+}
+
+static unsigned int __init pci_irq_swizzle(struct device_node *dp,
+                                          struct device_node *pp,
+                                          unsigned int irq)
+{
+       struct linux_prom_pci_registers *regs;
+       unsigned int devfn, slot, ret;
+
+       if (irq < 1 || irq > 4)
+               return irq;
+
+       regs = of_get_property(dp, "reg", NULL);
+       if (!regs)
+               return irq;
+
+       devfn = (regs->phys_hi >> 8) & 0xff;
+       slot = (devfn >> 3) & 0x1f;
+
+       ret = ((irq - 1 + (slot & 3)) & 3) + 1;
+
+       return ret;
+}
+
+static unsigned int __init build_one_device_irq(struct of_device *op,
+                                               struct device *parent,
+                                               unsigned int irq)
+{
+       struct device_node *dp = op->node;
+       struct device_node *pp, *ip;
+       unsigned int orig_irq = irq;
+
+       if (irq == 0xffffffff)
+               return irq;
+
+       if (dp->irq_trans) {
+               irq = dp->irq_trans->irq_build(dp, irq,
+                                              dp->irq_trans->data);
+#if 1
+               printk("%s: direct translate %x --> %x\n",
+                      dp->full_name, orig_irq, irq);
+#endif
+               return irq;
+       }
+
+       /* Something more complicated.  Walk up to the root, applying
+        * interrupt-map or bus specific translations, until we hit
+        * an IRQ translator.
+        *
+        * If we hit a bus type or situation we cannot handle, we
+        * stop and assume that the original IRQ number was in a
+        * format which has special meaning to it's immediate parent.
+        */
+       pp = dp->parent;
+       ip = NULL;
+       while (pp) {
+               void *imap, *imsk;
+               int imlen;
+
+               imap = of_get_property(pp, "interrupt-map", &imlen);
+               imsk = of_get_property(pp, "interrupt-map-mask", NULL);
+               if (imap && imsk) {
+                       struct device_node *iret;
+                       int this_orig_irq = irq;
+
+                       iret = apply_interrupt_map(dp, pp,
+                                                  imap, imlen, imsk,
+                                                  &irq);
+#if 1
+                       printk("%s: Apply [%s:%x] imap --> [%s:%x]\n",
+                              op->node->full_name,
+                              pp->full_name, this_orig_irq,
+                              (iret ? iret->full_name : "NULL"), irq);
+#endif
+                       if (!iret)
+                               break;
+
+                       if (iret->irq_trans) {
+                               ip = iret;
+                               break;
+                       }
+               } else {
+                       if (!strcmp(pp->type, "pci") ||
+                           !strcmp(pp->type, "pciex")) {
+                               unsigned int this_orig_irq = irq;
+
+                               irq = pci_irq_swizzle(dp, pp, irq);
+#if 1
+                               printk("%s: PCI swizzle [%s] %x --> %x\n",
+                                      op->node->full_name,
+                                      pp->full_name, this_orig_irq, irq);
+#endif
+                       }
+
+                       if (pp->irq_trans) {
+                               ip = pp;
+                               break;
+                       }
+               }
+               dp = pp;
+               pp = pp->parent;
+       }
+       if (!ip)
+               return orig_irq;
+
+       irq = ip->irq_trans->irq_build(op->node, irq,
+                                      ip->irq_trans->data);
+#if 1
+       printk("%s: Apply IRQ trans [%s] %x --> %x\n",
+              op->node->full_name, ip->full_name, orig_irq, irq);
+#endif
+
+       return irq;
+}
+
+static struct of_device * __init scan_one_device(struct device_node *dp,
+                                                struct device *parent)
+{
+       struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
+       unsigned int *irq;
+       int len, i;
+
+       if (!op)
+               return NULL;
+
+       op->node = dp;
+
+       op->clock_freq = of_getintprop_default(dp, "clock-frequency",
+                                              (25*1000*1000));
+       op->portid = of_getintprop_default(dp, "upa-portid", -1);
+       if (op->portid == -1)
+               op->portid = of_getintprop_default(dp, "portid", -1);
+
+       irq = of_get_property(dp, "interrupts", &len);
+       if (irq) {
+               memcpy(op->irqs, irq, len);
+               op->num_irqs = len / 4;
+       } else {
+               op->num_irqs = 0;
+       }
+
+       build_device_resources(op, parent);
+       for (i = 0; i < op->num_irqs; i++)
+               op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
+
+       op->dev.parent = parent;
+       op->dev.bus = &of_bus_type;
+       if (!parent)
+               strcpy(op->dev.bus_id, "root");
+       else
+               strcpy(op->dev.bus_id, dp->path_component_name);
+
+       if (of_device_register(op)) {
+               printk("%s: Could not register of device.\n",
+                      dp->full_name);
+               kfree(op);
+               op = NULL;
+       }
+
+       return op;
+}
+
+static void __init scan_tree(struct device_node *dp, struct device *parent)
+{
+       while (dp) {
+               struct of_device *op = scan_one_device(dp, parent);
+
+               if (op)
+                       scan_tree(dp->child, &op->dev);
+
+               dp = dp->sibling;
+       }
+}
+
+static void __init scan_of_devices(void)
+{
+       struct device_node *root = of_find_node_by_path("/");
+       struct of_device *parent;
+
+       parent = scan_one_device(root, NULL);
+       if (!parent)
+               return;
+
+       scan_tree(root->child, &parent->dev);
+}
+
 static int __init of_bus_driver_init(void)
 {
-       int err = 0;
+       int err;
 
+       err = bus_register(&of_bus_type);
 #ifdef CONFIG_PCI
        if (!err)
                err = bus_register(&isa_bus_type);
@@ -177,7 +858,11 @@ static int __init of_bus_driver_init(void)
        if (!err)
                err = bus_register(&sbus_bus_type);
 #endif
-       return 0;
+
+       if (!err)
+               scan_of_devices();
+
+       return err;
 }
 
 postcore_initcall(of_bus_driver_init);
index 20ca9ec8fd3bbef18c844490c4f8f553c9a23116..04ea6c2eb7a13cbaac5dd2c060cdcc5dabffc8c7 100644 (file)
@@ -307,7 +307,6 @@ static void __init pci_scan_each_controller_bus(void)
                p->scan_bus(p);
 }
 
-extern void clock_probe(void);
 extern void power_init(void);
 
 static int __init pcibios_init(void)
@@ -320,7 +319,6 @@ static int __init pcibios_init(void)
 
        isa_init();
        ebus_init();
-       clock_probe();
        power_init();
 
        return 0;
@@ -406,14 +404,8 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
 }
 EXPORT_SYMBOL(pcibios_bus_to_resource);
 
-extern int pci_irq_verbose;
-
 char * __init pcibios_setup(char *str)
 {
-       if (!strcmp(str, "irq_verbose")) {
-               pci_irq_verbose = 1;
-               return NULL;
-       }
        return str;
 }
 
index b06a2955bf5f720b30a1af3db2206de8f9f4d215..7a59cc72c844c438188f5fef41bb4adcc08ea523 100644 (file)
 
 #include <asm/pbm.h>
 #include <asm/prom.h>
+#include <asm/of_device.h>
 
 #include "pci_impl.h"
 
-/* Pass "pci=irq_verbose" on the kernel command line to enable this.  */
-int pci_irq_verbose;
-
 /* Fix self device of BUS and hook it into BUS->self.
  * The pci_scan_bus does not do this for the host bridge.
  */
@@ -169,6 +167,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
        }
        pcp->pbm = pbm;
        pcp->prom_node = dp;
+       pcp->op = of_find_device_by_node(dp);
        memcpy(pcp->prom_regs, pregs,
               nregs * sizeof(struct linux_prom_pci_registers));
        pcp->num_prom_regs = nregs;
@@ -549,296 +548,18 @@ void __init pci_assign_unassigned(struct pci_pbm_info *pbm,
                pci_assign_unassigned(pbm, bus);
 }
 
-static inline unsigned int pci_slot_swivel(struct pci_pbm_info *pbm,
-                                          struct pci_dev *toplevel_pdev,
-                                          struct pci_dev *pdev,
-                                          unsigned int interrupt)
-{
-       unsigned int ret;
-
-       if (unlikely(interrupt < 1 || interrupt > 4)) {
-               printk("%s: Device %s interrupt value of %u is strange.\n",
-                      pbm->name, pci_name(pdev), interrupt);
-               return interrupt;
-       }
-
-       ret = ((interrupt - 1 + (PCI_SLOT(pdev->devfn) & 3)) & 3) + 1;
-
-       if (pci_irq_verbose)
-               printk("%s: %s IRQ Swivel %s [%x:%x] -> [%x]\n",
-                      pbm->name, pci_name(toplevel_pdev), pci_name(pdev),
-                      interrupt, PCI_SLOT(pdev->devfn), ret);
-
-       return ret;
-}
-
-static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm,
-                                           struct pci_dev *toplevel_pdev,
-                                           struct pci_dev *pbus,
-                                           struct pci_dev *pdev,
-                                           unsigned int interrupt,
-                                           struct device_node **cnode)
-{
-       struct linux_prom_pci_intmap *imap;
-       struct linux_prom_pci_intmask *imask;
-       struct pcidev_cookie *pbus_pcp = pbus->sysdata;
-       struct pcidev_cookie *pdev_pcp = pdev->sysdata;
-       struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs;
-       struct property *prop;
-       int plen, num_imap, i;
-       unsigned int hi, mid, lo, irq, orig_interrupt;
-
-       *cnode = pbus_pcp->prom_node;
-
-       prop = of_find_property(pbus_pcp->prom_node, "interrupt-map", &plen);
-       if (!prop ||
-           (plen % sizeof(struct linux_prom_pci_intmap)) != 0) {
-               printk("%s: Device %s interrupt-map has bad len %d\n",
-                      pbm->name, pci_name(pbus), plen);
-               goto no_intmap;
-       }
-       imap = prop->value;
-       num_imap = plen / sizeof(struct linux_prom_pci_intmap);
-
-       prop = of_find_property(pbus_pcp->prom_node, "interrupt-map-mask", &plen);
-       if (!prop ||
-           (plen % sizeof(struct linux_prom_pci_intmask)) != 0) {
-               printk("%s: Device %s interrupt-map-mask has bad len %d\n",
-                      pbm->name, pci_name(pbus), plen);
-               goto no_intmap;
-       }
-       imask = prop->value;
-
-       orig_interrupt = interrupt;
-
-       hi   = pregs->phys_hi & imask->phys_hi;
-       mid  = pregs->phys_mid & imask->phys_mid;
-       lo   = pregs->phys_lo & imask->phys_lo;
-       irq  = interrupt & imask->interrupt;
-
-       for (i = 0; i < num_imap; i++) {
-               if (imap[i].phys_hi  == hi   &&
-                   imap[i].phys_mid == mid  &&
-                   imap[i].phys_lo  == lo   &&
-                   imap[i].interrupt == irq) {
-                       *cnode = of_find_node_by_phandle(imap[i].cnode);
-                       interrupt = imap[i].cinterrupt;
-               }
-       }
-
-       if (pci_irq_verbose)
-               printk("%s: %s MAP BUS %s DEV %s [%x] -> [%x]\n",
-                      pbm->name, pci_name(toplevel_pdev),
-                      pci_name(pbus), pci_name(pdev),
-                      orig_interrupt, interrupt);
-
-no_intmap:
-       return interrupt;
-}
-
-/* For each PCI bus on the way to the root:
- * 1) If it has an interrupt-map property, apply it.
- * 2) Else, swivel the interrupt number based upon the PCI device number.
- *
- * Return the "IRQ controller" node.  If this is the PBM's device node,
- * all interrupt translations are complete, else we should use that node's
- * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt.
- */
-static struct device_node * __init
-pci_intmap_match_to_root(struct pci_pbm_info *pbm,
-                        struct pci_dev *pdev,
-                        unsigned int *interrupt)
-{
-       struct pci_dev *toplevel_pdev = pdev;
-       struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata;
-       struct device_node *cnode = toplevel_pcp->prom_node;
-
-       while (pdev->bus->number != pbm->pci_first_busno) {
-               struct pci_dev *pbus = pdev->bus->self;
-               struct pcidev_cookie *pcp = pbus->sysdata;
-               struct property *prop;
-
-               prop = of_find_property(pcp->prom_node, "interrupt-map", NULL);
-               if (!prop) {
-                       *interrupt = pci_slot_swivel(pbm, toplevel_pdev,
-                                                    pdev, *interrupt);
-                       cnode = pcp->prom_node;
-               } else {
-                       *interrupt = pci_apply_intmap(pbm, toplevel_pdev,
-                                                     pbus, pdev,
-                                                     *interrupt, &cnode);
-
-                       while (pcp->prom_node != cnode &&
-                              pbus->bus->number != pbm->pci_first_busno) {
-                               pbus = pbus->bus->self;
-                               pcp = pbus->sysdata;
-                       }
-               }
-               pdev = pbus;
-
-               if (cnode == pbm->prom_node)
-                       break;
-       }
-
-       return cnode;
-}
-
-static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt)
-{
-       struct pcidev_cookie *dev_pcp = pdev->sysdata;
-       struct pci_pbm_info *pbm = dev_pcp->pbm;
-       struct linux_prom_pci_registers *reg;
-       struct device_node *cnode;
-       struct property *prop;
-       unsigned int hi, mid, lo, irq;
-       int i, plen;
-
-       cnode = pci_intmap_match_to_root(pbm, pdev, interrupt);
-       if (cnode == pbm->prom_node)
-               goto success;
-
-       prop = of_find_property(cnode, "reg", &plen);
-       if (!prop ||
-           (plen % sizeof(struct linux_prom_pci_registers)) != 0) {
-               printk("%s: OBP node %s reg property has bad len %d\n",
-                      pbm->name, cnode->full_name, plen);
-               goto fail;
-       }
-       reg = prop->value;
-
-       hi   = reg[0].phys_hi & pbm->pbm_intmask->phys_hi;
-       mid  = reg[0].phys_mid & pbm->pbm_intmask->phys_mid;
-       lo   = reg[0].phys_lo & pbm->pbm_intmask->phys_lo;
-       irq  = *interrupt & pbm->pbm_intmask->interrupt;
-
-       for (i = 0; i < pbm->num_pbm_intmap; i++) {
-               struct linux_prom_pci_intmap *intmap;
-
-               intmap = &pbm->pbm_intmap[i];
-
-               if (intmap->phys_hi  == hi  &&
-                   intmap->phys_mid == mid &&
-                   intmap->phys_lo  == lo  &&
-                   intmap->interrupt == irq) {
-                       *interrupt = intmap->cinterrupt;
-                       goto success;
-               }
-       }
-
-fail:
-       return 0;
-
-success:
-       if (pci_irq_verbose)
-               printk("%s: Routing bus[%2x] slot[%2x] to INO[%02x]\n",
-                      pbm->name,
-                      pdev->bus->number, PCI_SLOT(pdev->devfn),
-                      *interrupt);
-       return 1;
-}
-
 static void __init pdev_fixup_irq(struct pci_dev *pdev)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
-       struct pci_pbm_info *pbm = pcp->pbm;
-       struct pci_controller_info *p = pbm->parent;
-       unsigned int portid = pbm->portid;
-       unsigned int prom_irq;
-       struct device_node *dp = pcp->prom_node;
-       struct property *prop;
-
-       /* If this is an empty EBUS device, sometimes OBP fails to
-        * give it a valid fully specified interrupts property.
-        * The EBUS hooked up to SunHME on PCI I/O boards of
-        * Ex000 systems is one such case.
-        *
-        * The interrupt is not important so just ignore it.
-        */
-       if (pdev->vendor == PCI_VENDOR_ID_SUN &&
-           pdev->device == PCI_DEVICE_ID_SUN_EBUS &&
-           !dp->child) {
-               pdev->irq = 0;
-               return;
-       }
+       struct of_device *op = pcp->op;
 
-       prop = of_find_property(dp, "interrupts", NULL);
-       if (!prop) {
-               pdev->irq = 0;
+       if (op->irqs[0] == 0xffffffff) {
+               pdev->irq = PCI_IRQ_NONE;
                return;
        }
-       prom_irq = *(unsigned int *) prop->value;
-
-       if (tlb_type != hypervisor) {
-               /* Fully specified already? */
-               if (((prom_irq & PCI_IRQ_IGN) >> 6) == portid) {
-                       pdev->irq = p->irq_build(pbm, pdev, prom_irq);
-                       goto have_irq;
-               }
-
-               /* An onboard device? (bit 5 set) */
-               if ((prom_irq & PCI_IRQ_INO) & 0x20) {
-                       pdev->irq = p->irq_build(pbm, pdev, (portid << 6 | prom_irq));
-                       goto have_irq;
-               }
-       }
-
-       /* Can we find a matching entry in the interrupt-map? */
-       if (pci_intmap_match(pdev, &prom_irq)) {
-               pdev->irq = p->irq_build(pbm, pdev, (portid << 6) | prom_irq);
-               goto have_irq;
-       }
-
-       /* Ok, we have to do it the hard way. */
-       {
-               unsigned int bus, slot, line;
-
-               bus = (pbm == &pbm->parent->pbm_B) ? (1 << 4) : 0;
-
-               /* If we have a legal interrupt property, use it as
-                * the IRQ line.
-                */
-               if (prom_irq > 0 && prom_irq < 5) {
-                       line = ((prom_irq - 1) & 3);
-               } else {
-                       u8 pci_irq_line;
 
-                       /* Else just directly consult PCI config space. */
-                       pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pci_irq_line);
-                       line = ((pci_irq_line - 1) & 3);
-               }
-
-               /* Now figure out the slot.
-                *
-                * Basically, device number zero on the top-level bus is
-                * always the PCI host controller.  Slot 0 is then device 1.
-                * PBM A supports two external slots (0 and 1), and PBM B
-                * supports 4 external slots (0, 1, 2, and 3).  On-board PCI
-                * devices are wired to device numbers outside of these
-                * ranges. -DaveM
-                */
-               if (pdev->bus->number == pbm->pci_first_busno) {
-                       slot = PCI_SLOT(pdev->devfn) - pbm->pci_first_slot;
-               } else {
-                       struct pci_dev *bus_dev;
-
-                       /* Underneath a bridge, use slot number of parent
-                        * bridge which is closest to the PBM.
-                        */
-                       bus_dev = pdev->bus->self;
-                       while (bus_dev->bus &&
-                              bus_dev->bus->number != pbm->pci_first_busno)
-                               bus_dev = bus_dev->bus->self;
-
-                       slot = PCI_SLOT(bus_dev->devfn) - pbm->pci_first_slot;
-               }
-               slot = slot << 2;
-
-               pdev->irq = p->irq_build(pbm, pdev,
-                                        ((portid << 6) & PCI_IRQ_IGN) |
-                                        (bus | slot | line));
-       }
+       pdev->irq = op->irqs[0];
 
-have_irq:
        pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
                              pdev->irq & PCI_IRQ_INO);
 }
index 5b2261ebda6f98bd787ee3e143b55a2861677056..bf7b32b3670564f1834c08ec5918454969471c5c 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/irq.h>
 #include <asm/starfire.h>
 #include <asm/prom.h>
+#include <asm/of_device.h>
 
 #include "pci_impl.h"
 #include "iommu_common.h"
@@ -208,110 +209,6 @@ static struct pci_ops psycho_ops = {
        .write =        psycho_write_pci_cfg,
 };
 
-/* PSYCHO interrupt mapping support. */
-#define PSYCHO_IMAP_A_SLOT0    0x0c00UL
-#define PSYCHO_IMAP_B_SLOT0    0x0c20UL
-static unsigned long psycho_pcislot_imap_offset(unsigned long ino)
-{
-       unsigned int bus =  (ino & 0x10) >> 4;
-       unsigned int slot = (ino & 0x0c) >> 2;
-
-       if (bus == 0)
-               return PSYCHO_IMAP_A_SLOT0 + (slot * 8);
-       else
-               return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
-}
-
-#define PSYCHO_IMAP_SCSI       0x1000UL
-#define PSYCHO_IMAP_ETH                0x1008UL
-#define PSYCHO_IMAP_BPP                0x1010UL
-#define PSYCHO_IMAP_AU_REC     0x1018UL
-#define PSYCHO_IMAP_AU_PLAY    0x1020UL
-#define PSYCHO_IMAP_PFAIL      0x1028UL
-#define PSYCHO_IMAP_KMS                0x1030UL
-#define PSYCHO_IMAP_FLPY       0x1038UL
-#define PSYCHO_IMAP_SHW                0x1040UL
-#define PSYCHO_IMAP_KBD                0x1048UL
-#define PSYCHO_IMAP_MS         0x1050UL
-#define PSYCHO_IMAP_SER                0x1058UL
-#define PSYCHO_IMAP_TIM0       0x1060UL
-#define PSYCHO_IMAP_TIM1       0x1068UL
-#define PSYCHO_IMAP_UE         0x1070UL
-#define PSYCHO_IMAP_CE         0x1078UL
-#define PSYCHO_IMAP_A_ERR      0x1080UL
-#define PSYCHO_IMAP_B_ERR      0x1088UL
-#define PSYCHO_IMAP_PMGMT      0x1090UL
-#define PSYCHO_IMAP_GFX                0x1098UL
-#define PSYCHO_IMAP_EUPA       0x10a0UL
-
-static unsigned long __onboard_imap_off[] = {
-/*0x20*/       PSYCHO_IMAP_SCSI,
-/*0x21*/       PSYCHO_IMAP_ETH,
-/*0x22*/       PSYCHO_IMAP_BPP,
-/*0x23*/       PSYCHO_IMAP_AU_REC,
-/*0x24*/       PSYCHO_IMAP_AU_PLAY,
-/*0x25*/       PSYCHO_IMAP_PFAIL,
-/*0x26*/       PSYCHO_IMAP_KMS,
-/*0x27*/       PSYCHO_IMAP_FLPY,
-/*0x28*/       PSYCHO_IMAP_SHW,
-/*0x29*/       PSYCHO_IMAP_KBD,
-/*0x2a*/       PSYCHO_IMAP_MS,
-/*0x2b*/       PSYCHO_IMAP_SER,
-/*0x2c*/       PSYCHO_IMAP_TIM0,
-/*0x2d*/       PSYCHO_IMAP_TIM1,
-/*0x2e*/       PSYCHO_IMAP_UE,
-/*0x2f*/       PSYCHO_IMAP_CE,
-/*0x30*/       PSYCHO_IMAP_A_ERR,
-/*0x31*/       PSYCHO_IMAP_B_ERR,
-/*0x32*/       PSYCHO_IMAP_PMGMT
-};
-#define PSYCHO_ONBOARD_IRQ_BASE                0x20
-#define PSYCHO_ONBOARD_IRQ_LAST                0x32
-#define psycho_onboard_imap_offset(__ino) \
-       __onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
-
-#define PSYCHO_ICLR_A_SLOT0    0x1400UL
-#define PSYCHO_ICLR_SCSI       0x1800UL
-
-#define psycho_iclr_offset(ino)                                              \
-       ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
-                       (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
-
-static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
-                                    struct pci_dev *pdev,
-                                    unsigned int ino)
-{
-       unsigned long imap, iclr;
-       unsigned long imap_off, iclr_off;
-       int inofixup = 0;
-
-       ino &= PCI_IRQ_INO;
-       if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
-               /* PCI slot */
-               imap_off = psycho_pcislot_imap_offset(ino);
-       } else {
-               /* Onboard device */
-               if (ino > PSYCHO_ONBOARD_IRQ_LAST) {
-                       prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino);
-                       prom_halt();
-               }
-               imap_off = psycho_onboard_imap_offset(ino);
-       }
-
-       /* Now build the IRQ bucket. */
-       imap = pbm->controller_regs + imap_off;
-       imap += 4;
-
-       iclr_off = psycho_iclr_offset(ino);
-       iclr = pbm->controller_regs + iclr_off;
-       iclr += 4;
-
-       if ((ino & 0x20) == 0)
-               inofixup = ino & 0x03;
-
-       return build_irq(inofixup, iclr, imap);
-}
-
 /* PSYCHO error handling support. */
 enum psycho_error_type {
        UE_ERR, CE_ERR, PCI_ERR
@@ -944,51 +841,34 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
 #define  PSYCHO_ECCCTRL_EE      0x8000000000000000UL /* Enable ECC Checking */
 #define  PSYCHO_ECCCTRL_UE      0x4000000000000000UL /* Enable UE Interrupts */
 #define  PSYCHO_ECCCTRL_CE      0x2000000000000000UL /* Enable CE INterrupts */
-#define PSYCHO_UE_INO          0x2e
-#define PSYCHO_CE_INO          0x2f
-#define PSYCHO_PCIERR_A_INO    0x30
-#define PSYCHO_PCIERR_B_INO    0x31
 static void psycho_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
+       struct of_device *op = of_find_device_by_node(pbm->prom_node);
        unsigned long base = p->pbm_A.controller_regs;
-       unsigned int irq, portid = pbm->portid;
        u64 tmp;
 
-       /* Build IRQs and register handlers. */
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_UE_INO);
-       if (request_irq(irq, psycho_ue_intr,
-                       SA_SHIRQ, "PSYCHO UE", p) < 0) {
-               prom_printf("PSYCHO%d: Cannot register UE interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       if (!op)
+               return;
 
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_CE_INO);
-       if (request_irq(irq, psycho_ce_intr,
-                       SA_SHIRQ, "PSYCHO CE", p) < 0) {
-               prom_printf("PSYCHO%d: Cannot register CE interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       /* Psycho interrupt property order is:
+        * 0: PCIERR PBM B INO
+        * 1: UE ERR
+        * 2: CE ERR
+        * 3: POWER FAIL
+        * 4: SPARE HARDWARE
+        * 5: PCIERR PBM A INO
+        */
 
-       pbm = &p->pbm_A;
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO);
-       if (request_irq(irq, psycho_pcierr_intr,
-                       SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) {
-               prom_printf("PSYCHO%d(PBMA): Cannot register PciERR interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       if (op->num_irqs < 6)
+               return;
 
-       pbm = &p->pbm_B;
-       irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO);
-       if (request_irq(irq, psycho_pcierr_intr,
-                       SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) {
-               prom_printf("PSYCHO%d(PBMB): Cannot register PciERR interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       request_irq(op->irqs[1], psycho_ue_intr, SA_SHIRQ, "PSYCHO UE", p);
+       request_irq(op->irqs[2], psycho_ce_intr, SA_SHIRQ, "PSYCHO CE", p);
+       request_irq(op->irqs[5], psycho_pcierr_intr, SA_SHIRQ,
+                   "PSYCHO PCIERR-A", &p->pbm_A);
+       request_irq(op->irqs[0], psycho_pcierr_intr, SA_SHIRQ,
+                   "PSYCHO PCIERR-B", &p->pbm_B);
 
        /* Enable UE and CE interrupts for controller. */
        psycho_write(base + PSYCHO_ECC_CTRL,
@@ -1171,9 +1051,7 @@ static void psycho_iommu_init(struct pci_controller_info *p)
 
        /* If necessary, hook us up for starfire IRQ translations. */
        if (this_is_starfire)
-               p->starfire_cookie = starfire_hookup(p->pbm_A.portid);
-       else
-               p->starfire_cookie = NULL;
+               starfire_hookup(p->pbm_A.portid);
 }
 
 #define PSYCHO_IRQ_RETRY       0x1a00UL
@@ -1408,7 +1286,6 @@ void psycho_init(struct device_node *dp, char *model_name)
        p->index = pci_num_controllers++;
        p->pbms_same_domain = 0;
        p->scan_bus = psycho_scan_bus;
-       p->irq_build = psycho_irq_build;
        p->base_address_update = psycho_base_address_update;
        p->resource_adjust = psycho_resource_adjust;
        p->pci_ops = &psycho_ops;
index 26f194ce4400082774ae5bcb5a96e6be062ef1e8..5e087b0fb4c90b9db6d9b3d5fdfed67122cd8eda 100644 (file)
@@ -485,114 +485,6 @@ static struct pci_ops sabre_ops = {
        .write =        sabre_write_pci_cfg,
 };
 
-static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
-{
-       unsigned int bus =  (ino & 0x10) >> 4;
-       unsigned int slot = (ino & 0x0c) >> 2;
-
-       if (bus == 0)
-               return SABRE_IMAP_A_SLOT0 + (slot * 8);
-       else
-               return SABRE_IMAP_B_SLOT0 + (slot * 8);
-}
-
-static unsigned long __onboard_imap_off[] = {
-/*0x20*/       SABRE_IMAP_SCSI,
-/*0x21*/       SABRE_IMAP_ETH,
-/*0x22*/       SABRE_IMAP_BPP,
-/*0x23*/       SABRE_IMAP_AU_REC,
-/*0x24*/       SABRE_IMAP_AU_PLAY,
-/*0x25*/       SABRE_IMAP_PFAIL,
-/*0x26*/       SABRE_IMAP_KMS,
-/*0x27*/       SABRE_IMAP_FLPY,
-/*0x28*/       SABRE_IMAP_SHW,
-/*0x29*/       SABRE_IMAP_KBD,
-/*0x2a*/       SABRE_IMAP_MS,
-/*0x2b*/       SABRE_IMAP_SER,
-/*0x2c*/       0 /* reserved */,
-/*0x2d*/       0 /* reserved */,
-/*0x2e*/       SABRE_IMAP_UE,
-/*0x2f*/       SABRE_IMAP_CE,
-/*0x30*/       SABRE_IMAP_PCIERR,
-};
-#define SABRE_ONBOARD_IRQ_BASE         0x20
-#define SABRE_ONBOARD_IRQ_LAST         0x30
-#define sabre_onboard_imap_offset(__ino) \
-       __onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
-
-#define sabre_iclr_offset(ino)                                       \
-       ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
-                       (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
-
-/* When a device lives behind a bridge deeper in the PCI bus topology
- * than APB, a special sequence must run to make sure all pending DMA
- * transfers at the time of IRQ delivery are visible in the coherency
- * domain by the cpu.  This sequence is to perform a read on the far
- * side of the non-APB bridge, then perform a read of Sabre's DMA
- * write-sync register.
- */
-static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
-{
-       struct pci_dev *pdev = _arg1;
-       unsigned long sync_reg = (unsigned long) _arg2;
-       u16 _unused;
-
-       pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused);
-       sabre_read(sync_reg);
-}
-
-static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
-                                   struct pci_dev *pdev,
-                                   unsigned int ino)
-{
-       unsigned long imap, iclr;
-       unsigned long imap_off, iclr_off;
-       int inofixup = 0;
-       int virt_irq;
-
-       ino &= PCI_IRQ_INO;
-       if (ino < SABRE_ONBOARD_IRQ_BASE) {
-               /* PCI slot */
-               imap_off = sabre_pcislot_imap_offset(ino);
-       } else {
-               /* onboard device */
-               if (ino > SABRE_ONBOARD_IRQ_LAST) {
-                       prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
-                       prom_halt();
-               }
-               imap_off = sabre_onboard_imap_offset(ino);
-       }
-
-       /* Now build the IRQ bucket. */
-       imap = pbm->controller_regs + imap_off;
-       imap += 4;
-
-       iclr_off = sabre_iclr_offset(ino);
-       iclr = pbm->controller_regs + iclr_off;
-       iclr += 4;
-
-       if ((ino & 0x20) == 0)
-               inofixup = ino & 0x03;
-
-       virt_irq = build_irq(inofixup, iclr, imap);
-
-       if (pdev) {
-               struct pcidev_cookie *pcp = pdev->sysdata;
-
-               if (pdev->bus->number != pcp->pbm->pci_first_busno) {
-                       struct pci_controller_info *p = pcp->pbm->parent;
-
-                       irq_install_pre_handler(virt_irq,
-                                               sabre_wsync_handler,
-                                               pdev,
-                                               (void *)
-                                               p->pbm_A.controller_regs +
-                                               SABRE_WRSYNC);
-               }
-       }
-       return virt_irq;
-}
-
 /* SABRE error handling support. */
 static void sabre_check_iommu_error(struct pci_controller_info *p,
                                    unsigned long afsr,
@@ -929,17 +821,30 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
        return IRQ_HANDLED;
 }
 
-/* XXX What about PowerFail/PowerManagement??? -DaveM */
-#define SABRE_UE_INO           0x2e
-#define SABRE_CE_INO           0x2f
-#define SABRE_PCIERR_INO       0x30
 static void sabre_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
+       struct device_node *dp = pbm->prom_node;
+       struct of_device *op;
        unsigned long base = pbm->controller_regs;
-       unsigned long irq, portid = pbm->portid;
        u64 tmp;
 
+       if (pbm->chip_type == PBM_CHIP_TYPE_SABRE)
+               dp = dp->parent;
+
+       op = of_find_device_by_node(dp);
+       if (!op)
+               return;
+
+       /* Sabre/Hummingbird IRQ property layout is:
+        * 0: PCI ERR
+        * 1: UE ERR
+        * 2: CE ERR
+        * 3: POWER FAIL
+        */
+       if (op->num_irqs < 4)
+               return;
+
        /* We clear the error bits in the appropriate AFSR before
         * registering the handler so that we don't get spurious
         * interrupts.
@@ -948,32 +853,16 @@ static void sabre_register_error_handlers(struct pci_controller_info *p)
                    (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
                     SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
                     SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE));
-       irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_UE_INO);
-       if (request_irq(irq, sabre_ue_intr,
-                       SA_SHIRQ, "SABRE UE", p) < 0) {
-               prom_printf("SABRE%d: Cannot register UE interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+
+       request_irq(op->irqs[1], sabre_ue_intr, SA_SHIRQ, "SABRE UE", p);
 
        sabre_write(base + SABRE_CE_AFSR,
                    (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
                     SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR));
-       irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_CE_INO);
-       if (request_irq(irq, sabre_ce_intr,
-                       SA_SHIRQ, "SABRE CE", p) < 0) {
-               prom_printf("SABRE%d: Cannot register CE interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
 
-       irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_PCIERR_INO);
-       if (request_irq(irq, sabre_pcierr_intr,
-                       SA_SHIRQ, "SABRE PCIERR", p) < 0) {
-               prom_printf("SABRE%d: Cannot register PciERR interrupt.\n",
-                           p->index);
-               prom_halt();
-       }
+       request_irq(op->irqs[2], sabre_ce_intr, SA_SHIRQ, "SABRE CE", p);
+       request_irq(op->irqs[0], sabre_pcierr_intr, SA_SHIRQ,
+                   "SABRE PCIERR", p);
 
        tmp = sabre_read(base + SABRE_PCICTRL);
        tmp |= SABRE_PCICTRL_ERREN;
@@ -1492,7 +1381,6 @@ void sabre_init(struct device_node *dp, char *model_name)
        p->index = pci_num_controllers++;
        p->pbms_same_domain = 1;
        p->scan_bus = sabre_scan_bus;
-       p->irq_build = sabre_irq_build;
        p->base_address_update = sabre_base_address_update;
        p->resource_adjust = sabre_resource_adjust;
        p->pci_ops = &sabre_ops;
index f16449ccd7bc389d172509976e7171a3ca3c2125..5c6e2a9b91f8000e88587e5b29a6bfdbbe030ffc 100644 (file)
@@ -217,116 +217,6 @@ static struct pci_ops schizo_ops = {
        .write =        schizo_write_pci_cfg,
 };
 
-/* SCHIZO interrupt mapping support.  Unlike Psycho, for this controller the
- * imap/iclr registers are per-PBM.
- */
-#define SCHIZO_IMAP_BASE       0x1000UL
-#define SCHIZO_ICLR_BASE       0x1400UL
-
-static unsigned long schizo_imap_offset(unsigned long ino)
-{
-       return SCHIZO_IMAP_BASE + (ino * 8UL);
-}
-
-static unsigned long schizo_iclr_offset(unsigned long ino)
-{
-       return SCHIZO_ICLR_BASE + (ino * 8UL);
-}
-
-static void tomatillo_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
-{
-       unsigned long sync_reg = (unsigned long) _arg2;
-       u64 mask = 1UL << (ino & IMAP_INO);
-       u64 val;
-       int limit;
-
-       schizo_write(sync_reg, mask);
-
-       limit = 100000;
-       val = 0;
-       while (--limit) {
-               val = schizo_read(sync_reg);
-               if (!(val & mask))
-                       break;
-       }
-       if (limit <= 0) {
-               printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n",
-                      val, mask);
-       }
-
-       if (_arg1) {
-               static unsigned char cacheline[64]
-                       __attribute__ ((aligned (64)));
-
-               __asm__ __volatile__("rd %%fprs, %0\n\t"
-                                    "or %0, %4, %1\n\t"
-                                    "wr %1, 0x0, %%fprs\n\t"
-                                    "stda %%f0, [%5] %6\n\t"
-                                    "wr %0, 0x0, %%fprs\n\t"
-                                    "membar #Sync"
-                                    : "=&r" (mask), "=&r" (val)
-                                    : "0" (mask), "1" (val),
-                                    "i" (FPRS_FEF), "r" (&cacheline[0]),
-                                    "i" (ASI_BLK_COMMIT_P));
-       }
-}
-
-static unsigned long schizo_ino_to_iclr(struct pci_pbm_info *pbm,
-                                       unsigned int ino)
-{
-       ino &= PCI_IRQ_INO;
-       return pbm->pbm_regs + schizo_iclr_offset(ino) + 4;
-}
-
-static unsigned long schizo_ino_to_imap(struct pci_pbm_info *pbm,
-                                       unsigned int ino)
-{
-       ino &= PCI_IRQ_INO;
-       return pbm->pbm_regs + schizo_imap_offset(ino) + 4;
-}
-
-static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
-                                    struct pci_dev *pdev,
-                                    unsigned int ino)
-{
-       unsigned long imap, iclr;
-       int ign_fixup;
-       int virt_irq;
-
-       ino &= PCI_IRQ_INO;
-
-       /* Now build the IRQ bucket. */
-       imap = schizo_ino_to_imap(pbm, ino);
-       iclr = schizo_ino_to_iclr(pbm, ino);
-
-       /* On Schizo, no inofixup occurs.  This is because each
-        * INO has it's own IMAP register.  On Psycho and Sabre
-        * there is only one IMAP register for each PCI slot even
-        * though four different INOs can be generated by each
-        * PCI slot.
-        *
-        * But, for JBUS variants (essentially, Tomatillo), we have
-        * to fixup the lowest bit of the interrupt group number.
-        */
-       ign_fixup = 0;
-       if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
-               if (pbm->portid & 1)
-                       ign_fixup = (1 << 6);
-       }
-
-       virt_irq = build_irq(ign_fixup, iclr, imap);
-
-       if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
-               irq_install_pre_handler(virt_irq,
-                                       tomatillo_wsync_handler,
-                                       ((pbm->chip_version <= 4) ?
-                                        (void *) 1 : (void *) 0),
-                                       (void *) pbm->sync_reg);
-       }
-
-       return virt_irq;
-}
-
 /* SCHIZO error handling support. */
 enum schizo_error_type {
        UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR
@@ -362,34 +252,6 @@ struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
        return &p->pbm_A;
 }
 
-static void schizo_clear_other_err_intr(struct pci_controller_info *p, int irq)
-{
-       struct pci_pbm_info *pbm;
-       unsigned long iclr;
-
-       /* Do not clear the interrupt for the other PCI bus.
-        *
-        * This "ACK both PBM IRQs" only needs to be performed
-        * for chip-wide error interrupts.
-        */
-       if ((irq & IMAP_INO) == SCHIZO_PCIERR_A_INO ||
-           (irq & IMAP_INO) == SCHIZO_PCIERR_B_INO)
-               return;
-
-       pbm = pbm_for_ino(p, irq);
-       if (pbm == &p->pbm_A)
-               pbm = &p->pbm_B;
-       else
-               pbm = &p->pbm_A;
-
-       schizo_irq_build(pbm, NULL,
-                        (pbm->portid << 6) | (irq & IMAP_INO));
-
-       iclr = schizo_ino_to_iclr(pbm,
-                                 (pbm->portid << 6) | (irq & IMAP_INO));
-       upa_writel(ICLR_IDLE, iclr);
-}
-
 #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */
 #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */
 #define SCHIZO_STC_LINE        0xbb00UL /* --> 0xbb80 */
@@ -720,8 +582,6 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
        /* Interrogate IOMMU for error status. */
        schizo_check_iommu_error(p, UE_ERR);
 
-       schizo_clear_other_err_intr(p, irq);
-
        return IRQ_HANDLED;
 }
 
@@ -811,8 +671,6 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
                printk("(none)");
        printk("]\n");
 
-       schizo_clear_other_err_intr(p, irq);
-
        return IRQ_HANDLED;
 }
 
@@ -1033,8 +891,6 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
        if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR))
                pci_scan_for_parity_error(p, pbm, pbm->pci_bus);
 
-       schizo_clear_other_err_intr(p, irq);
-
        return IRQ_HANDLED;
 }
 
@@ -1090,7 +946,6 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
                printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n",
                       p->index, errlog);
 
-               schizo_clear_other_err_intr(p, irq);
                return IRQ_HANDLED;
        }
 
@@ -1098,7 +953,6 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
               p->index);
        schizo_check_iommu_error(p, SAFARI_ERR);
 
-       schizo_clear_other_err_intr(p, irq);
        return IRQ_HANDLED;
 }
 
@@ -1130,74 +984,47 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
 static void tomatillo_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm;
-       unsigned int irq;
+       struct of_device *op;
        u64 tmp, err_mask, err_no_mask;
 
-       /* Build IRQs and register handlers. */
+       /* Tomatillo IRQ property layout is:
+        * 0: PCIERR
+        * 1: UE ERR
+        * 2: CE ERR
+        * 3: SERR
+        * 4: POWER FAIL?
+        */
+
        pbm = pbm_for_ino(p, SCHIZO_UE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO);
-       if (request_irq(irq, schizo_ue_intr,
-                       SA_SHIRQ, "TOMATILLO UE", p) < 0) {
-               prom_printf("%s: Cannot register UE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_UE_INO));
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_UE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[1], schizo_ue_intr, SA_SHIRQ,
+                           "TOMATILLO_UE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_CE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO);
-       if (request_irq(irq, schizo_ce_intr,
-                       SA_SHIRQ, "TOMATILLO CE", p) < 0) {
-               prom_printf("%s: Cannot register CE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_CE_INO));
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_CE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[2], schizo_ce_intr, SA_SHIRQ,
+                           "TOMATILLO CE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO);
-       irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) |
-                                          SCHIZO_PCIERR_A_INO));
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) {
-               prom_printf("%s: Cannot register PBM A PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, ((pbm->portid << 6) |
-                                                SCHIZO_PCIERR_A_INO)));
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ,
+                           "TOMATILLO PCIERR-A", pbm);
+
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO);
-       irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) |
-                                           SCHIZO_PCIERR_B_INO));
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) {
-               prom_printf("%s: Cannot register PBM B PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, ((pbm->portid << 6) |
-                                                SCHIZO_PCIERR_B_INO)));
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ,
+                           "TOMATILLO PCIERR-B", pbm);
 
        pbm = pbm_for_ino(p, SCHIZO_SERR_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO);
-       if (request_irq(irq, schizo_safarierr_intr,
-                       SA_SHIRQ, "TOMATILLO SERR", p) < 0) {
-               prom_printf("%s: Cannot register SafariERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, ((pbm->portid << 6) |
-                                                SCHIZO_SERR_INO)));
-       upa_writel(tmp, (pbm->pbm_regs +
-                        schizo_imap_offset(SCHIZO_SERR_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[3], schizo_safarierr_intr, SA_SHIRQ,
+                           "TOMATILLO SERR", p);
 
        /* Enable UE and CE interrupts for controller. */
        schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL,
@@ -1265,64 +1092,47 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p)
 static void schizo_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm;
-       unsigned int irq;
+       struct of_device *op;
        u64 tmp, err_mask, err_no_mask;
 
-       /* Build IRQs and register handlers. */
+       /* Schizo IRQ property layout is:
+        * 0: PCIERR
+        * 1: UE ERR
+        * 2: CE ERR
+        * 3: SERR
+        * 4: POWER FAIL?
+        */
+
        pbm = pbm_for_ino(p, SCHIZO_UE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO);
-       if (request_irq(irq, schizo_ue_intr,
-                       SA_SHIRQ, "SCHIZO UE", p) < 0) {
-               prom_printf("%s: Cannot register UE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_UE_INO));
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_UE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[1], schizo_ue_intr, SA_SHIRQ,
+                           "SCHIZO_UE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_CE_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO);
-       if (request_irq(irq, schizo_ce_intr,
-                       SA_SHIRQ, "SCHIZO CE", p) < 0) {
-               prom_printf("%s: Cannot register CE interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_CE_INO));
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_CE_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[2], schizo_ce_intr, SA_SHIRQ,
+                           "SCHIZO CE", p);
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_A_INO);
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "SCHIZO PCIERR", pbm) < 0) {
-               prom_printf("%s: Cannot register PBM A PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_PCIERR_A_INO));
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ,
+                           "SCHIZO PCIERR-A", pbm);
+
 
        pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_B_INO);
-       if (request_irq(irq, schizo_pcierr_intr,
-                       SA_SHIRQ, "SCHIZO PCIERR", &p->pbm_B) < 0) {
-               prom_printf("%s: Cannot register PBM B PciERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_PCIERR_B_INO));
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ,
+                           "SCHIZO PCIERR-B", pbm);
 
        pbm = pbm_for_ino(p, SCHIZO_SERR_INO);
-       irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO);
-       if (request_irq(irq, schizo_safarierr_intr,
-                       SA_SHIRQ, "SCHIZO SERR", p) < 0) {
-               prom_printf("%s: Cannot register SafariERR interrupt.\n",
-                           pbm->name);
-               prom_halt();
-       }
-       tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_SERR_INO));
-       upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_SERR_INO) + 4));
+       op = of_find_device_by_node(pbm->prom_node);
+       if (op)
+               request_irq(op->irqs[3], schizo_safarierr_intr, SA_SHIRQ,
+                           "SCHIZO SERR", p);
 
        /* Enable UE and CE interrupts for controller. */
        schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL,
@@ -2022,7 +1832,6 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ
        p->scan_bus = (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
                       tomatillo_scan_bus :
                       schizo_scan_bus);
-       p->irq_build = schizo_irq_build;
        p->base_address_update = schizo_base_address_update;
        p->resource_adjust = schizo_resource_adjust;
        p->pci_ops = &schizo_ops;
index b69e2270a721103099184cbe3b456a48702b99c2..03ad4c06758ed95fd59d996a11fcc7784bc2c54b 100644 (file)
@@ -843,15 +843,6 @@ static void pci_sun4v_scan_bus(struct pci_controller_info *p)
        /* XXX register error interrupt handlers XXX */
 }
 
-static unsigned int pci_sun4v_irq_build(struct pci_pbm_info *pbm,
-                                       struct pci_dev *pdev,
-                                       unsigned int devino)
-{
-       u32 devhandle = pbm->devhandle;
-
-       return sun4v_build_irq(devhandle, devino);
-}
-
 static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
@@ -1200,7 +1191,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
        p->pbms_same_domain = 0;
 
        p->scan_bus = pci_sun4v_scan_bus;
-       p->irq_build = pci_sun4v_irq_build;
        p->base_address_update = pci_sun4v_base_address_update;
        p->resource_adjust = pci_sun4v_resource_adjust;
        p->pci_ops = &pci_sun4v_ops;
index 9496c77340143e3f1e650990607b684ea5b85023..4febeda958a3fee5585683b4bb1eddbf7e7a06cb 100644 (file)
 #include <linux/pm.h>
 
 #include <asm/system.h>
-#include <asm/ebus.h>
-#include <asm/isa.h>
 #include <asm/auxio.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+#include <asm/io.h>
 
 #include <linux/unistd.h>
 
@@ -30,6 +31,7 @@
 int scons_pwroff = 1; 
 
 #ifdef CONFIG_PCI
+#include <linux/pci.h>
 static void __iomem *power_reg;
 
 static DECLARE_WAIT_QUEUE_HEAD(powerd_wait);
@@ -115,27 +117,33 @@ static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
        return 1;
 }
 
-static void __devinit power_probe_common(struct of_device *dev, struct resource *res, unsigned int irq)
+static int __devinit power_probe(struct of_device *op, const struct of_device_id *match)
 {
-       power_reg = ioremap(res->start, 0x4);
+       struct resource *res = &op->resource[0];
+       unsigned int irq= op->irqs[0];
 
-       printk("power: Control reg at %p ... ", power_reg);
+       power_reg = of_ioremap(res, 0, 0x4, "power");
+
+       printk("%s: Control reg at %lx ... ",
+              op->node->name, res->start);
 
        poweroff_method = machine_halt;  /* able to use the standard halt */
 
-       if (has_button_interrupt(irq, dev->node)) {
+       if (has_button_interrupt(irq, op->node)) {
                if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
                        printk("Failed to start power daemon.\n");
-                       return;
+                       return 0;
                }
                printk("powerd running.\n");
 
                if (request_irq(irq,
-                               power_handler, SA_SHIRQ, "power", NULL) < 0)
+                               power_handler, 0, "power", NULL) < 0)
                        printk("power: Error, cannot register IRQ handler.\n");
        } else {
                printk("not using powerd.\n");
        }
+
+       return 0;
 }
 
 static struct of_device_id power_match[] = {
@@ -145,44 +153,15 @@ static struct of_device_id power_match[] = {
        {},
 };
 
-static int __devinit ebus_power_probe(struct of_device *dev, const struct of_device_id *match)
-{
-       struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
-       struct resource *res = &edev->resource[0];
-       unsigned int irq = edev->irqs[0];
-
-       power_probe_common(dev, res,irq);
-
-       return 0;
-}
-
-static struct of_platform_driver ebus_power_driver = {
-       .name           = "power",
-       .match_table    = power_match,
-       .probe          = ebus_power_probe,
-};
-
-static int __devinit isa_power_probe(struct of_device *dev, const struct of_device_id *match)
-{
-       struct sparc_isa_device *idev = to_isa_device(&dev->dev);
-       struct resource *res = &idev->resource;
-       unsigned int irq = idev->irq;
-
-       power_probe_common(dev, res,irq);
-
-       return 0;
-}
-
-static struct of_platform_driver isa_power_driver = {
+static struct of_platform_driver power_driver = {
        .name           = "power",
        .match_table    = power_match,
-       .probe          = isa_power_probe,
+       .probe          = power_probe,
 };
 
 void __init power_init(void)
 {
-       of_register_driver(&ebus_power_driver, &ebus_bus_type);
-       of_register_driver(&isa_power_driver, &isa_bus_type);
+       of_register_driver(&power_driver, &of_bus_type);
        return;
 }
 #endif /* CONFIG_PCI */
index 8e87e7ea0325bb5861ddbf3f16c523416c70ac9c..8a70c52c0447a92d593e9f6f832db36635e3217e 100644 (file)
@@ -15,6 +15,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/module.h>
 
 #include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/oplib.h>
+#include <asm/irq.h>
+#include <asm/asi.h>
+#include <asm/upa.h>
 
 static struct device_node *allnodes;
 
@@ -190,6 +195,36 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
 }
 EXPORT_SYMBOL(of_getintprop_default);
 
+int of_n_addr_cells(struct device_node *np)
+{
+       int* ip;
+       do {
+               if (np->parent)
+                       np = np->parent;
+               ip = of_get_property(np, "#address-cells", NULL);
+               if (ip != NULL)
+                       return *ip;
+       } while (np->parent);
+       /* No #address-cells property for the root node, default to 2 */
+       return 2;
+}
+EXPORT_SYMBOL(of_n_addr_cells);
+
+int of_n_size_cells(struct device_node *np)
+{
+       int* ip;
+       do {
+               if (np->parent)
+                       np = np->parent;
+               ip = of_get_property(np, "#size-cells", NULL);
+               if (ip != NULL)
+                       return *ip;
+       } while (np->parent);
+       /* No #size-cells property for the root node, default to 1 */
+       return 1;
+}
+EXPORT_SYMBOL(of_n_size_cells);
+
 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
 {
        struct property **prevp;
@@ -253,6 +288,754 @@ static void * __init prom_early_alloc(unsigned long size)
        return ret;
 }
 
+#ifdef CONFIG_PCI
+/* PSYCHO interrupt mapping support. */
+#define PSYCHO_IMAP_A_SLOT0    0x0c00UL
+#define PSYCHO_IMAP_B_SLOT0    0x0c20UL
+static unsigned long psycho_pcislot_imap_offset(unsigned long ino)
+{
+       unsigned int bus =  (ino & 0x10) >> 4;
+       unsigned int slot = (ino & 0x0c) >> 2;
+
+       if (bus == 0)
+               return PSYCHO_IMAP_A_SLOT0 + (slot * 8);
+       else
+               return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
+}
+
+#define PSYCHO_IMAP_SCSI       0x1000UL
+#define PSYCHO_IMAP_ETH                0x1008UL
+#define PSYCHO_IMAP_BPP                0x1010UL
+#define PSYCHO_IMAP_AU_REC     0x1018UL
+#define PSYCHO_IMAP_AU_PLAY    0x1020UL
+#define PSYCHO_IMAP_PFAIL      0x1028UL
+#define PSYCHO_IMAP_KMS                0x1030UL
+#define PSYCHO_IMAP_FLPY       0x1038UL
+#define PSYCHO_IMAP_SHW                0x1040UL
+#define PSYCHO_IMAP_KBD                0x1048UL
+#define PSYCHO_IMAP_MS         0x1050UL
+#define PSYCHO_IMAP_SER                0x1058UL
+#define PSYCHO_IMAP_TIM0       0x1060UL
+#define PSYCHO_IMAP_TIM1       0x1068UL
+#define PSYCHO_IMAP_UE         0x1070UL
+#define PSYCHO_IMAP_CE         0x1078UL
+#define PSYCHO_IMAP_A_ERR      0x1080UL
+#define PSYCHO_IMAP_B_ERR      0x1088UL
+#define PSYCHO_IMAP_PMGMT      0x1090UL
+#define PSYCHO_IMAP_GFX                0x1098UL
+#define PSYCHO_IMAP_EUPA       0x10a0UL
+
+static unsigned long __psycho_onboard_imap_off[] = {
+/*0x20*/       PSYCHO_IMAP_SCSI,
+/*0x21*/       PSYCHO_IMAP_ETH,
+/*0x22*/       PSYCHO_IMAP_BPP,
+/*0x23*/       PSYCHO_IMAP_AU_REC,
+/*0x24*/       PSYCHO_IMAP_AU_PLAY,
+/*0x25*/       PSYCHO_IMAP_PFAIL,
+/*0x26*/       PSYCHO_IMAP_KMS,
+/*0x27*/       PSYCHO_IMAP_FLPY,
+/*0x28*/       PSYCHO_IMAP_SHW,
+/*0x29*/       PSYCHO_IMAP_KBD,
+/*0x2a*/       PSYCHO_IMAP_MS,
+/*0x2b*/       PSYCHO_IMAP_SER,
+/*0x2c*/       PSYCHO_IMAP_TIM0,
+/*0x2d*/       PSYCHO_IMAP_TIM1,
+/*0x2e*/       PSYCHO_IMAP_UE,
+/*0x2f*/       PSYCHO_IMAP_CE,
+/*0x30*/       PSYCHO_IMAP_A_ERR,
+/*0x31*/       PSYCHO_IMAP_B_ERR,
+/*0x32*/       PSYCHO_IMAP_PMGMT
+};
+#define PSYCHO_ONBOARD_IRQ_BASE                0x20
+#define PSYCHO_ONBOARD_IRQ_LAST                0x32
+#define psycho_onboard_imap_offset(__ino) \
+       __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
+
+#define PSYCHO_ICLR_A_SLOT0    0x1400UL
+#define PSYCHO_ICLR_SCSI       0x1800UL
+
+#define psycho_iclr_offset(ino)                                              \
+       ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
+                       (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
+
+static unsigned int psycho_irq_build(struct device_node *dp,
+                                    unsigned int ino,
+                                    void *_data)
+{
+       unsigned long controller_regs = (unsigned long) _data;
+       unsigned long imap, iclr;
+       unsigned long imap_off, iclr_off;
+       int inofixup = 0;
+
+       ino &= 0x3f;
+       if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
+               /* PCI slot */
+               imap_off = psycho_pcislot_imap_offset(ino);
+       } else {
+               /* Onboard device */
+               if (ino > PSYCHO_ONBOARD_IRQ_LAST) {
+                       prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino);
+                       prom_halt();
+               }
+               imap_off = psycho_onboard_imap_offset(ino);
+       }
+
+       /* Now build the IRQ bucket. */
+       imap = controller_regs + imap_off;
+       imap += 4;
+
+       iclr_off = psycho_iclr_offset(ino);
+       iclr = controller_regs + iclr_off;
+       iclr += 4;
+
+       if ((ino & 0x20) == 0)
+               inofixup = ino & 0x03;
+
+       return build_irq(inofixup, iclr, imap);
+}
+
+static void psycho_irq_trans_init(struct device_node *dp)
+{
+       struct linux_prom64_registers *regs;
+
+       dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+       dp->irq_trans->irq_build = psycho_irq_build;
+
+       regs = of_get_property(dp, "reg", NULL);
+       dp->irq_trans->data = (void *) regs[2].phys_addr;
+}
+
+#define sabre_read(__reg) \
+({     u64 __ret; \
+       __asm__ __volatile__("ldxa [%1] %2, %0" \
+                            : "=r" (__ret) \
+                            : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
+                            : "memory"); \
+       __ret; \
+})
+
+struct sabre_irq_data {
+       unsigned long controller_regs;
+       unsigned int pci_first_busno;
+};
+#define SABRE_CONFIGSPACE      0x001000000UL
+#define SABRE_WRSYNC           0x1c20UL
+
+#define SABRE_CONFIG_BASE(CONFIG_SPACE)        \
+       (CONFIG_SPACE | (1UL << 24))
+#define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG)   \
+       (((unsigned long)(BUS)   << 16) |       \
+        ((unsigned long)(DEVFN) << 8)  |       \
+        ((unsigned long)(REG)))
+
+/* When a device lives behind a bridge deeper in the PCI bus topology
+ * than APB, a special sequence must run to make sure all pending DMA
+ * transfers at the time of IRQ delivery are visible in the coherency
+ * domain by the cpu.  This sequence is to perform a read on the far
+ * side of the non-APB bridge, then perform a read of Sabre's DMA
+ * write-sync register.
+ */
+static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
+{
+       unsigned int phys_hi = (unsigned int) (unsigned long) _arg1;
+       struct sabre_irq_data *irq_data = _arg2;
+       unsigned long controller_regs = irq_data->controller_regs;
+       unsigned long sync_reg = controller_regs + SABRE_WRSYNC;
+       unsigned long config_space = controller_regs + SABRE_CONFIGSPACE;
+       unsigned int bus, devfn;
+       u16 _unused;
+
+       config_space = SABRE_CONFIG_BASE(config_space);
+
+       bus = (phys_hi >> 16) & 0xff;
+       devfn = (phys_hi >> 8) & 0xff;
+
+       config_space |= SABRE_CONFIG_ENCODE(bus, devfn, 0x00);
+
+       __asm__ __volatile__("membar #Sync\n\t"
+                            "lduha [%1] %2, %0\n\t"
+                            "membar #Sync"
+                            : "=r" (_unused)
+                            : "r" ((u16 *) config_space),
+                              "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+
+       sabre_read(sync_reg);
+}
+
+#define SABRE_IMAP_A_SLOT0     0x0c00UL
+#define SABRE_IMAP_B_SLOT0     0x0c20UL
+#define SABRE_IMAP_SCSI                0x1000UL
+#define SABRE_IMAP_ETH         0x1008UL
+#define SABRE_IMAP_BPP         0x1010UL
+#define SABRE_IMAP_AU_REC      0x1018UL
+#define SABRE_IMAP_AU_PLAY     0x1020UL
+#define SABRE_IMAP_PFAIL       0x1028UL
+#define SABRE_IMAP_KMS         0x1030UL
+#define SABRE_IMAP_FLPY                0x1038UL
+#define SABRE_IMAP_SHW         0x1040UL
+#define SABRE_IMAP_KBD         0x1048UL
+#define SABRE_IMAP_MS          0x1050UL
+#define SABRE_IMAP_SER         0x1058UL
+#define SABRE_IMAP_UE          0x1070UL
+#define SABRE_IMAP_CE          0x1078UL
+#define SABRE_IMAP_PCIERR      0x1080UL
+#define SABRE_IMAP_GFX         0x1098UL
+#define SABRE_IMAP_EUPA                0x10a0UL
+#define SABRE_ICLR_A_SLOT0     0x1400UL
+#define SABRE_ICLR_B_SLOT0     0x1480UL
+#define SABRE_ICLR_SCSI                0x1800UL
+#define SABRE_ICLR_ETH         0x1808UL
+#define SABRE_ICLR_BPP         0x1810UL
+#define SABRE_ICLR_AU_REC      0x1818UL
+#define SABRE_ICLR_AU_PLAY     0x1820UL
+#define SABRE_ICLR_PFAIL       0x1828UL
+#define SABRE_ICLR_KMS         0x1830UL
+#define SABRE_ICLR_FLPY                0x1838UL
+#define SABRE_ICLR_SHW         0x1840UL
+#define SABRE_ICLR_KBD         0x1848UL
+#define SABRE_ICLR_MS          0x1850UL
+#define SABRE_ICLR_SER         0x1858UL
+#define SABRE_ICLR_UE          0x1870UL
+#define SABRE_ICLR_CE          0x1878UL
+#define SABRE_ICLR_PCIERR      0x1880UL
+
+static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
+{
+       unsigned int bus =  (ino & 0x10) >> 4;
+       unsigned int slot = (ino & 0x0c) >> 2;
+
+       if (bus == 0)
+               return SABRE_IMAP_A_SLOT0 + (slot * 8);
+       else
+               return SABRE_IMAP_B_SLOT0 + (slot * 8);
+}
+
+static unsigned long __sabre_onboard_imap_off[] = {
+/*0x20*/       SABRE_IMAP_SCSI,
+/*0x21*/       SABRE_IMAP_ETH,
+/*0x22*/       SABRE_IMAP_BPP,
+/*0x23*/       SABRE_IMAP_AU_REC,
+/*0x24*/       SABRE_IMAP_AU_PLAY,
+/*0x25*/       SABRE_IMAP_PFAIL,
+/*0x26*/       SABRE_IMAP_KMS,
+/*0x27*/       SABRE_IMAP_FLPY,
+/*0x28*/       SABRE_IMAP_SHW,
+/*0x29*/       SABRE_IMAP_KBD,
+/*0x2a*/       SABRE_IMAP_MS,
+/*0x2b*/       SABRE_IMAP_SER,
+/*0x2c*/       0 /* reserved */,
+/*0x2d*/       0 /* reserved */,
+/*0x2e*/       SABRE_IMAP_UE,
+/*0x2f*/       SABRE_IMAP_CE,
+/*0x30*/       SABRE_IMAP_PCIERR,
+};
+#define SABRE_ONBOARD_IRQ_BASE         0x20
+#define SABRE_ONBOARD_IRQ_LAST         0x30
+#define sabre_onboard_imap_offset(__ino) \
+       __sabre_onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
+
+#define sabre_iclr_offset(ino)                                       \
+       ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
+                       (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
+
+static unsigned int sabre_irq_build(struct device_node *dp,
+                                   unsigned int ino,
+                                   void *_data)
+{
+       struct sabre_irq_data *irq_data = _data;
+       unsigned long controller_regs = irq_data->controller_regs;
+       struct linux_prom_pci_registers *regs;
+       unsigned long imap, iclr;
+       unsigned long imap_off, iclr_off;
+       int inofixup = 0;
+       int virt_irq;
+
+       ino &= 0x3f;
+       if (ino < SABRE_ONBOARD_IRQ_BASE) {
+               /* PCI slot */
+               imap_off = sabre_pcislot_imap_offset(ino);
+       } else {
+               /* onboard device */
+               if (ino > SABRE_ONBOARD_IRQ_LAST) {
+                       prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
+                       prom_halt();
+               }
+               imap_off = sabre_onboard_imap_offset(ino);
+       }
+
+       /* Now build the IRQ bucket. */
+       imap = controller_regs + imap_off;
+       imap += 4;
+
+       iclr_off = sabre_iclr_offset(ino);
+       iclr = controller_regs + iclr_off;
+       iclr += 4;
+
+       if ((ino & 0x20) == 0)
+               inofixup = ino & 0x03;
+
+       virt_irq = build_irq(inofixup, iclr, imap);
+
+       regs = of_get_property(dp, "reg", NULL);
+       if (regs &&
+           ((regs->phys_hi >> 16) & 0xff) != irq_data->pci_first_busno) {
+               irq_install_pre_handler(virt_irq,
+                                       sabre_wsync_handler,
+                                       (void *) (long) regs->phys_hi,
+                                       (void *)
+                                       controller_regs +
+                                       SABRE_WRSYNC);
+       }
+
+       return virt_irq;
+}
+
+static void sabre_irq_trans_init(struct device_node *dp)
+{
+       struct linux_prom64_registers *regs;
+       struct sabre_irq_data *irq_data;
+       u32 *busrange;
+
+       dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+       dp->irq_trans->irq_build = sabre_irq_build;
+
+       irq_data = prom_early_alloc(sizeof(struct sabre_irq_data));
+
+       regs = of_get_property(dp, "reg", NULL);
+       irq_data->controller_regs = regs[0].phys_addr;
+
+       busrange = of_get_property(dp, "bus-range", NULL);
+       irq_data->pci_first_busno = busrange[0];
+
+       dp->irq_trans->data = irq_data;
+}
+
+/* SCHIZO interrupt mapping support.  Unlike Psycho, for this controller the
+ * imap/iclr registers are per-PBM.
+ */
+#define SCHIZO_IMAP_BASE       0x1000UL
+#define SCHIZO_ICLR_BASE       0x1400UL
+
+static unsigned long schizo_imap_offset(unsigned long ino)
+{
+       return SCHIZO_IMAP_BASE + (ino * 8UL);
+}
+
+static unsigned long schizo_iclr_offset(unsigned long ino)
+{
+       return SCHIZO_ICLR_BASE + (ino * 8UL);
+}
+
+static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs,
+                                       unsigned int ino)
+{
+       return pbm_regs + schizo_iclr_offset(ino) + 4;
+}
+
+static unsigned long schizo_ino_to_imap(unsigned long pbm_regs,
+                                       unsigned int ino)
+{
+       return pbm_regs + schizo_imap_offset(ino) + 4;
+}
+
+#define schizo_read(__reg) \
+({     u64 __ret; \
+       __asm__ __volatile__("ldxa [%1] %2, %0" \
+                            : "=r" (__ret) \
+                            : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
+                            : "memory"); \
+       __ret; \
+})
+#define schizo_write(__reg, __val) \
+       __asm__ __volatile__("stxa %0, [%1] %2" \
+                            : /* no outputs */ \
+                            : "r" (__val), "r" (__reg), \
+                              "i" (ASI_PHYS_BYPASS_EC_E) \
+                            : "memory")
+
+static void tomatillo_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
+{
+       unsigned long sync_reg = (unsigned long) _arg2;
+       u64 mask = 1UL << (ino & IMAP_INO);
+       u64 val;
+       int limit;
+
+       schizo_write(sync_reg, mask);
+
+       limit = 100000;
+       val = 0;
+       while (--limit) {
+               val = schizo_read(sync_reg);
+               if (!(val & mask))
+                       break;
+       }
+       if (limit <= 0) {
+               printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n",
+                      val, mask);
+       }
+
+       if (_arg1) {
+               static unsigned char cacheline[64]
+                       __attribute__ ((aligned (64)));
+
+               __asm__ __volatile__("rd %%fprs, %0\n\t"
+                                    "or %0, %4, %1\n\t"
+                                    "wr %1, 0x0, %%fprs\n\t"
+                                    "stda %%f0, [%5] %6\n\t"
+                                    "wr %0, 0x0, %%fprs\n\t"
+                                    "membar #Sync"
+                                    : "=&r" (mask), "=&r" (val)
+                                    : "0" (mask), "1" (val),
+                                    "i" (FPRS_FEF), "r" (&cacheline[0]),
+                                    "i" (ASI_BLK_COMMIT_P));
+       }
+}
+
+struct schizo_irq_data {
+       unsigned long pbm_regs;
+       unsigned long sync_reg;
+       u32 portid;
+       int chip_version;
+};
+
+static unsigned int schizo_irq_build(struct device_node *dp,
+                                    unsigned int ino,
+                                    void *_data)
+{
+       struct schizo_irq_data *irq_data = _data;
+       unsigned long pbm_regs = irq_data->pbm_regs;
+       unsigned long imap, iclr;
+       int ign_fixup;
+       int virt_irq;
+       int is_tomatillo;
+
+       ino &= 0x3f;
+
+       /* Now build the IRQ bucket. */
+       imap = schizo_ino_to_imap(pbm_regs, ino);
+       iclr = schizo_ino_to_iclr(pbm_regs, ino);
+
+       /* On Schizo, no inofixup occurs.  This is because each
+        * INO has it's own IMAP register.  On Psycho and Sabre
+        * there is only one IMAP register for each PCI slot even
+        * though four different INOs can be generated by each
+        * PCI slot.
+        *
+        * But, for JBUS variants (essentially, Tomatillo), we have
+        * to fixup the lowest bit of the interrupt group number.
+        */
+       ign_fixup = 0;
+
+       is_tomatillo = (irq_data->sync_reg != 0UL);
+
+       if (is_tomatillo) {
+               if (irq_data->portid & 1)
+                       ign_fixup = (1 << 6);
+       }
+
+       virt_irq = build_irq(ign_fixup, iclr, imap);
+
+       if (is_tomatillo) {
+               irq_install_pre_handler(virt_irq,
+                                       tomatillo_wsync_handler,
+                                       ((irq_data->chip_version <= 4) ?
+                                        (void *) 1 : (void *) 0),
+                                       (void *) irq_data->sync_reg);
+       }
+
+       return virt_irq;
+}
+
+static void schizo_irq_trans_init(struct device_node *dp)
+{
+       struct linux_prom64_registers *regs;
+       struct schizo_irq_data *irq_data;
+
+       dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+       dp->irq_trans->irq_build = schizo_irq_build;
+
+       irq_data = prom_early_alloc(sizeof(struct schizo_irq_data));
+
+       regs = of_get_property(dp, "reg", NULL);
+       dp->irq_trans->data = irq_data;
+
+       irq_data->pbm_regs = regs[0].phys_addr;
+       irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
+       irq_data->portid = of_getintprop_default(dp, "portid", 0);
+       irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
+}
+
+static unsigned int pci_sun4v_irq_build(struct device_node *dp,
+                                       unsigned int devino,
+                                       void *_data)
+{
+       u32 devhandle = (u32) (unsigned long) _data;
+
+       return sun4v_build_irq(devhandle, devino);
+}
+
+static void pci_sun4v_irq_trans_init(struct device_node *dp)
+{
+       struct linux_prom64_registers *regs;
+
+       dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+       dp->irq_trans->irq_build = pci_sun4v_irq_build;
+
+       regs = of_get_property(dp, "reg", NULL);
+       dp->irq_trans->data = (void *) (unsigned long)
+               ((regs->phys_addr >> 32UL) & 0x0fffffff);
+}
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_SBUS
+/* INO number to IMAP register offset for SYSIO external IRQ's.
+ * This should conform to both Sunfire/Wildfire server and Fusion
+ * desktop designs.
+ */
+#define SYSIO_IMAP_SLOT0       0x2c04UL
+#define SYSIO_IMAP_SLOT1       0x2c0cUL
+#define SYSIO_IMAP_SLOT2       0x2c14UL
+#define SYSIO_IMAP_SLOT3       0x2c1cUL
+#define SYSIO_IMAP_SCSI                0x3004UL
+#define SYSIO_IMAP_ETH         0x300cUL
+#define SYSIO_IMAP_BPP         0x3014UL
+#define SYSIO_IMAP_AUDIO       0x301cUL
+#define SYSIO_IMAP_PFAIL       0x3024UL
+#define SYSIO_IMAP_KMS         0x302cUL
+#define SYSIO_IMAP_FLPY                0x3034UL
+#define SYSIO_IMAP_SHW         0x303cUL
+#define SYSIO_IMAP_KBD         0x3044UL
+#define SYSIO_IMAP_MS          0x304cUL
+#define SYSIO_IMAP_SER         0x3054UL
+#define SYSIO_IMAP_TIM0                0x3064UL
+#define SYSIO_IMAP_TIM1                0x306cUL
+#define SYSIO_IMAP_UE          0x3074UL
+#define SYSIO_IMAP_CE          0x307cUL
+#define SYSIO_IMAP_SBERR       0x3084UL
+#define SYSIO_IMAP_PMGMT       0x308cUL
+#define SYSIO_IMAP_GFX         0x3094UL
+#define SYSIO_IMAP_EUPA                0x309cUL
+
+#define bogon     ((unsigned long) -1)
+static unsigned long sysio_irq_offsets[] = {
+       /* SBUS Slot 0 --> 3, level 1 --> 7 */
+       SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
+       SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
+       SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
+       SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
+       SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
+       SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
+       SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
+       SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
+
+       /* Onboard devices (not relevant/used on SunFire). */
+       SYSIO_IMAP_SCSI,
+       SYSIO_IMAP_ETH,
+       SYSIO_IMAP_BPP,
+       bogon,
+       SYSIO_IMAP_AUDIO,
+       SYSIO_IMAP_PFAIL,
+       bogon,
+       bogon,
+       SYSIO_IMAP_KMS,
+       SYSIO_IMAP_FLPY,
+       SYSIO_IMAP_SHW,
+       SYSIO_IMAP_KBD,
+       SYSIO_IMAP_MS,
+       SYSIO_IMAP_SER,
+       bogon,
+       bogon,
+       SYSIO_IMAP_TIM0,
+       SYSIO_IMAP_TIM1,
+       bogon,
+       bogon,
+       SYSIO_IMAP_UE,
+       SYSIO_IMAP_CE,
+       SYSIO_IMAP_SBERR,
+       SYSIO_IMAP_PMGMT,
+};
+
+#undef bogon
+
+#define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
+
+/* Convert Interrupt Mapping register pointer to associated
+ * Interrupt Clear register pointer, SYSIO specific version.
+ */
+#define SYSIO_ICLR_UNUSED0     0x3400UL
+#define SYSIO_ICLR_SLOT0       0x340cUL
+#define SYSIO_ICLR_SLOT1       0x344cUL
+#define SYSIO_ICLR_SLOT2       0x348cUL
+#define SYSIO_ICLR_SLOT3       0x34ccUL
+static unsigned long sysio_imap_to_iclr(unsigned long imap)
+{
+       unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0;
+       return imap + diff;
+}
+
+static unsigned int sbus_of_build_irq(struct device_node *dp,
+                                     unsigned int ino,
+                                     void *_data)
+{
+       unsigned long reg_base = (unsigned long) _data;
+       struct linux_prom_registers *regs;
+       unsigned long imap, iclr;
+       int sbus_slot = 0;
+       int sbus_level = 0;
+
+       ino &= 0x3f;
+
+       regs = of_get_property(dp, "reg", NULL);
+       if (regs)
+               sbus_slot = regs->which_io;
+
+       if (ino < 0x20)
+               ino += (sbus_slot * 8);
+
+       imap = sysio_irq_offsets[ino];
+       if (imap == ((unsigned long)-1)) {
+               prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n",
+                           ino);
+               prom_halt();
+       }
+       imap += reg_base;
+
+       /* SYSIO inconsistency.  For external SLOTS, we have to select
+        * the right ICLR register based upon the lower SBUS irq level
+        * bits.
+        */
+       if (ino >= 0x20) {
+               iclr = sysio_imap_to_iclr(imap);
+       } else {
+               sbus_level = ino & 0x7;
+
+               switch(sbus_slot) {
+               case 0:
+                       iclr = reg_base + SYSIO_ICLR_SLOT0;
+                       break;
+               case 1:
+                       iclr = reg_base + SYSIO_ICLR_SLOT1;
+                       break;
+               case 2:
+                       iclr = reg_base + SYSIO_ICLR_SLOT2;
+                       break;
+               default:
+               case 3:
+                       iclr = reg_base + SYSIO_ICLR_SLOT3;
+                       break;
+               };
+
+               iclr += ((unsigned long)sbus_level - 1UL) * 8UL;
+       }
+       return build_irq(sbus_level, iclr, imap);
+}
+
+static void sbus_irq_trans_init(struct device_node *dp)
+{
+       struct linux_prom64_registers *regs;
+
+       dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+       dp->irq_trans->irq_build = sbus_of_build_irq;
+
+       regs = of_get_property(dp, "reg", NULL);
+       dp->irq_trans->data = (void *) (unsigned long) regs->phys_addr;
+}
+#endif /* CONFIG_SBUS */
+
+
+static unsigned int central_build_irq(struct device_node *dp,
+                                     unsigned int ino,
+                                     void *_data)
+{
+       struct device_node *central_dp = _data;
+       struct of_device *central_op = of_find_device_by_node(central_dp);
+       struct resource *res;
+       unsigned long imap, iclr;
+       u32 tmp;
+
+       if (!strcmp(dp->name, "eeprom")) {
+               res = &central_op->resource[5];
+       } else if (!strcmp(dp->name, "zs")) {
+               res = &central_op->resource[4];
+       } else if (!strcmp(dp->name, "clock-board")) {
+               res = &central_op->resource[3];
+       } else {
+               return ino;
+       }
+
+       imap = res->start + 0x00UL;
+       iclr = res->start + 0x10UL;
+
+       /* Set the INO state to idle, and disable.  */
+       upa_writel(0, iclr);
+       upa_readl(iclr);
+
+       tmp = upa_readl(imap);
+       tmp &= ~0x80000000;
+       upa_writel(tmp, imap);
+
+       return build_irq(0, iclr, imap);
+}
+
+static void central_irq_trans_init(struct device_node *dp)
+{
+       dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+       dp->irq_trans->irq_build = central_build_irq;
+
+       dp->irq_trans->data = dp;
+}
+
+struct irq_trans {
+       const char *name;
+       void (*init)(struct device_node *);
+};
+
+#ifdef CONFIG_PCI
+static struct irq_trans pci_irq_trans_table[] = {
+       { "SUNW,sabre", sabre_irq_trans_init },
+       { "pci108e,a000", sabre_irq_trans_init },
+       { "pci108e,a001", sabre_irq_trans_init },
+       { "SUNW,psycho", psycho_irq_trans_init },
+       { "pci108e,8000", psycho_irq_trans_init },
+       { "SUNW,schizo", schizo_irq_trans_init },
+       { "pci108e,8001", schizo_irq_trans_init },
+       { "SUNW,schizo+", schizo_irq_trans_init },
+       { "pci108e,8002", schizo_irq_trans_init },
+       { "SUNW,tomatillo", schizo_irq_trans_init },
+       { "pci108e,a801", schizo_irq_trans_init },
+       { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
+};
+#endif
+
+static void irq_trans_init(struct device_node *dp)
+{
+       const char *model;
+       int i;
+
+       model = of_get_property(dp, "model", NULL);
+       if (!model)
+               model = of_get_property(dp, "compatible", NULL);
+       if (!model)
+               return;
+
+#ifdef CONFIG_PCI
+       for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
+               struct irq_trans *t = &pci_irq_trans_table[i];
+
+               if (!strcmp(model, t->name))
+                       return t->init(dp);
+       }
+#endif
+#ifdef CONFIG_SBUS
+       if (!strcmp(dp->name, "sbus") ||
+           !strcmp(dp->name, "sbi"))
+               return sbus_irq_trans_init(dp);
+#endif
+       if (!strcmp(dp->name, "central"))
+               return central_irq_trans_init(dp->child);
+}
+
 static int is_root_node(const struct device_node *dp)
 {
        if (!dp)
@@ -676,10 +1459,10 @@ static struct device_node * __init create_node(phandle node)
        dp->type = get_one_property(node, "device_type");
        dp->node = node;
 
-       /* Build interrupts later... */
-
        dp->properties = build_prop_list(node);
 
+       irq_trans_init(dp);
+
        return dp;
 }
 
index ac05e0f692efb22c80fa8c6fcce37a4446ae0d9f..ef68aa4fec6524259a525bdca10458fc3c094a6b 100644 (file)
@@ -1221,9 +1221,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
 
        /* Now some Xfire specific grot... */
        if (this_is_starfire)
-               sbus->starfire_cookie = starfire_hookup(sbus->portid);
-       else
-               sbus->starfire_cookie = NULL;
+               starfire_hookup(sbus->portid);
 
        sysio_register_error_handlers(sbus);
 }
@@ -1269,8 +1267,6 @@ int __init sbus_arch_preinit(void)
 void __init sbus_arch_postinit(void)
 {
        extern void firetruck_init(void);
-       extern void clock_probe(void);
 
        firetruck_init();
-       clock_probe();
 }
index ae859d40771ece3a4c71cd189132ad784e827dbc..b930fee7708a703f8cffbe65662bbe25ced6c8e7 100644 (file)
@@ -54,7 +54,7 @@ struct starfire_irqinfo {
 static struct starfire_irqinfo *sflist = NULL;
 
 /* Beam me up Scott(McNeil)y... */
-void *starfire_hookup(int upaid)
+void starfire_hookup(int upaid)
 {
        struct starfire_irqinfo *p;
        unsigned long treg_base, hwmid, i;
@@ -81,8 +81,6 @@ void *starfire_hookup(int upaid)
        p->upaid = upaid;
        p->next = sflist;
        sflist = p;
-
-       return (void *) p;
 }
 
 unsigned int starfire_translate(unsigned long imap,
index 348b820355615b221d71c83741fe92580053ae99..5f3dd4d800cd49d7cb87782571af052ff0bb7a3e 100644 (file)
 #include <asm/timer.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/fhc.h>
-#include <asm/pbm.h>
-#include <asm/ebus.h>
-#include <asm/isa.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/starfire.h>
 #include <asm/smp.h>
 #include <asm/sections.h>
@@ -770,237 +767,106 @@ static int __init clock_model_matches(char *model)
        return 1;
 }
 
-static void __init __clock_assign_common(void __iomem *addr, char *model)
+static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
 {
-       if (model[5] == '0' && model[6] == '2') {
-               mstk48t02_regs = addr;
-       } else if(model[5] == '0' && model[6] == '8') {
-               mstk48t08_regs = addr;
-               mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
-       } else {
-               mstk48t59_regs = addr;
-               mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
-       }
-}
-
-static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
-                                       char *model)
-{
-       unsigned long addr;
-
-       addr = ((unsigned long) clk_reg[0].phys_addr |
-               (((unsigned long) clk_reg[0].which_io) << 32UL));
-
-       __clock_assign_common((void __iomem *) addr, model);
-}
-
-static int __init clock_probe_central(void)
-{
-       struct linux_prom_registers clk_reg[2], *pr;
-       struct device_node *dp;
-       char *model;
+       struct device_node *dp = op->node;
+       char *model = of_get_property(dp, "model", NULL);
+       unsigned long size, flags;
+       void __iomem *regs;
 
-       if (!central_bus)
-               return 0;
-
-       /* Get Central FHC's prom node.  */
-       dp = central_bus->child->prom_node;
-
-       /* Then get the first child device below it.  */
-       dp = dp->child;
-
-       while (dp) {
-               model = of_get_property(dp, "model", NULL);
-               if (!model || !clock_model_matches(model))
-                       goto next_sibling;
-
-               pr = of_get_property(dp, "reg", NULL);
-               memcpy(clk_reg, pr, sizeof(clk_reg));
-
-               apply_fhc_ranges(central_bus->child, clk_reg, 1);
-               apply_central_ranges(central_bus, clk_reg, 1);
-
-               clock_assign_clk_reg(clk_reg, model);
-               return 1;
+       if (!model || !clock_model_matches(model))
+               return -ENODEV;
 
-       next_sibling:
-               dp = dp->sibling;
-       }
+       /* On an Enterprise system there can be multiple mostek clocks.
+        * We should only match the one that is on the central FHC bus.
+        */
+       if (!strcmp(dp->parent->name, "fhc") &&
+           strcmp(dp->parent->parent->name, "central") != 0)
+               return -ENODEV;
 
-       return 0;
-}
+       size = (op->resource[0].end - op->resource[0].start) + 1;
+       regs = of_ioremap(&op->resource[0], 0, size, "clock");
+       if (!regs)
+               return -ENOMEM;
 
-#ifdef CONFIG_PCI
-static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
-{
        if (!strcmp(model, "ds1287") ||
            !strcmp(model, "m5819") ||
            !strcmp(model, "m5819p") ||
            !strcmp(model, "m5823")) {
-               ds1287_regs = res->start;
+               ds1287_regs = (unsigned long) regs;
+       } else if (model[5] == '0' && model[6] == '2') {
+               mstk48t02_regs = regs;
+       } else if(model[5] == '0' && model[6] == '8') {
+               mstk48t08_regs = regs;
+               mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
        } else {
-               mstk48t59_regs = (void __iomem *) res->start;
+               mstk48t59_regs = regs;
                mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
        }
-}
-
-static int __init clock_probe_one_ebus_dev(struct linux_ebus_device *edev)
-{
-       struct device_node *dp = edev->prom_node;
-       char *model;
-
-       model = of_get_property(dp, "model", NULL);
-       if (!clock_model_matches(model))
-               return 0;
 
-       clock_isa_ebus_assign_regs(&edev->resource[0], model);
+       printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, regs);
 
-       return 1;
-}
-
-static int __init clock_probe_ebus(void)
-{
-       struct linux_ebus *ebus;
+       local_irq_save(flags);
 
-       for_each_ebus(ebus) {
-               struct linux_ebus_device *edev;
+       if (mstk48t02_regs != NULL) {
+               /* Report a low battery voltage condition. */
+               if (has_low_battery())
+                       prom_printf("NVRAM: Low battery voltage!\n");
 
-               for_each_ebusdev(edev, ebus) {
-                       if (clock_probe_one_ebus_dev(edev))
-                               return 1;
-               }
+               /* Kick start the clock if it is completely stopped. */
+               if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
+                       kick_start_clock();
        }
 
-       return 0;
-}
-
-static int __init clock_probe_one_isa_dev(struct sparc_isa_device *idev)
-{
-       struct device_node *dp = idev->prom_node;
-       char *model;
-
-       model = of_get_property(dp, "model", NULL);
-       if (!clock_model_matches(model))
-               return 0;
-
-       clock_isa_ebus_assign_regs(&idev->resource, model);
-
-       return 1;
-}
-
-static int __init clock_probe_isa(void)
-{
-       struct sparc_isa_bridge *isa_br;
-
-       for_each_isa(isa_br) {
-               struct sparc_isa_device *isa_dev;
-
-               for_each_isadev(isa_dev, isa_br) {
-                       if (clock_probe_one_isa_dev(isa_dev))
-                               return 1;
-               }
-       }
+       set_system_time();
+       
+       local_irq_restore(flags);
 
        return 0;
 }
-#endif /* CONFIG_PCI */
-
-#ifdef CONFIG_SBUS
-static int __init clock_probe_one_sbus_dev(struct sbus_bus *sbus, struct sbus_dev *sdev)
-{
-       struct resource *res;
-       char model[64];
-       void __iomem *addr;
-
-       prom_getstring(sdev->prom_node, "model", model, sizeof(model));
-       if (!clock_model_matches(model))
-               return 0;
-
-       res = &sdev->resource[0];
-       addr = sbus_ioremap(res, 0, 0x800UL, "eeprom");
 
-       __clock_assign_common(addr, model);
-
-       return 1;
-}
-
-static int __init clock_probe_sbus(void)
-{
-       struct sbus_bus *sbus;
-
-       for_each_sbus(sbus) {
-               struct sbus_dev *sdev;
-
-               for_each_sbusdev(sdev, sbus) {
-                       if (clock_probe_one_sbus_dev(sbus, sdev))
-                               return 1;
-               }
-       }
+static struct of_device_id clock_match[] = {
+       {
+               .name = "eeprom",
+       },
+       {
+               .name = "rtc",
+       },
+       {},
+};
 
-       return 0;
-}
-#endif
+static struct of_platform_driver clock_driver = {
+       .name           = "clock",
+       .match_table    = clock_match,
+       .probe          = clock_probe,
+};
 
-void __init clock_probe(void)
+static int __init clock_init(void)
 {
-       static int invoked;
-       unsigned long flags;
-
-       if (invoked)
-               return;
-       invoked = 1;
-
        if (this_is_starfire) {
                xtime.tv_sec = starfire_get_time();
                xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
                set_normalized_timespec(&wall_to_monotonic,
                                        -xtime.tv_sec, -xtime.tv_nsec);
-               return;
+               return 0;
        }
        if (tlb_type == hypervisor) {
                xtime.tv_sec = hypervisor_get_time();
                xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
                set_normalized_timespec(&wall_to_monotonic,
                                        -xtime.tv_sec, -xtime.tv_nsec);
-               return;
-       }
-
-       /* Check FHC Central then EBUSs then ISA bridges then SBUSs.
-        * That way we handle the presence of multiple properly.
-        *
-        * As a special case, machines with Central must provide the
-        * timer chip there.
-        */
-       if (!clock_probe_central() &&
-#ifdef CONFIG_PCI
-           !clock_probe_ebus() &&
-           !clock_probe_isa() &&
-#endif
-#ifdef CONFIG_SBUS
-           !clock_probe_sbus()
-#endif
-               ) {
-               printk(KERN_WARNING "No clock chip found.\n");
-               return;
-       }
-
-       local_irq_save(flags);
-
-       if (mstk48t02_regs != NULL) {
-               /* Report a low battery voltage condition. */
-               if (has_low_battery())
-                       prom_printf("NVRAM: Low battery voltage!\n");
-
-               /* Kick start the clock if it is completely stopped. */
-               if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
-                       kick_start_clock();
+               return 0;
        }
 
-       set_system_time();
-       
-       local_irq_restore(flags);
+       return of_register_driver(&clock_driver, &of_bus_type);
 }
 
+/* Must be after subsys_initcall() so that busses are probed.  Must
+ * be before device_initcall() because things like the RTC driver
+ * need to see the clock registers.
+ */
+fs_initcall(clock_init);
+
 /* This is gets the master TICK_INT timer going. */
 static unsigned long sparc64_init_timers(void)
 {
index bb2d685778555e9fb9f65a0fcbd69d23b9d18112..a9b765271b85f9da4546c846f446ab383cecd781 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/bitops.h>
+#include <linux/kallsyms.h>
 #include <asm/fpumacro.h>
 
 /* #define DEBUG_MNA */
@@ -291,7 +292,8 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
        if (count < 5) {
                last_time = jiffies;
                count++;
-               printk("Kernel unaligned access at TPC[%lx]\n", regs->tpc);
+               printk("Kernel unaligned access at TPC[%lx] ", regs->tpc);
+               print_symbol("%s\n", regs->tpc);
        }
 
        if (!ok_for_kernel(insn) || dir == both) {
index fc6669e8dde189640a053c40f629e63720795d9c..bc3df95bc05773b9a74419c6692f342dd9005120 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 #include <linux/syscalls.h>
 #include <linux/in.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include <net/sock.h>
 
@@ -190,8 +189,6 @@ init_socksys(void)
                return ret;
        }
 
-       devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUSR|S_IWUSR, "socksys");
-
        file = fcheck(ret);
        /* N.B. Is this valid? Suppose the f_ops are in a module ... */
        socksys_file_ops = *file->f_op;
@@ -207,5 +204,4 @@ cleanup_socksys(void)
 {
        if (unregister_chrdev(30, "socksys"))
                printk ("Couldn't unregister socksys character device\n");
-       devfs_remove ("socksys");
 }
index 6c2d4ccaf20f63cc59ed049e4f960bf546665af6..5ca57ca337136034799e3dad4df7d733802dc4bc 100644 (file)
@@ -8,7 +8,6 @@
 #include "linux/list.h"
 #include "linux/kd.h"
 #include "linux/interrupt.h"
-#include "linux/devfs_fs_kernel.h"
 #include "asm/uaccess.h"
 #include "chan_kern.h"
 #include "irq_user.h"
@@ -655,7 +654,6 @@ struct tty_driver *line_register_devfs(struct lines *set,
 
        driver->driver_name = line_driver->name;
        driver->name = line_driver->device_name;
-       driver->devfs_name = line_driver->devfs_name;
        driver->major = line_driver->major;
        driver->minor_start = line_driver->minor_start;
        driver->type = line_driver->type;
index a4d6415bc8c4820340a299a58e7b340ee33cbcf0..6dafd6fbfdaed13be0f48424f1e811fd24955b89 100644 (file)
@@ -54,7 +54,6 @@ static int ssl_remove(int n);
 static struct line_driver driver = {
        .name                   = "UML serial line",
        .device_name            = "ttyS",
-       .devfs_name             = "tts/",
        .major                  = TTY_MAJOR,
        .minor_start            = 64,
        .type                   = TTY_DRIVER_TYPE_SERIAL,
index 61db8b2fc83f5780624a92e2510812db891dd36e..856f568c2687fd485a111d2f68843bb3918ac7dc 100644 (file)
@@ -60,7 +60,6 @@ static int con_remove(int n);
 static struct line_driver driver = {
        .name                   = "UML console",
        .device_name            = "tty",
-       .devfs_name             = "vc/",
        .major                  = TTY_MAJOR,
        .minor_start            = 0,
        .type                   = TTY_DRIVER_TYPE_CONSOLE,
index 290cec6d69e23e8981b570d973a5800ddf2993fd..0345e255124798d3f26965a327b6e44ce701fa0a 100644 (file)
@@ -25,7 +25,6 @@
 #include "linux/blkdev.h"
 #include "linux/hdreg.h"
 #include "linux/init.h"
-#include "linux/devfs_fs_kernel.h"
 #include "linux/cdrom.h"
 #include "linux/proc_fs.h"
 #include "linux/ctype.h"
@@ -628,7 +627,6 @@ static int ubd_new_disk(int major, u64 size, int unit,
                        
 {
        struct gendisk *disk;
-       char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
        int err;
 
        disk = alloc_disk(1 << UBD_SHIFT);
@@ -639,20 +637,10 @@ static int ubd_new_disk(int major, u64 size, int unit,
        disk->first_minor = unit << UBD_SHIFT;
        disk->fops = &ubd_blops;
        set_capacity(disk, size / 512);
-       if(major == MAJOR_NR){
+       if(major == MAJOR_NR)
                sprintf(disk->disk_name, "ubd%c", 'a' + unit);
-               sprintf(disk->devfs_name, "ubd/disc%d", unit);
-               sprintf(from, "ubd/%d", unit);
-               sprintf(to, "disc%d/disc", unit);
-               err = devfs_mk_symlink(from, to);
-               if(err)
-                       printk("ubd_new_disk failed to make link from %s to "
-                              "%s, error = %d\n", from, to, err);
-       }
-       else {
+       else
                sprintf(disk->disk_name, "ubd_fake%d", unit);
-               sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
-       }
 
        /* sysfs register (not for ide fake devices) */
        if (major == MAJOR_NR) {
@@ -841,7 +829,6 @@ int ubd_init(void)
 {
         int i;
 
-       devfs_mk_dir("ubd");
        if (register_blkdev(MAJOR_NR, "ubd"))
                return -1;
 
@@ -855,7 +842,6 @@ int ubd_init(void)
                char name[sizeof("ubd_nnn\0")];
 
                snprintf(name, sizeof(name), "ubd_%d", fake_major);
-               devfs_mk_dir(name);
                if (register_blkdev(fake_major, "ubd"))
                        return -1;
        }
index 6ac0f8252e21e3dfdf55d359c0d46c8f7dbc069a..27bf2f6fbc05a60d398cb9b2b8ef0a51605711b2 100644 (file)
@@ -17,7 +17,6 @@
 struct line_driver {
        char *name;
        char *device_name;
-       char *devfs_name;
        short major;
        short minor_start;
        short type;
index 2bcebdc3eedbc193546c7b28b26af627368dc306..01fa23580c85f4dd707f166dca06f49226924078 100644 (file)
 *(.text.__end_that_request_first)
 *(.text.wake_up_bit)
 *(.text.unuse_mm)
-*(.text.skb_release_data)
 *(.text.shrink_icache_memory)
 *(.text.sched_balance_self)
 *(.text.__pmd_alloc)
index fde9334059af595428f3f871599a538e3c3a29b0..a486eb1f1640207c29351a99cddd38ae4684fdca 100644 (file)
@@ -1018,7 +1018,7 @@ he_init_irq(struct he_dev *he_dev)
        return 0;
 }
 
-static int __init
+static int __devinit
 he_start(struct atm_dev *dev)
 {
        struct he_dev *he_dev;
index 0aabfc2a59d9e42a574673772a34765dc64f5ab6..325325afabec839302521e16c09ec78532bdfeba 100644 (file)
@@ -358,7 +358,7 @@ static const struct atmphy_ops idt77105_ops = {
 };
 
 
-int idt77105_init(struct atm_dev *dev)
+int __devinit idt77105_init(struct atm_dev *dev)
 {
        dev->phy = &idt77105_ops;
        return 0;
index 8ba8218aaefe0c60a29ed2ba7111e27e1e6a66b1..3fd2bc8997618b787825a7e55deb5ff9240fdd45 100644 (file)
@@ -76,7 +76,7 @@
 #define IDT77105_CTRSEL_RHEC   0x01    /* W, Rx HEC Error Counter */
 
 #ifdef __KERNEL__
-int idt77105_init(struct atm_dev *dev) __init;
+int idt77105_init(struct atm_dev *dev);
 #endif
 
 /*
index 2e2e50e1167a3b59f31a809bfbea43992b19b478..333a7bc609d24b0337bdb2d928ebd8f3d2d57b56 100644 (file)
@@ -2284,7 +2284,7 @@ static int reset_sar(struct atm_dev *dev)
 }  
          
          
-static int __init ia_init(struct atm_dev *dev)
+static int __devinit ia_init(struct atm_dev *dev)
 {  
        IADEV *iadev;  
        unsigned long real_base;
@@ -2480,7 +2480,7 @@ static void ia_free_rx(IADEV *iadev)
                          iadev->rx_dle_dma);  
 }
 
-static int __init ia_start(struct atm_dev *dev)
+static int __devinit ia_start(struct atm_dev *dev)
 {  
        IADEV *iadev;  
        int error;  
index b1d063cc4fbe0f6903359bf3328566e0e50aee93..f04f39c00833cc86dc572f6b00e32e8f0204c903 100644 (file)
@@ -289,7 +289,7 @@ static const struct atmphy_ops suni_ops = {
 };
 
 
-int suni_init(struct atm_dev *dev)
+int __devinit suni_init(struct atm_dev *dev)
 {
        unsigned char mri;
 
index dd8a1501142f9a7acab30803c86d5390d666dbf4..50ca1aa4ee3b3956550f23fce6d1b098f0c86e30 100644 (file)
@@ -2530,7 +2530,6 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
        blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
        disk->queue = RequestQueue;
        sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
-       sprintf(disk->devfs_name, "rd/host%d/target%d", Controller->ControllerNumber, n);
        disk->major = MajorNumber;
        disk->first_minor = n << DAC960_MaxPartitionsBits;
        disk->fops = &DAC960_BlockDeviceOperations;
index 196c0ec9cd5421da1c1f278d15fc66e5d474b8f4..a317e43039526ab586eae5a1f2bb73a9fe31345c 100644 (file)
@@ -1732,13 +1732,10 @@ int acsi_init( void )
                struct gendisk *disk = acsi_gendisk[i];
                sprintf(disk->disk_name, "ad%c", 'a'+i);
                aip = &acsi_info[NDevices];
-               sprintf(disk->devfs_name, "ad/target%d/lun%d", aip->target, aip->lun);
                disk->major = ACSI_MAJOR;
                disk->first_minor = i << 4;
-               if (acsi_info[i].type != HARDDISK) {
+               if (acsi_info[i].type != HARDDISK)
                        disk->minors = 1;
-                       strcat(disk->devfs_name, "/disc");
-               }
                disk->fops = &acsi_fops;
                disk->private_data = &acsi_info[i];
                set_capacity(disk, acsi_info[i].size);
index 4cb9c13362874cedbed44c24a2982046d1e74e4c..4030a8fd11872992e2c5040746c873f6e8a6f01a 100644 (file)
@@ -65,7 +65,6 @@ not be guaranteed. There are several ways to assure this:
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 
 #include <asm/pgtable.h>
@@ -1005,11 +1004,6 @@ int slm_init( void )
        BufferP = SLMBuffer;
        SLMState = IDLE;
        
-       devfs_mk_dir("slm");
-       for (i = 0; i < MAX_SLM; i++) {
-               devfs_mk_cdev(MKDEV(ACSI_MAJOR, i),
-                               S_IFCHR|S_IRUSR|S_IWUSR, "slm/%d", i);
-       }
        return 0;
 }
 
@@ -1032,10 +1026,6 @@ int init_module(void)
 
 void cleanup_module(void)
 {
-       int i;
-       for (i = 0; i < MAX_SLM; i++)
-               devfs_remove("slm/%d", i);
-       devfs_remove("slm");
        if (unregister_chrdev( ACSI_MAJOR, "slm" ) != 0)
                printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
        atari_stram_free( SLMBuffer );
index 39b0f53186e8a2a6532799c6ac172c4eeab7b96e..05fb08312c01c619fbc176a5246f277d4a90b34a 100644 (file)
@@ -3248,7 +3248,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 
                q->queuedata = hba[i];
                sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
-               sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j);
                disk->major = hba[i]->major;
                disk->first_minor = j << NWD_SHIFT;
                disk->fops = &cciss_fops;
index 5eb6fb7b5cfacfba6c84672cd38aaf631f401c85..bfd245df0a8c5bb81a79828d38b65b153e5dd0e3 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/blkpg.h>
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/init.h>
 #include <linux/hdreg.h>
 #include <linux/spinlock.h>
@@ -348,7 +347,6 @@ static void __devexit cpqarray_remove_one(int i)
        for(j = 0; j < NWD; j++) {
                if (ida_gendisk[i][j]->flags & GENHD_FL_UP)
                        del_gendisk(ida_gendisk[i][j]);
-               devfs_remove("ida/c%dd%d",i,j);
                put_disk(ida_gendisk[i][j]);
        }
        blk_cleanup_queue(hba[i]->queue);
@@ -1807,8 +1805,6 @@ static void getgeometry(int ctlr)
 
                                }
 
-                               sprintf(disk->devfs_name, "ida/c%dd%d", ctlr, log_unit);
-
                                info_p->phys_drives =
                                    sense_config_buf->ctlr_phys_drv;
                                info_p->drv_assign_map
@@ -1844,7 +1840,6 @@ static void __exit cpqarray_exit(void)
                }
        }
 
-       devfs_remove("ida");
        remove_proc_entry("cpqarray", proc_root_driver);
 }
 
index dff1e67b1dd4e2768447ac92465caf8e1cceb97a..0242cbb86a8793d24ac4617fc344a43f6dcf9ca4 100644 (file)
@@ -177,7 +177,6 @@ static int print_unex = 1;
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/platform_device.h>
 #include <linux/buffer_head.h> /* for invalidate_buffers() */
 #include <linux/mutex.h>
@@ -224,7 +223,6 @@ static struct completion device_release;
 static unsigned short virtual_dma_port = 0x3f0;
 irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int set_dor(int fdc, char mask, char data);
-static void register_devfs_entries(int drive) __init;
 
 #define K_64   0x10000         /* 64KB */
 
@@ -3676,7 +3674,6 @@ static void __init config_types(void)
                                first = 0;
                        }
                        printk("%s fd%d is %s", prepend, drive, name);
-                       register_devfs_entries(drive);
                }
                *UDP = *params;
        }
@@ -3954,37 +3951,6 @@ static struct block_device_operations floppy_fops = {
        .media_changed  = check_floppy_change,
        .revalidate_disk = floppy_revalidate,
 };
-static char *table[] = {
-       "", "d360", "h1200", "u360", "u720", "h360", "h720",
-       "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410",
-       "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743",
-       "h880", "u1040", "u1120", "h1600", "u1760", "u1920",
-       "u3200", "u3520", "u3840", "u1840", "u800", "u1600",
-       NULL
-};
-static int t360[] = { 1, 0 },
-       t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23, 0 },
-       t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13,
-                       17, 21, 22, 30, 0 };
-static int *table_sup[] =
-    { NULL, t360, t1200, t3in + 5 + 8, t3in + 5, t3in, t3in };
-
-static void __init register_devfs_entries(int drive)
-{
-       int base_minor = (drive < 4) ? drive : (124 + drive);
-
-       if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
-               int i = 0;
-               do {
-                       int minor = base_minor + (table_sup[UDP->cmos][i] << 2);
-
-                       devfs_mk_bdev(MKDEV(FLOPPY_MAJOR, minor),
-                                     S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |
-                                     S_IWGRP, "floppy/%d%s", drive,
-                                     table[table_sup[UDP->cmos][i]]);
-               } while (table_sup[UDP->cmos][i++]);
-       }
-}
 
 /*
  * Floppy Driver initialization
@@ -4261,11 +4227,9 @@ static int __init floppy_init(void)
                motor_off_timer[dr].function = motor_off_callback;
        }
 
-       devfs_mk_dir("floppy");
-
        err = register_blkdev(FLOPPY_MAJOR, "fd");
        if (err)
-               goto out_devfs_remove;
+               goto out_put_disk;
 
        floppy_queue = blk_init_queue(do_fd_request, &floppy_lock);
        if (!floppy_queue) {
@@ -4424,8 +4388,6 @@ out_unreg_region:
        blk_cleanup_queue(floppy_queue);
 out_unreg_blkdev:
        unregister_blkdev(FLOPPY_MAJOR, "fd");
-out_devfs_remove:
-       devfs_remove("floppy");
 out_put_disk:
        while (dr--) {
                del_timer(&motor_off_timer[dr]);
@@ -4586,19 +4548,6 @@ static void floppy_release_irq_and_dma(void)
 
 static char *floppy;
 
-static void unregister_devfs_entries(int drive)
-{
-       int i;
-
-       if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
-               i = 0;
-               do {
-                       devfs_remove("floppy/%d%s", drive,
-                                    table[table_sup[UDP->cmos][i]]);
-               } while (table_sup[UDP->cmos][i++]);
-       }
-}
-
 static void __init parse_floppy_cfg_string(char *cfg)
 {
        char *ptr;
@@ -4635,13 +4584,11 @@ void cleanup_module(void)
                if ((allowed_drive_mask & (1 << drive)) &&
                    fdc_state[FDC(drive)].version != FDC_NONE) {
                        del_gendisk(disks[drive]);
-                       unregister_devfs_entries(drive);
                        device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
                        platform_device_unregister(&floppy_device[drive]);
                }
                put_disk(disks[drive]);
        }
-       devfs_remove("floppy");
 
        del_timer_sync(&fd_timeout);
        del_timer_sync(&fd_timer);
index 18dd026f470dcf6d1d6d056df23d299efb2fa422..013c5daddb0b3bfc1163506a0be14961c9ac32e1 100644 (file)
@@ -63,7 +63,6 @@
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
@@ -1277,8 +1276,6 @@ static int __init loop_init(void)
                        goto out_mem3;
        }
 
-       devfs_mk_dir("loop");
-
        for (i = 0; i < max_loop; i++) {
                struct loop_device *lo = &loop_dev[i];
                struct gendisk *disk = disks[i];
@@ -1296,7 +1293,6 @@ static int __init loop_init(void)
                disk->first_minor = i;
                disk->fops = &lo_fops;
                sprintf(disk->disk_name, "loop%d", i);
-               sprintf(disk->devfs_name, "loop/%d", i);
                disk->private_data = lo;
                disk->queue = lo->lo_queue;
        }
@@ -1310,7 +1306,6 @@ static int __init loop_init(void)
 out_mem4:
        while (i--)
                blk_cleanup_queue(loop_dev[i].lo_queue);
-       devfs_remove("loop");
        i = max_loop;
 out_mem3:
        while (i--)
@@ -1333,7 +1328,6 @@ static void loop_exit(void)
                blk_cleanup_queue(loop_dev[i].lo_queue);
                put_disk(disks[i]);
        }
-       devfs_remove("loop");
        if (unregister_blkdev(LOOP_MAJOR, "loop"))
                printk(KERN_WARNING "loop: cannot unregister blkdev\n");
 
index 7f554f2ed0797af3b39d87d4354609169203fdb0..39662f0c9cce65afd9da3b397607093f05a3f026 100644 (file)
@@ -29,8 +29,6 @@
 #include <linux/kernel.h>
 #include <net/sock.h>
 
-#include <linux/devfs_fs_kernel.h>
-
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/types.h>
@@ -642,7 +640,6 @@ static int __init nbd_init(void)
        printk(KERN_INFO "nbd: registered device at major %d\n", NBD_MAJOR);
        dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags);
 
-       devfs_mk_dir("nbd");
        for (i = 0; i < nbds_max; i++) {
                struct gendisk *disk = nbd_dev[i].disk;
                nbd_dev[i].file = NULL;
@@ -660,7 +657,6 @@ static int __init nbd_init(void)
                disk->private_data = &nbd_dev[i];
                disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
                sprintf(disk->disk_name, "nbd%d", i);
-               sprintf(disk->devfs_name, "nbd/%d", i);
                set_capacity(disk, 0x7ffffc00ULL << 1); /* 2 TB */
                add_disk(disk);
        }
@@ -686,7 +682,6 @@ static void __exit nbd_cleanup(void)
                        put_disk(disk);
                }
        }
-       devfs_remove("nbd");
        unregister_blkdev(NBD_MAJOR, "nbd");
        printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR);
 }
index 79b868254032a68505abb3140b8918f8395ee4e2..13f998aa1cd3ffc19ccf402fd901b91e8b0dbf2d 100644 (file)
@@ -156,7 +156,6 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/mtio.h>
@@ -674,25 +673,15 @@ static int __init pg_init(void)
                err = PTR_ERR(pg_class);
                goto out_chrdev;
        }
-       devfs_mk_dir("pg");
        for (unit = 0; unit < PG_UNITS; unit++) {
                struct pg *dev = &devices[unit];
-               if (dev->present) {
+               if (dev->present)
                        class_device_create(pg_class, NULL, MKDEV(major, unit),
                                        NULL, "pg%u", unit);
-                       err = devfs_mk_cdev(MKDEV(major, unit),
-                                     S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
-                                     unit);
-                       if (err) 
-                               goto out_class;
-               }
        }
        err = 0;
        goto out;
 
-out_class:
-       class_device_destroy(pg_class, MKDEV(major, unit));
-       class_destroy(pg_class);
 out_chrdev:
        unregister_chrdev(major, "pg");
 out:
@@ -705,13 +694,10 @@ static void __exit pg_exit(void)
 
        for (unit = 0; unit < PG_UNITS; unit++) {
                struct pg *dev = &devices[unit];
-               if (dev->present) {
+               if (dev->present)
                        class_device_destroy(pg_class, MKDEV(major, unit));
-                       devfs_remove("pg/%u", unit);
-               }
        }
        class_destroy(pg_class);
-       devfs_remove("pg");
        unregister_chrdev(major, name);
 
        for (unit = 0; unit < PG_UNITS; unit++) {
index d2013d362403819c49c2e21ffe54f64f311796cd..35fb2663672146d0cdbd1ed15ea36da68d1bb223 100644 (file)
@@ -141,7 +141,6 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/mtio.h>
@@ -971,32 +970,15 @@ static int __init pt_init(void)
                goto out_chrdev;
        }
 
-       devfs_mk_dir("pt");
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present) {
                        class_device_create(pt_class, NULL, MKDEV(major, unit),
                                        NULL, "pt%d", unit);
-                       err = devfs_mk_cdev(MKDEV(major, unit),
-                                     S_IFCHR | S_IRUSR | S_IWUSR,
-                                     "pt/%d", unit);
-                       if (err) {
-                               class_device_destroy(pt_class, MKDEV(major, unit));
-                               goto out_class;
-                       }
                        class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
                                        NULL, "pt%dn", unit);
-                       err = devfs_mk_cdev(MKDEV(major, unit + 128),
-                                     S_IFCHR | S_IRUSR | S_IWUSR,
-                                     "pt/%dn", unit);
-                       if (err) {
-                               class_device_destroy(pt_class, MKDEV(major, unit + 128));
-                               goto out_class;
-                       }
                }
        goto out;
 
-out_class:
-       class_destroy(pt_class);
 out_chrdev:
        unregister_chrdev(major, "pt");
 out:
@@ -1009,12 +991,9 @@ static void __exit pt_exit(void)
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present) {
                        class_device_destroy(pt_class, MKDEV(major, unit));
-                       devfs_remove("pt/%d", unit);
                        class_device_destroy(pt_class, MKDEV(major, unit + 128));
-                       devfs_remove("pt/%dn", unit);
                }
        class_destroy(pt_class);
-       devfs_remove("pt");
        unregister_chrdev(major, name);
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present)
index a04f60693c396446d4a310e8c1df0eaef62c5012..3e4cce5e4736351befab56db81c42527223dade8 100644 (file)
@@ -2612,7 +2612,6 @@ static struct file_operations pkt_ctl_fops = {
 static struct miscdevice pkt_misc = {
        .minor          = MISC_DYNAMIC_MINOR,
        .name           = "pktcdvd",
-       .devfs_name     = "pktcdvd/control",
        .fops           = &pkt_ctl_fops
 };
 
index bea75f2cb211ca342814766f963b546071c8b223..a729013a39737b24541a999f38950c7206ae6181 100644 (file)
@@ -421,7 +421,6 @@ static int __init ps2esdi_geninit(void)
                disk->major = PS2ESDI_MAJOR;
                disk->first_minor = i<<6;
                sprintf(disk->disk_name, "ed%c", 'a'+i);
-               sprintf(disk->devfs_name, "ed/target%d", i);
                disk->fops = &ps2esdi_fops;
                ps2esdi_gendisk[i] = disk;
        }
index 0378da04cfa23c0c38b967a0162aee3563119171..a9e1c2524c2a9c99b93b36c544e716eb299cdc7f 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/pagemap.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
@@ -412,7 +411,6 @@ static void __exit rd_cleanup(void)
                put_disk(rd_disks[i]);
                blk_cleanup_queue(rd_queue[i]);
        }
-       devfs_remove("rd");
        unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
 }
 
@@ -442,8 +440,6 @@ static int __init rd_init(void)
                goto out;
        }
 
-       devfs_mk_dir("rd");
-
        for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) {
                struct gendisk *disk = rd_disks[i];
 
@@ -461,7 +457,6 @@ static int __init rd_init(void)
                disk->queue = rd_queue[i];
                disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
                sprintf(disk->disk_name, "ram%d", i);
-               sprintf(disk->devfs_name, "rd/%d", i);
                set_capacity(disk, rd_size * 2);
                add_disk(rd_disks[i]);
        }
index 01f042f6f1c42874e9090ce60f0e925d7b73726c..628877945f9badbae4f529f63e2add13292d35cf 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/fd.h>
 #include <linux/ioctl.h>
 #include <linux/blkdev.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
@@ -1019,8 +1018,6 @@ int swim3_init(void)
        int err = -ENOMEM;
        int i;
 
-       devfs_mk_dir("floppy");
-
        swim = find_devices("floppy");
        while (swim && (floppy_count < MAX_FLOPPIES))
        {
@@ -1064,7 +1061,6 @@ int swim3_init(void)
                disk->queue = swim3_queue;
                disk->flags |= GENHD_FL_REMOVABLE;
                sprintf(disk->disk_name, "fd%d", i);
-               sprintf(disk->devfs_name, "floppy/%d", i);
                set_capacity(disk, 2880);
                add_disk(disk);
        }
index 8144ce9f4df0543555aa71573ad1c69a43748013..10a4aa5fb54df10d0f48b710a02bd12a26d382f5 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/spinlock.h>
 #include <linux/blkdev.h>
 #include <linux/sched.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/interrupt.h>
 #include <linux/compiler.h>
 #include <linux/workqueue.h>
@@ -1510,7 +1509,6 @@ static int carm_init_disks(struct carm_host *host)
                port->disk = disk;
                sprintf(disk->disk_name, DRV_NAME "/%u",
                        (unsigned int) (host->id * CARM_MAX_PORTS) + i);
-               sprintf(disk->devfs_name, DRV_NAME "/%u_%u", host->id, i);
                disk->major = host->major;
                disk->first_minor = i * CARM_MINORS_PER_MAJOR;
                disk->fops = &carm_bd_ops;
@@ -1672,8 +1670,6 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (host->flags & FL_DYN_MAJOR)
                host->major = rc;
 
-       devfs_mk_dir(DRV_NAME);
-
        rc = carm_init_disks(host);
        if (rc)
                goto err_out_blkdev_disks;
@@ -1739,7 +1735,6 @@ static void carm_remove_one (struct pci_dev *pdev)
 
        free_irq(pdev->irq, host);
        carm_free_disks(host);
-       devfs_remove(DRV_NAME);
        unregister_blkdev(host->major, host->name);
        if (host->major == 160)
                clear_bit(0, &carm_major_alloc);
index 60e9a9457c6b0789b7b29e0e8c36e148b9424653..d62b49fbf10c319334ca6f26e49f58a46747b6f3 100644 (file)
 #include <linux/usb.h>
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/timer.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
-#define DEVFS_NAME DRV_NAME
 
 #define UB_MAJOR 180
 
@@ -2291,7 +2289,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
                goto err_diskalloc;
 
        sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
-       sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
        disk->major = UB_MAJOR;
        disk->first_minor = lun->id * UB_PARTS_PER_LUN;
        disk->fops = &ub_bd_fops;
@@ -2445,7 +2442,6 @@ static int __init ub_init(void)
 
        if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
                goto err_regblkdev;
-       devfs_mk_dir(DEVFS_NAME);
 
        if ((rc = usb_register(&ub_driver)) != 0)
                goto err_register;
@@ -2454,7 +2450,6 @@ static int __init ub_init(void)
        return 0;
 
 err_register:
-       devfs_remove(DEVFS_NAME);
        unregister_blkdev(UB_MAJOR, DRV_NAME);
 err_regblkdev:
        return rc;
@@ -2464,7 +2459,6 @@ static void __exit ub_exit(void)
 {
        usb_deregister(&ub_driver);
 
-       devfs_remove(DEVFS_NAME);
        unregister_blkdev(UB_MAJOR, DRV_NAME);
        usb_usual_clear_present(USB_US_TYPE_UB);
 }
index f7d4c65a7b8c369a76c3b7b82d8cb98ce03dcfa0..585197b95af762118d5692b0d5303b713f95f472 100644 (file)
@@ -1192,7 +1192,6 @@ static int __init mm_init(void)
        for (i = 0; i < num_cards; i++) {
                struct gendisk *disk = mm_gendisk[i];
                sprintf(disk->disk_name, "umem%c", 'a'+i);
-               sprintf(disk->devfs_name, "umem/card%d", i);
                spin_lock_init(&cards[i].lock);
                disk->major = major_nr;
                disk->first_minor  = i << MM_SHIFT;
index b0df4f5ab97afff4d490e9781fae37bd9984a210..ec5a1b90a0a24133d1043fb19290a1d296b11125 100644 (file)
@@ -59,7 +59,6 @@ MODULE_LICENSE("GPL");
  * numbers 0-255 we get a maximum of 32 disks.
  */
 #define VIOD_GENHD_NAME                "iseries/vd"
-#define VIOD_GENHD_DEVFS_NAME  "iseries/disc"
 
 #define VIOD_VERS              "1.64"
 
@@ -523,8 +522,6 @@ retry:
        else
                snprintf(g->disk_name, sizeof(g->disk_name),
                                VIOD_GENHD_NAME "%c", 'a' + (dev_no % 26));
-       snprintf(g->devfs_name, sizeof(g->devfs_name),
-                       "%s%d", VIOD_GENHD_DEVFS_NAME, dev_no);
        g->fops = &viodasd_fops;
        g->queue = q;
        g->private_data = d;
index cbce7c5e9445638474640e59738db7b7cec3b74b..e828e4cbd3e1122a0ca3abb48e7ed2de51a6bf81 100644 (file)
@@ -215,7 +215,6 @@ static int __init xd_init(void)
                disk->major = XT_DISK_MAJOR;
                disk->first_minor = i<<6;
                sprintf(disk->disk_name, "xd%c", i+'a');
-               sprintf(disk->devfs_name, "xd/target%d", i);
                disk->fops = &xd_fops;
                disk->private_data = p;
                disk->queue = xd_queue;
index bb5e8d665a2a3ce8bd41fbd647bd06eeec772541..82ddbdd7bd4ba18f0718e388f6db83b8131992a9 100644 (file)
@@ -354,7 +354,6 @@ z2_init(void)
     z2ram_gendisk->first_minor = 0;
     z2ram_gendisk->fops = &z2_fops;
     sprintf(z2ram_gendisk->disk_name, "z2ram");
-    strcpy(z2ram_gendisk->devfs_name, z2ram_gendisk->disk_name);
 
     z2ram_gendisk->queue = z2_queue;
     add_disk(z2ram_gendisk);
index ec004897b63494e220f87a211056903731a5b122..ec469497c10ff46abbb5818d8ea8726284f05d4a 100644 (file)
@@ -1918,7 +1918,6 @@ static int __init aztcd_init(void)
        azt_disk->first_minor = 0;
        azt_disk->fops = &azt_fops;
        sprintf(azt_disk->disk_name, "aztcd");
-       sprintf(azt_disk->devfs_name, "aztcd");
        azt_disk->queue = azt_queue;
        add_disk(azt_disk);
        azt_invalidate_buffers();
index 72ffd64e8b1e8c43ad7a3bc39fc05fbf5b3d5978..5f0f2027f29e46ebb6593662423b4f8522792dfd 100644 (file)
 #include <linux/hdreg.h>
 #include <linux/genhd.h>
 #include <linux/ioport.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/init.h>
index f43a988dd413e0cc9fbdbf2db9e9fef04f2c948d..4ee288688fed492378f87fb2f10c1fdcf587fe7d 100644 (file)
@@ -187,7 +187,6 @@ History:
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/cdrom.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
index ad5464ab99bce830fc22984ff1cf77ac176c51d2..b6ee50a2916d79b6a8c9c4e9f46b6ef6443f035d 100644 (file)
@@ -955,7 +955,6 @@ static int __init gscd_init(void)
        gscd_disk->first_minor = 0;
        gscd_disk->fops = &gscd_fops;
        sprintf(gscd_disk->disk_name, "gscd");
-       sprintf(gscd_disk->devfs_name, "gscd");
 
        if (register_blkdev(MAJOR_NR, "gscd")) {
                ret = -EIO;
index 0f6e7aab8d2cb18cc294b08919d87752fcf3444d..788c7a0b2fe301600f4a5c6106e12fdb95592007 100644 (file)
@@ -74,7 +74,6 @@ static const char *mcdx_c_version
 #include <linux/major.h>
 #define MAJOR_NR MITSUMI_X_CDROM_MAJOR
 #include <linux/blkdev.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include "mcdx.h"
 
index 0b0eab4f40fa989dd9c215b089282bc8d8fa106a..25032d7edc55e19a3f63a8e3dfd92a70ddca767c 100644 (file)
@@ -2033,7 +2033,6 @@ static int __init optcd_init(void)
        optcd_disk->first_minor = 0;
        optcd_disk->fops = &opt_fops;
        sprintf(optcd_disk->disk_name, "optcd");
-       sprintf(optcd_disk->devfs_name, "optcd");
 
        if (!request_region(optcd_port, 4, "optcd")) {
                printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
index 05c9e865ecaf85a33eafa3be2cfe0bb837a71148..2fc966c65a0e4458293150c62cba30eda352e659 100644 (file)
 #include <linux/kernel.h>
 #include <linux/cdrom.h>
 #include <linux/ioport.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/major.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
@@ -5808,8 +5807,6 @@ int __init sbpcd_init(void)
                return -ENOMEM;
        }
 
-       devfs_mk_dir("sbp");
-
        for (j=0;j<NR_SBPCD;j++)
        {
                struct cdrom_device_info * sbpcd_infop;
@@ -5871,7 +5868,6 @@ int __init sbpcd_init(void)
                disk->fops = &sbpcd_bdops;
                strcpy(disk->disk_name, sbpcd_infop->name);
                disk->flags = GENHD_FL_CD;
-               sprintf(disk->devfs_name, "sbp/c0t%d", p->drv_id);
                p->disk = disk;
                if (register_cdrom(sbpcd_infop))
                {
@@ -5906,7 +5902,6 @@ static void sbpcd_exit(void)
                if (D_S[j].drv_id==-1) continue;
                del_gendisk(D_S[j].disk);
                put_disk(D_S[j].disk);
-               devfs_remove("sbp/c0t%d", j);
                vfree(D_S[j].sbp_buf);
                if (D_S[j].sbp_audsiz>0)
                        vfree(D_S[j].aud_buf);
@@ -5917,7 +5912,6 @@ static void sbpcd_exit(void)
                }
                vfree(D_S[j].sbpcd_infop);
        }
-       devfs_remove("sbp");
        msg(DBG_INF, "%s module released.\n", major_name);
 }
 
index 74b1cadbf161d2adc2f7d61933622bfb8f75bc5e..bf5aef4e555b2d71696e8540a3840bb1258d5f27 100644 (file)
@@ -1695,7 +1695,6 @@ static int __init sjcd_init(void)
        sjcd_disk->first_minor = 0,
        sjcd_disk->fops = &sjcd_fops,
        sprintf(sjcd_disk->disk_name, "sjcd");
-       sprintf(sjcd_disk->devfs_name, "sjcd");
 
        if (!request_region(sjcd_base, 4,"sjcd")) {
                printk
index e6565992643260580cbbcaf7e5209a1744fd97f2..8f7cc452af8da7143a7e77280ba639f909ea1857 100644 (file)
@@ -1589,7 +1589,6 @@ static int __init sony535_init(void)
        cdu_disk->first_minor = 0;
        cdu_disk->fops = &cdu_fops;
        sprintf(cdu_disk->disk_name, "cdu");
-       sprintf(cdu_disk->devfs_name, "cdu535");
 
        if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) {
                printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
index af6b3bfd169ba1ccb7dc8f77c44bafad408f7dd0..54ca931e19ea0a0c0b36bc896432278dc1361812 100644 (file)
@@ -49,7 +49,6 @@
 #include <asm/iseries/vio.h>
 
 #define VIOCD_DEVICE                   "iseries/vcd"
-#define VIOCD_DEVICE_DEVFS             "iseries/vcd"
 
 #define VIOCD_VERS "1.06"
 
@@ -688,8 +687,6 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        gendisk->first_minor = deviceno;
        strncpy(gendisk->disk_name, c->name,
                        sizeof(gendisk->disk_name));
-       snprintf(gendisk->devfs_name, sizeof(gendisk->devfs_name),
-                       VIOCD_DEVICE_DEVFS "%d", deviceno);
        blk_queue_max_hw_segments(q, 1);
        blk_queue_max_phys_segments(q, 1);
        blk_queue_max_sectors(q, 4096 / 512);
index 9826a399fa02b053c2bf9568a5192e510bb873f3..22f8cf218cc6443a1af9f523ae49dfc47fe56340 100644 (file)
@@ -1,6 +1,7 @@
 config AGP
        tristate "/dev/agpgart (AGP Support)"
        depends on ALPHA || IA64 || PPC || X86
+       depends on PCI
        ---help---
          AGP (Accelerated Graphics Port) is a bus system mainly used to
          connect graphics cards to the rest of the system.
index f690ee8cb7324fbf195946def5d05b7ef63f7f7c..f74eeeb8e37709167933ac53c3b7e23c41f2488f 100644 (file)
@@ -734,7 +734,7 @@ int __init agp_amd64_init(void)
 
        if (agp_off)
                return -EINVAL;
-       if (pci_register_driver(&agp_amd64_pci_driver) > 0) {
+       if (pci_register_driver(&agp_amd64_pci_driver) < 0) {
                struct pci_dev *dev;
                if (!agp_try_unsupported && !agp_try_unsupported_boot) {
                        printk(KERN_INFO PFX "No supported AGP bridge found.\n");
index 160564345993df646b5e803fcf804089b36614d2..f244c6682738a70842147beab1ac42b96f82fbf4 100644 (file)
@@ -41,7 +41,6 @@ static struct gatt_mask ati_generic_masks[] =
 };
 
 
-
 typedef struct _ati_page_map {
        unsigned long *real;
        unsigned long __iomem *remapped;
@@ -141,7 +140,8 @@ static int ati_create_gatt_pages(int nr_tables)
        ati_generic_private.num_tables = nr_tables;
        ati_generic_private.gatt_pages = tables;
 
-       if (retval != 0) ati_free_gatt_pages();
+       if (retval != 0)
+               ati_free_gatt_pages();
 
        return retval;
 }
@@ -219,16 +219,16 @@ static int ati_configure(void)
        ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
 
        if (is_r200())
-               pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000);
+               pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000);
        else
                pci_write_config_dword(agp_bridge->dev, ATI_RS300_IG_AGPMODE, 0x20000);
 
        /* address to map too */
-        /*
+       /*
        pci_read_config_dword(agp_bridge.dev, AGP_APBASE, &temp);
        agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
        printk(KERN_INFO PFX "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
-        */
+       */
        writel(0x60000, ati_generic_private.registers+ATI_GART_FEATURE_ID);
        readl(ati_generic_private.registers+ATI_GART_FEATURE_ID);       /* PCI Posting.*/
 
@@ -245,18 +245,20 @@ static int ati_configure(void)
 
 
 #ifdef CONFIG_PM
-static int agp_ati_resume(struct pci_dev *dev)
+static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state)
 {
-       pci_restore_state(dev);
+       pci_save_state(dev);
+       pci_set_power_state(dev, 3);
 
-       return ati_configure();
+       return 0;
 }
 
-static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state)
+static int agp_ati_resume(struct pci_dev *dev)
 {
-       pci_save_state(dev);
+       pci_set_power_state(dev, 0);
+       pci_restore_state(dev);
 
-       return 0;
+       return ati_configure();
 }
 #endif
 
@@ -321,9 +323,9 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start,
        unsigned long __iomem *cur_gatt;
        unsigned long addr;
 
-       if (type != 0 || mem->type != 0) {
+       if (type != 0 || mem->type != 0)
                return -EINVAL;
-       }
+
        for (i = pg_start; i < (mem->page_count + pg_start); i++) {
                addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
                cur_gatt = GET_GATT(addr);
@@ -502,9 +504,8 @@ found:
 
        bridge->dev = pdev;
        bridge->capndx = cap_ptr;
-       
-       bridge->driver = &ati_generic_bridge;
 
+       bridge->driver = &ati_generic_bridge;
 
        printk(KERN_INFO PFX "Detected Ati %s chipset\n",
                        devs[j].chipset_name);
@@ -546,8 +547,8 @@ static struct pci_driver agp_ati_pci_driver = {
        .probe          = agp_ati_probe,
        .remove         = agp_ati_remove,
 #ifdef CONFIG_PM
-       .resume         = agp_ati_resume,
        .suspend        = agp_ati_suspend,
+       .resume         = agp_ati_resume,
 #endif
 };
 
index 4c67135c12d853052b389657d1fba450e1c3dfe4..df7f37b2739abe007a9f9f629f301941f65cadf7 100644 (file)
@@ -376,6 +376,29 @@ static void __devexit agp_nvidia_remove(struct pci_dev *pdev)
        agp_put_bridge(bridge);
 }
 
+#ifdef CONFIG_PM
+static int agp_nvidia_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       pci_save_state (pdev);
+       pci_set_power_state (pdev, 3);
+
+       return 0;
+}
+
+static int agp_nvidia_resume(struct pci_dev *pdev)
+{
+       /* set power state 0 and restore PCI space */
+       pci_set_power_state (pdev, 0);
+       pci_restore_state(pdev);
+
+       /* reconfigure AGP hardware again */
+       nvidia_configure();
+
+       return 0;
+}
+#endif
+
+
 static struct pci_device_id agp_nvidia_pci_table[] = {
        {
        .class          = (PCI_CLASS_BRIDGE_HOST << 8),
@@ -403,6 +426,10 @@ static struct pci_driver agp_nvidia_pci_driver = {
        .id_table       = agp_nvidia_pci_table,
        .probe          = agp_nvidia_probe,
        .remove         = agp_nvidia_remove,
+#ifdef CONFIG_PM
+       .suspend        = agp_nvidia_suspend,
+       .resume         = agp_nvidia_resume,
+#endif
 };
 
 static int __init agp_nvidia_init(void)
index 122e7a72a4e178755dedce7922ff91b2f29a2f3e..2657eeba7da63aec1bce32abe8e45a5a4fcb89a0 100644 (file)
@@ -5250,7 +5250,6 @@ cy_init(void)
     cy_serial_driver->owner = THIS_MODULE;
     cy_serial_driver->driver_name = "cyclades";
     cy_serial_driver->name = "ttyC";
-    cy_serial_driver->devfs_name = "tts/C";
     cy_serial_driver->major = CYCLADES_MAJOR;
     cy_serial_driver->minor_start = 0;
     cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
index e233cf280bc024498c3fdd637d219e8159bb6f2a..09b413618b5781e8c8294e66396361ab5e6354df 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 #include <linux/device.h>
 
@@ -518,17 +517,9 @@ static int __init dsp56k_init_driver(void)
        }
        class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
 
-       err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
-                     S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
-       if(err)
-               goto out_class;
-
        printk(banner);
        goto out;
 
-out_class:
-       class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
-       class_destroy(dsp56k_class);
 out_chrdev:
        unregister_chrdev(DSP56K_MAJOR, "dsp56k");
 out:
@@ -541,7 +532,6 @@ static void __exit dsp56k_cleanup_driver(void)
        class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
        class_destroy(dsp56k_class);
        unregister_chrdev(DSP56K_MAJOR, "dsp56k");
-       devfs_remove("dsp56k");
 }
 module_exit(dsp56k_cleanup_driver);
 
index 87dcaa237f0753eb3e9f821bf17bb27b211b729d..da2c89f1b8bc9e15399e37a56a091ad9ea0870ff 100644 (file)
@@ -62,7 +62,6 @@
 #include <linux/init.h>                /* for __init, module_{init,exit} */
 #include <linux/poll.h>                /* for POLLIN, etc. */
 #include <linux/dtlk.h>                /* local header file for DoubleTalk values */
-#include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 
 #ifdef TRACING
@@ -337,9 +336,6 @@ static int __init dtlk_init(void)
        if (dtlk_dev_probe() == 0)
                printk(", MAJOR %d\n", dtlk_major);
 
-       devfs_mk_cdev(MKDEV(dtlk_major, DTLK_MINOR),
-                      S_IFCHR | S_IRUSR | S_IWUSR, "dtlk");
-
        init_timer(&dtlk_timer);
        dtlk_timer.function = dtlk_timer_tick;
        init_waitqueue_head(&dtlk_process_list);
@@ -357,7 +353,6 @@ static void __exit dtlk_cleanup (void)
 
        dtlk_write_tts(DTLK_CLEAR);
        unregister_chrdev(dtlk_major, "dtlk");
-       devfs_remove("dtlk");
        release_region(dtlk_port_lpc, DTLK_IO_EXTENT);
 }
 
index dc0602ae8503041046e794790957c33be39d9ba8..d0b3890d93021165572b53ef876f01729704ffb3 100644 (file)
@@ -1232,7 +1232,6 @@ static int __init pc_init(void)
 
        pc_driver->owner = THIS_MODULE;
        pc_driver->name = "ttyD"; 
-       pc_driver->devfs_name = "tts/D";
        pc_driver->major = DIGI_MAJOR; 
        pc_driver->minor_start = 0;
        pc_driver->type = TTY_DRIVER_TYPE_SERIAL;
index 922174d527ae6325ed63562e1929f44892a9ded7..9827d170ca17ff7cc0726ef09fd83c90de64a3fd 100644 (file)
@@ -2449,7 +2449,6 @@ static int __init espserial_init(void)
        
        esp_driver->owner = THIS_MODULE;
        esp_driver->name = "ttyP";
-       esp_driver->devfs_name = "tts/P";
        esp_driver->major = ESP_IN_MAJOR;
        esp_driver->minor_start = 0;
        esp_driver->type = TTY_DRIVER_TYPE_SERIAL;
index 821357ce7e0e86c3a529b7c3ae8850e9a7e9404c..3eeb869a9a11f22dca28bff078f5d9ae96998c77 100644 (file)
@@ -33,7 +33,6 @@
 #endif
 #include <linux/fcntl.h>
 #include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include <linux/zftape.h>
 #include <linux/init.h>
@@ -332,29 +331,11 @@ KERN_INFO
        zft_class = class_create(THIS_MODULE, "zft");
        for (i = 0; i < 4; i++) {
                class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
-               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
-                               S_IFCHR | S_IRUSR | S_IWUSR,
-                               "qft%i", i);
                class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
-               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
-                               S_IFCHR | S_IRUSR | S_IWUSR,
-                               "nqft%i", i);
                class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
-               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
-                               S_IFCHR | S_IRUSR | S_IWUSR,
-                               "zqft%i", i);
                class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
-               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
-                               S_IFCHR | S_IRUSR | S_IWUSR,
-                               "nzqft%i", i);
                class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
-               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
-                               S_IFCHR | S_IRUSR | S_IWUSR,
-                               "rawqft%i", i);
                class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
-               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
-                               S_IFCHR | S_IRUSR | S_IWUSR,
-                               "nrawqft%i", i);
        }
 
 #ifdef CONFIG_ZFT_COMPRESSOR
@@ -380,17 +361,11 @@ static void zft_exit(void)
                TRACE(ft_t_info, "successful");
        }
         for (i = 0; i < 4; i++) {
-               devfs_remove("qft%i", i);
                class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i));
-               devfs_remove("nqft%i", i);
                class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4));
-               devfs_remove("zqft%i", i);
                class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16));
-               devfs_remove("nzqft%i", i);
                class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20));
-               devfs_remove("rawqft%i", i);
                class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32));
-               devfs_remove("nrawqft%i", i);
                class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36));
        }
        class_destroy(zft_class);
index a5c6a9d7ff0805319d42ee5ceb03020058821c59..6e380aecea6a3ba04ecf53bb80a9009027b70894 100644 (file)
@@ -820,7 +820,6 @@ int __init hvc_init(void)
                return -ENOMEM;
 
        drv->owner = THIS_MODULE;
-       drv->devfs_name = "hvc/";
        drv->driver_name = "hvc";
        drv->name = "hvc";
        drv->major = HVC_MAJOR;
index afa26b65dac3b7fb4313df3e1b6e003951bf2d9d..130dedc37568bce89af0630870c1f111c04ca2f9 100644 (file)
@@ -1363,7 +1363,6 @@ static int __init hvcs_module_init(void)
 
        hvcs_tty_driver->driver_name = hvcs_driver_name;
        hvcs_tty_driver->name = hvcs_device_node;
-       hvcs_tty_driver->devfs_name = hvcs_device_node;
 
        /*
         * We'll let the system assign us a major number, indicated by leaving
index a0370ed752ce01725b4458fb00335adb5ccb905f..7b04eb1532051846a6354650753e542fb5a00c75 100644 (file)
@@ -1154,7 +1154,6 @@ static int __init hvsi_init(void)
                return -ENOMEM;
 
        hvsi_driver->owner = THIS_MODULE;
-       hvsi_driver->devfs_name = "hvsi/";
        hvsi_driver->driver_name = "hvsi";
        hvsi_driver->name = "hvsi";
        hvsi_driver->major = HVSI_MAJOR;
index 9ab33c3d359fae4279f338e826280d06bda983ed..8619542766cb28cfdda56efc600c97bbe7afe4e8 100644 (file)
@@ -91,7 +91,6 @@
 #include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
@@ -414,9 +413,7 @@ cleanup_module(void)
                        /* free io addresses and Tibet */
                        release_region( ip2config.addr[i], 8 );
                        class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
-                       devfs_remove("ip2/ipl%d", i);
                        class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
-                       devfs_remove("ip2/stat%d", i);
                }
                /* Disable and remove interrupt handler. */
                if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 
@@ -425,7 +422,6 @@ cleanup_module(void)
                }
        }
        class_destroy(ip2_class);
-       devfs_remove("ip2");
        if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
                printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
        }
@@ -675,7 +671,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
 
        ip2_tty_driver->owner               = THIS_MODULE;
        ip2_tty_driver->name                 = "ttyF";
-       ip2_tty_driver->devfs_name          = "tts/F";
        ip2_tty_driver->driver_name          = pcDriver_name;
        ip2_tty_driver->major                = IP2_TTY_MAJOR;
        ip2_tty_driver->minor_start          = 0;
@@ -683,7 +678,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
        ip2_tty_driver->subtype              = SERIAL_TYPE_NORMAL;
        ip2_tty_driver->init_termios         = tty_std_termios;
        ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
-       ip2_tty_driver->flags                = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       ip2_tty_driver->flags                = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        tty_set_operations(ip2_tty_driver, &ip2_ops);
 
        ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
@@ -724,26 +719,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
                                class_device_create(ip2_class, NULL,
                                                MKDEV(IP2_IPL_MAJOR, 4 * i),
                                                NULL, "ipl%d", i);
-                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
-                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
-                                               "ip2/ipl%d", i);
-                               if (err) {
-                                       class_device_destroy(ip2_class,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i));
-                                       goto out_class;
-                               }
-
                                class_device_create(ip2_class, NULL,
                                                MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
                                                NULL, "stat%d", i);
-                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
-                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
-                                               "ip2/stat%d", i);
-                               if (err) {
-                                       class_device_destroy(ip2_class,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
-                                       goto out_class;
-                               }
 
                            for ( box = 0; box < ABS_MAX_BOXES; ++box )
                            {
index e1c95374984cccb89fec0427b5185de80dab6785..da637adbbfaaf218ca26bc186ec772044b16c659 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/poll.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/ipmi.h>
 #include <linux/mutex.h>
 #include <linux/init.h>
@@ -804,9 +803,6 @@ static void ipmi_new_smi(int if_num, struct device *device)
        dev_t dev = MKDEV(ipmi_major, if_num);
        struct ipmi_reg_list *entry;
 
-       devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
-                     "ipmidev/%d", if_num);
-
        entry = kmalloc(sizeof(*entry), GFP_KERNEL);
        if (!entry) {
                printk(KERN_ERR "ipmi_devintf: Unable to create the"
@@ -836,7 +832,6 @@ static void ipmi_smi_gone(int if_num)
        }
        class_device_destroy(ipmi_class, dev);
        mutex_unlock(&reg_list_mutex);
-       devfs_remove("ipmidev/%d", if_num);
 }
 
 static struct ipmi_smi_watcher smi_watcher =
@@ -872,8 +867,6 @@ static __init int init_ipmi_devintf(void)
                ipmi_major = rv;
        }
 
-       devfs_mk_dir(DEVICE_NAME);
-
        rv = ipmi_smi_watcher_register(&smi_watcher);
        if (rv) {
                unregister_chrdev(ipmi_major, DEVICE_NAME);
@@ -898,7 +891,6 @@ static __exit void cleanup_ipmi(void)
        mutex_unlock(&reg_list_mutex);
        class_destroy(ipmi_class);
        ipmi_smi_watcher_unregister(&smi_watcher);
-       devfs_remove(DEVICE_NAME);
        unregister_chrdev(ipmi_major, DEVICE_NAME);
 }
 module_exit(cleanup_ipmi);
index efaaa1937ab6dc2115e7d5057744213db9e3e75b..478bf4d7d0659ac14922eb76adfecfcb448a6cbd 100644 (file)
@@ -1581,7 +1581,6 @@ static int __devinit isicom_register_tty_driver(void)
 
        isicom_normal->owner                    = THIS_MODULE;
        isicom_normal->name                     = "ttyM";
-       isicom_normal->devfs_name               = "isicom/";
        isicom_normal->major                    = ISICOM_NMAJOR;
        isicom_normal->minor_start              = 0;
        isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
index 216c79256de3e36566bc3bb2df61d9c7c5a6b269..c74e5660a9b7e244607007b1af933665348d97e7 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/eisa.h>
@@ -826,11 +825,8 @@ static void __exit istallion_module_exit(void)
                return;
        }
        put_tty_driver(stli_serial);
-       for (i = 0; i < 4; i++) {
-               devfs_remove("staliomem/%d", i);
+       for (i = 0; i < 4; i++)
                class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i));
-       }
-       devfs_remove("staliomem");
        class_destroy(istallion_class);
        if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
                printk("STALLION: failed to un-register serial memory device, "
@@ -4728,16 +4724,11 @@ int __init stli_init(void)
                printk(KERN_ERR "STALLION: failed to register serial memory "
                                "device\n");
 
-       devfs_mk_dir("staliomem");
        istallion_class = class_create(THIS_MODULE, "staliomem");
-       for (i = 0; i < 4; i++) {
-               devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
-                              S_IFCHR | S_IRUSR | S_IWUSR,
-                              "staliomem/%d", i);
+       for (i = 0; i < 4; i++)
                class_device_create(istallion_class, NULL,
                                MKDEV(STL_SIOMEMMAJOR, i),
                                NULL, "staliomem%d", i);
-       }
 
 /*
  *     Set up the tty driver structure and register us as a driver.
index e572605252935c8562b64dbfcb6ed483fbd10756..b11a390581bad05ea210165731cb2dcbbc013944 100644 (file)
 #include <linux/major.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/delay.h>
@@ -807,8 +806,6 @@ static int lp_register(int nr, struct parport *port)
 
        class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
                                "lp%d", nr);
-       devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
-                       "printers/%d", nr);
 
        printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 
               (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
@@ -907,7 +904,6 @@ static int __init lp_init (void)
                return -EIO;
        }
 
-       devfs_mk_dir("printers");
        lp_class = class_create(THIS_MODULE, "printer");
        if (IS_ERR(lp_class)) {
                err = PTR_ERR(lp_class);
@@ -933,7 +929,6 @@ static int __init lp_init (void)
 out_class:
        class_destroy(lp_class);
 out_devfs:
-       devfs_remove("printers");
        unregister_chrdev(LP_MAJOR, "lp");
        return err;
 }
@@ -981,10 +976,8 @@ static void lp_cleanup_module (void)
                if (lp_table[offset].dev == NULL)
                        continue;
                parport_unregister_device(lp_table[offset].dev);
-               devfs_remove("printers/%d", offset);
                class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
        }
-       devfs_remove("printers");
        class_destroy(lp_class);
 }
 
index 1fa9fa157c125652fea7cd314534992c4875a73b..6fe7b6c6c462efb0936e16f27e73a19e0438912e 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/tty.h>
 #include <linux/capability.h>
 #include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/ptrace.h>
 #include <linux/device.h>
 #include <linux/highmem.h>
@@ -941,13 +940,10 @@ static int __init chr_dev_init(void)
                printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 
        mem_class = class_create(THIS_MODULE, "mem");
-       for (i = 0; i < ARRAY_SIZE(devlist); i++) {
+       for (i = 0; i < ARRAY_SIZE(devlist); i++)
                class_device_create(mem_class, NULL,
                                        MKDEV(MEM_MAJOR, devlist[i].minor),
                                        NULL, devlist[i].name);
-               devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
-                               S_IFCHR | devlist[i].mode, devlist[i].name);
-       }
        
        return 0;
 }
index 96eb2a709e21d66ca7772d75c83ca79d595c81bf..dfe1cede391602b96d155a2fdb59dd0b2eebae3f 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/device.h>
@@ -204,7 +203,7 @@ int misc_register(struct miscdevice * misc)
 {
        struct miscdevice *c;
        dev_t dev;
-       int err;
+       int err = 0;
 
        down(&misc_sem);
        list_for_each_entry(c, &misc_list, list) {
@@ -228,10 +227,6 @@ int misc_register(struct miscdevice * misc)
 
        if (misc->minor < DYNAMIC_MINORS)
                misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
-       if (misc->devfs_name[0] == '\0') {
-               snprintf(misc->devfs_name, sizeof(misc->devfs_name),
-                               "misc/%s", misc->name);
-       }
        dev = MKDEV(MISC_MAJOR, misc->minor);
 
        misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
@@ -241,13 +236,6 @@ int misc_register(struct miscdevice * misc)
                goto out;
        }
 
-       err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, 
-                           misc->devfs_name);
-       if (err) {
-               class_device_destroy(misc_class, dev);
-               goto out;
-       }
-
        /*
         * Add it to the front, so that later devices can "override"
         * earlier defaults
@@ -278,7 +266,6 @@ int misc_deregister(struct miscdevice * misc)
        down(&misc_sem);
        list_del(&misc->list);
        class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
-       devfs_remove(misc->devfs_name);
        if (i < DYNAMIC_MINORS && i>0) {
                misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
        }
index d65b3109318a347f402f51db1d9bcf6c9107bf4f..95e8122b8068d47bd617fdc7726b78eafffbdb7c 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/mmtimer.h>
 #include <linux/miscdevice.h>
 #include <linux/posix-timers.h>
@@ -694,7 +693,6 @@ static int __init mmtimer_init(void)
                return -1;
        }
 
-       strcpy(mmtimer_miscdev.devfs_name, MMTIMER_NAME);
        if (misc_register(&mmtimer_miscdev)) {
                printk(KERN_ERR "%s: failed to register device\n",
                       MMTIMER_NAME);
index 01247cccb89f26cbb0d52b7dee3757c36c43db64..52ef61f54ba0bc225c94f10a0e2470baf9e5926e 100644 (file)
@@ -342,7 +342,6 @@ static int __init moxa_init(void)
        init_MUTEX(&moxaBuffSem);
        moxaDriver->owner = THIS_MODULE;
        moxaDriver->name = "ttyMX";
-       moxaDriver->devfs_name = "tts/a";
        moxaDriver->major = ttymajor;
        moxaDriver->minor_start = 0;
        moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;
index bee6c47b45bdd162e33e50e32171667dd6df8df8..24231d9743dc297a7db77bbb0796e190163591ca 100644 (file)
@@ -60,7 +60,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/ioctl.h>
 #include <linux/parport.h>
 #include <linux/ctype.h>
@@ -770,7 +769,7 @@ static struct parport_driver pp_driver = {
 
 static int __init ppdev_init (void)
 {
-       int i, err = 0;
+       int err = 0;
 
        if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
                printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
@@ -782,11 +781,6 @@ static int __init ppdev_init (void)
                err = PTR_ERR(ppdev_class);
                goto out_chrdev;
        }
-       devfs_mk_dir("parports");
-       for (i = 0; i < PARPORT_MAX; i++) {
-               devfs_mk_cdev(MKDEV(PP_MAJOR, i),
-                               S_IFCHR | S_IRUGO | S_IWUGO, "parports/%d", i);
-       }
        if (parport_register_driver(&pp_driver)) {
                printk (KERN_WARNING CHRDEV ": unable to register with parport\n");
                goto out_class;
@@ -796,9 +790,6 @@ static int __init ppdev_init (void)
        goto out;
 
 out_class:
-       for (i = 0; i < PARPORT_MAX; i++)
-               devfs_remove("parports/%d", i);
-       devfs_remove("parports");
        class_destroy(ppdev_class);
 out_chrdev:
        unregister_chrdev(PP_MAJOR, CHRDEV);
@@ -808,12 +799,8 @@ out:
 
 static void __exit ppdev_cleanup (void)
 {
-       int i;
        /* Clean up all parport stuff */
-       for (i = 0; i < PARPORT_MAX; i++)
-               devfs_remove("parports/%d", i);
        parport_unregister_driver(&pp_driver);
-       devfs_remove("parports");
        class_destroy(ppdev_class);
        unregister_chrdev (PP_MAJOR, CHRDEV);
 }
index 0c17f61549b432b5d395aa39ee9b1d6e3036d26a..9491e43075667be1f1e48ada2803bc77ae5a7b54 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/major.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/sysctl.h>
 
 #include <asm/uaccess.h>
@@ -265,7 +264,6 @@ static void __init legacy_pty_init(void)
        pty_driver->owner = THIS_MODULE;
        pty_driver->driver_name = "pty_master";
        pty_driver->name = "pty";
-       pty_driver->devfs_name = "pty/m";
        pty_driver->major = PTY_MASTER_MAJOR;
        pty_driver->minor_start = 0;
        pty_driver->type = TTY_DRIVER_TYPE_PTY;
@@ -283,7 +281,6 @@ static void __init legacy_pty_init(void)
        pty_slave_driver->owner = THIS_MODULE;
        pty_slave_driver->driver_name = "pty_slave";
        pty_slave_driver->name = "ttyp";
-       pty_slave_driver->devfs_name = "pty/s";
        pty_slave_driver->major = PTY_SLAVE_MAJOR;
        pty_slave_driver->minor_start = 0;
        pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
@@ -351,7 +348,6 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
 
 static void __init unix98_pty_init(void)
 {
-       devfs_mk_dir("pts");
        ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
        if (!ptm_driver)
                panic("Couldn't allocate Unix98 ptm driver");
@@ -372,7 +368,7 @@ static void __init unix98_pty_init(void)
        ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
        ptm_driver->init_termios.c_lflag = 0;
        ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
-               TTY_DRIVER_NO_DEVFS | TTY_DRIVER_DEVPTS_MEM;
+               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
        ptm_driver->other = pts_driver;
        tty_set_operations(ptm_driver, &pty_ops);
        ptm_driver->ioctl = pty_unix98_ioctl;
@@ -387,7 +383,7 @@ static void __init unix98_pty_init(void)
        pts_driver->init_termios = tty_std_termios;
        pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
        pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
-               TTY_DRIVER_NO_DEVFS | TTY_DRIVER_DEVPTS_MEM;
+               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
        pts_driver->other = ptm_driver;
        tty_set_operations(pts_driver, &pty_ops);
        
index 15a7b408652449ee421a14cf1e1fcc56004eed4e..9bf97c5e38c041e47dbb340f314740ddc43f3c5e 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <linux/init.h>
 #include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/major.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
@@ -288,7 +287,6 @@ static struct cdev raw_cdev = {
 
 static int __init raw_init(void)
 {
-       int i;
        dev_t dev = MKDEV(RAW_MAJOR, 0);
 
        if (register_chrdev_region(dev, MAX_RAW_MINORS, "raw"))
@@ -310,13 +308,6 @@ static int __init raw_init(void)
        }
        class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 
-       devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
-                     S_IFCHR | S_IRUGO | S_IWUGO,
-                     "raw/rawctl");
-       for (i = 1; i < MAX_RAW_MINORS; i++)
-               devfs_mk_cdev(MKDEV(RAW_MAJOR, i),
-                             S_IFCHR | S_IRUGO | S_IWUGO,
-                             "raw/raw%d", i);
        return 0;
 
 error:
@@ -326,12 +317,6 @@ error:
 
 static void __exit raw_exit(void)
 {
-       int i;
-
-       for (i = 1; i < MAX_RAW_MINORS; i++)
-               devfs_remove("raw/raw%d", i);
-       devfs_remove("raw/rawctl");
-       devfs_remove("raw");
        class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
        class_destroy(raw_class);
        cdev_del(&raw_cdev);
index 657c0d88f48c439e6788e4bf4d9bc2e24c1a5550..c84c3c3f10c3e4f27950c2e9075379fe87083679 100644 (file)
@@ -1634,7 +1634,6 @@ static inline int rc_init_drivers(void)
        memset(IRQ_to_board, 0, sizeof(IRQ_to_board));
        riscom_driver->owner = THIS_MODULE;
        riscom_driver->name = "ttyL";
-       riscom_driver->devfs_name = "tts/L";
        riscom_driver->major = RISCOM8_NORMAL_MAJOR;
        riscom_driver->type = TTY_DRIVER_TYPE_SERIAL;
        riscom_driver->subtype = SERIAL_TYPE_NORMAL;
index 0708c5164c830b7fd6d9863a3e65efac3b9e5289..0ac131881322c96920b049c45e8aa64d5fbdb635 100644 (file)
@@ -2426,8 +2426,7 @@ static int __init rp_init(void)
         */
 
        rocket_driver->owner = THIS_MODULE;
-       rocket_driver->flags = TTY_DRIVER_NO_DEVFS;
-       rocket_driver->devfs_name = "tts/R";
+       rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV;
        rocket_driver->name = "ttyR";
        rocket_driver->driver_name = "Comtrol RocketPort";
        rocket_driver->major = TTY_ROCKET_MAJOR;
@@ -2438,7 +2437,7 @@ static int __init rp_init(void)
        rocket_driver->init_termios.c_cflag =
            B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 #ifdef ROCKET_SOFT_FLOW
-       rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 #endif
        tty_set_operations(rocket_driver, &rocket_ops);
 
index 037c940ac71b8bb10b4dd2788aff141980ddba63..c851eeaa406913967ba03f154d1fdba1e2d6835c 100644 (file)
@@ -2235,7 +2235,6 @@ scrn[1] = '\0';
     /* Initialize the tty_driver structure */
     
     cy_serial_driver->owner = THIS_MODULE;
-    cy_serial_driver->devfs_name = "tts/";
     cy_serial_driver->name = "ttyS";
     cy_serial_driver->major = TTY_MAJOR;
     cy_serial_driver->minor_start = 64;
index 00b4a2187164ce408ebac2e3e5b3e7f3ef3291ed..0f7a542d9041052f730ecef16aaead6e1bfbdb4b 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 
@@ -757,11 +756,8 @@ static void __exit stallion_module_exit(void)
                        "errno=%d\n", -i);
                return;
        }
-       for (i = 0; i < 4; i++) {
-               devfs_remove("staliomem/%d", i);
+       for (i = 0; i < 4; i++)
                class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
-       }
-       devfs_remove("staliomem");
        if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
                printk("STALLION: failed to un-register serial memory device, "
                        "errno=%d\n", -i);
@@ -3044,22 +3040,16 @@ static int __init stl_init(void)
  */
        if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
                printk("STALLION: failed to register serial board device\n");
-       devfs_mk_dir("staliomem");
 
        stallion_class = class_create(THIS_MODULE, "staliomem");
-       for (i = 0; i < 4; i++) {
-               devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
-                               S_IFCHR|S_IRUSR|S_IWUSR,
-                               "staliomem/%d", i);
+       for (i = 0; i < 4; i++)
                class_device_create(stallion_class, NULL,
                                    MKDEV(STL_SIOMEMMAJOR, i), NULL,
                                    "staliomem%d", i);
-       }
 
        stl_serial->owner = THIS_MODULE;
        stl_serial->driver_name = stl_drvname;
        stl_serial->name = "ttyE";
-       stl_serial->devfs_name = "tts/E";
        stl_serial->major = STL_SERIALMAJOR;
        stl_serial->minor_start = 0;
        stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
index 079db5a935a1210520d332071d6a47611182dfa4..f7802e5bd7ca757069e91beabf09c1cb4017222c 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/ioport.h>
 #include <asm/io.h>
 #include <linux/bitops.h>
-#include <linux/devfs_fs_kernel.h>     /* DevFs support */
 #include <linux/parport.h>             /* Our code depend on parport */
 #include <linux/device.h>
 
@@ -443,12 +442,6 @@ tipar_register(int nr, struct parport *port)
 
        class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
                        TIPAR_MINOR + nr), NULL, "par%d", nr);
-       /* Use devfs, tree: /dev/ticables/par/[0..2] */
-       err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
-                       S_IFCHR | S_IRUGO | S_IWUGO,
-                       "ticables/par/%d", nr);
-       if (err)
-               goto out_class;
 
        /* Display informations */
        pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
@@ -460,11 +453,7 @@ tipar_register(int nr, struct parport *port)
                pr_info("tipar%d: link cable not found\n", nr);
 
        err = 0;
-       goto out;
 
-out_class:
-       class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr));
-       class_destroy(tipar_class);
 out:
        return err;
 }
@@ -507,9 +496,6 @@ tipar_init_module(void)
                goto out;
        }
 
-       /* Use devfs with tree: /dev/ticables/par/[0..2] */
-       devfs_mk_dir("ticables/par");
-
        tipar_class = class_create(THIS_MODULE, "ticables");
        if (IS_ERR(tipar_class)) {
                err = PTR_ERR(tipar_class);
@@ -528,7 +514,6 @@ out_class:
        class_destroy(tipar_class);
 
 out_chrdev:
-       devfs_remove("ticables/par");
        unregister_chrdev(TIPAR_MAJOR, "tipar");
 out:
        return err;     
@@ -549,10 +534,8 @@ tipar_cleanup_module(void)
                        continue;
                parport_unregister_device(table[i].dev);
                class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
-               devfs_remove("ticables/par/%d", i);
        }
        class_destroy(tipar_class);
-       devfs_remove("ticables/par");
 
        pr_info("tipar: module unloaded\n");
 }
index 8d19f7281f0b4b1bab12b801b8ff141e349bd495..a1143238fecabb28e844717346b7aefa88307318 100644 (file)
 #include <linux/kbd_kern.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include <linux/kmod.h>
 
@@ -2955,8 +2954,8 @@ static struct class *tty_class;
  * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error).
  *
  * This call is required to be made to register an individual tty device if
- * the tty driver's flags have the TTY_DRIVER_NO_DEVFS bit set.  If that
- * bit is not set, this function should not be called.
+ * the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set.  If that
+ * bit is not set, this function should not be called by a tty driver.
  */
 struct class_device *tty_register_device(struct tty_driver *driver,
                                         unsigned index, struct device *device)
@@ -2970,9 +2969,6 @@ struct class_device *tty_register_device(struct tty_driver *driver,
                return ERR_PTR(-EINVAL);
        }
 
-       devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
-                       "%s%d", driver->devfs_name, index + driver->name_base);
-
        if (driver->type == TTY_DRIVER_TYPE_PTY)
                pty_line_name(driver, index, name);
        else
@@ -2991,7 +2987,6 @@ struct class_device *tty_register_device(struct tty_driver *driver,
  */
 void tty_unregister_device(struct tty_driver *driver, unsigned index)
 {
-       devfs_remove("%s%d", driver->devfs_name, index + driver->name_base);
        class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index);
 }
 
@@ -3113,7 +3108,7 @@ int tty_register_driver(struct tty_driver *driver)
        
        list_add(&driver->tty_drivers, &tty_drivers);
        
-       if ( !(driver->flags & TTY_DRIVER_NO_DEVFS) ) {
+       if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) {
                for(i = 0; i < driver->num; i++)
                    tty_register_device(driver, i, NULL);
        }
@@ -3156,7 +3151,7 @@ int tty_unregister_driver(struct tty_driver *driver)
                        driver->termios_locked[i] = NULL;
                        kfree(tp);
                }
-               if (!(driver->flags & TTY_DRIVER_NO_DEVFS))
+               if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
                        tty_unregister_device(driver, i);
        }
        p = driver->ttys;
@@ -3232,14 +3227,12 @@ static int __init tty_init(void)
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
                panic("Couldn't register /dev/tty driver\n");
-       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
        class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
 
        cdev_init(&console_cdev, &console_fops);
        if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
                panic("Couldn't register /dev/console driver\n");
-       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
        class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
 
 #ifdef CONFIG_UNIX98_PTYS
@@ -3247,7 +3240,6 @@ static int __init tty_init(void)
        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
                panic("Couldn't register /dev/ptmx driver\n");
-       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
        class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 #endif
 
@@ -3256,7 +3248,6 @@ static int __init tty_init(void)
        if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
                panic("Couldn't register /dev/tty0 driver\n");
-       devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
        class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
 
        vty_init();
index 3c1dafaa3441eacbeae9e2f924219fd5fea5e5fe..234d7f3fb114e161fde4aa7de491325e446db384 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
@@ -478,12 +477,6 @@ static struct class *vc_class;
 
 void vcs_make_devfs(struct tty_struct *tty)
 {
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 1),
-                       S_IFCHR|S_IRUSR|S_IWUSR,
-                       "vcc/%u", tty->index + 1);
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
-                       S_IFCHR|S_IRUSR|S_IWUSR,
-                       "vcc/a%u", tty->index + 1);
        class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
                        NULL, "vcs%u", tty->index + 1);
        class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
@@ -491,8 +484,6 @@ void vcs_make_devfs(struct tty_struct *tty)
 }
 void vcs_remove_devfs(struct tty_struct *tty)
 {
-       devfs_remove("vcc/%u", tty->index + 1);
-       devfs_remove("vcc/a%u", tty->index + 1);
        class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
        class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
 }
@@ -503,8 +494,6 @@ int __init vcs_init(void)
                panic("unable to get major %d for vcs device", VCS_MAJOR);
        vc_class = class_create(THIS_MODULE, "vc");
 
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
        class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
        class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
        return 0;
index 4e5360388748e7facd991ceefe64a06439f3b35c..07f5ce4b28e368672ec52f161abd3b5ed6606a34 100644 (file)
@@ -1152,7 +1152,6 @@ static int __init viocons_init2(void)
        viotty_driver = alloc_tty_driver(VTTY_PORTS);
        viotty_driver->owner = THIS_MODULE;
        viotty_driver->driver_name = "vioconsole";
-       viotty_driver->devfs_name = "vcs/";
        viotty_driver->name = "tty";
        viotty_driver->name_base = 1;
        viotty_driver->major = TTY_MAJOR;
index 11c7e9de595862a9747b6b19b18d0499e357da6b..198f1505ae238fac3396ddff561e1c5c2834b7fc 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/major.h>
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
@@ -246,7 +245,6 @@ static struct device *tape_device[VIOTAPE_MAX_TAPE];
  */
 static struct {
        unsigned char   cur_part;
-       int             dev_handle;
        unsigned char   part_stat_rwi[MAX_PARTITIONS];
 } state[VIOTAPE_MAX_TAPE];
 
@@ -959,12 +957,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
                        "iseries!vt%d", i);
        class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
                        NULL, "iseries!nvt%d", i);
-       devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
-                       "iseries/vt%d", i);
-       devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i | 0x80),
-                       S_IFCHR | S_IRUSR | S_IWUSR, "iseries/nvt%d", i);
        sprintf(tapename, "iseries/vt%d", i);
-       state[i].dev_handle = devfs_register_tape(tapename);
        printk(VIOTAPE_KERN_INFO "tape %s is iSeries "
                        "resource %10.10s type %4.4s, model %3.3s\n",
                        tapename, viotape_unitinfo[i].rsrcname,
@@ -976,9 +969,6 @@ static int viotape_remove(struct vio_dev *vdev)
 {
        int i = vdev->unit_address;
 
-       devfs_remove("iseries/nvt%d", i);
-       devfs_remove("iseries/vt%d", i);
-       devfs_unregister_tape(state[i].dev_handle);
        class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
        class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
        return 0;
index fd00822ac145ea50f224321874a107d67cfb670c..fe99fc1aba45c9d3978693dbb12dba5a6e330c76 100644 (file)
@@ -147,7 +147,6 @@ static int scc_init_drivers(void)
        scc_driver->owner = THIS_MODULE;
        scc_driver->driver_name = "scc";
        scc_driver->name = "ttyS";
-       scc_driver->devfs_name = "tts/";
        scc_driver->major = TTY_MAJOR;
        scc_driver->minor_start = SCC_MINOR_BASE;
        scc_driver->type = TTY_DRIVER_TYPE_SERIAL;
index 714d95ff2f1e462fe36c881a17a7fb61ea5414a9..d6f65032649ab83398407026accffa8c9071ffdd 100644 (file)
@@ -79,7 +79,6 @@
 #include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
 #include <linux/tiocl.h>
@@ -2663,7 +2662,6 @@ int __init vty_init(void)
        if (!console_driver)
                panic("Couldn't allocate console driver\n");
        console_driver->owner = THIS_MODULE;
-       console_driver->devfs_name = "vc/";
        console_driver->name = "tty";
        console_driver->name_base = 1;
        console_driver->major = TTY_MAJOR;
index 99fa42402e71ee7f373a335c928ed1218c73ffd6..bfafd4846a08024f1b470de94bc52d5f1793365d 100644 (file)
@@ -3527,8 +3527,6 @@ static int ide_cd_probe(ide_drive_t *drive)
        drive->driver_data = info;
 
        g->minors = 1;
-       snprintf(g->devfs_name, sizeof(g->devfs_name),
-                       "%s/cd", drive->devfs_name);
        g->driverfs_dev = &drive->gendev;
        g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
        if (ide_cdrom_setup(drive)) {
index f033d732f387277fbabe2fe7bb4123afe371a9d8..d0227c39ced16d763c9242f85ee77415ddb36040 100644 (file)
@@ -1018,7 +1018,6 @@ static void ide_disk_release(struct kref *kref)
        struct gendisk *g = idkp->disk;
 
        drive->driver_data = NULL;
-       drive->devfs_name[0] = '\0';
        g->private_data = NULL;
        put_disk(g);
        kfree(idkp);
@@ -1222,7 +1221,6 @@ static int ide_disk_probe(ide_drive_t *drive)
                drive->attach = 1;
 
        g->minors = 1 << PARTN_BITS;
-       strcpy(g->devfs_name, drive->devfs_name);
        g->driverfs_dev = &drive->gendev;
        g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
        set_capacity(g, idedisk_capacity(drive));
index 4656587aa2f70d2e1deced9716664f89162f7f91..68628327c0f55ce9c33e6938d350e4de09c702a1 100644 (file)
@@ -2176,7 +2176,6 @@ static int ide_floppy_probe(ide_drive_t *drive)
 
        g->minors = 1 << PARTN_BITS;
        g->driverfs_dev = &drive->gendev;
-       strcpy(g->devfs_name, drive->devfs_name);
        g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
        g->fops = &idefloppy_ops;
        drive->attach = 1;
index 9ebf8ae2a5e30676d83369c32a8aa6c5546fed84..0d5038a2856060ac369bd7f61195e449e79758b7 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
 #include <linux/kmod.h>
 #include <linux/pci.h>
@@ -1279,10 +1278,6 @@ static void drive_release_dev (struct device *dev)
        ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
 
        spin_lock_irq(&ide_lock);
-       if (drive->devfs_name[0] != '\0') {
-               devfs_remove(drive->devfs_name);
-               drive->devfs_name[0] = '\0';
-       }
        ide_remove_drive_from_hwgroup(drive);
        kfree(drive->id);
        drive->id = NULL;
@@ -1316,12 +1311,6 @@ static void init_gendisk (ide_hwif_t *hwif)
                drive->gendev.bus = &ide_bus_type;
                drive->gendev.driver_data = drive;
                drive->gendev.release = drive_release_dev;
-               if (drive->present) {
-                       sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d",
-                               (hwif->channel && hwif->mate) ?
-                               hwif->mate->index : hwif->index,
-                               hwif->channel, unit, drive->lun);
-               }
        }
        blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
                        THIS_MODULE, ata_probe, ata_lock, hwif);
index 09f3a7dab28ade081cd5e0fe94120aaa96fc8e8d..4b91101e12b7715fee6682f6dcc8124006f672f6 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/major.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
 #include <linux/slab.h>
@@ -4726,9 +4725,6 @@ static void ide_tape_release(struct kref *kref)
                        MKDEV(IDETAPE_MAJOR, tape->minor));
        class_device_destroy(idetape_sysfs_class,
                        MKDEV(IDETAPE_MAJOR, tape->minor + 128));
-       devfs_remove("%s/mt", drive->devfs_name);
-       devfs_remove("%s/mtn", drive->devfs_name);
-       devfs_unregister_tape(g->number);
        idetape_devs[tape->minor] = NULL;
        g->private_data = NULL;
        put_disk(g);
@@ -4902,14 +4898,6 @@ static int ide_tape_probe(ide_drive_t *drive)
        class_device_create(idetape_sysfs_class, NULL,
                        MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name);
 
-       devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
-                       S_IFCHR | S_IRUGO | S_IWUGO,
-                       "%s/mt", drive->devfs_name);
-       devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor + 128),
-                       S_IFCHR | S_IRUGO | S_IWUGO,
-                       "%s/mtn", drive->devfs_name);
-
-       g->number = devfs_register_tape(drive->devfs_name);
        g->fops = &idetape_block_ops;
        ide_register_region(g);
 
index 59fe358048b32ebebf029eb292f0cd960215352f..1cdf44205162cc79f347a45727e9261df4dbf53a 100644 (file)
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/completion.h>
 #include <linux/reboot.h>
 #include <linux/cdrom.h>
@@ -592,13 +591,8 @@ void ide_unregister(unsigned int index)
                goto abort;
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                drive = &hwif->drives[unit];
-               if (!drive->present) {
-                       if (drive->devfs_name[0] != '\0') {
-                               devfs_remove(drive->devfs_name);
-                               drive->devfs_name[0] = '\0';
-                       }
+               if (!drive->present)
                        continue;
-               }
                spin_unlock_irq(&ide_lock);
                device_unregister(&drive->gendev);
                wait_for_completion(&drive->gendev_rel_comp);
@@ -1996,7 +1990,6 @@ EXPORT_SYMBOL_GPL(ide_bus_type);
 static int __init ide_init(void)
 {
        printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
-       devfs_mk_dir("ide");
        system_bus_speed = ide_system_bus_speed();
 
        bus_register(&ide_bus_type);
@@ -2074,7 +2067,6 @@ void cleanup_module (void)
 #ifdef CONFIG_PROC_FS
        proc_ide_destroy();
 #endif
-       devfs_remove("ide");
 
        bus_unregister(&ide_bus_type);
 }
index 6d66351805a2506e8c8d75dcf090b23197d82a0d..9cad197a4e685f8f4ade42abe1bcb28a4100e8bc 100644 (file)
@@ -3,11 +3,9 @@
 
 #include <linux/config.h>
 #include <asm/io.h>
-
-#ifdef CONFIG_PCI
 #include <asm/oplib.h>
-#include <asm/ebus.h>
-#endif
+#include <asm/prom.h>
+#include <asm/of_device.h>
 
 static int i8042_kbd_irq = -1;
 static int i8042_aux_irq = -1;
@@ -48,54 +46,83 @@ static inline void i8042_write_command(int val)
 #define OBP_PS2MS_NAME1                "kdmouse"
 #define OBP_PS2MS_NAME2                "mouse"
 
+static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_device_id *match)
+{
+       struct device_node *dp = op->node;
+
+       dp = dp->child;
+       while (dp) {
+               if (!strcmp(dp->name, OBP_PS2KBD_NAME1) ||
+                   !strcmp(dp->name, OBP_PS2KBD_NAME2)) {
+                       struct of_device *kbd = of_find_device_by_node(dp);
+                       unsigned int irq = kbd->irqs[0];
+                       if (irq == 0xffffffff)
+                               irq = op->irqs[0];
+                       i8042_kbd_irq = irq;
+                       kbd_iobase = of_ioremap(&kbd->resource[0],
+                                               0, 8, "kbd");
+               } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) ||
+                          !strcmp(dp->name, OBP_PS2MS_NAME2)) {
+                       struct of_device *ms = of_find_device_by_node(dp);
+                       unsigned int irq = ms->irqs[0];
+                       if (irq == 0xffffffff)
+                               irq = op->irqs[0];
+                       i8042_aux_irq = irq;
+               }
+
+               dp = dp->sibling;
+       }
+
+       return 0;
+}
+
+static int __devexit sparc_i8042_remove(struct of_device *op)
+{
+       of_iounmap(kbd_iobase, 8);
+
+       return 0;
+}
+
+static struct of_device_id sparc_i8042_match[] = {
+       {
+               .name = "8042",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, i8042_match);
+
+static struct of_platform_driver sparc_i8042_driver = {
+       .name           = "i8042",
+       .match_table    = sparc_i8042_match,
+       .probe          = sparc_i8042_probe,
+       .remove         = __devexit_p(sparc_i8042_remove),
+};
+
 static int __init i8042_platform_init(void)
 {
 #ifndef CONFIG_PCI
        return -ENODEV;
 #else
-       char prop[128];
-       int len;
+       struct device_node *root = of_find_node_by_path("/");
 
-       len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop));
-       if (len < 0) {
-               printk("i8042: Cannot get name property of root OBP node.\n");
-               return -ENODEV;
-       }
-       if (strncmp(prop, "SUNW,JavaStation-1", len) == 0) {
+       if (!strcmp(root->name, "SUNW,JavaStation-1")) {
                /* Hardcoded values for MrCoffee.  */
                i8042_kbd_irq = i8042_aux_irq = 13 | 0x20;
                kbd_iobase = ioremap(0x71300060, 8);
                if (!kbd_iobase)
                        return -ENODEV;
        } else {
-               struct linux_ebus *ebus;
-               struct linux_ebus_device *edev;
-               struct linux_ebus_child *child;
-
-               for_each_ebus(ebus) {
-                       for_each_ebusdev(edev, ebus) {
-                               if (!strcmp(edev->prom_node->name, "8042"))
-                                       goto edev_found;
-                       }
-               }
-               return -ENODEV;
-
-       edev_found:
-               for_each_edevchild(edev, child) {
-                       if (!strcmp(child->prom_node->name, OBP_PS2KBD_NAME1) ||
-                           !strcmp(child->prom_node->name, OBP_PS2KBD_NAME2)) {
-                               i8042_kbd_irq = child->irqs[0];
-                               kbd_iobase =
-                                       ioremap(child->resource[0].start, 8);
-                       }
-                       if (!strcmp(child->prom_node->name, OBP_PS2MS_NAME1) ||
-                           !strcmp(child->prom_node->name, OBP_PS2MS_NAME2))
-                               i8042_aux_irq = child->irqs[0];
-               }
+               int err = of_register_driver(&sparc_i8042_driver,
+                                            &of_bus_type);
+               if (err)
+                       return err;
+
                if (i8042_kbd_irq == -1 ||
                    i8042_aux_irq == -1) {
-                       printk("i8042: Error, 8042 device lacks both kbd and "
-                              "mouse nodes.\n");
+                       if (kbd_iobase) {
+                               of_iounmap(kbd_iobase, 8);
+                               kbd_iobase = (void __iomem *) NULL;
+                       }
                        return -ENODEV;
                }
        }
@@ -109,7 +136,10 @@ static int __init i8042_platform_init(void)
 static inline void i8042_platform_exit(void)
 {
 #ifdef CONFIG_PCI
-       iounmap(kbd_iobase);
+       struct device_node *root = of_find_node_by_path("/");
+
+       if (strcmp(root->name, "SUNW,JavaStation-1"))
+               of_unregister_driver(&sparc_i8042_driver);
 #endif
 }
 
index 5a2703b536dc0948bcb8c1b530c6cbff80eb4482..71a8eea816cb1466f698288e36943d45c4db41fb 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/major.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/wait.h>
 #include <linux/mutex.h>
index 2e541fa020241c468d95dff4f38047cf344f929b..a518ec531021955eed502742a5cec7d007f88bd8 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/isdn/capiutil.h>
 #include <linux/isdn/capicmd.h>
 #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
@@ -1337,7 +1336,6 @@ static int capinc_tty_init(void)
 
        drv->owner = THIS_MODULE;
        drv->driver_name = "capi_nc";
-       drv->devfs_name = "capi/";
        drv->name = "capi";
        drv->major = capi_ttymajor;
        drv->minor_start = 0;
@@ -1516,8 +1514,6 @@ static int __init capi_init(void)
        }
 
        class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
-       devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
-                       "isdn/capi20");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        if (capinc_tty_init() < 0) {
@@ -1552,7 +1548,6 @@ static void __exit capi_exit(void)
        class_device_destroy(capi_class, MKDEV(capi_major, 0));
        class_destroy(capi_class);
        unregister_chrdev(capi_major, "capi20");
-       devfs_remove("isdn/capi20");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        capinc_tty_exit();
index 8a45715dd4c10393e6ea9314df12c2abee67ccf4..3845defd49010b840f781740ddbc7d5290e15f5d 100644 (file)
@@ -41,7 +41,6 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
 #define GIGASET_MINORS     1
 #define GIGASET_MINOR      16
 #define GIGASET_MODULENAME "bas_gigaset"
-#define GIGASET_DEVFSNAME  "gig/bas/"
 #define GIGASET_DEVNAME    "ttyGB"
 
 /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
@@ -2349,8 +2348,7 @@ static int __init bas_gigaset_init(void)
        /* allocate memory for our driver state and intialize it */
        if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
                                       GIGASET_MODULENAME, GIGASET_DEVNAME,
-                                      GIGASET_DEVFSNAME, &gigops,
-                                      THIS_MODULE)) == NULL)
+                                      &gigops, THIS_MODULE)) == NULL)
                goto error;
 
        /* allocate memory for our device state and intialize it */
index 2a56bf33a6738ac47a31ecad684f2b9945aa06d7..aca165d43aa050952dbaaac63e34241cbfd10dd7 100644 (file)
@@ -1092,14 +1092,12 @@ EXPORT_SYMBOL_GPL(gigaset_freedriver);
  *     minors          Number of minors this driver can handle
  *     procname        Name of the driver
  *     devname         Name of the device files (prefix without minor number)
- *     devfsname       Devfs name of the device files without %d
  * return value:
  *     Pointer to the gigaset_driver structure on success, NULL on failure.
  */
 struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
                                          const char *procname,
                                          const char *devname,
-                                         const char *devfsname,
                                          const struct gigaset_ops *ops,
                                          struct module *owner)
 {
@@ -1139,7 +1137,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
                drv->cs[i].minor_index = i;
        }
 
-       gigaset_if_initdriver(drv, procname, devname, devfsname);
+       gigaset_if_initdriver(drv, procname, devname);
 
        spin_lock_irqsave(&driver_lock, flags);
        list_add(&drv->list, &drivers);
index 8d63d822104fb53bad713ede2175016f800dba4f..1ca3bfdef51d0c43f0cdd839028cf477856589d1 100644 (file)
@@ -769,7 +769,6 @@ void gigaset_block_channels(struct cardstate *cs);
 struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
                                          const char *procname,
                                          const char *devname,
-                                         const char *devfsname,
                                          const struct gigaset_ops *ops,
                                          struct module *owner);
 
@@ -892,7 +891,7 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
 
 /* initialize interface */
 void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
-                          const char *devname, const char *devfsname);
+                          const char *devname);
 /* release interface */
 void gigaset_if_freedriver(struct gigaset_driver *drv);
 /* add minor */
index 74fd234956c8949ac2042161b9254456c87b0dda..bd2e4267528e58aadbcb4f770f75b4cccbc72ba0 100644 (file)
@@ -673,10 +673,9 @@ EXPORT_SYMBOL_GPL(gigaset_if_receive);
  *     drv             Driver
  *     procname        Name of the driver (e.g. for /proc/tty/drivers)
  *     devname         Name of the device files (prefix without minor number)
- *     devfsname       Devfs name of the device files without %d
  */
 void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
-                          const char *devname, const char *devfsname)
+                          const char *devname)
 {
        unsigned minors = drv->minors;
        int ret;
@@ -692,7 +691,7 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
        tty->major =            GIG_MAJOR,
        tty->type =             TTY_DRIVER_TYPE_SERIAL,
        tty->subtype =          SERIAL_TYPE_NORMAL,
-       tty->flags =            TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+       tty->flags =            TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 
        tty->driver_name =      procname;
        tty->name =             devname;
@@ -700,7 +699,6 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
        tty->num =              drv->minors;
 
        tty->owner =            THIS_MODULE;
-       tty->devfs_name =       devfsname;
 
        tty->init_termios          = tty_std_termios; //FIXME
        tty->init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME
index d86ab68114b0c7848126661c2009816658093c9d..6e05d9d4a51ad13ad0acd55a4b9b9c6a26b3eaa9 100644 (file)
@@ -41,7 +41,6 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
 #define GIGASET_MINORS     1
 #define GIGASET_MINOR      8
 #define GIGASET_MODULENAME "usb_gigaset"
-#define GIGASET_DEVFSNAME  "gig/usb/"
 #define GIGASET_DEVNAME    "ttyGU"
 
 #define IF_WRITEBUF 2000 //FIXME  // WAKEUP_CHARS: 256
@@ -896,8 +895,7 @@ static int __init usb_gigaset_init(void)
        /* allocate memory for our driver state and intialize it */
        if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
                                       GIGASET_MODULENAME, GIGASET_DEVNAME,
-                                      GIGASET_DEVFSNAME, &ops,
-                                      THIS_MODULE)) == NULL)
+                                      &ops, THIS_MODULE)) == NULL)
                goto error;
 
        /* allocate memory for our device state and intialize it */
index 6146f7633be5d421b9c113836c22654bd8cbb1b3..b163c5909182d40286c0b01ce41a18448efd40a2 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <linux/poll.h>
-#include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
 
 #include "platform.h"
@@ -178,7 +177,6 @@ static struct file_operations divas_maint_fops = {
 
 static void divas_maint_unregister_chrdev(void)
 {
-       devfs_remove(DEVNAME);
        unregister_chrdev(major, DEVNAME);
 }
 
@@ -190,7 +188,6 @@ static int DIVA_INIT_FUNCTION divas_maint_register_chrdev(void)
                       DRIVERLNAME);
                return (0);
        }
-       devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
 
        return (1);
 }
index df715b47e2b43f64239821353ab4f9b22c3de4fb..6e7d89a31c1d668a3c2f4b02a28a6542c06b38ae 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
-#include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
 
 #include "platform.h"
@@ -145,7 +144,6 @@ static struct file_operations divas_idi_fops = {
 
 static void divas_idi_unregister_chrdev(void)
 {
-       devfs_remove(DEVNAME);
        unregister_chrdev(major, DEVNAME);
 }
 
@@ -157,7 +155,6 @@ static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void)
                       DRIVERLNAME);
                return (0);
        }
-       devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
 
        return (1);
 }
index c9b26e86d183090555540d582eca4631c03d05d8..9dee6a39104c617774454f4da58a968f6a5b57b0 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <linux/ioport.h>
@@ -678,7 +677,6 @@ static struct file_operations divas_fops = {
 
 static void divas_unregister_chrdev(void)
 {
-       devfs_remove(DEVNAME);
        unregister_chrdev(major, DEVNAME);
 }
 
@@ -690,7 +688,6 @@ static int DIVA_INIT_FUNCTION divas_register_chrdev(void)
                       DRIVERLNAME);
                return (0);
        }
-       devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
 
        return (1);
 }
index 433389daedb2ab9208b2f45b2bd3320ff18cf5ff..0a53a990c100a2662102cab27823c1b6a7e0b5a0 100644 (file)
@@ -1890,14 +1890,13 @@ isdn_tty_modem_init(void)
        if (!m->tty_modem)
                return -ENOMEM;
        m->tty_modem->name = "ttyI";
-       m->tty_modem->devfs_name = "isdn/ttyI";
        m->tty_modem->major = ISDN_TTY_MAJOR;
        m->tty_modem->minor_start = 0;
        m->tty_modem->type = TTY_DRIVER_TYPE_SERIAL;
        m->tty_modem->subtype = SERIAL_TYPE_NORMAL;
        m->tty_modem->init_termios = tty_std_termios;
        m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        m->tty_modem->driver_name = "isdn_tty";
        tty_set_operations(m->tty_modem, &modem_ops);
        retval = tty_register_driver(m->tty_modem);
index 259fd8973ce94c076064a2323a38b467d325d9c4..9f1a049dc226a4d2a3086130ab0164f7889edbd2 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
@@ -904,8 +903,6 @@ adbdev_init(void)
                return;
        }
 
-       devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb");
-
        adb_dev_class = class_create(THIS_MODULE, "adb");
        if (IS_ERR(adb_dev_class))
                return;
index 3edb3477f987d4199c32d94e96d03e2c40e3ef1f..d13bb15a8a02981f69706048d32bfc64b83b73c1 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/dm-ioctl.h>
 #include <linux/hdreg.h>
 
@@ -68,14 +67,12 @@ static int dm_hash_init(void)
 {
        init_buckets(_name_buckets);
        init_buckets(_uuid_buckets);
-       devfs_mk_dir(DM_DIR);
        return 0;
 }
 
 static void dm_hash_exit(void)
 {
        dm_hash_remove_all(0);
-       devfs_remove(DM_DIR);
 }
 
 /*-----------------------------------------------------------------
@@ -171,25 +168,6 @@ static void free_cell(struct hash_cell *hc)
        }
 }
 
-/*
- * devfs stuff.
- */
-static int register_with_devfs(struct hash_cell *hc)
-{
-       struct gendisk *disk = dm_disk(hc->md);
-
-       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
-                     S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
-                     DM_DIR "/%s", hc->name);
-       return 0;
-}
-
-static int unregister_with_devfs(struct hash_cell *hc)
-{
-       devfs_remove(DM_DIR"/%s", hc->name);
-       return 0;
-}
-
 /*
  * The kdev_t and uuid of a device can never change once it is
  * initially inserted.
@@ -226,7 +204,6 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi
                }
                list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
        }
-       register_with_devfs(cell);
        dm_get(md);
        dm_set_mdptr(md, cell);
        up_write(&_hash_lock);
@@ -246,7 +223,6 @@ static void __hash_remove(struct hash_cell *hc)
        /* remove from the dev hash */
        list_del(&hc->uuid_list);
        list_del(&hc->name_list);
-       unregister_with_devfs(hc);
        dm_set_mdptr(hc->md, NULL);
 
        table = dm_get_table(hc->md);
@@ -342,16 +318,11 @@ static int dm_hash_rename(const char *old, const char *new)
        /*
         * rename and move the name cell.
         */
-       unregister_with_devfs(hc);
-
        list_del(&hc->name_list);
        old_name = hc->name;
        hc->name = new_name;
        list_add(&hc->name_list, _name_buckets + hash_str(new_name));
 
-       /* rename the device node in devfs */
-       register_with_devfs(hc);
-
        /*
         * Wake up any dm event waiters.
         */
@@ -1501,7 +1472,6 @@ static struct file_operations _ctl_fops = {
 static struct miscdevice _dm_misc = {
        .minor          = MISC_DYNAMIC_MINOR,
        .name           = DM_NAME,
-       .devfs_name     = "mapper/control",
        .fops           = &_ctl_fops
 };
 
index 3ed2e53b9eb6aa71051e7aafc3ecbbee132b732c..c99bf9f017599a1002a15f608ea356639239dedd 100644 (file)
@@ -167,7 +167,7 @@ static void local_exit(void)
        bioset_free(dm_set);
 
        if (unregister_blkdev(_major, _name) < 0)
-               DMERR("devfs_unregister_blkdev failed");
+               DMERR("unregister_blkdev failed");
 
        _major = 0;
 
index 306268ec99ff11572e975145f3f916ee4144cf63..2ec1b3520a0b7245344610bba7fd1763beb9d25d 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/raid/md.h>
 #include <linux/raid/bitmap.h>
 #include <linux/sysctl.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/suspend.h>
 #include <linux/poll.h>
@@ -2911,13 +2910,10 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
        }
        disk->major = MAJOR(dev);
        disk->first_minor = unit << shift;
-       if (partitioned) {
+       if (partitioned)
                sprintf(disk->disk_name, "md_d%d", unit);
-               sprintf(disk->devfs_name, "md/d%d", unit);
-       } else {
+       else
                sprintf(disk->disk_name, "md%d", unit);
-               sprintf(disk->devfs_name, "md/%d", unit);
-       }
        disk->fops = &md_fops;
        disk->private_data = mddev;
        disk->queue = mddev->queue;
@@ -5538,8 +5534,6 @@ static void md_geninit(void)
 
 static int __init md_init(void)
 {
-       int minor;
-
        printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d,"
                        " MD_SB_DISKS=%d\n",
                        MD_MAJOR_VERSION, MD_MINOR_VERSION,
@@ -5553,23 +5547,11 @@ static int __init md_init(void)
                unregister_blkdev(MAJOR_NR, "md");
                return -1;
        }
-       devfs_mk_dir("md");
        blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE,
                                md_probe, NULL, NULL);
        blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE,
                            md_probe, NULL, NULL);
 
-       for (minor=0; minor < MAX_MD_DEVS; ++minor)
-               devfs_mk_bdev(MKDEV(MAJOR_NR, minor),
-                               S_IFBLK|S_IRUSR|S_IWUSR,
-                               "md/%d", minor);
-
-       for (minor=0; minor < MAX_MD_DEVS; ++minor)
-               devfs_mk_bdev(MKDEV(mdp_major, minor<<MdpMinorShift),
-                             S_IFBLK|S_IRUSR|S_IWUSR,
-                             "md/mdp%d", minor);
-
-
        register_reboot_notifier(&md_notifier);
        raid_table_header = register_sysctl_table(raid_root_table, 1);
 
@@ -5625,15 +5607,9 @@ static __exit void md_exit(void)
 {
        mddev_t *mddev;
        struct list_head *tmp;
-       int i;
+
        blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS);
        blk_unregister_region(MKDEV(mdp_major,0), MAX_MD_DEVS << MdpMinorShift);
-       for (i=0; i < MAX_MD_DEVS; i++)
-               devfs_remove("md/%d", i);
-       for (i=0; i < MAX_MD_DEVS; i++)
-               devfs_remove("md/d%d", i);
-
-       devfs_remove("md");
 
        unregister_blkdev(MAJOR_NR,"md");
        unregister_blkdev(mdp_major, "mdp");
index 134c2bbbeeb5f75e89921413850a0bffec367ed6..40774feb8953d241566ef2cc79d3e5a11d3fdeb2 100644 (file)
@@ -231,10 +231,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 
        mutex_unlock(&dvbdev_register_lock);
 
-       devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
-                       S_IFCHR | S_IRUSR | S_IWUSR,
-                       "dvb/adapter%d/%s%d", adap->num, dnames[type], id);
-
        class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
                            adap->device, "dvb%d.%s%d", adap->num, dnames[type], id);
 
@@ -252,9 +248,6 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
        if (!dvbdev)
                return;
 
-       devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num,
-                       dnames[dvbdev->type], dvbdev->id);
-
        class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
                                        dvbdev->type, dvbdev->id)));
 
@@ -302,7 +295,6 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu
 
        printk ("DVB: registering new adapter (%s).\n", name);
 
-       devfs_mk_dir("dvb/adapter%d", num);
        adap->num = num;
        adap->name = name;
        adap->module = module;
@@ -319,8 +311,6 @@ EXPORT_SYMBOL(dvb_register_adapter);
 
 int dvb_unregister_adapter(struct dvb_adapter *adap)
 {
-       devfs_remove("dvb/adapter%d", adap->num);
-
        if (mutex_lock_interruptible(&dvbdev_register_lock))
                return -ERESTARTSYS;
        list_del (&adap->list_head);
@@ -410,8 +400,6 @@ static int __init init_dvbdev(void)
                goto error;
        }
 
-       devfs_mk_dir("dvb");
-
        dvb_class = class_create(THIS_MODULE, "dvb");
        if (IS_ERR(dvb_class)) {
                retval = PTR_ERR(dvb_class);
@@ -428,7 +416,6 @@ error:
 
 static void __exit exit_dvbdev(void)
 {
-       devfs_remove("dvb");
        class_destroy(dvb_class);
        cdev_del(&dvb_device_cdev);
        unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
index d7a976d040d72249ab8d5558529d328802356c4e..7a7f75fd168c30f19bf622a349322994914ca336 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/poll.h>
 #include <linux/fs.h>
 #include <linux/list.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 
 #define DVB_MAJOR 212
index 3e2e12124bae0228bd91a69fee9183129fe2bc32..9c79696da08a60d622aaf347cc5a67609fe74388 100644 (file)
@@ -6,10 +6,6 @@
 #include <linux/netdevice.h>
 #include <linux/i2c.h>
 
-#ifdef CONFIG_DEVFS_FS
-#include <linux/devfs_fs_kernel.h>
-#endif
-
 #include <linux/dvb/video.h>
 #include <linux/dvb/audio.h>
 #include <linux/dvb/dmx.h>
index 14559ef6153c4ead4a0468e1411a35ef70c5e5ca..336b2fe1a5f2e13463ba5247bdf41085103ff965 100644 (file)
@@ -126,10 +126,6 @@ struct ttusb {
 
        int revision;
 
-#if 0
-       devfs_handle_t stc_devfs_handle;
-#endif
-
        struct dvb_frontend* fe;
 };
 
@@ -1746,13 +1742,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
                return -ENODEV;
        }
 
-#if 0
-       ttusb->stc_devfs_handle =
-           devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME,
-                          DEVFS_FL_DEFAULT, 0, 192,
-                          S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
-                          | S_IROTH | S_IWOTH, &stc_fops, ttusb);
-#endif
        usb_set_intfdata(intf, (void *) ttusb);
 
        frontend_init(ttusb);
index 87b37b7691dad387cd082b10c030b9c0829947f3..c1b1db65e66821544b541ca37eed4d9fa2491643 100644 (file)
@@ -115,7 +115,6 @@ static struct file_operations rds_fops = {
 static struct miscdevice rds_miscdev = {
        .minor          = MISC_DYNAMIC_MINOR,
        .name           = "radiotext",
-       .devfs_name     = "v4l/rds/radiotext",
        .fops           = &rds_fops,
 };
 
index 6e08e32346eb9272774c14796e81a0c36da8b7e7..ae14f5f32039cffb00016bc07ab677a340b343a1 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
index 2dfa7f23d0ca28f7e08a2fa7167184789c32cc29..b26ebaff226f49182537c0a350ff4189969eaddf 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
@@ -1563,10 +1562,6 @@ int video_register_device(struct video_device *vfd, int type, int nr)
        video_device[i]=vfd;
        vfd->minor=i;
        mutex_unlock(&videodev_lock);
-
-       sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base);
-       devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor),
-                       S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name);
        mutex_init(&vfd->lock);
 
        /* sysfs class */
@@ -1575,7 +1570,7 @@ int video_register_device(struct video_device *vfd, int type, int nr)
                vfd->class_dev.dev = vfd->dev;
        vfd->class_dev.class       = &video_class;
        vfd->class_dev.devt        = MKDEV(VIDEO_MAJOR, vfd->minor);
-       strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE);
+       sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
        class_device_register(&vfd->class_dev);
        class_device_create_file(&vfd->class_dev,
                                &class_device_attr_name);
@@ -1604,7 +1599,6 @@ void video_unregister_device(struct video_device *vfd)
        if(video_device[vfd->minor]!=vfd)
                panic("videodev: bad unregister");
 
-       devfs_remove(vfd->devfs_name);
        video_device[vfd->minor]=NULL;
        class_device_unregister(&vfd->class_dev);
        mutex_unlock(&videodev_lock);
index 7d4c5497785b3c1dd1d1709733b5a899e5547c6a..1ddc2fb429d5668a2f653c2c3e5d7561e5a4a92d 100644 (file)
@@ -1089,7 +1089,6 @@ static int i2o_block_probe(struct device *dev)
        gd = i2o_blk_dev->gd;
        gd->first_minor = unit << 4;
        sprintf(gd->disk_name, "i2o/hd%c", 'a' + unit);
-       sprintf(gd->devfs_name, "i2o/hd%c", 'a' + unit);
        gd->driverfs_dev = &i2o_dev->device;
 
        /* setup request queue */
index 587458b370b9a9d71c817d0375d140847f01c505..115cc21094b941a243d323756f127f905b14e0bf 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/hdreg.h>
 #include <linux/kdev_t.h>
 #include <linux/blkdev.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/mutex.h>
 
 #include <linux/mmc/card.h>
@@ -409,7 +408,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
         */
 
        sprintf(md->disk->disk_name, "mmcblk%d", devidx);
-       sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
 
        blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
 
@@ -555,7 +553,6 @@ static int __init mmc_blk_init(void)
        if (major == 0)
                major = res;
 
-       devfs_mk_dir("mmc");
        return mmc_register_driver(&mmc_driver);
 
  out:
@@ -565,7 +562,6 @@ static int __init mmc_blk_init(void)
 static void __exit mmc_blk_exit(void)
 {
        mmc_unregister_driver(&mmc_driver);
-       devfs_remove("mmc");
        unregister_blkdev(major, "mmc");
 }
 
index 7635736cc791f6151c8f5f236050a51f430ebe9a..d55b0f7939a645a27ddc60082c466cfa5d7b6efd 100644 (file)
@@ -57,8 +57,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.4.42"
-#define DRV_MODULE_RELDATE     "June 12, 2006"
+#define DRV_MODULE_VERSION     "1.4.43"
+#define DRV_MODULE_RELDATE     "June 28, 2006"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -1676,7 +1676,7 @@ bnx2_tx_int(struct bnx2 *bp)
 
                tx_free_bd += last + 1;
 
-               dev_kfree_skb_irq(skb);
+               dev_kfree_skb(skb);
 
                hw_cons = bp->hw_tx_cons =
                        sblk->status_tx_quick_consumer_index0;
@@ -1824,7 +1824,7 @@ reuse_rx:
                if ((len > (bp->dev->mtu + ETH_HLEN)) &&
                        (ntohs(skb->protocol) != 0x8100)) {
 
-                       dev_kfree_skb_irq(skb);
+                       dev_kfree_skb(skb);
                        goto next_rx;
 
                }
@@ -3643,7 +3643,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
                                skb_shinfo(skb)->frags[j].size,
                                PCI_DMA_TODEVICE);
                }
-               dev_kfree_skb_any(skb);
+               dev_kfree_skb(skb);
                i += j + 1;
        }
 
@@ -3669,7 +3669,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
 
                rx_buf->skb = NULL;
 
-               dev_kfree_skb_any(skb);
+               dev_kfree_skb(skb);
        }
 }
 
@@ -3999,7 +3999,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        udelay(5);
 
        pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
-       dev_kfree_skb_irq(skb);
+       dev_kfree_skb(skb);
 
        if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) {
                goto loopback_test_done;
@@ -4541,7 +4541,7 @@ bnx2_close(struct net_device *dev)
        bnx2_netif_stop(bp);
        del_timer_sync(&bp->timer);
        if (bp->flags & NO_WOL_FLAG)
-               reset_code = BNX2_DRV_MSG_CODE_UNLOAD;
+               reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
        else if (bp->wol)
                reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
        else
@@ -5128,6 +5128,16 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data)
        return 0;
 }
 
+static int
+bnx2_set_tso(struct net_device *dev, u32 data)
+{
+       if (data)
+               dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
+       else
+               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
+       return 0;
+}
+
 #define BNX2_NUM_STATS 46
 
 static struct {
@@ -5445,7 +5455,7 @@ static struct ethtool_ops bnx2_ethtool_ops = {
        .set_sg                 = ethtool_op_set_sg,
 #ifdef BCM_TSO
        .get_tso                = ethtool_op_get_tso,
-       .set_tso                = ethtool_op_set_tso,
+       .set_tso                = bnx2_set_tso,
 #endif
        .self_test_count        = bnx2_self_test_count,
        .self_test              = bnx2_self_test,
@@ -5926,7 +5936,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 #endif
 #ifdef BCM_TSO
-       dev->features |= NETIF_F_TSO;
+       dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
 #endif
 
        netif_carrier_off(bp->dev);
@@ -5968,7 +5978,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
        netif_device_detach(dev);
        del_timer_sync(&bp->timer);
        if (bp->flags & NO_WOL_FLAG)
-               reset_code = BNX2_DRV_MSG_CODE_UNLOAD;
+               reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
        else if (bp->wol)
                reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
        else
index 5845e334941b4f8e71ca80ad5c674bf7a7ffd5e9..658c5ee95c73ecdea4bd4c34c74e68e2b82b54bb 100644 (file)
@@ -4174,6 +4174,7 @@ struct fw_info {
 #define BNX2_DRV_MSG_CODE_PULSE                         0x06000000
 #define BNX2_DRV_MSG_CODE_DIAG                  0x07000000
 #define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL        0x09000000
+#define BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN                 0x0b000000
 
 #define BNX2_DRV_MSG_DATA                       0x00ff0000
 #define BNX2_DRV_MSG_DATA_WAIT0                         0x00010000
index d2ce4896abff24605d8b4ab37cf221f6e78f8107..e9e6d99a9add263619e2278f756b59ab29709aa4 100644 (file)
@@ -350,7 +350,7 @@ config TOSHIBA_FIR
 
 config AU1000_FIR
        tristate "Alchemy Au1000 SIR/FIR"
-       depends on MIPS_AU1000 && IRDA
+       depends on SOC_AU1000 && IRDA
 
 config SMC_IRCC_FIR
        tristate "SMSC IrCC (EXPERIMENTAL)"
index 754297fc8f224f086fd52fe8597969576bb34001..47f6f64d604c980b2c5a553a5500a01fca4b1b78 100644 (file)
@@ -101,7 +101,7 @@ static int transceiver_type = MCS_TSC_VISHAY;
 module_param(transceiver_type, int, 0444);
 MODULE_PARM_DESC(transceiver_type, "IR transceiver type, see mcs7780.h.");
 
-struct usb_driver mcs_driver = {
+static struct usb_driver mcs_driver = {
        .name = "mcs7780",
        .probe = mcs_probe,
        .disconnect = mcs_disconnect,
index d643a097faa5cd8de1a234179d17ab55aa336ed3..425ff5b117f1c3e2da4338ee44e9dbce25f318fe 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/netdevice.h>
 #include <linux/poll.h>
 #include <linux/ppp_defs.h>
@@ -863,10 +862,6 @@ static int __init ppp_init(void)
                        goto out_chrdev;
                }
                class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
-               err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
-                               S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
-               if (err)
-                       goto out_class;
        }
 
 out:
@@ -874,9 +869,6 @@ out:
                printk(KERN_ERR "failed to register PPP device (%d)\n", err);
        return err;
 
-out_class:
-       class_device_destroy(ppp_class, MKDEV(PPP_MAJOR,0));
-       class_destroy(ppp_class);
 out_chrdev:
        unregister_chrdev(PPP_MAJOR, "ppp");
        goto out;
@@ -2681,7 +2673,6 @@ static void __exit ppp_cleanup(void)
        cardmap_destroy(&all_ppp_units);
        if (unregister_chrdev(PPP_MAJOR, "ppp") != 0)
                printk(KERN_ERR "PPP: failed to unregister PPP device\n");
-       devfs_remove("ppp");
        class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
        class_destroy(ppp_class);
 }
index c33ead3470db718886007204291a5fdc0861ad2b..9b246e44f7562cc3b1d3a6519487464b443236cc 100644 (file)
@@ -2523,7 +2523,7 @@ static struct ethtool_ops hme_ethtool_ops = {
 static int hme_version_printed;
 
 #ifdef CONFIG_SBUS
-void __init quattro_get_ranges(struct quattro *qp)
+void __devinit quattro_get_ranges(struct quattro *qp)
 {
        struct sbus_dev *sdev = qp->quattro_dev;
        int err;
@@ -2539,7 +2539,7 @@ void __init quattro_get_ranges(struct quattro *qp)
        qp->nranges = (err / sizeof(struct linux_prom_ranges));
 }
 
-static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp)
+static void __devinit quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp)
 {
        struct sbus_dev *sdev = hp->happy_dev;
        int rng;
@@ -2566,7 +2566,7 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h
  *
  * Return NULL on failure.
  */
-static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev)
+static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev)
 {
        struct sbus_dev *sdev;
        struct quattro *qp;
@@ -2618,7 +2618,7 @@ static void __init quattro_sbus_register_irqs(void)
        }
 }
 
-static void __devexit quattro_sbus_free_irqs(void)
+static void quattro_sbus_free_irqs(void)
 {
        struct quattro *qp;
 
@@ -2662,7 +2662,7 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_SBUS
-static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
+static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
 {
        struct device_node *dp = sdev->ofdev.node;
        struct quattro *qp = NULL;
index 6c62d5c882683f09267e06e9dade80f1cfb9482d..732c5edec2e5edd3cab20c8d0aa43233b8fab8c8 100644 (file)
@@ -780,7 +780,6 @@ static struct miscdevice tun_miscdev = {
        .minor = TUN_MINOR,
        .name = "tun",
        .fops = &tun_fops,
-       .devfs_name = "net/tun",
 };
 
 /* ethtool interface */
index e392ee8b37a14828e02b8fc9198d8f8ab0618747..be5e33814cb144ea7db78787342c6dda1e7e0a08 100644 (file)
@@ -85,7 +85,6 @@
 #include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -393,7 +392,6 @@ static int __init cosa_init(void)
                err = -ENODEV;
                goto out;
        }
-       devfs_mk_dir("cosa");
        cosa_class = class_create(THIS_MODULE, "cosa");
        if (IS_ERR(cosa_class)) {
                err = PTR_ERR(cosa_class);
@@ -402,13 +400,6 @@ static int __init cosa_init(void)
        for (i=0; i<nr_cards; i++) {
                class_device_create(cosa_class, NULL, MKDEV(cosa_major, i),
                                NULL, "cosa%d", i);
-               err = devfs_mk_cdev(MKDEV(cosa_major, i),
-                               S_IFCHR|S_IRUSR|S_IWUSR,
-                               "cosa/%d", i);
-               if (err) {
-                       class_device_destroy(cosa_class, MKDEV(cosa_major, i));
-                       goto out_chrdev;                
-               }
        }
        err = 0;
        goto out;
@@ -426,12 +417,9 @@ static void __exit cosa_exit(void)
        int i;
        printk(KERN_INFO "Unloading the cosa module\n");
 
-       for (i=0; i<nr_cards; i++) {
+       for (i=0; i<nr_cards; i++)
                class_device_destroy(cosa_class, MKDEV(cosa_major, i));
-               devfs_remove("cosa/%d", i);
-       }
        class_destroy(cosa_class);
-       devfs_remove("cosa");
        for (cosa=cosa_cards; nr_cards--; cosa++) {
                /* Clean up the per-channel data */
                for (i=0; i<cosa->nchannels; i++) {
index bafcd2f20ae241071e5fad970684bd4f088df9fa..2dc179b14ce6484e5dd6f53a8221461d0854857f 100644 (file)
@@ -1834,7 +1834,6 @@ dasd_exit(void)
        }
        dasd_gendisk_exit();
        dasd_devmap_exit();
-       devfs_remove("dasd");
        if (dasd_debug_area != NULL) {
                debug_unregister(dasd_debug_area);
                dasd_debug_area = NULL;
@@ -2107,9 +2106,6 @@ dasd_init(void)
 
        dasd_diag_discipline_pointer = NULL;
 
-       rc = devfs_mk_dir("dasd");
-       if (rc)
-               goto failed;
        rc = dasd_devmap_init();
        if (rc)
                goto failed;
index fce2835e7d19a5008427665b0ef9110e8c920e2a..61ffde718a7a84f881969d0b51a5a0cd394b4829 100644 (file)
@@ -68,8 +68,6 @@ dasd_gendisk_alloc(struct dasd_device *device)
        }
        len += sprintf(gdp->disk_name + len, "%c", 'a'+(device->devindex%26));
 
-       sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id);
-
        if (device->features & DASD_FEATURE_READONLY)
                set_disk_ro(gdp, 1);
        gdp->private_data = device;
index 03a83efc34c4f71db19f4403c2170554fa4f9f91..3ccf06d28ba11ba2cc6b793c41317fd7c92d8758 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/module.h>
 #include <linux/wait.h>
 #include <linux/blkdev.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/genhd.h>
 #include <linux/hdreg.h>
 #include <linux/interrupt.h>
index 54ecd548c3185b1aac9a78e7343b079bce771ea9..4c1e56b9b98dbaafa5b85cc6d74138489112248f 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/hdreg.h>  /* HDIO_GETGEO */
 #include <linux/sysdev.h>
 #include <linux/bio.h>
-#include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
 
 #define XPRAM_NAME     "xpram"
@@ -439,8 +438,6 @@ static int __init xpram_setup_blkdev(void)
        if (rc < 0)
                goto out;
 
-       devfs_mk_dir("slram");
-
        /*
         * Assign the other needed values: make request function, sizes and
         * hardsect size. All the minor devices feature the same value.
@@ -469,14 +466,12 @@ static int __init xpram_setup_blkdev(void)
                disk->private_data = &xpram_devices[i];
                disk->queue = xpram_queue;
                sprintf(disk->disk_name, "slram%d", i);
-               sprintf(disk->devfs_name, "slram/%d", i);
                set_capacity(disk, xpram_sizes[i] << 1);
                add_disk(disk);
        }
 
        return 0;
 out_unreg:
-       devfs_remove("slram");
        unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
 out:
        while (i--)
@@ -495,7 +490,6 @@ static void __exit xpram_exit(void)
                put_disk(xpram_disks[i]);
        }
        unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
-       devfs_remove("slram");
        blk_cleanup_queue(xpram_queue);
        sysdev_unregister(&xpram_sys_device);
        sysdev_class_unregister(&xpram_sysclass);
index fb7bc9e5eebc90a20c09ae40f07b3df2a4c3e950..a138b1510093cc53a6538a99c47fe020da53518a 100644 (file)
@@ -586,7 +586,6 @@ static struct file_operations mon_fops = {
 
 static struct miscdevice mon_dev = {
        .name       = "monreader",
-       .devfs_name = "monreader",
        .fops       = &mon_fops,
        .minor      = MISC_DYNAMIC_MINOR,
 };
index 9a141776873fc42de018fb59f1cb8a681819a6e5..7d26a3e4cb80797f10256e5de65f389f619cd960 100644 (file)
@@ -1785,7 +1785,6 @@ tty3270_init(void)
         * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
         */
        driver->owner = THIS_MODULE;
-       driver->devfs_name = "ttyTUB/";
        driver->driver_name = "ttyTUB";
        driver->name = "ttyTUB";
        driver->major = IBM_TTY3270_MAJOR;
@@ -1793,7 +1792,7 @@ tty3270_init(void)
        driver->type = TTY_DRIVER_TYPE_SYSTEM;
        driver->subtype = SYSTEM_TYPE_TTY;
        driver->init_termios = tty_std_termios;
-       driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS;
+       driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV;
        tty_set_operations(driver, &tty3270_ops);
        ret = tty_register_driver(driver);
        if (ret) {
index 982acc7303ea299c1566e8580b3027556941a516..b2f20ab8431a05c6c53ffe460e51696d720c00e0 100644 (file)
@@ -411,7 +411,6 @@ static struct miscdevice z90crypt_misc_device = {
        .minor      = Z90CRYPT_MINOR,
        .name       = DEV_NAME,
        .fops       = &z90crypt_fops,
-       .devfs_name = DEV_NAME
 };
 
 /**
index ccb20a6f5f36d7593b991d985cb8a478f704368f..385f4f768311500ea278ae379bf7a29b86d196c0 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/major.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -1031,11 +1030,6 @@ static int __init bpp_init(void)
                instances[idx].opened = 0;
                probeLptPort(idx);
        }
-       devfs_mk_dir("bpp");
-       for (idx = 0; idx < BPP_NO; idx++) {
-               devfs_mk_cdev(MKDEV(BPP_MAJOR, idx),
-                               S_IFCHR | S_IRUSR | S_IWUSR, "bpp/%d", idx);
-       }
 
        return 0;
 }
@@ -1044,9 +1038,6 @@ static void __exit bpp_cleanup(void)
 {
        unsigned idx;
 
-       for (idx = 0; idx < BPP_NO; idx++)
-               devfs_remove("bpp/%d", idx);
-       devfs_remove("bpp");
        unregister_chrdev(BPP_MAJOR, dev_name);
 
        for (idx = 0;  idx < BPP_NO; idx++) {
index 8045cd5e7cb3389041cdef112aac185f6d90b968..63941a259b927436f2f96e7589d8e8267e48ffa9 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _LINUX_VFC_H_
 #define _LINUX_VFC_H_
 
-#include <linux/devfs_fs_kernel.h>
-
 /*
  * The control register for the vfc is at offset 0x4000
  * The first field ram bank is located at offset 0x5000
index ddcd330b9e891a46291650b12d917f90923c5277..55b2b31bd7abbf0d2dbcde64af303c952b442821 100644 (file)
@@ -164,10 +164,6 @@ int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance)
                return -EINVAL;
        if (init_vfc_hw(dev))
                return -EIO;
-
-       devfs_mk_cdev(MKDEV(VFC_MAJOR, instance),
-                       S_IFCHR | S_IRUSR | S_IWUSR,
-                       "vfc/%d", instance);
        return 0;
 }
 
@@ -677,7 +673,6 @@ static int vfc_probe(void)
                kfree(vfc_dev_lst);
                return -EIO;
        }
-       devfs_mk_dir("vfc");
        instance = 0;
        for_all_sbusdev(sdev, sbus) {
                if (strcmp(sdev->prom_name, "vfc") == 0) {
@@ -717,7 +712,6 @@ static void deinit_vfc_device(struct vfc_dev *dev)
 {
        if(dev == NULL)
                return;
-       devfs_remove("vfc/%d", dev->instance);
        sbus_iounmap(dev->regs, sizeof(struct vfc_regs));
        kfree(dev);
 }
@@ -731,7 +725,6 @@ void cleanup_module(void)
        for (devp = vfc_dev_lst; *devp; devp++)
                deinit_vfc_device(*devp);
 
-       devfs_remove("vfc");
        kfree(vfc_dev_lst);
        return;
 }
index 7572665a885516d89ece6dcb5898154a14be2916..9fd0de4b7afdb961608af0d0c62b1e7c8d56cbf6 100644 (file)
@@ -479,7 +479,6 @@ static struct uart_driver serial21285_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "ttyFB",
        .dev_name               = "ttyFB",
-       .devfs_name             = "ttyFB",
        .major                  = SERIAL_21285_MAJOR,
        .minor                  = SERIAL_21285_MINOR,
        .nr                     = 1,
index bbf78aaf9e01f074d15bf6db21042feb9dec5591..f361b356bd1d693f79a8777e9a568fdc9878267b 100644 (file)
@@ -2354,7 +2354,6 @@ int __init serial8250_start_console(struct uart_port *port, char *options)
 static struct uart_driver serial8250_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "serial",
-       .devfs_name             = "tts/",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
        .minor                  = 64,
index db5b25fafed42dfc36261dc6a4232e88d068f18a..df9500bdaded4ebe5903e57e56dc16a746e7d6b7 100644 (file)
@@ -863,7 +863,6 @@ static struct uart_driver at91_uart = {
        .owner                  = THIS_MODULE,
        .driver_name            = "at91_serial",
        .dev_name               = AT91_DEVICENAME,
-       .devfs_name             = AT91_DEVICENAME,
        .major                  = SERIAL_AT91_MAJOR,
        .minor                  = MINOR_START,
        .nr                     = AT91_NR_UART,
index 5cacc5e74a9246e1982150027b95e96b4dbbd9c6..b84137cdeb2be6c55d361280f01021bb7ba70ad7 100644 (file)
@@ -4878,7 +4878,7 @@ rs_init(void)
        driver->init_termios = tty_std_termios;
        driver->init_termios.c_cflag =
                B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
-       driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        driver->termios = serial_termios;
        driver->termios_locked = serial_termios_locked;
 
index bf71bad5c34f7ff14f3d55ec66d7f6db397e50b8..466d06cc7d3762473b812ddf45a4d4146dbd0e28 100644 (file)
@@ -768,11 +768,7 @@ void __init dz_serial_console_init(void)
 static struct uart_driver dz_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "serial",
-#ifdef CONFIG_DEVFS
-       .dev_name               = "tts/%d",
-#else
        .dev_name               = "ttyS%d",
-#endif
        .major                  = TTY_MAJOR,
        .minor                  = 64,
        .nr                     = DZ_NB_PORT,
index d202eb4f3848f0cade4b4b2ed841f34f76703241..da85bafa09423fab636cc784d3dd1c98eb5de9e9 100644 (file)
@@ -888,7 +888,6 @@ static struct uart_driver imx_reg = {
        .owner          = THIS_MODULE,
        .driver_name    = DRIVER_NAME,
        .dev_name       = "ttySMX",
-       .devfs_name     = "ttsmx/",
        .major          = SERIAL_IMX_MAJOR,
        .minor          = MINOR_START,
        .nr             = ARRAY_SIZE(imx_ports),
index 651772474ac17d6687b4722f337b06765c2e7524..56b093ecd779eac6c122130d08724ac92baa9f9c 100644 (file)
@@ -1085,7 +1085,6 @@ static struct console ip22zilog_console = {
 static struct uart_driver ip22zilog_reg = {
        .owner          = THIS_MODULE,
        .driver_name    = "serial",
-       .devfs_name     = "tts/",
        .dev_name       = "ttyS",
        .major          = TTY_MAJOR,
        .minor          = 64,
index 321a40f33b5042c93db4baac5ef6300c1f7f1f68..6a2a25d9b59638762f0c1830dbbd7d6056094fcd 100644 (file)
@@ -1131,7 +1131,6 @@ console_initcall(m32r_sio_console_init);
 static struct uart_driver m32r_sio_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "sio",
-       .devfs_name             = "tts/",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
        .minor                  = 64,
index 8ad242934368e43f66b7fbe1cbff628a047e9bc1..29c0630e3e64a2edfdfd83e98a098f313854a613 100644 (file)
@@ -1713,7 +1713,6 @@ mcfrs_init(void)
        /* Initialize the tty_driver structure */
        mcfrs_serial_driver->owner = THIS_MODULE;
        mcfrs_serial_driver->name = "ttyS";
-       mcfrs_serial_driver->devfs_name = "ttys/";
        mcfrs_serial_driver->driver_name = "serial";
        mcfrs_serial_driver->major = TTY_MAJOR;
        mcfrs_serial_driver->minor_start = 64;
index 6459edc7f5c5e09d23bef78c590abfe677a5a813..1aa34844218cee9065bf7e3f8d4304af5b688fff 100644 (file)
@@ -693,7 +693,6 @@ static struct uart_driver mpc52xx_uart_driver = {
        .owner          = THIS_MODULE,
        .driver_name    = "mpc52xx_psc_uart",
        .dev_name       = "ttyPSC",
-       .devfs_name     = "ttyPSC",
        .major          = SERIAL_PSC_MAJOR,
        .minor          = SERIAL_PSC_MINOR,
        .nr             = MPC52xx_PSC_MAXNUM,
index 94681922ea0a6a2e874bef249520ce541a035ee4..1cd102f84bfad80bd789016880ddb4a9f2d0c94d 100644 (file)
@@ -315,7 +315,6 @@ struct mpsc_port_info *mpsc_device_remove(int index);
 #define MPSC_MAJOR             204
 #define MPSC_MINOR_START       44
 #define        MPSC_DRIVER_NAME        "MPSC"
-#define        MPSC_DEVFS_NAME         "ttymm/"
 #define        MPSC_DEV_NAME           "ttyMM"
 #define        MPSC_VERSION            "1.00"
 
@@ -1863,7 +1862,6 @@ static struct platform_driver mpsc_shared_driver = {
 static struct uart_driver mpsc_reg = {
        .owner       = THIS_MODULE,
        .driver_name = MPSC_DRIVER_NAME,
-       .devfs_name  = MPSC_DEVFS_NAME,
        .dev_name    = MPSC_DEV_NAME,
        .major       = MPSC_MAJOR,
        .minor       = MPSC_MINOR_START,
index 513ff8597707bf5c642f0dd1d02aad97356fdf7f..e3ba7e17a240b8cc080c11aacc7979d49454403f 100644 (file)
@@ -101,7 +101,6 @@ static DEFINE_MUTEX(pmz_irq_mutex);
 static struct uart_driver pmz_uart_reg = {
        .owner          =       THIS_MODULE,
        .driver_name    =       "ttyS",
-       .devfs_name     =       "tts/",
        .dev_name       =       "ttyS",
        .major          =       TTY_MAJOR,
 };
index ae3649568541d091a24e121f391d061f514285fd..0fa0ccc9ed272b9c7dc8f9b4d71a64cc800969ed 100644 (file)
@@ -780,7 +780,6 @@ static struct uart_pxa_port serial_pxa_ports[] = {
 static struct uart_driver serial_pxa_reg = {
        .owner          = THIS_MODULE,
        .driver_name    = "PXA serial",
-       .devfs_name     = "tts/",
        .dev_name       = "ttyS",
        .major          = TTY_MAJOR,
        .minor          = 64,
index 837b6da520b3aeb0f9bbd0897ead81f123233b55..4c62ab949ecc3e01aaf04da45ca23cb7d2443a21 100644 (file)
@@ -149,7 +149,6 @@ s3c24xx_serial_dbg(const char *fmt, ...)
 /* UART name and device definitions */
 
 #define S3C24XX_SERIAL_NAME    "ttySAC"
-#define S3C24XX_SERIAL_DEVFS    "tts/"
 #define S3C24XX_SERIAL_MAJOR   204
 #define S3C24XX_SERIAL_MINOR   64
 
@@ -952,7 +951,6 @@ static struct uart_driver s3c24xx_uart_drv = {
        .nr             = 3,
        .cons           = S3C24XX_SERIAL_CONSOLE,
        .driver_name    = S3C24XX_SERIAL_NAME,
-       .devfs_name     = S3C24XX_SERIAL_DEVFS,
        .major          = S3C24XX_SERIAL_MAJOR,
        .minor          = S3C24XX_SERIAL_MINOR,
 };
index c2d9068b491d8c0dacb549b365196174ef0ec63f..8bbd8567669cdf955888cc0bccd4542a9470faab 100644 (file)
@@ -816,7 +816,6 @@ static struct uart_driver sa1100_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "ttySA",
        .dev_name               = "ttySA",
-       .devfs_name             = "ttySA",
        .major                  = SERIAL_SA1100_MAJOR,
        .minor                  = MINOR_START,
        .nr                     = NR_PORTS,
index 17839e753e4cfb1fb550832d8613b0ec579c83ef..7dc1e67b6851b2e0ade005e73be8aea60a7df782 100644 (file)
@@ -2153,7 +2153,6 @@ int uart_register_driver(struct uart_driver *drv)
 
        normal->owner           = drv->owner;
        normal->driver_name     = drv->driver_name;
-       normal->devfs_name      = drv->devfs_name;
        normal->name            = drv->dev_name;
        normal->major           = drv->major;
        normal->minor_start     = drv->minor;
@@ -2161,7 +2160,7 @@ int uart_register_driver(struct uart_driver *drv)
        normal->subtype         = SERIAL_TYPE_NORMAL;
        normal->init_termios    = tty_std_termios;
        normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       normal->flags           = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       normal->flags           = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        normal->driver_state    = drv;
        tty_set_operations(normal, &uart_ops);
 
@@ -2312,7 +2311,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
        mutex_unlock(&state->mutex);
 
        /*
-        * Remove the devices from devfs
+        * Remove the devices from the tty layer
         */
        tty_unregister_device(drv->tty_driver, port->line);
 
index 3bdee64d1a997101f12f49f9f7c509c25694cbd8..a901a7e446f3ca91c696989fd35426a5151401e2 100644 (file)
@@ -69,12 +69,10 @@ static char *serial_name = "TX39/49 Serial driver";
 #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
 /* "ttyS" is used for standard serial driver */
 #define TXX9_TTY_NAME "ttyTX"
-#define TXX9_TTY_DEVFS_NAME "tttx/"
 #define TXX9_TTY_MINOR_START   (64 + 64)       /* ttyTX0(128), ttyTX1(129) */
 #else
 /* acts like standard serial driver */
 #define TXX9_TTY_NAME "ttyS"
-#define TXX9_TTY_DEVFS_NAME "tts/"
 #define TXX9_TTY_MINOR_START   64
 #endif
 #define TXX9_TTY_MAJOR TTY_MAJOR
@@ -971,7 +969,6 @@ console_initcall(serial_txx9_console_init);
 static struct uart_driver serial_txx9_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "serial_txx9",
-       .devfs_name             = TXX9_TTY_DEVFS_NAME,
        .dev_name               = TXX9_TTY_NAME,
        .major                  = TXX9_TTY_MAJOR,
        .minor                  = TXX9_TTY_MINOR_START,
index 44f6bf79bbe12725fc0ba499501ba49625bcda60..d97f3ca6cc29996b6f4a5ed274a2b90f0af1f05c 100644 (file)
@@ -1699,9 +1699,6 @@ static char banner[] __initdata =
 static struct uart_driver sci_uart_driver = {
        .owner          = THIS_MODULE,
        .driver_name    = "sci",
-#ifdef CONFIG_DEVFS_FS
-       .devfs_name     = "ttsc/",
-#endif
        .dev_name       = "ttySC",
        .major          = SCI_MAJOR,
        .minor          = SCI_MINOR_START,
index ba22e256c6f77267c8a95cb50b583ed349f994d6..d36bc4003399ed27021299a92585adbd1e062d66 100644 (file)
@@ -353,7 +353,6 @@ static struct uart_ops sunhv_pops = {
 static struct uart_driver sunhv_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "serial",
-       .devfs_name             = "tts/",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
 };
index e4c0fd2d6a9d54f1332d60304fd2c6dd23b42f0f..141fedbefbc4cd51096b4d8a2569e14722a933d8 100644 (file)
@@ -1,7 +1,7 @@
 /* sunsab.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 2002  David S. Miller (davem@redhat.com)
+ * Copyright (C) 2002, 2006  David S. Miller (davem@davemloft.net)
  *
  * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
  *   Maxim Krasnyanskiy <maxk@qualcomm.com>
@@ -12,7 +12,7 @@
  *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
  *
  * Ported to new 2.5.x UART layer.
- *   David S. Miller <davem@redhat.com>
+ *   David S. Miller <davem@davemloft.net>
  */
 
 #include <linux/config.h>
@@ -37,8 +37,8 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/oplib.h>
-#include <asm/ebus.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 
 #if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -851,7 +851,6 @@ static struct uart_ops sunsab_pops = {
 static struct uart_driver sunsab_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "serial",
-       .devfs_name             = "tts/",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
 };
@@ -977,199 +976,188 @@ static inline struct console *SUNSAB_CONSOLE(void)
 #define sunsab_console_init()  do { } while (0)
 #endif
 
-static void __init for_each_sab_edev(void (*callback)(struct linux_ebus_device *, void *), void *arg)
+static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
+                                    struct of_device *op,
+                                    unsigned long offset,
+                                    int line)
 {
-       struct linux_ebus *ebus;
-       struct linux_ebus_device *edev = NULL;
-
-       for_each_ebus(ebus) {
-               for_each_ebusdev(edev, ebus) {
-                       if (!strcmp(edev->prom_node->name, "se")) {
-                               callback(edev, arg);
-                               continue;
-                       } else if (!strcmp(edev->prom_node->name, "serial")) {
-                               char *compat;
-                               int clen;
-
-                               /* On RIO this can be an SE, check it.  We could
-                                * just check ebus->is_rio, but this is more portable.
-                                */
-                               compat = of_get_property(edev->prom_node,
-                                                        "compatible", &clen);
-                               if (compat && clen > 0) {
-                                       if (strncmp(compat, "sab82532", 8) == 0) {
-                                               callback(edev, arg);
-                                               continue;
-                                       }
-                               }
-                       }
-               }
-       }
-}
+       up->port.line = line;
+       up->port.dev = &op->dev;
+
+       up->port.mapbase = op->resource[0].start + offset;
+       up->port.membase = of_ioremap(&op->resource[0], offset,
+                                     sizeof(union sab82532_async_regs),
+                                     "sab");
+       if (!up->port.membase)
+               return -ENOMEM;
+       up->regs = (union sab82532_async_regs __iomem *) up->port.membase;
 
-static void __init sab_count_callback(struct linux_ebus_device *edev, void *arg)
-{
-       int *count_p = arg;
+       up->port.irq = op->irqs[0];
 
-       (*count_p)++;
-}
+       up->port.fifosize = SAB82532_XMIT_FIFO_SIZE;
+       up->port.iotype = UPIO_MEM;
 
-static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg)
-{
-       int *instance_p = arg;
-       struct uart_sunsab_port *up;
-       unsigned long regs, offset;
-       int i;
+       writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc);
 
-       /* Note: ports are located in reverse order */
-       regs = edev->resource[0].start;
-       offset = sizeof(union sab82532_async_regs);
-       for (i = 0; i < 2; i++) {
-               up = &sunsab_ports[(*instance_p * 2) + 1 - i];
+       up->port.ops = &sunsab_pops;
+       up->port.type = PORT_SUNSAB;
+       up->port.uartclk = SAB_BASE_BAUD;
 
-               memset(up, 0, sizeof(*up));
-               up->regs = ioremap(regs + offset, sizeof(union sab82532_async_regs));
-               up->port.irq = edev->irqs[0];
-               up->port.fifosize = SAB82532_XMIT_FIFO_SIZE;
-               up->port.mapbase = (unsigned long)up->regs;
-               up->port.iotype = UPIO_MEM;
+       up->type = readb(&up->regs->r.vstr) & 0x0f;
+       writeb(~((1 << 1) | (1 << 2) | (1 << 4)), &up->regs->w.pcr);
+       writeb(0xff, &up->regs->w.pim);
+       if ((up->port.line & 0x1) == 0) {
+               up->pvr_dsr_bit = (1 << 0);
+               up->pvr_dtr_bit = (1 << 1);
+       } else {
+               up->pvr_dsr_bit = (1 << 3);
+               up->pvr_dtr_bit = (1 << 2);
+       }
+       up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4);
+       writeb(up->cached_pvr, &up->regs->w.pvr);
+       up->cached_mode = readb(&up->regs->rw.mode);
+       up->cached_mode |= SAB82532_MODE_FRTS;
+       writeb(up->cached_mode, &up->regs->rw.mode);
+       up->cached_mode |= SAB82532_MODE_RTS;
+       writeb(up->cached_mode, &up->regs->rw.mode);
 
-               writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc);
+       up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
+       up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
 
-               offset -= sizeof(union sab82532_async_regs);
+       if (!(up->port.line & 0x01)) {
+               int err;
+
+               err = request_irq(up->port.irq, sunsab_interrupt,
+                                 SA_SHIRQ, "sab", up);
+               if (err) {
+                       of_iounmap(up->port.membase,
+                                  sizeof(union sab82532_async_regs));
+                       return err;
+               }
        }
-       
-       (*instance_p)++;
+
+       return 0;
 }
 
-static int __init probe_for_sabs(void)
+static int __devinit sab_probe(struct of_device *op, const struct of_device_id *match)
 {
-       int this_sab = 0;
+       static int inst;
+       struct uart_sunsab_port *up;
+       int err;
+
+       up = &sunsab_ports[inst * 2];
+
+       err = sunsab_init_one(&up[0], op,
+                             sizeof(union sab82532_async_regs),
+                             (inst * 2) + 0);
+       if (err)
+               return err;
+
+       err = sunsab_init_one(&up[0], op, 0,
+                             (inst * 2) + 1);
+       if (err) {
+               of_iounmap(up[0].port.membase,
+                          sizeof(union sab82532_async_regs));
+               free_irq(up[0].port.irq, &up[0]);
+               return err;
+       }
 
-       /* Find device instances.  */
-       for_each_sab_edev(&sab_count_callback, &this_sab);
-       if (!this_sab)
-               return -ENODEV;
+       uart_add_one_port(&sunsab_reg, &up[0].port);
+       uart_add_one_port(&sunsab_reg, &up[1].port);
 
-       /* Allocate tables.  */
-       sunsab_ports = kmalloc(sizeof(struct uart_sunsab_port) * this_sab * 2,
-                              GFP_KERNEL);
-       if (!sunsab_ports)
-               return -ENOMEM;
+       dev_set_drvdata(&op->dev, &up[0]);
 
-       num_channels = this_sab * 2;
+       inst++;
 
-       this_sab = 0;
-       for_each_sab_edev(&sab_attach_callback, &this_sab);
        return 0;
 }
 
-static void __init sunsab_init_hw(void)
+static void __devexit sab_remove_one(struct uart_sunsab_port *up)
 {
-       int i;
-
-       for (i = 0; i < num_channels; i++) {
-               struct uart_sunsab_port *up = &sunsab_ports[i];
-
-               up->port.line = i;
-               up->port.ops = &sunsab_pops;
-               up->port.type = PORT_SUNSAB;
-               up->port.uartclk = SAB_BASE_BAUD;
-
-               up->type = readb(&up->regs->r.vstr) & 0x0f;
-               writeb(~((1 << 1) | (1 << 2) | (1 << 4)), &up->regs->w.pcr);
-               writeb(0xff, &up->regs->w.pim);
-               if (up->port.line == 0) {
-                       up->pvr_dsr_bit = (1 << 0);
-                       up->pvr_dtr_bit = (1 << 1);
-               } else {
-                       up->pvr_dsr_bit = (1 << 3);
-                       up->pvr_dtr_bit = (1 << 2);
-               }
-               up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4);
-               writeb(up->cached_pvr, &up->regs->w.pvr);
-               up->cached_mode = readb(&up->regs->rw.mode);
-               up->cached_mode |= SAB82532_MODE_FRTS;
-               writeb(up->cached_mode, &up->regs->rw.mode);
-               up->cached_mode |= SAB82532_MODE_RTS;
-               writeb(up->cached_mode, &up->regs->rw.mode);
-
-               up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
-               up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
-
-               if (!(up->port.line & 0x01)) {
-                       if (request_irq(up->port.irq, sunsab_interrupt,
-                                       SA_SHIRQ, "serial(sab82532)", up)) {
-                               printk("sunsab%d: can't get IRQ %x\n",
-                                      i, up->port.irq);
-                               continue;
-                       }
-               }
-       }
+       uart_remove_one_port(&sunsab_reg, &up->port);
+       if (!(up->port.line & 1))
+               free_irq(up->port.irq, up);
+       of_iounmap(up->port.membase,
+                  sizeof(union sab82532_async_regs));
 }
 
-static int __init sunsab_init(void)
+static int __devexit sab_remove(struct of_device *op)
 {
-       int ret = probe_for_sabs();
-       int i;
-
-       if (ret < 0)
-               return ret;
+       struct uart_sunsab_port *up = dev_get_drvdata(&op->dev);
 
-       sunsab_init_hw();
+       sab_remove_one(&up[0]);
+       sab_remove_one(&up[1]);
 
-       sunsab_reg.minor = sunserial_current_minor;
-       sunsab_reg.nr = num_channels;
+       dev_set_drvdata(&op->dev, NULL);
 
-       ret = uart_register_driver(&sunsab_reg);
-       if (ret < 0) {
-               int i;
+       return 0;
+}
 
-               for (i = 0; i < num_channels; i++) {
-                       struct uart_sunsab_port *up = &sunsab_ports[i];
+static struct of_device_id sab_match[] = {
+       {
+               .name = "se",
+       },
+       {
+               .name = "serial",
+               .compatible = "sab82532",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, sab_match);
 
-                       if (!(up->port.line & 0x01))
-                               free_irq(up->port.irq, up);
-                       iounmap(up->regs);
-               }
-               kfree(sunsab_ports);
-               sunsab_ports = NULL;
+static struct of_platform_driver sab_driver = {
+       .name           = "sab",
+       .match_table    = sab_match,
+       .probe          = sab_probe,
+       .remove         = __devexit_p(sab_remove),
+};
 
-               return ret;
+static int __init sunsab_init(void)
+{
+       struct device_node *dp;
+       int err;
+
+       num_channels = 0;
+       for_each_node_by_name(dp, "su")
+               num_channels += 2;
+       for_each_node_by_name(dp, "serial") {
+               if (of_device_is_compatible(dp, "sab82532"))
+                       num_channels += 2;
        }
 
-       sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64;
+       if (num_channels) {
+               sunsab_ports = kzalloc(sizeof(struct uart_sunsab_port) *
+                                      num_channels, GFP_KERNEL);
+               if (!sunsab_ports)
+                       return -ENOMEM;
 
-       sunsab_reg.cons = SUNSAB_CONSOLE();
+               sunsab_reg.minor = sunserial_current_minor;
+               sunsab_reg.nr = num_channels;
 
-       sunserial_current_minor += num_channels;
-       
-       for (i = 0; i < num_channels; i++) {
-               struct uart_sunsab_port *up = &sunsab_ports[i];
+               err = uart_register_driver(&sunsab_reg);
+               if (err) {
+                       kfree(sunsab_ports);
+                       sunsab_ports = NULL;
 
-               uart_add_one_port(&sunsab_reg, &up->port);
+                       return err;
+               }
+
+               sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64;
+               sunsab_reg.cons = SUNSAB_CONSOLE();
+               sunserial_current_minor += num_channels;
        }
 
-       return 0;
+       return of_register_driver(&sab_driver, &of_bus_type);
 }
 
 static void __exit sunsab_exit(void)
 {
-       int i;
-
-       for (i = 0; i < num_channels; i++) {
-               struct uart_sunsab_port *up = &sunsab_ports[i];
-
-               uart_remove_one_port(&sunsab_reg, &up->port);
-
-               if (!(up->port.line & 0x01))
-                       free_irq(up->port.irq, up);
-               iounmap(up->regs);
+       of_unregister_driver(&sab_driver);
+       if (num_channels) {
+               sunserial_current_minor -= num_channels;
+               uart_unregister_driver(&sunsab_reg);
        }
 
-       sunserial_current_minor -= num_channels;
-       uart_unregister_driver(&sunsab_reg);
-
        kfree(sunsab_ports);
        sunsab_ports = NULL;
 }
index 0268b307c01e439e96c248cd554bb6f73a4ba462..73a043b914ef61a1f32b3e9d35b9d9e3e595af98 100644 (file)
@@ -12,7 +12,7 @@
  *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
  *
  * Converted to new 2.5.x UART layer.
- *   David S. Miller (davem@redhat.com), 2002-Jul-29
+ *   David S. Miller (davem@davemloft.net), 2002-Jul-29
  */
 
 #include <linux/config.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/oplib.h>
-#include <asm/ebus.h>
-#ifdef CONFIG_SPARC64
-#include <asm/isa.h>
-#endif
+#include <asm/prom.h>
+#include <asm/of_device.h>
 
 #if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -94,10 +91,10 @@ struct uart_sunsu_port {
        /* Probing information.  */
        enum su_type            su_type;
        unsigned int            type_probed;    /* XXX Stupid */
-       int                     port_node;
+       unsigned long           reg_size;
 
 #ifdef CONFIG_SERIO
-       struct serio            *serio;
+       struct serio            serio;
        int                     serio_open;
 #endif
 };
@@ -509,7 +506,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
                /* Stop-A is handled by drivers/char/keyboard.c now. */
                if (up->su_type == SU_PORT_KBD) {
 #ifdef CONFIG_SERIO
-                       serio_interrupt(up->serio, ch, 0, regs);
+                       serio_interrupt(&up->serio, ch, 0, regs);
 #endif
                } else if (up->su_type == SU_PORT_MS) {
                        int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -523,7 +520,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
 
                        case 0:
 #ifdef CONFIG_SERIO
-                               serio_interrupt(up->serio, ch, 0, regs);
+                               serio_interrupt(&up->serio, ch, 0, regs);
 #endif
                                break;
                        };
@@ -1031,99 +1028,14 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
 {
        unsigned char status1, status2, scratch, scratch2, scratch3;
        unsigned char save_lcr, save_mcr;
-       struct linux_ebus_device *dev = NULL;
-       struct linux_ebus *ebus;
-#ifdef CONFIG_SPARC64
-       struct sparc_isa_bridge *isa_br;
-       struct sparc_isa_device *isa_dev;
-#endif
-#ifndef CONFIG_SPARC64
-       struct linux_prom_registers reg0;
-#endif
        unsigned long flags;
 
-       if (!up->port_node || !up->su_type)
+       if (up->su_type == SU_PORT_NONE)
                return;
 
        up->type_probed = PORT_UNKNOWN;
        up->port.iotype = UPIO_MEM;
 
-       /*
-        * First we look for Ebus-bases su's
-        */
-       for_each_ebus(ebus) {
-               for_each_ebusdev(dev, ebus) {
-                       if (dev->prom_node->node == up->port_node) {
-                               /*
-                                * The EBus is broken on sparc; it delivers
-                                * virtual addresses in resources. Oh well...
-                                * This is correct on sparc64, though.
-                                */
-                               up->port.membase = (char *) dev->resource[0].start;
-                               /*
-                                * This is correct on both architectures.
-                                */
-                               up->port.mapbase = dev->resource[0].start;
-                               up->port.irq = dev->irqs[0];
-                               goto ebus_done;
-                       }
-               }
-       }
-
-#ifdef CONFIG_SPARC64
-       for_each_isa(isa_br) {
-               for_each_isadev(isa_dev, isa_br) {
-                       if (isa_dev->prom_node->node == up->port_node) {
-                               /* Same on sparc64. Cool architecure... */
-                               up->port.membase = (char *) isa_dev->resource.start;
-                               up->port.mapbase = isa_dev->resource.start;
-                               up->port.irq = isa_dev->irq;
-                               goto ebus_done;
-                       }
-               }
-       }
-#endif
-
-#ifdef CONFIG_SPARC64
-       /*
-        * Not on Ebus, bailing.
-        */
-       return;
-#else
-       /*
-        * Not on Ebus, must be OBIO.
-        */
-       if (prom_getproperty(up->port_node, "reg",
-                            (char *)&reg0, sizeof(reg0)) == -1) {
-               prom_printf("sunsu: no \"reg\" property\n");
-               return;
-       }
-       prom_apply_obio_ranges(&reg0, 1);
-       if (reg0.which_io != 0) {       /* Just in case... */
-               prom_printf("sunsu: bus number nonzero: 0x%x:%x\n",
-                   reg0.which_io, reg0.phys_addr);
-               return;
-       }
-       up->port.mapbase = reg0.phys_addr;
-       if ((up->port.membase = ioremap(reg0.phys_addr, reg0.reg_size)) == 0) {
-               prom_printf("sunsu: Cannot map registers.\n");
-               return;
-       }
-
-       /*
-        * 0x20 is sun4m thing, Dave Redman heritage.
-        * See arch/sparc/kernel/irq.c.
-        */
-#define IRQ_4M(n)      ((n)|0x20)
-
-       /*
-        * There is no intr property on MrCoffee, so hardwire it.
-        */
-       up->port.irq = IRQ_4M(13);
-#endif
-
-ebus_done:
-
        spin_lock_irqsave(&up->port.lock, flags);
 
        if (!(up->port.flags & UPF_BUGGY_UART)) {
@@ -1265,23 +1177,17 @@ out:
 static struct uart_driver sunsu_reg = {
        .owner                  = THIS_MODULE,
        .driver_name            = "serial",
-       .devfs_name             = "tts/",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
 };
 
-static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
+static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
 {
        int quot, baud;
 #ifdef CONFIG_SERIO
        struct serio *serio;
 #endif
 
-       spin_lock_init(&up->port.lock);
-       up->port.line = channel;
-       up->port.type = PORT_UNKNOWN;
-       up->port.uartclk = (SU_BASE_BAUD * 16);
-
        if (up->su_type == SU_PORT_KBD) {
                up->cflag = B1200 | CS8 | CLOCAL | CREAD;
                baud = 1200;
@@ -1293,41 +1199,31 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
 
        sunsu_autoconfig(up);
        if (up->port.type == PORT_UNKNOWN)
-               return -1;
-
-       printk(KERN_INFO "su%d at 0x%p (irq = %d) is a %s\n",
-              channel,
-              up->port.membase, up->port.irq,
-              sunsu_type(&up->port));
+               return -ENODEV;
 
 #ifdef CONFIG_SERIO
-       up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-       if (serio) {
-               memset(serio, 0, sizeof(*serio));
-
-               serio->port_data = up;
-
-               serio->id.type = SERIO_RS232;
-               if (up->su_type == SU_PORT_KBD) {
-                       serio->id.proto = SERIO_SUNKBD;
-                       strlcpy(serio->name, "sukbd", sizeof(serio->name));
-               } else {
-                       serio->id.proto = SERIO_SUN;
-                       serio->id.extra = 1;
-                       strlcpy(serio->name, "sums", sizeof(serio->name));
-               }
-               strlcpy(serio->phys, (channel == 0 ? "su/serio0" : "su/serio1"),
-                       sizeof(serio->phys));
-
-               serio->write = sunsu_serio_write;
-               serio->open = sunsu_serio_open;
-               serio->close = sunsu_serio_close;
+       serio = &up->serio;
+       serio->port_data = up;
 
-               serio_register_port(serio);
+       serio->id.type = SERIO_RS232;
+       if (up->su_type == SU_PORT_KBD) {
+               serio->id.proto = SERIO_SUNKBD;
+               strlcpy(serio->name, "sukbd", sizeof(serio->name));
        } else {
-               printk(KERN_WARNING "su%d: not enough memory for serio port\n",
-                       channel);
+               serio->id.proto = SERIO_SUN;
+               serio->id.extra = 1;
+               strlcpy(serio->name, "sums", sizeof(serio->name));
        }
+       strlcpy(serio->phys,
+               (!(up->port.line & 1) ? "su/serio0" : "su/serio1"),
+               sizeof(serio->phys));
+
+       serio->write = sunsu_serio_write;
+       serio->open = sunsu_serio_open;
+       serio->close = sunsu_serio_close;
+       serio->dev.parent = up->port.dev;
+
+       serio_register_port(serio);
 #endif
 
        sunsu_change_speed(&up->port, up->cflag, 0, quot);
@@ -1459,22 +1355,20 @@ static struct console sunsu_cons = {
  *     Register console.
  */
 
-static inline struct console *SUNSU_CONSOLE(void)
+static inline struct console *SUNSU_CONSOLE(int num_uart)
 {
        int i;
 
        if (con_is_present())
                return NULL;
 
-       for (i = 0; i < UART_NR; i++) {
+       for (i = 0; i < num_uart; i++) {
                int this_minor = sunsu_reg.minor + i;
 
                if ((this_minor - 64) == (serial_console - 1))
                        break;
        }
-       if (i == UART_NR)
-               return NULL;
-       if (sunsu_ports[i].port_node == 0)
+       if (i == num_uart)
                return NULL;
 
        sunsu_cons.index = i;
@@ -1482,252 +1376,184 @@ static inline struct console *SUNSU_CONSOLE(void)
        return &sunsu_cons;
 }
 #else
-#define SUNSU_CONSOLE()                        (NULL)
+#define SUNSU_CONSOLE(num_uart)                (NULL)
 #define sunsu_serial_console_init()    do { } while (0)
 #endif
 
-static int __init sunsu_serial_init(void)
+static enum su_type __devinit su_get_type(struct device_node *dp)
 {
-       int instance, ret, i;
+       struct device_node *ap = of_find_node_by_path("/aliases");
 
-       /* How many instances do we need?  */
-       instance = 0;
-       for (i = 0; i < UART_NR; i++) {
-               struct uart_sunsu_port *up = &sunsu_ports[i];
+       if (ap) {
+               char *keyb = of_get_property(ap, "keyboard", NULL);
+               char *ms = of_get_property(ap, "mouse", NULL);
 
-               if (up->su_type == SU_PORT_MS ||
-                   up->su_type == SU_PORT_KBD)
-                       continue;
-
-               spin_lock_init(&up->port.lock);
-               up->port.flags |= UPF_BOOT_AUTOCONF;
-               up->port.type = PORT_UNKNOWN;
-               up->port.uartclk = (SU_BASE_BAUD * 16);
+               if (keyb) {
+                       if (dp == of_find_node_by_path(keyb))
+                               return SU_PORT_KBD;
+               }
+               if (ms) {
+                       if (dp == of_find_node_by_path(ms))
+                               return SU_PORT_MS;
+               }
+       }
 
-               sunsu_autoconfig(up);
-               if (up->port.type == PORT_UNKNOWN)
-                       continue;
+       return SU_PORT_PORT;
+}
 
-               up->port.line = instance++;
-               up->port.ops = &sunsu_pops;
-       }
+static int __devinit su_probe(struct of_device *op, const struct of_device_id *match)
+{
+       static int inst;
+       struct device_node *dp = op->node;
+       struct uart_sunsu_port *up;
+       struct resource *rp;
+       int err;
 
-       sunsu_reg.minor = sunserial_current_minor;
+       if (inst >= UART_NR)
+               return -EINVAL;
 
-       sunsu_reg.nr = instance;
+       up = &sunsu_ports[inst];
+       up->port.line = inst;
 
-       ret = uart_register_driver(&sunsu_reg);
-       if (ret < 0)
-               return ret;
+       spin_lock_init(&up->port.lock);
 
-       sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
+       up->su_type = su_get_type(dp);
 
-       sunserial_current_minor += instance;
+       rp = &op->resource[0];
+       up->port.mapbase = op->resource[0].start;
 
-       sunsu_reg.cons = SUNSU_CONSOLE();
+       up->reg_size = (rp->end - rp->start) + 1;
+       up->port.membase = of_ioremap(rp, 0, up->reg_size, "su");
+       if (!up->port.membase)
+               return -ENOMEM;
 
-       for (i = 0; i < UART_NR; i++) {
-               struct uart_sunsu_port *up = &sunsu_ports[i];
+       up->port.irq = op->irqs[0];
 
-               /* Do not register Keyboard/Mouse lines with UART
-                * layer.
-                */
-               if (up->su_type == SU_PORT_MS ||
-                   up->su_type == SU_PORT_KBD)
-                       continue;
+       up->port.dev = &op->dev;
 
-               if (up->port.type == PORT_UNKNOWN)
-                       continue;
+       up->port.type = PORT_UNKNOWN;
+       up->port.uartclk = (SU_BASE_BAUD * 16);
 
-               uart_add_one_port(&sunsu_reg, &up->port);
+       err = 0;
+       if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) {
+               err = sunsu_kbd_ms_init(up);
+               if (err)
+                       goto out_unmap;
        }
 
-       return 0;
-}
+       up->port.flags |= UPF_BOOT_AUTOCONF;
 
-static int su_node_ok(int node, char *name, int namelen)
-{
-       if (strncmp(name, "su", namelen) == 0 ||
-           strncmp(name, "su_pnp", namelen) == 0)
-               return 1;
-
-       if (strncmp(name, "serial", namelen) == 0) {
-               char compat[32];
-               int clen;
-
-               /* Is it _really_ a 'su' device? */
-               clen = prom_getproperty(node, "compatible", compat, sizeof(compat));
-               if (clen > 0) {
-                       if (strncmp(compat, "sab82532", 8) == 0) {
-                               /* Nope, Siemens serial, not for us. */
-                               return 0;
-                       }
-               }
-               return 1;
-       }
+       sunsu_autoconfig(up);
 
-       return 0;
-}
+       err = -ENODEV;
+       if (up->port.type == PORT_UNKNOWN)
+               goto out_unmap;
 
-#define SU_PROPSIZE    128
+       up->port.ops = &sunsu_pops;
 
-/*
- * Scan status structure.
- * "prop" is a local variable but it eats stack to keep it in each
- * stack frame of a recursive procedure.
- */
-struct su_probe_scan {
-       int msnode, kbnode;     /* PROM nodes for mouse and keyboard */
-       int msx, kbx;           /* minors for mouse and keyboard */
-       int devices;            /* scan index */
-       char prop[SU_PROPSIZE];
-};
+       err = uart_add_one_port(&sunsu_reg, &up->port);
+       if (err)
+               goto out_unmap;
 
-/*
- * We have several platforms which present 'su' in different parts
- * of the device tree. 'su' may be found under obio, ebus, isa and pci.
- * We walk over the tree and find them wherever PROM hides them.
- */
-static void __init su_probe_any(struct su_probe_scan *t, int sunode)
-{
-       struct uart_sunsu_port *up;
-       int len;
+       dev_set_drvdata(&op->dev, up);
 
-       if (t->devices >= UART_NR)
-               return;
+       inst++;
 
-       for (; sunode != 0; sunode = prom_getsibling(sunode)) {
-               len = prom_getproperty(sunode, "name", t->prop, SU_PROPSIZE);
-               if (len <= 1)
-                       continue;               /* Broken PROM node */
-
-               if (su_node_ok(sunode, t->prop, len)) {
-                       up = &sunsu_ports[t->devices];
-                       if (t->kbnode != 0 && sunode == t->kbnode) {
-                               t->kbx = t->devices;
-                               up->su_type = SU_PORT_KBD;
-                       } else if (t->msnode != 0 && sunode == t->msnode) {
-                               t->msx = t->devices;
-                               up->su_type = SU_PORT_MS;
-                       } else {
-#ifdef CONFIG_SPARC64
-                               /*
-                                * Do not attempt to use the truncated
-                                * keyboard/mouse ports as serial ports
-                                * on Ultras with PC keyboard attached.
-                                */
-                               if (prom_getbool(sunode, "mouse"))
-                                       continue;
-                               if (prom_getbool(sunode, "keyboard"))
-                                       continue;
-#endif
-                               up->su_type = SU_PORT_PORT;
-                       }
-                       up->port_node = sunode;
-                       ++t->devices;
-               } else {
-                       su_probe_any(t, prom_getchild(sunode));
-               }
-       }
+       return 0;
+
+out_unmap:
+       of_iounmap(up->port.membase, up->reg_size);
+       return err;
 }
 
-static int __init sunsu_probe(void)
+static int __devexit su_remove(struct of_device *dev)
 {
-       int node;
-       int len;
-       struct su_probe_scan scan;
+       struct uart_sunsu_port *up = dev_get_drvdata(&dev->dev);;
 
-       /*
-        * First, we scan the tree.
-        */
-       scan.devices = 0;
-       scan.msx = -1;
-       scan.kbx = -1;
-       scan.kbnode = 0;
-       scan.msnode = 0;
+       if (up->su_type == SU_PORT_MS ||
+           up->su_type == SU_PORT_KBD) {
+#ifdef CONFIG_SERIO
+               serio_unregister_port(&up->serio);
+#endif
+       } else if (up->port.type != PORT_UNKNOWN)
+               uart_remove_one_port(&sunsu_reg, &up->port);
 
-       /*
-        * Get the nodes for keyboard and mouse from 'aliases'...
-        */
-        node = prom_getchild(prom_root_node);
-       node = prom_searchsiblings(node, "aliases");
-       if (node != 0) {
-               len = prom_getproperty(node, "keyboard", scan.prop, SU_PROPSIZE);
-               if (len > 0) {
-                       scan.prop[len] = 0;
-                       scan.kbnode = prom_finddevice(scan.prop);
-               }
+       return 0;
+}
 
-               len = prom_getproperty(node, "mouse", scan.prop, SU_PROPSIZE);
-               if (len > 0) {
-                       scan.prop[len] = 0;
-                       scan.msnode = prom_finddevice(scan.prop);
-               }
-       }
+static struct of_device_id su_match[] = {
+       {
+               .name = "su",
+       },
+       {
+               .name = "su_pnp",
+       },
+       {
+               .name = "serial",
+               .compatible = "su",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, su_match);
 
-       su_probe_any(&scan, prom_getchild(prom_root_node));
+static struct of_platform_driver su_driver = {
+       .name           = "su",
+       .match_table    = su_match,
+       .probe          = su_probe,
+       .remove         = __devexit_p(su_remove),
+};
 
-       /*
-        * Second, we process the special case of keyboard and mouse.
-        *
-        * Currently if we got keyboard and mouse hooked to "su" ports
-        * we do not use any possible remaining "su" as a serial port.
-        * Thus, we ignore values of .msx and .kbx, then compact ports.
-        */
-       if (scan.msx != -1 && scan.kbx != -1) {
-               sunsu_ports[0].su_type = SU_PORT_MS;
-               sunsu_ports[0].port_node = scan.msnode;
-               sunsu_kbd_ms_init(&sunsu_ports[0], 0);
+static int num_uart;
 
-               sunsu_ports[1].su_type = SU_PORT_KBD;
-               sunsu_ports[1].port_node = scan.kbnode;
-               sunsu_kbd_ms_init(&sunsu_ports[1], 1);
+static int __init sunsu_init(void)
+{
+       struct device_node *dp;
+       int err;
 
-               return 0;
+       num_uart = 0;
+       for_each_node_by_name(dp, "su") {
+               if (su_get_type(dp) == SU_PORT_PORT)
+                       num_uart++;
        }
-
-       if (scan.msx != -1 || scan.kbx != -1) {
-               printk("sunsu_probe: cannot match keyboard and mouse, confused\n");
-               return -ENODEV;
+       for_each_node_by_name(dp, "su_pnp") {
+               if (su_get_type(dp) == SU_PORT_PORT)
+                       num_uart++;
+       }
+       for_each_node_by_name(dp, "serial") {
+               if (of_device_is_compatible(dp, "su")) {
+                       if (su_get_type(dp) == SU_PORT_PORT)
+                               num_uart++;
+               }
        }
 
-       if (scan.devices == 0)
-               return -ENODEV;
+       if (num_uart) {
+               sunsu_reg.minor = sunserial_current_minor;
+               sunsu_reg.nr = num_uart;
+               err = uart_register_driver(&sunsu_reg);
+               if (err)
+                       return err;
+               sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
+               sunserial_current_minor += num_uart;
+               sunsu_reg.cons = SUNSU_CONSOLE(num_uart);
+       }
 
-       /*
-        * Console must be initiated after the generic initialization.
-        */
-               sunsu_serial_init();
+       err = of_register_driver(&su_driver, &of_bus_type);
+       if (err && num_uart)
+               uart_unregister_driver(&sunsu_reg);
 
-       return 0;
+       return err;
 }
 
 static void __exit sunsu_exit(void)
 {
-       int i, saw_uart;
-
-       saw_uart = 0;
-       for (i = 0; i < UART_NR; i++) {
-               struct uart_sunsu_port *up = &sunsu_ports[i];
-
-               if (up->su_type == SU_PORT_MS ||
-                   up->su_type == SU_PORT_KBD) {
-#ifdef CONFIG_SERIO
-                       if (up->serio) {
-                               serio_unregister_port(up->serio);
-                               up->serio = NULL;
-                       }
-#endif
-               } else if (up->port.type != PORT_UNKNOWN) {
-                       uart_remove_one_port(&sunsu_reg, &up->port);
-                       saw_uart++;
-               }
-       }
-
-       if (saw_uart)
+       if (num_uart)
                uart_unregister_driver(&sunsu_reg);
 }
 
-module_init(sunsu_probe);
+module_init(sunsu_init);
 module_exit(sunsu_exit);
+
+MODULE_AUTHOR("Eddie C. Dost, Peter Zaitcev, and David S. Miller");
+MODULE_DESCRIPTION("Sun SU serial port driver");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 76c9bac9271f9a9bc110157303ef589d8f66269f..1caa286a6be680c4f7097eeec101d1a0eb071bf5 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * sunzilog.c
+/* sunzilog.c: Zilog serial driver for Sparc systems.
  *
  * Driver for Zilog serial chips found on Sun workstations and
  * servers.  This driver could actually be made more generic.
@@ -10,7 +9,7 @@
  * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their
  * work there.
  *
- *  Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ *  Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/config.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#ifdef CONFIG_SPARC64
-#include <asm/fhc.h>
-#endif
-#include <asm/sbus.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 
 #if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -65,7 +62,7 @@
 #define ZSDELAY()
 #define ZSDELAY_LONG()
 #define ZS_WSYNC(__channel) \
-       sbus_readb(&((__channel)->control))
+       readb(&((__channel)->control))
 #endif
 
 static int num_sunzilog;
@@ -107,7 +104,7 @@ struct uart_sunzilog_port {
        unsigned char                   prev_status;
 
 #ifdef CONFIG_SERIO
-       struct serio                    *serio;
+       struct serio                    serio;
        int                             serio_open;
 #endif
 };
@@ -138,9 +135,9 @@ static unsigned char read_zsreg(struct zilog_channel __iomem *channel,
 {
        unsigned char retval;
 
-       sbus_writeb(reg, &channel->control);
+       writeb(reg, &channel->control);
        ZSDELAY();
-       retval = sbus_readb(&channel->control);
+       retval = readb(&channel->control);
        ZSDELAY();
 
        return retval;
@@ -149,9 +146,9 @@ static unsigned char read_zsreg(struct zilog_channel __iomem *channel,
 static void write_zsreg(struct zilog_channel __iomem *channel,
                        unsigned char reg, unsigned char value)
 {
-       sbus_writeb(reg, &channel->control);
+       writeb(reg, &channel->control);
        ZSDELAY();
-       sbus_writeb(value, &channel->control);
+       writeb(value, &channel->control);
        ZSDELAY();
 }
 
@@ -162,17 +159,17 @@ static void sunzilog_clear_fifo(struct zilog_channel __iomem *channel)
        for (i = 0; i < 32; i++) {
                unsigned char regval;
 
-               regval = sbus_readb(&channel->control);
+               regval = readb(&channel->control);
                ZSDELAY();
                if (regval & Rx_CH_AV)
                        break;
 
                regval = read_zsreg(channel, R1);
-               sbus_readb(&channel->data);
+               readb(&channel->data);
                ZSDELAY();
 
                if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
-                       sbus_writeb(ERR_RES, &channel->control);
+                       writeb(ERR_RES, &channel->control);
                        ZSDELAY();
                        ZS_WSYNC(channel);
                }
@@ -194,7 +191,7 @@ static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *
                udelay(100);
        }
 
-       sbus_writeb(ERR_RES, &channel->control);
+       writeb(ERR_RES, &channel->control);
        ZSDELAY();
        ZS_WSYNC(channel);
 
@@ -291,7 +288,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
                /* Stop-A is handled by drivers/char/keyboard.c now. */
 #ifdef CONFIG_SERIO
                if (up->serio_open)
-                       serio_interrupt(up->serio, ch, 0, regs);
+                       serio_interrupt(&up->serio, ch, 0, regs);
 #endif
        } else if (ZS_IS_MOUSE(up)) {
                int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -306,7 +303,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
                case 0:
 #ifdef CONFIG_SERIO
                        if (up->serio_open)
-                               serio_interrupt(up->serio, ch, 0, regs);
+                               serio_interrupt(&up->serio, ch, 0, regs);
 #endif
                        break;
                };
@@ -330,12 +327,12 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
 
                r1 = read_zsreg(channel, R1);
                if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
-                       sbus_writeb(ERR_RES, &channel->control);
+                       writeb(ERR_RES, &channel->control);
                        ZSDELAY();
                        ZS_WSYNC(channel);
                }
 
-               ch = sbus_readb(&channel->control);
+               ch = readb(&channel->control);
                ZSDELAY();
 
                /* This funny hack depends upon BRK_ABRT not interfering
@@ -347,7 +344,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
                if (!(ch & Rx_CH_AV))
                        break;
 
-               ch = sbus_readb(&channel->data);
+               ch = readb(&channel->data);
                ZSDELAY();
 
                ch &= up->parity_mask;
@@ -406,10 +403,10 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
 {
        unsigned char status;
 
-       status = sbus_readb(&channel->control);
+       status = readb(&channel->control);
        ZSDELAY();
 
-       sbus_writeb(RES_EXT_INT, &channel->control);
+       writeb(RES_EXT_INT, &channel->control);
        ZSDELAY();
        ZS_WSYNC(channel);
 
@@ -421,7 +418,7 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
                         * confusing the PROM.
                         */
                        while (1) {
-                               status = sbus_readb(&channel->control);
+                               status = readb(&channel->control);
                                ZSDELAY();
                                if (!(status & BRK_ABRT))
                                        break;
@@ -458,7 +455,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
        struct circ_buf *xmit;
 
        if (ZS_IS_CONS(up)) {
-               unsigned char status = sbus_readb(&channel->control);
+               unsigned char status = readb(&channel->control);
                ZSDELAY();
 
                /* TX still busy?  Just wait for the next TX done interrupt.
@@ -487,7 +484,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
 
        if (up->port.x_char) {
                up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
-               sbus_writeb(up->port.x_char, &channel->data);
+               writeb(up->port.x_char, &channel->data);
                ZSDELAY();
                ZS_WSYNC(channel);
 
@@ -506,7 +503,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
                goto ack_tx_int;
 
        up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
-       sbus_writeb(xmit->buf[xmit->tail], &channel->data);
+       writeb(xmit->buf[xmit->tail], &channel->data);
        ZSDELAY();
        ZS_WSYNC(channel);
 
@@ -519,7 +516,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
        return;
 
 ack_tx_int:
-       sbus_writeb(RES_Tx_P, &channel->control);
+       writeb(RES_Tx_P, &channel->control);
        ZSDELAY();
        ZS_WSYNC(channel);
 }
@@ -540,7 +537,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
                /* Channel A */
                tty = NULL;
                if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
-                       sbus_writeb(RES_H_IUS, &channel->control);
+                       writeb(RES_H_IUS, &channel->control);
                        ZSDELAY();
                        ZS_WSYNC(channel);
 
@@ -563,7 +560,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
                spin_lock(&up->port.lock);
                tty = NULL;
                if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
-                       sbus_writeb(RES_H_IUS, &channel->control);
+                       writeb(RES_H_IUS, &channel->control);
                        ZSDELAY();
                        ZS_WSYNC(channel);
 
@@ -594,7 +591,7 @@ static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *p
        unsigned char status;
 
        channel = ZILOG_CHANNEL_FROM_PORT(port);
-       status = sbus_readb(&channel->control);
+       status = readb(&channel->control);
        ZSDELAY();
 
        return status;
@@ -682,7 +679,7 @@ static void sunzilog_start_tx(struct uart_port *port)
        up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
        up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
 
-       status = sbus_readb(&channel->control);
+       status = readb(&channel->control);
        ZSDELAY();
 
        /* TX busy?  Just wait for the TX done interrupt.  */
@@ -693,7 +690,7 @@ static void sunzilog_start_tx(struct uart_port *port)
         * IRQ sending engine.
         */
        if (port->x_char) {
-               sbus_writeb(port->x_char, &channel->data);
+               writeb(port->x_char, &channel->data);
                ZSDELAY();
                ZS_WSYNC(channel);
 
@@ -702,7 +699,7 @@ static void sunzilog_start_tx(struct uart_port *port)
        } else {
                struct circ_buf *xmit = &port->info->xmit;
 
-               sbus_writeb(xmit->buf[xmit->tail], &channel->data);
+               writeb(xmit->buf[xmit->tail], &channel->data);
                ZSDELAY();
                ZS_WSYNC(channel);
 
@@ -779,7 +776,7 @@ static void __sunzilog_startup(struct uart_sunzilog_port *up)
        struct zilog_channel __iomem *channel;
 
        channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
-       up->prev_status = sbus_readb(&channel->control);
+       up->prev_status = readb(&channel->control);
 
        /* Enable receiver and transmitter.  */
        up->curregs[R3] |= RxENAB;
@@ -963,7 +960,7 @@ sunzilog_set_termios(struct uart_port *port, struct termios *termios,
 
 static const char *sunzilog_type(struct uart_port *port)
 {
-       return "SunZilog";
+       return "zs";
 }
 
 /* We do not request/release mappings of the registers here, this
@@ -1012,242 +1009,55 @@ static struct uart_sunzilog_port *sunzilog_port_table;
 static struct zilog_layout __iomem **sunzilog_chip_regs;
 
 static struct uart_sunzilog_port *sunzilog_irq_chain;
-static int zilog_irq = -1;
 
 static struct uart_driver sunzilog_reg = {
        .owner          =       THIS_MODULE,
        .driver_name    =       "ttyS",
-       .devfs_name     =       "tts/",
        .dev_name       =       "ttyS",
        .major          =       TTY_MAJOR,
 };
 
-static void * __init alloc_one_table(unsigned long size)
-{
-       void *ret;
-
-       ret = kmalloc(size, GFP_KERNEL);
-       if (ret != NULL)
-               memset(ret, 0, size);
-
-       return ret;
-}
-
-static void __init sunzilog_alloc_tables(void)
-{
-       sunzilog_port_table = 
-               alloc_one_table(NUM_CHANNELS * sizeof(struct uart_sunzilog_port));
-       sunzilog_chip_regs = 
-               alloc_one_table(NUM_SUNZILOG * sizeof(struct zilog_layout __iomem *));
-
-       if (sunzilog_port_table == NULL || sunzilog_chip_regs == NULL) {
-               prom_printf("SunZilog: Cannot allocate tables.\n");
-               prom_halt();
-       }
-}
-
-#ifdef CONFIG_SPARC64
-
-/* We used to attempt to use the address property of the Zilog device node
- * but that totally is not necessary on sparc64.
- */
-static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
+static int __init sunzilog_alloc_tables(void)
 {
-       void __iomem *mapped_addr;
-       unsigned int sun4u_ino;
-       struct sbus_bus *sbus = NULL;
-       struct sbus_dev *sdev = NULL;
-       int err;
-
-       if (central_bus == NULL) {
-               for_each_sbus(sbus) {
-                       for_each_sbusdev(sdev, sbus) {
-                               if (sdev->prom_node == zsnode)
-                                       goto found;
-                       }
-               }
-       }
- found:
-       if (sdev == NULL && central_bus == NULL) {
-               prom_printf("SunZilog: sdev&&central == NULL for "
-                           "Zilog %d in get_zs_sun4u.\n", chip);
-               prom_halt();
-       }
-       if (central_bus == NULL) {
-               mapped_addr =
-                       sbus_ioremap(&sdev->resource[0], 0,
-                                    PAGE_SIZE,
-                                    "Zilog Registers");
-       } else {
-               struct linux_prom_registers zsregs[1];
-
-               err = prom_getproperty(zsnode, "reg",
-                                      (char *) &zsregs[0],
-                                      sizeof(zsregs));
-               if (err == -1) {
-                       prom_printf("SunZilog: Cannot map "
-                                   "Zilog %d regs on "
-                                   "central bus.\n", chip);
-                       prom_halt();
-               }
-               apply_fhc_ranges(central_bus->child,
-                                &zsregs[0], 1);
-               apply_central_ranges(central_bus, &zsregs[0], 1);
-               mapped_addr = (void __iomem *)
-                       ((((u64)zsregs[0].which_io)<<32UL) |
-                       ((u64)zsregs[0].phys_addr));
-       }
-
-       if (zilog_irq == -1) {
-               if (central_bus) {
-                       unsigned long iclr, imap;
-
-                       iclr = central_bus->child->fhc_regs.uregs
-                               + FHC_UREGS_ICLR;
-                       imap = central_bus->child->fhc_regs.uregs
-                               + FHC_UREGS_IMAP;
-                       zilog_irq = build_irq(0, iclr, imap);
-               } else {
-                       err = prom_getproperty(zsnode, "interrupts",
-                                              (char *) &sun4u_ino,
-                                              sizeof(sun4u_ino));
-                       zilog_irq = sbus_build_irq(sbus_root, sun4u_ino);
-               }
-       }
-
-       return (struct zilog_layout __iomem *) mapped_addr;
-}
-#else /* CONFIG_SPARC64 */
-
-/*
- * XXX The sun4d case is utterly screwed: it tries to re-walk the tree
- * (for the 3rd time) in order to find bootbus and cpu. Streamline it.
- */
-static struct zilog_layout __iomem * __init get_zs_sun4cmd(int chip, int node)
-{
-       struct linux_prom_irqs irq_info[2];
-       void __iomem *mapped_addr = NULL;
-       int zsnode, cpunode, bbnode;
-       struct linux_prom_registers zsreg[4];
-       struct resource res;
-
-       if (sparc_cpu_model == sun4d) {
-               int walk;
-
-               zsnode = 0;
-               bbnode = 0;
-               cpunode = 0;
-               for (walk = prom_getchild(prom_root_node);
-                    (walk = prom_searchsiblings(walk, "cpu-unit")) != 0;
-                    walk = prom_getsibling(walk)) {
-                       bbnode = prom_getchild(walk);
-                       if (bbnode &&
-                           (bbnode = prom_searchsiblings(bbnode, "bootbus"))) {
-                               if ((zsnode = prom_getchild(bbnode)) == node) {
-                                       cpunode = walk;
-                                       break;
-                               }
-                       }
-               }
-               if (!walk) {
-                       prom_printf("SunZilog: Cannot find the %d'th bootbus on sun4d.\n",
-                                   (chip / 2));
-                       prom_halt();
-               }
+       struct uart_sunzilog_port *up;
+       unsigned long size;
+       int i;
 
-               if (prom_getproperty(zsnode, "reg",
-                                    (char *) zsreg, sizeof(zsreg)) == -1) {
-                       prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
-                       prom_halt();
-               }
-               /* XXX Looks like an off by one? */
-               prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
-               res.start = zsreg[0].phys_addr;
-               res.end = res.start + (8 - 1);
-               res.flags = zsreg[0].which_io | IORESOURCE_IO;
-               mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
+       size = NUM_CHANNELS * sizeof(struct uart_sunzilog_port);
+       sunzilog_port_table = kzalloc(size, GFP_KERNEL);
+       if (!sunzilog_port_table)
+               return -ENOMEM;
 
-       } else {
-               zsnode = node;
+       for (i = 0; i < NUM_CHANNELS; i++) {
+               up = &sunzilog_port_table[i];
 
-#if 0 /* XXX When was this used? */
-               if (prom_getintdefault(zsnode, "slave", -1) != chipid) {
-                       zsnode = prom_getsibling(zsnode);
-                       continue;
-               }
-#endif
+               spin_lock_init(&up->port.lock);
 
-               /*
-                * "address" is only present on ports that OBP opened
-                * (from Mitch Bradley's "Hitchhiker's Guide to OBP").
-                * We do not use it.
-                */
+               if (i == 0)
+                       sunzilog_irq_chain = up;
 
-               if (prom_getproperty(zsnode, "reg",
-                                    (char *) zsreg, sizeof(zsreg)) == -1) {
-                       prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
-                       prom_halt();
-               }
-               if (sparc_cpu_model == sun4m)   /* Crude. Pass parent. XXX */
-                       prom_apply_obio_ranges(zsreg, 1);
-               res.start = zsreg[0].phys_addr;
-               res.end = res.start + (8 - 1);
-               res.flags = zsreg[0].which_io | IORESOURCE_IO;
-               mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
+               if (i < NUM_CHANNELS - 1)
+                       up->next = up + 1;
+               else
+                       up->next = NULL;
        }
 
-       if (prom_getproperty(zsnode, "intr",
-                            (char *) irq_info, sizeof(irq_info))
-                   % sizeof(struct linux_prom_irqs)) {
-               prom_printf("SunZilog: Cannot get IRQ property for Zilog %d.\n",
-                           chip);
-               prom_halt();
-       }
-       if (zilog_irq == -1) {
-               zilog_irq = irq_info[0].pri;
-       } else if (zilog_irq != irq_info[0].pri) {
-               /* XXX. Dumb. Should handle per-chip IRQ, for add-ons. */
-               prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
-                           chip);
-               prom_halt();
+       size = NUM_SUNZILOG * sizeof(struct zilog_layout __iomem *);
+       sunzilog_chip_regs = kzalloc(size, GFP_KERNEL);
+       if (!sunzilog_chip_regs) {
+               kfree(sunzilog_port_table);
+               sunzilog_irq_chain = NULL;
+               return -ENOMEM;
        }
 
-       return (struct zilog_layout __iomem *) mapped_addr;
+       return 0;
 }
-#endif /* !(CONFIG_SPARC64) */
 
-/* Get the address of the registers for SunZilog instance CHIP.  */
-static struct zilog_layout __iomem * __init get_zs(int chip, int node)
+static void sunzilog_free_tables(void)
 {
-       if (chip < 0 || chip >= NUM_SUNZILOG) {
-               prom_printf("SunZilog: Illegal chip number %d in get_zs.\n", chip);
-               prom_halt();
-       }
-
-#ifdef CONFIG_SPARC64
-       return get_zs_sun4u(chip, node);
-#else
-
-       if (sparc_cpu_model == sun4) {
-               struct resource res;
-
-               /* Not probe-able, hard code it. */
-               switch (chip) {
-               case 0:
-                       res.start = 0xf1000000;
-                       break;
-               case 1:
-                       res.start = 0xf0000000;
-                       break;
-               };
-               zilog_irq = 12;
-               res.end = (res.start + (8 - 1));
-               res.flags = IORESOURCE_IO;
-               return sbus_ioremap(&res, 0, 8, "SunZilog");
-       }
-
-       return get_zs_sun4cmd(chip, node);
-#endif
+       kfree(sunzilog_port_table);
+       sunzilog_irq_chain = NULL;
+       kfree(sunzilog_chip_regs);
 }
 
 #define ZS_PUT_CHAR_MAX_DELAY  2000    /* 10 ms */
@@ -1261,7 +1071,7 @@ static void sunzilog_putchar(struct uart_port *port, int ch)
         * udelay with ZSDELAY as that is a NOP on some platforms.  -DaveM
         */
        do {
-               unsigned char val = sbus_readb(&channel->control);
+               unsigned char val = readb(&channel->control);
                if (val & Tx_BUF_EMP) {
                        ZSDELAY();
                        break;
@@ -1269,7 +1079,7 @@ static void sunzilog_putchar(struct uart_port *port, int ch)
                udelay(5);
        } while (--loops);
 
-       sbus_writeb(ch, &channel->data);
+       writeb(ch, &channel->data);
        ZSDELAY();
        ZS_WSYNC(channel);
 }
@@ -1386,28 +1196,6 @@ static struct console sunzilog_console = {
        .data   =       &sunzilog_reg,
 };
 
-static int __init sunzilog_console_init(void)
-{
-       int i;
-
-       if (con_is_present())
-               return 0;
-
-       for (i = 0; i < NUM_CHANNELS; i++) {
-               int this_minor = sunzilog_reg.minor + i;
-
-               if ((this_minor - 64) == (serial_console - 1))
-                       break;
-       }
-       if (i == NUM_CHANNELS)
-               return 0;
-
-       sunzilog_console.index = i;
-       sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS;
-       register_console(&sunzilog_console);
-       return 0;
-}
-
 static inline struct console *SUNZILOG_CONSOLE(void)
 {
        int i;
@@ -1432,101 +1220,8 @@ static inline struct console *SUNZILOG_CONSOLE(void)
 
 #else
 #define SUNZILOG_CONSOLE()     (NULL)
-#define sunzilog_console_init() do { } while (0)
 #endif
 
-/*
- * We scan the PROM tree recursively. This is the most reliable way
- * to find Zilog nodes on various platforms. However, we face an extreme
- * shortage of kernel stack, so we must be very careful. To that end,
- * we scan only to a certain depth, and we use a common property buffer
- * in the scan structure.
- */
-#define ZS_PROPSIZE  128
-#define ZS_SCAN_DEPTH  5
-
-struct zs_probe_scan {
-       int depth;
-       void (*scanner)(struct zs_probe_scan *t, int node);
-
-       int devices;
-       char prop[ZS_PROPSIZE];
-};
-
-static int __inline__ sunzilog_node_ok(int node, const char *name, int len)
-{
-       if (strncmp(name, "zs", len) == 0)
-               return 1;
-       /* Don't fold this procedure just yet. Compare to su_node_ok(). */
-       return 0;
-}
-
-static void __init sunzilog_scan(struct zs_probe_scan *t, int node)
-{
-       int len;
-
-       for (; node != 0; node = prom_getsibling(node)) {
-               len = prom_getproperty(node, "name", t->prop, ZS_PROPSIZE);
-               if (len <= 1)
-                       continue;               /* Broken PROM node */
-               if (sunzilog_node_ok(node, t->prop, len)) {
-                       (*t->scanner)(t, node);
-               } else {
-                       if (t->depth < ZS_SCAN_DEPTH) {
-                               t->depth++;
-                               sunzilog_scan(t, prom_getchild(node));
-                               --t->depth;
-                       }
-               }
-       }
-}
-
-static void __init sunzilog_prepare(void)
-{
-       struct uart_sunzilog_port *up;
-       struct zilog_layout __iomem *rp;
-       int channel, chip;
-
-       /*
-        * Temporary fix.
-        */
-       for (channel = 0; channel < NUM_CHANNELS; channel++)
-               spin_lock_init(&sunzilog_port_table[channel].port.lock);
-
-       sunzilog_irq_chain = up = &sunzilog_port_table[0];
-       for (channel = 0; channel < NUM_CHANNELS - 1; channel++)
-               up[channel].next = &up[channel + 1];
-       up[channel].next = NULL;
-
-       for (chip = 0; chip < NUM_SUNZILOG; chip++) {
-               rp = sunzilog_chip_regs[chip];
-               up[(chip * 2) + 0].port.membase = (void __iomem *)&rp->channelA;
-               up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB;
-
-               /* Channel A */
-               up[(chip * 2) + 0].port.iotype = UPIO_MEM;
-               up[(chip * 2) + 0].port.irq = zilog_irq;
-               up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
-               up[(chip * 2) + 0].port.fifosize = 1;
-               up[(chip * 2) + 0].port.ops = &sunzilog_pops;
-               up[(chip * 2) + 0].port.type = PORT_SUNZILOG;
-               up[(chip * 2) + 0].port.flags = 0;
-               up[(chip * 2) + 0].port.line = (chip * 2) + 0;
-               up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
-
-               /* Channel B */
-               up[(chip * 2) + 1].port.iotype = UPIO_MEM;
-               up[(chip * 2) + 1].port.irq = zilog_irq;
-               up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
-               up[(chip * 2) + 1].port.fifosize = 1;
-               up[(chip * 2) + 1].port.ops = &sunzilog_pops;
-               up[(chip * 2) + 1].port.type = PORT_SUNZILOG;
-               up[(chip * 2) + 1].port.flags = 0;
-               up[(chip * 2) + 1].port.line = (chip * 2) + 1;
-               up[(chip * 2) + 1].flags |= 0;
-       }
-}
-
 static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
 {
        int baud, brg;
@@ -1540,8 +1235,6 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
                up->cflag = B4800 | CS8 | CLOCAL | CREAD;
                baud = 4800;
        }
-       printk(KERN_INFO "zs%d at 0x%p (irq = %d) is a SunZilog\n",
-              channel, up->port.membase, zilog_irq);
 
        up->curregs[R15] = BRKIE;
        brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
@@ -1553,216 +1246,268 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
 #ifdef CONFIG_SERIO
 static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel)
 {
-       struct serio *serio;
-
-       up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-       if (serio) {
-               memset(serio, 0, sizeof(*serio));
-
-               serio->port_data = up;
-
-               serio->id.type = SERIO_RS232;
-               if (channel == KEYBOARD_LINE) {
-                       serio->id.proto = SERIO_SUNKBD;
-                       strlcpy(serio->name, "zskbd", sizeof(serio->name));
-               } else {
-                       serio->id.proto = SERIO_SUN;
-                       serio->id.extra = 1;
-                       strlcpy(serio->name, "zsms", sizeof(serio->name));
-               }
-               strlcpy(serio->phys,
-                       (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
-                       sizeof(serio->phys));
+       struct serio *serio = &up->serio;
 
-               serio->write = sunzilog_serio_write;
-               serio->open = sunzilog_serio_open;
-               serio->close = sunzilog_serio_close;
+       serio->port_data = up;
 
-               serio_register_port(serio);
+       serio->id.type = SERIO_RS232;
+       if (channel == KEYBOARD_LINE) {
+               serio->id.proto = SERIO_SUNKBD;
+               strlcpy(serio->name, "zskbd", sizeof(serio->name));
        } else {
-               printk(KERN_WARNING "zs%d: not enough memory for serio port\n",
-                       channel);
+               serio->id.proto = SERIO_SUN;
+               serio->id.extra = 1;
+               strlcpy(serio->name, "zsms", sizeof(serio->name));
        }
+       strlcpy(serio->phys,
+               (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
+               sizeof(serio->phys));
+
+       serio->write = sunzilog_serio_write;
+       serio->open = sunzilog_serio_open;
+       serio->close = sunzilog_serio_close;
+       serio->dev.parent = up->port.dev;
+
+       serio_register_port(serio);
 }
 #endif
 
-static void __init sunzilog_init_hw(void)
+static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
 {
-       int i;
-
-       for (i = 0; i < NUM_CHANNELS; i++) {
-               struct uart_sunzilog_port *up = &sunzilog_port_table[i];
-               struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
-               unsigned long flags;
-               int baud, brg;
+       struct zilog_channel __iomem *channel;
+       unsigned long flags;
+       int baud, brg;
 
-               spin_lock_irqsave(&up->port.lock, flags);
+       channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
 
-               if (ZS_IS_CHANNEL_A(up)) {
-                       write_zsreg(channel, R9, FHWRES);
-                       ZSDELAY_LONG();
-                       (void) read_zsreg(channel, R0);
-               }
+       spin_lock_irqsave(&up->port.lock, flags);
+       if (ZS_IS_CHANNEL_A(up)) {
+               write_zsreg(channel, R9, FHWRES);
+               ZSDELAY_LONG();
+               (void) read_zsreg(channel, R0);
+       }
 
-               if (i == KEYBOARD_LINE || i == MOUSE_LINE) {
-                       sunzilog_init_kbdms(up, i);
-                       up->curregs[R9] |= (NV | MIE);
-                       write_zsreg(channel, R9, up->curregs[R9]);
-               } else {
-                       /* Normal serial TTY. */
-                       up->parity_mask = 0xff;
-                       up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
-                       up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
-                       up->curregs[R3] = RxENAB | Rx8;
-                       up->curregs[R5] = TxENAB | Tx8;
-                       up->curregs[R9] = NV | MIE;
-                       up->curregs[R10] = NRZ;
-                       up->curregs[R11] = TCBR | RCBR;
-                       baud = 9600;
-                       brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
-                       up->curregs[R12] = (brg & 0xff);
-                       up->curregs[R13] = (brg >> 8) & 0xff;
-                       up->curregs[R14] = BRSRC | BRENAB;
-                       __load_zsregs(channel, up->curregs);
-                       write_zsreg(channel, R9, up->curregs[R9]);
-               }
+       if (up->port.line == KEYBOARD_LINE ||
+           up->port.line == MOUSE_LINE) {
+               sunzilog_init_kbdms(up, up->port.line);
+               up->curregs[R9] |= (NV | MIE);
+               write_zsreg(channel, R9, up->curregs[R9]);
+       } else {
+               /* Normal serial TTY. */
+               up->parity_mask = 0xff;
+               up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
+               up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
+               up->curregs[R3] = RxENAB | Rx8;
+               up->curregs[R5] = TxENAB | Tx8;
+               up->curregs[R9] = NV | MIE;
+               up->curregs[R10] = NRZ;
+               up->curregs[R11] = TCBR | RCBR;
+               baud = 9600;
+               brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
+               up->curregs[R12] = (brg & 0xff);
+               up->curregs[R13] = (brg >> 8) & 0xff;
+               up->curregs[R14] = BRSRC | BRENAB;
+               __load_zsregs(channel, up->curregs);
+               write_zsreg(channel, R9, up->curregs[R9]);
+       }
 
-               spin_unlock_irqrestore(&up->port.lock, flags);
+       spin_unlock_irqrestore(&up->port.lock, flags);
 
 #ifdef CONFIG_SERIO
-               if (i == KEYBOARD_LINE || i == MOUSE_LINE)
-                       sunzilog_register_serio(up, i);
+       if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE)
+               sunzilog_register_serio(up, up->port.line);
 #endif
-       }
-}
-
-static struct zilog_layout __iomem * __init get_zs(int chip, int node);
-
-static void __init sunzilog_scan_probe(struct zs_probe_scan *t, int node)
-{
-       sunzilog_chip_regs[t->devices] = get_zs(t->devices, node);
-       t->devices++;
 }
 
-static int __init sunzilog_ports_init(void)
+static int __devinit zs_get_instance(struct device_node *dp)
 {
-       struct zs_probe_scan scan;
        int ret;
-       int uart_count;
-       int i;
-
-       printk(KERN_DEBUG "SunZilog: %d chips.\n", NUM_SUNZILOG);
-
-       scan.scanner = sunzilog_scan_probe;
-       scan.depth = 0;
-       scan.devices = 0;
-       sunzilog_scan(&scan, prom_getchild(prom_root_node));
-
-       sunzilog_prepare();
 
-       if (request_irq(zilog_irq, sunzilog_interrupt, SA_SHIRQ,
-                       "SunZilog", sunzilog_irq_chain)) {
-               prom_printf("SunZilog: Unable to register zs interrupt handler.\n");
-               prom_halt();
-       }
+       ret = of_getintprop_default(dp, "slave", -1);
+       if (ret != -1)
+               return ret;
 
-       sunzilog_init_hw();
+       if (of_find_property(dp, "keyboard", NULL))
+               ret = 1;
+       else
+               ret = 0;
 
-       /* We can only init this once we have probed the Zilogs
-        * in the system. Do not count channels assigned to keyboards
-        * or mice when we are deciding how many ports to register.
-        */
-       uart_count = 0;
-       for (i = 0; i < NUM_CHANNELS; i++) {
-               struct uart_sunzilog_port *up = &sunzilog_port_table[i];
+       return ret;
+}
 
-               if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up))
-                       continue;
+static int zilog_irq = -1;
 
-               uart_count++;
-       }
-               
-       sunzilog_reg.nr = uart_count;
-       sunzilog_reg.minor = sunserial_current_minor;
+static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match)
+{
+       struct of_device *op = to_of_device(&dev->dev);
+       struct uart_sunzilog_port *up;
+       struct zilog_layout __iomem *rp;
+       int inst = zs_get_instance(dev->node);
+       int err;
 
-       ret = uart_register_driver(&sunzilog_reg);
-       if (ret == 0) {
-               sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
-               sunzilog_reg.cons = SUNZILOG_CONSOLE();
+       sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
+                                             sizeof(struct zilog_layout),
+                                             "zs");
+       if (!sunzilog_chip_regs[inst])
+               return -ENOMEM;
 
-               sunserial_current_minor += uart_count;
+       rp = sunzilog_chip_regs[inst];
 
-               for (i = 0; i < NUM_CHANNELS; i++) {
-                       struct uart_sunzilog_port *up = &sunzilog_port_table[i];
+       if (zilog_irq == -1) {
+               zilog_irq = op->irqs[0];
+               err = request_irq(zilog_irq, sunzilog_interrupt, SA_SHIRQ,
+                                 "zs", sunzilog_irq_chain);
+               if (err) {
+                       of_iounmap(rp, sizeof(struct zilog_layout));
 
-                       if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up))
-                               continue;
+                       return err;
+               }
+       }
 
-                       if (uart_add_one_port(&sunzilog_reg, &up->port)) {
-                               printk(KERN_ERR
-                                   "SunZilog: failed to add port zs%d\n", i);
-                       }
+       up = &sunzilog_port_table[inst * 2];
+
+       /* Channel A */
+       up[0].port.mapbase = op->resource[0].start + 0x00;
+       up[0].port.membase = (void __iomem *) &rp->channelA;
+       up[0].port.iotype = UPIO_MEM;
+       up[0].port.irq = op->irqs[0];
+       up[0].port.uartclk = ZS_CLOCK;
+       up[0].port.fifosize = 1;
+       up[0].port.ops = &sunzilog_pops;
+       up[0].port.type = PORT_SUNZILOG;
+       up[0].port.flags = 0;
+       up[0].port.line = (inst * 2) + 0;
+       up[0].port.dev = &op->dev;
+       up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
+       if (inst == 1)
+               up[0].flags |= SUNZILOG_FLAG_CONS_KEYB;
+       sunzilog_init_hw(&up[0]);
+
+       /* Channel B */
+       up[1].port.mapbase = op->resource[0].start + 0x04;
+       up[1].port.membase = (void __iomem *) &rp->channelB;
+       up[1].port.iotype = UPIO_MEM;
+       up[1].port.irq = op->irqs[0];
+       up[1].port.uartclk = ZS_CLOCK;
+       up[1].port.fifosize = 1;
+       up[1].port.ops = &sunzilog_pops;
+       up[1].port.type = PORT_SUNZILOG;
+       up[1].port.flags = 0;
+       up[1].port.line = (inst * 2) + 1;
+       up[1].port.dev = &op->dev;
+       up[1].flags |= 0;
+       if (inst == 1)
+               up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE;
+       sunzilog_init_hw(&up[1]);
+
+       if (inst != 1) {
+               err = uart_add_one_port(&sunzilog_reg, &up[0].port);
+               if (err) {
+                       of_iounmap(rp, sizeof(struct zilog_layout));
+                       return err;
+               }
+               err = uart_add_one_port(&sunzilog_reg, &up[1].port);
+               if (err) {
+                       uart_remove_one_port(&sunzilog_reg, &up[0].port);
+                       of_iounmap(rp, sizeof(struct zilog_layout));
+                       return err;
                }
        }
 
-       return ret;
+       dev_set_drvdata(&dev->dev, &up[0]);
+
+       return 0;
 }
 
-static void __init sunzilog_scan_count(struct zs_probe_scan *t, int node)
+static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
 {
-       t->devices++;
+       if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
+#ifdef CONFIG_SERIO
+               serio_unregister_port(&up->serio);
+#endif
+       } else
+               uart_remove_one_port(&sunzilog_reg, &up->port);
 }
 
-static int __init sunzilog_ports_count(void)
+static int __devexit zs_remove(struct of_device *dev)
 {
-       struct zs_probe_scan scan;
+       struct uart_sunzilog_port *up = dev_get_drvdata(&dev->dev);
+       struct zilog_layout __iomem *regs;
 
-       /* Sun4 Zilog setup is hard coded, no probing to do.  */
-       if (sparc_cpu_model == sun4)
-               return 2;
+       zs_remove_one(&up[0]);
+       zs_remove_one(&up[1]);
 
-       scan.scanner = sunzilog_scan_count;
-       scan.depth = 0;
-       scan.devices = 0;
+       regs = sunzilog_chip_regs[up[0].port.line / 2];
+       of_iounmap(regs, sizeof(struct zilog_layout));
 
-       sunzilog_scan(&scan, prom_getchild(prom_root_node));
+       dev_set_drvdata(&dev->dev, NULL);
 
-       return scan.devices;
+       return 0;
 }
 
+static struct of_device_id zs_match[] = {
+       {
+               .name = "zs",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, zs_match);
+
+static struct of_platform_driver zs_driver = {
+       .name           = "zs",
+       .match_table    = zs_match,
+       .probe          = zs_probe,
+       .remove         = __devexit_p(zs_remove),
+};
+
 static int __init sunzilog_init(void)
 {
+       struct device_node *dp;
+       int err;
 
-       NUM_SUNZILOG = sunzilog_ports_count();
-       if (NUM_SUNZILOG == 0)
-               return -ENODEV;
+       NUM_SUNZILOG = 0;
+       for_each_node_by_name(dp, "zs")
+               NUM_SUNZILOG++;
 
-       sunzilog_alloc_tables();
+       if (NUM_SUNZILOG) {
+               int uart_count;
 
-       sunzilog_ports_init();
+               err = sunzilog_alloc_tables();
+               if (err)
+                       return err;
 
-       return 0;
+               /* Subtract 1 for keyboard, 1 for mouse.  */
+               uart_count = (NUM_SUNZILOG * 2) - 2;
+
+               sunzilog_reg.nr = uart_count;
+               sunzilog_reg.minor = sunserial_current_minor;
+               err = uart_register_driver(&sunzilog_reg);
+               if (err) {
+                       sunzilog_free_tables();
+                       return err;
+               }
+               sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
+               sunzilog_reg.cons = SUNZILOG_CONSOLE();
+
+               sunserial_current_minor += uart_count;
+       }
+
+       return of_register_driver(&zs_driver, &of_bus_type);
 }
 
 static void __exit sunzilog_exit(void)
 {
-       int i;
+       of_unregister_driver(&zs_driver);
 
-       for (i = 0; i < NUM_CHANNELS; i++) {
-               struct uart_sunzilog_port *up = &sunzilog_port_table[i];
-
-               if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
-#ifdef CONFIG_SERIO
-                       if (up->serio) {
-                               serio_unregister_port(up->serio);
-                               up->serio = NULL;
-                       }
-#endif
-               } else
-                       uart_remove_one_port(&sunzilog_reg, &up->port);
+       if (zilog_irq != -1) {
+               free_irq(zilog_irq, sunzilog_irq_chain);
+               zilog_irq = -1;
        }
 
-       uart_unregister_driver(&sunzilog_reg);
+       if (NUM_SUNZILOG) {
+               uart_unregister_driver(&sunzilog_reg);
+               sunzilog_free_tables();
+       }
 }
 
 module_init(sunzilog_init);
@@ -1770,4 +1515,5 @@ module_exit(sunzilog_exit);
 
 MODULE_AUTHOR("David S. Miller");
 MODULE_DESCRIPTION("Sun Zilog serial port driver");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index df705fda42436f392308138a2634ddb4628998f6..a0da2aaf71c4436d60de6d7086b5b21b682527bd 100644 (file)
@@ -468,7 +468,6 @@ static struct uart_ops v850e_uart_ops = {
 static struct uart_driver v850e_uart_driver = {
        .owner                  = THIS_MODULE,
        .driver_name            = "v850e_uart",
-       .devfs_name             = "tts/",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
        .minor                  = V850E_UART_MINOR_BASE,
index df5e8713fa312290efab20f4794d00d1391b258a..017571ffa19cec0bd744cea32743fd561a99c4c8 100644 (file)
@@ -911,7 +911,6 @@ static struct uart_driver siu_uart_driver = {
        .owner          = THIS_MODULE,
        .driver_name    = "SIU",
        .dev_name       = "ttyVR",
-       .devfs_name     = "ttvr/",
        .major          = SIU_MAJOR,
        .minor          = SIU_MINOR_BASE,
        .cons           = SERIAL_VR41XX_CONSOLE,
index 2dffa8e303b27ade495f47fa3ef8ca01690adb7e..7f27b356eaf723450d3598db9d62a60a5ab3a441 100644 (file)
@@ -1745,7 +1745,6 @@ int __init zs_init(void)
        /* Not all of this is exactly right for us. */
 
        serial_driver->owner = THIS_MODULE;
-       serial_driver->devfs_name = "tts/";
        serial_driver->name = "ttyS";
        serial_driver->major = TTY_MAJOR;
        serial_driver->minor_start = 64;
@@ -1754,7 +1753,7 @@ int __init zs_init(void)
        serial_driver->init_termios = tty_std_termios;
        serial_driver->init_termios.c_cflag =
                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        tty_set_operations(serial_driver, &serial_ops);
 
        if (tty_register_driver(serial_driver))
index e166fffea86ba5b971df5d6fd7e4f2c95240e689..e41f49afd0f4792dfe8e3b0290b398590a90d886 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/kmod.h>
 #include <linux/sem.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/mutex.h>
 
 #define PHONE_NUM_DEVICES      256
@@ -106,8 +105,6 @@ int phone_register_device(struct phone_device *p, int unit)
                if (phone_device[i] == NULL) {
                        phone_device[i] = p;
                        p->minor = i;
-                       devfs_mk_cdev(MKDEV(PHONE_MAJOR,i),
-                               S_IFCHR|S_IRUSR|S_IWUSR, "phone/%d", i);
                        mutex_unlock(&phone_lock);
                        return 0;
                }
@@ -125,7 +122,6 @@ void phone_unregister_device(struct phone_device *pfd)
        mutex_lock(&phone_lock);
        if (phone_device[pfd->minor] != pfd)
                panic("phone: bad unregister");
-       devfs_remove("phone/%d", pfd->minor);
        phone_device[pfd->minor] = NULL;
        mutex_unlock(&phone_lock);
 }
index d41dc67ba4ccb74220dde9405a4df44ad86c93ce..3670d77e912ca4a068a3dc46e93ae8696aeca242 100644 (file)
@@ -1145,12 +1145,11 @@ static int __init acm_init(void)
        acm_tty_driver->owner = THIS_MODULE,
        acm_tty_driver->driver_name = "acm",
        acm_tty_driver->name = "ttyACM",
-       acm_tty_driver->devfs_name = "usb/acm/",
        acm_tty_driver->major = ACM_TTY_MAJOR,
        acm_tty_driver->minor_start = 0,
        acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
        acm_tty_driver->subtype = SERIAL_TYPE_NORMAL,
-       acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+       acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        acm_tty_driver->init_termios = tty_std_termios;
        acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        tty_set_operations(acm_tty_driver, &acm_ops);
index 269ce7f4ad6608f56ab79aeb1e7e3a0d97593bc3..735e9dbd39fdfaedec41a6ac59f91a07bb0f1381 100644 (file)
@@ -60,7 +60,7 @@
 #include <linux/usb_ch9.h>
 #include <linux/usb_gadget.h>
 
-#include <asm/arch/hardware/intel_udc.h>
+#include <asm/arch/udc.h>
 
 
 /*
index 9d6e1d295528f5e30a17d5d3360ef6092cd56f55..416acac879df5d3b96d43d99bfe984a3bb9081bd 100644 (file)
@@ -588,12 +588,11 @@ static int __init gs_module_init(void)
        gs_tty_driver->owner = THIS_MODULE;
        gs_tty_driver->driver_name = GS_SHORT_NAME;
        gs_tty_driver->name = "ttygs";
-       gs_tty_driver->devfs_name = "usb/ttygs/";
        gs_tty_driver->major = GS_MAJOR;
        gs_tty_driver->minor_start = GS_MINOR_START;
        gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
        gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
-       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        gs_tty_driver->init_termios = tty_std_termios;
        gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        tty_set_operations(gs_tty_driver, &gs_tty_ops);
index a30135c7cfe6a4f59550e2fce18fd18e43d4fc15..f466f89eeb6d542353652fe0f9d1a77f631f9fe6 100644 (file)
@@ -1059,13 +1059,12 @@ static int __init usb_serial_init(void)
 
        usb_serial_tty_driver->owner = THIS_MODULE;
        usb_serial_tty_driver->driver_name = "usbserial";
-       usb_serial_tty_driver->devfs_name = "usb/tts/";
        usb_serial_tty_driver->name =   "ttyUSB";
        usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;
        usb_serial_tty_driver->minor_start = 0;
        usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
        usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
-       usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        usb_serial_tty_driver->init_termios = tty_std_termios;
        usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        tty_set_operations(usb_serial_tty_driver, &serial_ops);
index 6577fdfdfc16ac2050874318dcabc03922ef8a20..c66e3d52cbf3bac8a9c0cf74c7af5651da47cb6a 100644 (file)
@@ -1,6 +1,6 @@
 /* bw2.c: BWTWO frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
-#ifdef CONFIG_SPARC32
-#include <asm/sun4paddr.h>
-#endif
-
 #include "sbuslib.h"
 
 /*
@@ -59,30 +56,30 @@ static struct fb_ops bw2_ops = {
 #define BWTWO_REGISTER_OFFSET 0x400000
 
 struct bt_regs {
-       volatile u32 addr;
-       volatile u32 color_map;
-       volatile u32 control;
-       volatile u32 cursor;
+       u32 addr;
+       u32 color_map;
+       u32 control;
+       u32 cursor;
 };
 
 struct bw2_regs {
        struct bt_regs  cmap;
-       volatile u8     control;
-       volatile u8     status;
-       volatile u8     cursor_start;
-       volatile u8     cursor_end;
-       volatile u8     h_blank_start;
-       volatile u8     h_blank_end;
-       volatile u8     h_sync_start;
-       volatile u8     h_sync_end;
-       volatile u8     comp_sync_end;
-       volatile u8     v_blank_start_high;
-       volatile u8     v_blank_start_low;
-       volatile u8     v_blank_end;
-       volatile u8     v_sync_start;
-       volatile u8     v_sync_end;
-       volatile u8     xfer_holdoff_start;
-       volatile u8     xfer_holdoff_end;
+       u8      control;
+       u8      status;
+       u8      cursor_start;
+       u8      cursor_end;
+       u8      h_blank_start;
+       u8      h_blank_end;
+       u8      h_sync_start;
+       u8      h_sync_end;
+       u8      comp_sync_end;
+       u8      v_blank_start_high;
+       u8      v_blank_start_low;
+       u8      v_blank_end;
+       u8      v_sync_start;
+       u8      v_sync_end;
+       u8      xfer_holdoff_start;
+       u8      xfer_holdoff_end;
 };
 
 /* Status Register Constants */
@@ -117,9 +114,8 @@ struct bw2_par {
 #define BW2_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 /**
@@ -174,9 +170,7 @@ static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(bw2_mmap_map,
                                  par->physbase, par->fbsize,
-                                 (par->sdev ?
-                                  par->sdev->reg_addrs[0].which_io :
-                                  0),
+                                 par->which_io,
                                  vma);
 }
 
@@ -288,139 +282,124 @@ static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
 struct all_info {
        struct fb_info info;
        struct bw2_par par;
-       struct list_head list;
 };
-static LIST_HEAD(bw2_list);
 
-static void bw2_init_one(struct sbus_dev *sdev)
+static int __devinit bw2_init_one(struct of_device *op)
 {
+       struct device_node *dp = op->node;
        struct all_info *all;
-       struct resource *resp;
-#ifdef CONFIG_SUN4
-       struct resource res;
-#endif
-       int linebytes;
+       int linebytes, err;
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "bw2: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
-
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
-
-#ifdef CONFIG_SUN4
-       if (!sdev) {
-               all->par.physbase = sun4_bwtwo_physaddr;
-               res.start = sun4_bwtwo_physaddr;
-               res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
-               res.flags = IORESOURCE_IO;
-               resp = &res;
-               all->info.var.xres = all->info.var.xres_virtual = 1152;
-               all->info.var.yres = all->info.var.yres_virtual = 900;
-               all->info.var.bits_per_pixel = 1;
-               linebytes = 1152 / 8;
-       } else
-#else
-       {
-               BUG_ON(!sdev);
-               all->par.physbase = sdev->reg_addrs[0].phys_addr;
-               resp = &sdev->resource[0];
-               sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1);
-               linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                              all->info.var.xres);
-       }
-#endif
+
+       all->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
+
+       sbusfb_fill_var(&all->info.var, dp->node, 1);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
+
        all->info.var.red.length = all->info.var.green.length =
                all->info.var.blue.length = all->info.var.bits_per_pixel;
        all->info.var.red.offset = all->info.var.green.offset =
                all->info.var.blue.offset = 0;
 
-       all->par.regs = sbus_ioremap(resp, BWTWO_REGISTER_OFFSET,
-                            sizeof(struct bw2_regs), "bw2 regs");
+       all->par.regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET,
+                                  sizeof(struct bw2_regs), "bw2 regs");
 
-       if (sdev && !prom_getbool(sdev->prom_node, "width"))
+       if (!of_find_property(dp, "width", NULL))
                bw2_do_default_mode(&all->par, &all->info, &linebytes);
 
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
        all->info.flags = FBINFO_DEFAULT;
        all->info.fbops = &bw2_ops;
-#if defined(CONFIG_SPARC32)
-       if (sdev)
-               all->info.screen_base = (char __iomem *)
-                       prom_getintdefault(sdev->prom_node, "address", 0);
-#endif
-       if (!all->info.screen_base)
-               all->info.screen_base =
-                       sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram");
+
+       all->info.screen_base =
+               sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
        all->info.par = &all->par;
 
        bw2_blank(0, &all->info);
 
        bw2_init_fix(&all->info, linebytes);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "bw2: Could not register framebuffer.\n");
+       err= register_framebuffer(&all->info);
+       if (err < 0) {
+               of_iounmap(all->par.regs, sizeof(struct bw2_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &bw2_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: bwtwo at %lx:%lx\n",
+              dp->full_name,
+              all->par.which_io, all->par.physbase);
 
-       printk("bw2: bwtwo at %lx:%lx\n",
-              (long) (sdev ? sdev->reg_addrs[0].which_io : 0),
-              (long) all->par.physbase);
+       return 0;
 }
 
-int __init bw2_init(void)
+static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("bw2fb", NULL))
-               return -ENODEV;
+       return bw2_init_one(op);
+}
 
-#ifdef CONFIG_SUN4
-       bw2_init_one(NULL);
-#endif
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "bwtwo"))
-                       bw2_init_one(sdev);
-       }
+static int __devexit bw2_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+
+       of_iounmap(all->par.regs, sizeof(struct bw2_regs));
+       of_iounmap(all->info.screen_base, all->par.fbsize);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit bw2_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id bw2_match[] = {
+       {
+               .name = "bwtwo",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, bw2_match);
 
-       list_for_each_safe(pos, tmp, &bw2_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver bw2_driver = {
+       .name           = "bw2",
+       .match_table    = bw2_match,
+       .probe          = bw2_probe,
+       .remove         = __devexit_p(bw2_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               kfree(all);
-       }
+static int __init bw2_init(void)
+{
+       if (fb_get_options("bw2fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&bw2_driver, &of_bus_type);
 }
 
-int __init
-bw2_setup(char *arg)
+static void __exit bw2_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       return of_unregister_driver(&bw2_driver);
 }
 
-module_init(bw2_init);
 
-#ifdef MODULE
+module_init(bw2_init);
 module_exit(bw2_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 63b6c79c8a0a98195c00a59cfed6387d57f61f15..7f926c619b61790558c53918df181477c565c3d9 100644 (file)
@@ -1,6 +1,6 @@
 /* cg14.c: CGFOURTEEN frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
  *
@@ -18,8 +18,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -99,73 +99,73 @@ static struct fb_ops cg14_ops = {
 #define CG14_MCR_PIXMODE_32            3
 
 struct cg14_regs{
-       volatile u8 mcr;        /* Master Control Reg */
-       volatile u8 ppr;        /* Packed Pixel Reg */
-       volatile u8 tms[2];     /* Test Mode Status Regs */
-       volatile u8 msr;        /* Master Status Reg */
-       volatile u8 fsr;        /* Fault Status Reg */
-       volatile u8 rev;        /* Revision & Impl */
-       volatile u8 ccr;        /* Clock Control Reg */
-       volatile u32 tmr;       /* Test Mode Read Back */
-       volatile u8 mod;        /* Monitor Operation Data Reg */
-       volatile u8 acr;        /* Aux Control */
+       u8 mcr; /* Master Control Reg */
+       u8 ppr; /* Packed Pixel Reg */
+       u8 tms[2];      /* Test Mode Status Regs */
+       u8 msr; /* Master Status Reg */
+       u8 fsr; /* Fault Status Reg */
+       u8 rev; /* Revision & Impl */
+       u8 ccr; /* Clock Control Reg */
+       u32 tmr;        /* Test Mode Read Back */
+       u8 mod; /* Monitor Operation Data Reg */
+       u8 acr; /* Aux Control */
        u8 xxx0[6];
-       volatile u16 hct;       /* Hor Counter */
-       volatile u16 vct;       /* Vert Counter */
-       volatile u16 hbs;       /* Hor Blank Start */
-       volatile u16 hbc;       /* Hor Blank Clear */
-       volatile u16 hss;       /* Hor Sync Start */
-       volatile u16 hsc;       /* Hor Sync Clear */
-       volatile u16 csc;       /* Composite Sync Clear */
-       volatile u16 vbs;       /* Vert Blank Start */
-       volatile u16 vbc;       /* Vert Blank Clear */
-       volatile u16 vss;       /* Vert Sync Start */
-       volatile u16 vsc;       /* Vert Sync Clear */
-       volatile u16 xcs;
-       volatile u16 xcc;
-       volatile u16 fsa;       /* Fault Status Address */
-       volatile u16 adr;       /* Address Registers */
+       u16 hct;        /* Hor Counter */
+       u16 vct;        /* Vert Counter */
+       u16 hbs;        /* Hor Blank Start */
+       u16 hbc;        /* Hor Blank Clear */
+       u16 hss;        /* Hor Sync Start */
+       u16 hsc;        /* Hor Sync Clear */
+       u16 csc;        /* Composite Sync Clear */
+       u16 vbs;        /* Vert Blank Start */
+       u16 vbc;        /* Vert Blank Clear */
+       u16 vss;        /* Vert Sync Start */
+       u16 vsc;        /* Vert Sync Clear */
+       u16 xcs;
+       u16 xcc;
+       u16 fsa;        /* Fault Status Address */
+       u16 adr;        /* Address Registers */
        u8 xxx1[0xce];
-       volatile u8 pcg[0x100]; /* Pixel Clock Generator */
-       volatile u32 vbr;       /* Frame Base Row */
-       volatile u32 vmcr;      /* VBC Master Control */
-       volatile u32 vcr;       /* VBC refresh */
-       volatile u32 vca;       /* VBC Config */
+       u8 pcg[0x100]; /* Pixel Clock Generator */
+       u32 vbr;        /* Frame Base Row */
+       u32 vmcr;       /* VBC Master Control */
+       u32 vcr;        /* VBC refresh */
+       u32 vca;        /* VBC Config */
 };
 
 #define CG14_CCR_ENABLE        0x04
 #define CG14_CCR_SELECT 0x02   /* HW/Full screen */
 
 struct cg14_cursor {
-       volatile u32 cpl0[32];  /* Enable plane 0 */
-       volatile u32 cpl1[32];  /* Color selection plane */
-       volatile u8 ccr;        /* Cursor Control Reg */
+       u32 cpl0[32];   /* Enable plane 0 */
+       u32 cpl1[32];  /* Color selection plane */
+       u8 ccr; /* Cursor Control Reg */
        u8 xxx0[3];
-       volatile u16 cursx;     /* Cursor x,y position */
-       volatile u16 cursy;     /* Cursor x,y position */
-       volatile u32 color0;
-       volatile u32 color1;
+       u16 cursx;      /* Cursor x,y position */
+       u16 cursy;      /* Cursor x,y position */
+       u32 color0;
+       u32 color1;
        u32 xxx1[0x1bc];
-       volatile u32 cpl0i[32]; /* Enable plane 0 autoinc */
-       volatile u32 cpl1i[32]; /* Color selection autoinc */
+       u32 cpl0i[32];  /* Enable plane 0 autoinc */
+       u32 cpl1i[32]; /* Color selection autoinc */
 };
 
 struct cg14_dac {
-       volatile u8 addr;       /* Address Register */
+       u8 addr;        /* Address Register */
        u8 xxx0[255];
-       volatile u8 glut;       /* Gamma table */
+       u8 glut;        /* Gamma table */
        u8 xxx1[255];
-       volatile u8 select;     /* Register Select */
+       u8 select;      /* Register Select */
        u8 xxx2[255];
-       volatile u8 mode;       /* Mode Register */
+       u8 mode;        /* Mode Register */
 };
 
 struct cg14_xlut{
-       volatile u8 x_xlut [256];
-       volatile u8 x_xlutd [256];
+       u8 x_xlut [256];
+       u8 x_xlutd [256];
        u8 xxx0[0x600];
-       volatile u8 x_xlut_inc [256];
-       volatile u8 x_xlutd_inc [256];
+       u8 x_xlut_inc [256];
+       u8 x_xlutd_inc [256];
 };
 
 /* Color look up table (clut) */
@@ -204,7 +204,6 @@ struct cg14_par {
 
        int                     mode;
        int                     ramsize;
-       struct sbus_dev         *sdev;
 };
 
 static void __cg14_reset(struct cg14_par *par)
@@ -355,14 +354,9 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  *  Initialisation
  */
 
-static void cg14_init_fix(struct fb_info *info, int linebytes)
+static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
 {
-       struct cg14_par *par = (struct cg14_par *)info->par;
-       const char *name;
-
-       name = "cgfourteen";
-       if (par->sdev)
-               name = par->sdev->prom_name;
+       const char *name = dp->name;
 
        strlcpy(info->fix.id, name, sizeof(info->fix.id));
 
@@ -456,98 +450,81 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = {
 struct all_info {
        struct fb_info info;
        struct cg14_par par;
-       struct list_head list;
 };
-static LIST_HEAD(cg14_list);
 
-static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
+static void cg14_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       unsigned long phys, rphys;
-       u32 bases[6];
-       int is_8mb, linebytes, i;
-
-       if (!sdev) {
-               if (prom_getproperty(node, "address",
-                                    (char *) &bases[0], sizeof(bases)) <= 0
-                   || !bases[0]) {
-                       printk(KERN_ERR "cg14: Device is not mapped.\n");
-                       return;
-               }
-               if (__get_iospace(bases[0]) != __get_iospace(bases[1])) {
-                       printk(KERN_ERR "cg14: I/O spaces don't match.\n");
-                       return;
-               }
-       }
+       if (all->par.regs)
+               of_iounmap(all->par.regs, sizeof(struct cg14_regs));
+       if (all->par.clut)
+               of_iounmap(all->par.clut, sizeof(struct cg14_clut));
+       if (all->par.cursor)
+               of_iounmap(all->par.cursor, sizeof(struct cg14_cursor));
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, all->par.fbsize);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "cg14: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit cg14_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int is_8mb, linebytes, i, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
 
-       sbusfb_fill_var(&all->info.var, node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.sdev = sdev;
-       if (sdev) {
-               rphys = sdev->reg_addrs[0].phys_addr;
-               all->par.physbase = phys = sdev->reg_addrs[1].phys_addr;
-               all->par.iospace = sdev->reg_addrs[0].which_io;
-
-               all->par.regs = sbus_ioremap(&sdev->resource[0], 0,
-                                    sizeof(struct cg14_regs),
-                                    "cg14 regs");
-               all->par.clut = sbus_ioremap(&sdev->resource[0], CG14_CLUT1,
-                                    sizeof(struct cg14_clut),
-                                    "cg14 clut");
-               all->par.cursor = sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS,
-                                    sizeof(struct cg14_cursor),
-                                    "cg14 cursor");
-               all->info.screen_base = sbus_ioremap(&sdev->resource[1], 0,
-                                    all->par.fbsize, "cg14 ram");
+       if (!strcmp(dp->parent->name, "sbus") ||
+           !strcmp(dp->parent->name, "sbi")) {
+               all->par.physbase = op->resource[0].start;
+               all->par.iospace = op->resource[0].flags & IORESOURCE_BITS;
        } else {
-               rphys = __get_phys(bases[0]);
-               all->par.physbase = phys = __get_phys(bases[1]);
-               all->par.iospace = __get_iospace(bases[0]);
-               all->par.regs = (struct cg14_regs __iomem *)(unsigned long)bases[0];
-               all->par.clut = (struct cg14_clut __iomem *)((unsigned long)bases[0] +
-                                                    CG14_CLUT1);
-               all->par.cursor =
-                       (struct cg14_cursor __iomem *)((unsigned long)bases[0] +
-                                              CG14_CURSORREGS);
-
-               all->info.screen_base = (char __iomem *)(unsigned long)bases[1];
+               all->par.physbase = op->resource[1].start;
+               all->par.iospace = op->resource[0].flags & IORESOURCE_BITS;
        }
 
-       prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases));
-       is_8mb = (bases[5] == 0x800000);
+       all->par.regs = of_ioremap(&op->resource[0], 0,
+                                  sizeof(struct cg14_regs), "cg14 regs");
+       all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1,
+                                  sizeof(struct cg14_clut), "cg14 clut");
+       all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS,
+                                  sizeof(struct cg14_cursor), "cg14 cursor");
 
-       if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) {
-               extern void __cg14_mmap_sized_wrongly(void);
+       all->info.screen_base = of_ioremap(&op->resource[1], 0,
+                                          all->par.fbsize, "cg14 ram");
 
-               __cg14_mmap_sized_wrongly();
-       }
+       if (!all->par.regs || !all->par.clut || !all->par.cursor ||
+           !all->info.screen_base)
+               cg14_unmap_regs(all);
+
+       is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
+                 (8 * 1024 * 1024));
+
+       BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map));
                
-       memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map));
+       memcpy(&all->par.mmap_map, &__cg14_mmap_map,
+              sizeof(all->par.mmap_map));
+
        for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
                struct sbus_mmap_map *map = &all->par.mmap_map[i];
 
                if (!map->size)
                        break;
                if (map->poff & 0x80000000)
-                       map->poff = (map->poff & 0x7fffffff) + rphys - phys;
+                       map->poff = (map->poff & 0x7fffffff) +
+                               (op->resource[0].start -
+                                op->resource[1].start);
                if (is_8mb &&
                    map->size >= 0x100000 &&
                    map->size <= 0x400000)
@@ -564,84 +541,87 @@ static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
        __cg14_reset(&all->par);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "cg14: Could not allocate color map.\n");
+               cg14_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
        fb_set_cmap(&all->info.cmap, &all->info);
 
-       cg14_init_fix(&all->info, linebytes);
+       cg14_init_fix(&all->info, linebytes, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "cg14: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               cg14_unmap_regs(all);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &cg14_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("cg14: cgfourteen at %lx:%lx, %dMB\n",
-              all->par.iospace, all->par.physbase, all->par.ramsize >> 20);
+       printk("%s: cgfourteen at %lx:%lx, %dMB\n",
+              dp->full_name,
+              all->par.iospace, all->par.physbase,
+              all->par.ramsize >> 20);
 
+       return 0;
 }
 
-int __init cg14_init(void)
+static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("cg14fb", NULL))
-               return -ENODEV;
+       return cg14_init_one(op);
+}
 
-#ifdef CONFIG_SPARC32
-       {
-               int root, node;
-
-               root = prom_getchild(prom_root_node);
-               root = prom_searchsiblings(root, "obio");
-               if (root) {
-                       node = prom_searchsiblings(prom_getchild(root),
-                                                  "cgfourteen");
-                       if (node)
-                               cg14_init_one(NULL, node, root);
-               }
-       }
-#endif
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "cgfourteen"))
-                       cg14_init_one(sdev, sdev->prom_node, sbus->prom_node);
-       }
+static int __devexit cg14_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       cg14_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit cg14_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id cg14_match[] = {
+       {
+               .name = "cgfourteen",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cg14_match);
 
-       list_for_each_safe(pos, tmp, &cg14_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver cg14_driver = {
+       .name           = "cg14",
+       .match_table    = cg14_match,
+       .probe          = cg14_probe,
+       .remove         = __devexit_p(cg14_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+int __init cg14_init(void)
+{
+       if (fb_get_options("cg14fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&cg14_driver, &of_bus_type);
 }
 
-int __init
-cg14_setup(char *arg)
+void __exit cg14_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&cg14_driver);
 }
 
 module_init(cg14_init);
-
-#ifdef MODULE
 module_exit(cg14_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 3de6e1b5ab2f4008efd29b32805c9e3bd874dec1..9c8c753ef4541de8710966e9c87480bc407b5faf 100644 (file)
@@ -1,6 +1,6 @@
 /* cg3.c: CGTHREE frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,9 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -80,30 +81,30 @@ enum cg3_type {
 };
 
 struct bt_regs {
-       volatile u32 addr;
-       volatile u32 color_map;
-       volatile u32 control;
-       volatile u32 cursor;
+       u32 addr;
+       u32 color_map;
+       u32 control;
+       u32 cursor;
 };
 
 struct cg3_regs {
        struct bt_regs  cmap;
-       volatile u8     control;
-       volatile u8     status;
-       volatile u8     cursor_start;
-       volatile u8     cursor_end;
-       volatile u8     h_blank_start;
-       volatile u8     h_blank_end;
-       volatile u8     h_sync_start;
-       volatile u8     h_sync_end;
-       volatile u8     comp_sync_end;
-       volatile u8     v_blank_start_high;
-       volatile u8     v_blank_start_low;
-       volatile u8     v_blank_end;
-       volatile u8     v_sync_start;
-       volatile u8     v_sync_end;
-       volatile u8     xfer_holdoff_start;
-       volatile u8     xfer_holdoff_end;
+       u8      control;
+       u8      status;
+       u8      cursor_start;
+       u8      cursor_end;
+       u8      h_blank_start;
+       u8      h_blank_end;
+       u8      h_sync_start;
+       u8      h_sync_end;
+       u8      comp_sync_end;
+       u8      v_blank_start_high;
+       u8      v_blank_start_low;
+       u8      v_blank_end;
+       u8      v_sync_start;
+       u8      v_sync_end;
+       u8      xfer_holdoff_start;
+       u8      xfer_holdoff_end;
 };
 
 /* Offset of interesting structures in the OBIO space */
@@ -120,9 +121,8 @@ struct cg3_par {
 #define CG3_FLAG_RDI           0x00000002
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 /**
@@ -235,7 +235,7 @@ static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(cg3_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
+                                 par->which_io,
                                  vma);
 }
 
@@ -252,11 +252,9 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  */
 
 static void
-cg3_init_fix(struct fb_info *info, int linebytes)
+cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
 {
-       struct cg3_par *par = (struct cg3_par *)info->par;
-
-       strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
+       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -267,16 +265,15 @@ cg3_init_fix(struct fb_info *info, int linebytes)
 }
 
 static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
-                                   struct sbus_dev *sdev)
+                                   struct device_node *dp)
 {
-       char buffer[40];
+       char *params;
        char *p;
        int ww, hh;
 
-       *buffer = 0;
-       prom_getstring(sdev->prom_node, "params", buffer, sizeof(buffer));
-       if (*buffer) {
-               ww = simple_strtoul(buffer, &p, 10);
+       params = of_get_property(dp, "params", NULL);
+       if (params) {
+               ww = simple_strtoul(params, &p, 10);
                if (ww && *p == 'x') {
                        hh = simple_strtoul(p + 1, &p, 10);
                        if (hh && *p == '-') {
@@ -348,11 +345,11 @@ static void cg3_do_default_mode(struct cg3_par *par)
                sbus_writeb(p[1], regp);
        }
        for (p = cg3_dacvals; *p; p += 2) {
-               volatile u8 __iomem *regp;
+               u8 __iomem *regp;
 
-               regp = (volatile u8 __iomem *)&par->regs->cmap.addr;
+               regp = (u8 __iomem *)&par->regs->cmap.addr;
                sbus_writeb(p[0], regp);
-               regp = (volatile u8 __iomem *)&par->regs->cmap.control;
+               regp = (u8 __iomem *)&par->regs->cmap.control;
                sbus_writeb(p[1], regp);
        }
 }
@@ -360,129 +357,137 @@ static void cg3_do_default_mode(struct cg3_par *par)
 struct all_info {
        struct fb_info info;
        struct cg3_par par;
-       struct list_head list;
 };
-static LIST_HEAD(cg3_list);
 
-static void cg3_init_one(struct sbus_dev *sdev)
+static int __devinit cg3_init_one(struct of_device *op)
 {
+       struct device_node *dp = op->node;
        struct all_info *all;
-       int linebytes;
-
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "cg3: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.physbase = sdev->reg_addrs[0].phys_addr;
+       all->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
-       if (!strcmp(sdev->prom_name, "cgRDI"))
+       if (!strcmp(dp->name, "cgRDI"))
                all->par.flags |= CG3_FLAG_RDI;
        if (all->par.flags & CG3_FLAG_RDI)
-               cg3_rdi_maybe_fixup_var(&all->info.var, sdev);
+               cg3_rdi_maybe_fixup_var(&all->info.var, dp);
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.regs = sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
-                            sizeof(struct cg3_regs), "cg3 regs");
+       all->par.regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET,
+                                  sizeof(struct cg3_regs), "cg3 regs");
 
        all->info.flags = FBINFO_DEFAULT;
        all->info.fbops = &cg3_ops;
-#ifdef CONFIG_SPARC32
-       all->info.screen_base = (char __iomem *)
-               prom_getintdefault(sdev->prom_node, "address", 0);
-#endif
-       if (!all->info.screen_base)
-               all->info.screen_base =
-                       sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
-                                    all->par.fbsize, "cg3 ram");
+       all->info.screen_base =
+               of_ioremap(&op->resource[0], CG3_RAM_OFFSET,
+                          all->par.fbsize, "cg3 ram");
        all->info.par = &all->par;
 
        cg3_blank(0, &all->info);
 
-       if (!prom_getbool(sdev->prom_node, "width"))
+       if (!of_find_property(dp, "width", NULL))
                cg3_do_default_mode(&all->par);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "cg3: Could not allocate color map.\n");
+               of_iounmap(all->par.regs, sizeof(struct cg3_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
        fb_set_cmap(&all->info.cmap, &all->info);
 
-       cg3_init_fix(&all->info, linebytes);
+       cg3_init_fix(&all->info, linebytes, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "cg3: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               of_iounmap(all->par.regs, sizeof(struct cg3_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &cg3_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: cg3 at %lx:%lx\n",
+              dp->full_name, all->par.which_io, all->par.physbase);
 
-       printk("cg3: %s at %lx:%lx\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+       return 0;
 }
 
-int __init cg3_init(void)
+static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("cg3fb", NULL))
-               return -ENODEV;
+       return cg3_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "cgthree") ||
-                   !strcmp(sdev->prom_name, "cgRDI"))
-                       cg3_init_one(sdev);
-       }
+static int __devexit cg3_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       of_iounmap(all->par.regs, sizeof(struct cg3_regs));
+       of_iounmap(all->info.screen_base, all->par.fbsize);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit cg3_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id cg3_match[] = {
+       {
+               .name = "cgthree",
+       },
+       {
+               .name = "cgRDI",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cg3_match);
 
-       list_for_each_safe(pos, tmp, &cg3_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver cg3_driver = {
+       .name           = "cg3",
+       .match_table    = cg3_match,
+       .probe          = cg3_probe,
+       .remove         = __devexit_p(cg3_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+static int __init cg3_init(void)
+{
+       if (fb_get_options("cg3fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&cg3_driver, &of_bus_type);
 }
 
-int __init
-cg3_setup(char *arg)
+static void __exit cg3_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&cg3_driver);
 }
 
 module_init(cg3_init);
-
-#ifdef MODULE
 module_exit(cg3_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 7aab91ead6818ee70d7484aedacc001a6ecd8739..64146be2eeb0c746a65ca96799ff5850a7477794 100644 (file)
@@ -1,6 +1,6 @@
 /* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -164,89 +164,89 @@ static struct fb_ops cg6_ops = {
 
 /* The contents are unknown */
 struct cg6_tec {
-       volatile int tec_matrix;
-       volatile int tec_clip;
-       volatile int tec_vdc;
+       int tec_matrix;
+       int tec_clip;
+       int tec_vdc;
 };
 
 struct cg6_thc {
-        uint thc_pad0[512];
-       volatile uint thc_hs;           /* hsync timing */
-       volatile uint thc_hsdvs;
-       volatile uint thc_hd;
-       volatile uint thc_vs;           /* vsync timing */
-       volatile uint thc_vd;
-       volatile uint thc_refresh;
-       volatile uint thc_misc;
-       uint thc_pad1[56];
-       volatile uint thc_cursxy;       /* cursor x,y position (16 bits each) */
-       volatile uint thc_cursmask[32]; /* cursor mask bits */
-       volatile uint thc_cursbits[32]; /* what to show where mask enabled */
+        u32 thc_pad0[512];
+       u32 thc_hs;             /* hsync timing */
+       u32 thc_hsdvs;
+       u32 thc_hd;
+       u32 thc_vs;             /* vsync timing */
+       u32 thc_vd;
+       u32 thc_refresh;
+       u32 thc_misc;
+       u32 thc_pad1[56];
+       u32 thc_cursxy; /* cursor x,y position (16 bits each) */
+       u32 thc_cursmask[32];   /* cursor mask bits */
+       u32 thc_cursbits[32];   /* what to show where mask enabled */
 };
 
 struct cg6_fbc {
-       u32             xxx0[1];
-       volatile u32    mode;
-       volatile u32    clip;
-       u32             xxx1[1];            
-       volatile u32    s;
-       volatile u32    draw;
-       volatile u32    blit;
-       volatile u32    font;
-       u32             xxx2[24];
-       volatile u32    x0, y0, z0, color0;
-       volatile u32    x1, y1, z1, color1;
-       volatile u32    x2, y2, z2, color2;
-       volatile u32    x3, y3, z3, color3;
-       volatile u32    offx, offy;
-       u32             xxx3[2];
-       volatile u32    incx, incy;
-       u32             xxx4[2];
-       volatile u32    clipminx, clipminy;
-       u32             xxx5[2];
-       volatile u32    clipmaxx, clipmaxy;
-       u32             xxx6[2];
-       volatile u32    fg;
-       volatile u32    bg;
-       volatile u32    alu;
-       volatile u32    pm;
-       volatile u32    pixelm;
-       u32             xxx7[2];
-       volatile u32    patalign;
-       volatile u32    pattern[8];
-       u32             xxx8[432];
-       volatile u32    apointx, apointy, apointz;
-       u32             xxx9[1];
-       volatile u32    rpointx, rpointy, rpointz;
-       u32             xxx10[5];
-       volatile u32    pointr, pointg, pointb, pointa;
-       volatile u32    alinex, aliney, alinez;
-       u32             xxx11[1];
-       volatile u32    rlinex, rliney, rlinez;
-       u32             xxx12[5];
-       volatile u32    liner, lineg, lineb, linea;
-       volatile u32    atrix, atriy, atriz;
-       u32             xxx13[1];
-       volatile u32    rtrix, rtriy, rtriz;
-       u32             xxx14[5];
-       volatile u32    trir, trig, trib, tria;
-       volatile u32    aquadx, aquady, aquadz;
-       u32             xxx15[1];
-       volatile u32    rquadx, rquady, rquadz;
-       u32             xxx16[5];
-       volatile u32    quadr, quadg, quadb, quada;
-       volatile u32    arectx, arecty, arectz;
-       u32             xxx17[1];
-       volatile u32    rrectx, rrecty, rrectz;
-       u32             xxx18[5];
-       volatile u32    rectr, rectg, rectb, recta;
+       u32     xxx0[1];
+       u32     mode;
+       u32     clip;
+       u32     xxx1[1];            
+       u32     s;
+       u32     draw;
+       u32     blit;
+       u32     font;
+       u32     xxx2[24];
+       u32     x0, y0, z0, color0;
+       u32     x1, y1, z1, color1;
+       u32     x2, y2, z2, color2;
+       u32     x3, y3, z3, color3;
+       u32     offx, offy;
+       u32     xxx3[2];
+       u32     incx, incy;
+       u32     xxx4[2];
+       u32     clipminx, clipminy;
+       u32     xxx5[2];
+       u32     clipmaxx, clipmaxy;
+       u32     xxx6[2];
+       u32     fg;
+       u32     bg;
+       u32     alu;
+       u32     pm;
+       u32     pixelm;
+       u32     xxx7[2];
+       u32     patalign;
+       u32     pattern[8];
+       u32     xxx8[432];
+       u32     apointx, apointy, apointz;
+       u32     xxx9[1];
+       u32     rpointx, rpointy, rpointz;
+       u32     xxx10[5];
+       u32     pointr, pointg, pointb, pointa;
+       u32     alinex, aliney, alinez;
+       u32     xxx11[1];
+       u32     rlinex, rliney, rlinez;
+       u32     xxx12[5];
+       u32     liner, lineg, lineb, linea;
+       u32     atrix, atriy, atriz;
+       u32     xxx13[1];
+       u32     rtrix, rtriy, rtriz;
+       u32     xxx14[5];
+       u32     trir, trig, trib, tria;
+       u32     aquadx, aquady, aquadz;
+       u32     xxx15[1];
+       u32     rquadx, rquady, rquadz;
+       u32     xxx16[5];
+       u32     quadr, quadg, quadb, quada;
+       u32     arectx, arecty, arectz;
+       u32     xxx17[1];
+       u32     rrectx, rrecty, rrectz;
+       u32     xxx18[5];
+       u32     rectr, rectg, rectb, recta;
 };
 
 struct bt_regs {
-       volatile u32 addr;
-       volatile u32 color_map;
-       volatile u32 control;
-       volatile u32 cursor;
+       u32 addr;
+       u32 color_map;
+       u32 control;
+       u32 cursor;
 };
 
 struct cg6_par {
@@ -255,15 +255,14 @@ struct cg6_par {
        struct cg6_fbc          __iomem *fbc;
        struct cg6_thc          __iomem *thc;
        struct cg6_tec          __iomem *tec;
-       volatile u32            __iomem *fhc;
+       u32                     __iomem *fhc;
 
        u32                     flags;
 #define CG6_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 static int cg6_sync(struct fb_info *info)
@@ -529,8 +528,7 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(cg6_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
@@ -658,62 +656,75 @@ static void cg6_chip_init(struct fb_info *info)
 struct all_info {
        struct fb_info info;
        struct cg6_par par;
-       struct list_head list;
 };
-static LIST_HEAD(cg6_list);
 
-static void cg6_init_one(struct sbus_dev *sdev)
+static void cg6_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       int linebytes;
+       if (all->par.fbc)
+               of_iounmap(all->par.fbc, 4096);
+       if (all->par.tec)
+               of_iounmap(all->par.tec, sizeof(struct cg6_tec));
+       if (all->par.thc)
+               of_iounmap(all->par.thc, sizeof(struct cg6_thc));
+       if (all->par.bt)
+               of_iounmap(all->par.bt, sizeof(struct bt_regs));
+       if (all->par.fhc)
+               of_iounmap(all->par.fhc, sizeof(u32));
+
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, all->par.fbsize);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "cg6: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit cg6_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.physbase = sdev->reg_addrs[0].phys_addr;
+       all->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
-       if (prom_getbool(sdev->prom_node, "dblbuf"))
+       if (of_find_property(dp, "dblbuf", NULL))
                all->par.fbsize *= 4;
 
-       all->par.fbc = sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET,
-                            4096, "cgsix fbc");
-       all->par.tec = sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET,
-                            sizeof(struct cg6_tec), "cgsix tec");
-       all->par.thc = sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET,
-                            sizeof(struct cg6_thc), "cgsix thc");
-       all->par.bt = sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET,
-                            sizeof(struct bt_regs), "cgsix dac");
-       all->par.fhc = sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET,
-                            sizeof(u32), "cgsix fhc");
+       all->par.fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET,
+                                 4096, "cgsix fbc");
+       all->par.tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET,
+                                 sizeof(struct cg6_tec), "cgsix tec");
+       all->par.thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET,
+                                 sizeof(struct cg6_thc), "cgsix thc");
+       all->par.bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET,
+                                sizeof(struct bt_regs), "cgsix dac");
+       all->par.fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET,
+                                 sizeof(u32), "cgsix fhc");
 
        all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT |
                           FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
        all->info.fbops = &cg6_ops;
-#ifdef CONFIG_SPARC32
-       all->info.screen_base = (char __iomem *)
-               prom_getintdefault(sdev->prom_node, "address", 0);
-#endif
-       if (!all->info.screen_base)
-               all->info.screen_base = 
-                       sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET,
-                                    all->par.fbsize, "cgsix ram");
+
+       all->info.screen_base =  of_ioremap(&op->resource[0], CG6_RAM_OFFSET,
+                                           all->par.fbsize, "cgsix ram");
+       if (!all->par.fbc || !all->par.tec || !all->par.thc ||
+           !all->par.bt || !all->par.fhc || !all->info.screen_base) {
+               cg6_unmap_regs(all);
+               kfree(all);
+               return -ENOMEM;
+       }
+
        all->info.par = &all->par;
 
        all->info.var.accel_flags = FB_ACCELF_TEXT;
@@ -723,72 +734,90 @@ static void cg6_init_one(struct sbus_dev *sdev)
        cg6_blank(0, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "cg6: Could not allocate color map.\n");
+               cg6_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
        fb_set_cmap(&all->info.cmap, &all->info);
        cg6_init_fix(&all->info, linebytes);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "cg6: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
+               cg6_unmap_regs(all);
                fb_dealloc_cmap(&all->info.cmap);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &cg6_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("cg6: CGsix [%s] at %lx:%lx\n",
+       printk("%s: CGsix [%s] at %lx:%lx\n",
+              dp->full_name,
               all->info.fix.id,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+              all->par.which_io, all->par.physbase);
+
+       return 0;
 }
 
-int __init cg6_init(void)
+static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("cg6fb", NULL))
-               return -ENODEV;
+       return cg6_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "cgsix") ||
-                   !strcmp(sdev->prom_name, "cgthree+"))
-                       cg6_init_one(sdev);
-       }
+static int __devexit cg6_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       cg6_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit cg6_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id cg6_match[] = {
+       {
+               .name = "cgsix",
+       },
+       {
+               .name = "cgthree+",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cg6_match);
 
-       list_for_each_safe(pos, tmp, &cg6_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver cg6_driver = {
+       .name           = "cg6",
+       .match_table    = cg6_match,
+       .probe          = cg6_probe,
+       .remove         = __devexit_p(cg6_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+static int __init cg6_init(void)
+{
+       if (fb_get_options("cg6fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&cg6_driver, &of_bus_type);
 }
 
-int __init
-cg6_setup(char *arg)
+static void __exit cg6_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&cg6_driver);
 }
 
 module_init(cg6_init);
-
-#ifdef MODULE
 module_exit(cg6_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 31143afe7c95899303bac5571dcf833e7c26174e..a171daab0ad0b7467f97c5fde87fefb1ec1f8569 100644 (file)
@@ -32,7 +32,6 @@
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
 #endif
-#include <linux/devfs_fs_kernel.h>
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/efi.h>
@@ -1331,8 +1330,6 @@ register_framebuffer(struct fb_info *fb_info)
        fb_add_videomode(&mode, &fb_info->modelist);
        registered_fb[i] = fb_info;
 
-       devfs_mk_cdev(MKDEV(FB_MAJOR, i),
-                       S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i);
        event.info = fb_info;
        blocking_notifier_call_chain(&fb_notifier_list,
                            FB_EVENT_FB_REGISTERED, &event);
@@ -1359,7 +1356,6 @@ unregister_framebuffer(struct fb_info *fb_info)
        i = fb_info->node;
        if (!registered_fb[i])
                return -EINVAL;
-       devfs_remove("fb/%d", i);
 
        if (fb_info->pixmap.addr &&
            (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
@@ -1432,7 +1428,6 @@ fbmem_init(void)
 {
        create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);
 
-       devfs_mk_dir("fb");
        if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
                printk("unable to get major %d for fb devs\n", FB_MAJOR);
 
index 7633e41adda158a38688c056057fd15c91bf974d..2a0e8210d398e6c964aa69028161cd3af471a44d 100644 (file)
@@ -1,6 +1,6 @@
 /* ffb.c: Creator/Elite3D frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
  *
  * Driver layout based loosely on tgafb.c, see that file for credits.
@@ -19,7 +19,8 @@
 
 #include <asm/io.h>
 #include <asm/upa.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -184,161 +185,161 @@ static struct fb_ops ffb_ops = {
 
 struct ffb_fbc {
        /* Next vertex registers */
-       u32             xxx1[3];
-       volatile u32    alpha;
-       volatile u32    red;
-       volatile u32    green;
-       volatile u32    blue;
-       volatile u32    depth;
-       volatile u32    y;
-       volatile u32    x;
-       u32             xxx2[2];
-       volatile u32    ryf;
-       volatile u32    rxf;
-       u32             xxx3[2];
+       u32     xxx1[3];
+       u32     alpha;
+       u32     red;
+       u32     green;
+       u32     blue;
+       u32     depth;
+       u32     y;
+       u32     x;
+       u32     xxx2[2];
+       u32     ryf;
+       u32     rxf;
+       u32     xxx3[2];
        
-       volatile u32    dmyf;
-       volatile u32    dmxf;
-       u32             xxx4[2];
-       volatile u32    ebyi;
-       volatile u32    ebxi;
-       u32             xxx5[2];
-       volatile u32    by;
-       volatile u32    bx;
-       u32             dy;
-       u32             dx;
-       volatile u32    bh;
-       volatile u32    bw;
-       u32             xxx6[2];
+       u32     dmyf;
+       u32     dmxf;
+       u32     xxx4[2];
+       u32     ebyi;
+       u32     ebxi;
+       u32     xxx5[2];
+       u32     by;
+       u32     bx;
+       u32     dy;
+       u32     dx;
+       u32     bh;
+       u32     bw;
+       u32     xxx6[2];
        
-       u32             xxx7[32];
+       u32     xxx7[32];
        
        /* Setup unit vertex state register */
-       volatile u32    suvtx;
-       u32             xxx8[63];
+       u32     suvtx;
+       u32     xxx8[63];
        
        /* Control registers */
-       volatile u32    ppc;
-       volatile u32    wid;
-       volatile u32    fg;
-       volatile u32    bg;
-       volatile u32    consty;
-       volatile u32    constz;
-       volatile u32    xclip;
-       volatile u32    dcss;
-       volatile u32    vclipmin;
-       volatile u32    vclipmax;
-       volatile u32    vclipzmin;
-       volatile u32    vclipzmax;
-       volatile u32    dcsf;
-       volatile u32    dcsb;
-       volatile u32    dczf;
-       volatile u32    dczb;
+       u32     ppc;
+       u32     wid;
+       u32     fg;
+       u32     bg;
+       u32     consty;
+       u32     constz;
+       u32     xclip;
+       u32     dcss;
+       u32     vclipmin;
+       u32     vclipmax;
+       u32     vclipzmin;
+       u32     vclipzmax;
+       u32     dcsf;
+       u32     dcsb;
+       u32     dczf;
+       u32     dczb;
        
-       u32             xxx9;
-       volatile u32    blendc;
-       volatile u32    blendc1;
-       volatile u32    blendc2;
-       volatile u32    fbramitc;
-       volatile u32    fbc;
-       volatile u32    rop;
-       volatile u32    cmp;
-       volatile u32    matchab;
-       volatile u32    matchc;
-       volatile u32    magnab;
-       volatile u32    magnc;
-       volatile u32    fbcfg0;
-       volatile u32    fbcfg1;
-       volatile u32    fbcfg2;
-       volatile u32    fbcfg3;
+       u32     xxx9;
+       u32     blendc;
+       u32     blendc1;
+       u32     blendc2;
+       u32     fbramitc;
+       u32     fbc;
+       u32     rop;
+       u32     cmp;
+       u32     matchab;
+       u32     matchc;
+       u32     magnab;
+       u32     magnc;
+       u32     fbcfg0;
+       u32     fbcfg1;
+       u32     fbcfg2;
+       u32     fbcfg3;
        
-       u32             ppcfg;
-       volatile u32    pick;
-       volatile u32    fillmode;
-       volatile u32    fbramwac;
-       volatile u32    pmask;
-       volatile u32    xpmask;
-       volatile u32    ypmask;
-       volatile u32    zpmask;
-       volatile u32    clip0min;
-       volatile u32    clip0max;
-       volatile u32    clip1min;
-       volatile u32    clip1max;
-       volatile u32    clip2min;
-       volatile u32    clip2max;
-       volatile u32    clip3min;
-       volatile u32    clip3max;
+       u32     ppcfg;
+       u32     pick;
+       u32     fillmode;
+       u32     fbramwac;
+       u32     pmask;
+       u32     xpmask;
+       u32     ypmask;
+       u32     zpmask;
+       u32     clip0min;
+       u32     clip0max;
+       u32     clip1min;
+       u32     clip1max;
+       u32     clip2min;
+       u32     clip2max;
+       u32     clip3min;
+       u32     clip3max;
        
        /* New 3dRAM III support regs */
-       volatile u32    rawblend2;
-       volatile u32    rawpreblend;
-       volatile u32    rawstencil;
-       volatile u32    rawstencilctl;
-       volatile u32    threedram1;
-       volatile u32    threedram2;
-       volatile u32    passin;
-       volatile u32    rawclrdepth;
-       volatile u32    rawpmask;
-       volatile u32    rawcsrc;
-       volatile u32    rawmatch;
-       volatile u32    rawmagn;
-       volatile u32    rawropblend;
-       volatile u32    rawcmp;
-       volatile u32    rawwac;
-       volatile u32    fbramid;
+       u32     rawblend2;
+       u32     rawpreblend;
+       u32     rawstencil;
+       u32     rawstencilctl;
+       u32     threedram1;
+       u32     threedram2;
+       u32     passin;
+       u32     rawclrdepth;
+       u32     rawpmask;
+       u32     rawcsrc;
+       u32     rawmatch;
+       u32     rawmagn;
+       u32     rawropblend;
+       u32     rawcmp;
+       u32     rawwac;
+       u32     fbramid;
        
-       volatile u32    drawop;
-       u32             xxx10[2];
-       volatile u32    fontlpat;
-       u32             xxx11;
-       volatile u32    fontxy;
-       volatile u32    fontw;
-       volatile u32    fontinc;
-       volatile u32    font;
-       u32             xxx12[3];
-       volatile u32    blend2;
-       volatile u32    preblend;
-       volatile u32    stencil;
-       volatile u32    stencilctl;
-
-       u32             xxx13[4];       
-       volatile u32    dcss1;
-       volatile u32    dcss2;
-       volatile u32    dcss3;
-       volatile u32    widpmask;
-       volatile u32    dcs2;
-       volatile u32    dcs3;
-       volatile u32    dcs4;
-       u32             xxx14;
-       volatile u32    dcd2;
-       volatile u32    dcd3;
-       volatile u32    dcd4;
-       u32             xxx15;
+       u32     drawop;
+       u32     xxx10[2];
+       u32     fontlpat;
+       u32     xxx11;
+       u32     fontxy;
+       u32     fontw;
+       u32     fontinc;
+       u32     font;
+       u32     xxx12[3];
+       u32     blend2;
+       u32     preblend;
+       u32     stencil;
+       u32     stencilctl;
+
+       u32     xxx13[4];       
+       u32     dcss1;
+       u32     dcss2;
+       u32     dcss3;
+       u32     widpmask;
+       u32     dcs2;
+       u32     dcs3;
+       u32     dcs4;
+       u32     xxx14;
+       u32     dcd2;
+       u32     dcd3;
+       u32     dcd4;
+       u32     xxx15;
        
-       volatile u32    pattern[32];
+       u32     pattern[32];
        
-       u32             xxx16[256];
+       u32     xxx16[256];
        
-       volatile u32    devid;
-       u32             xxx17[63];
+       u32     devid;
+       u32     xxx17[63];
        
-       volatile u32    ucsr;
-       u32             xxx18[31];
+       u32     ucsr;
+       u32     xxx18[31];
        
-       volatile u32    mer;
+       u32     mer;
 };
 
 struct ffb_dac {
-       volatile u32    type;
-       volatile u32    value;
-       volatile u32    type2;
-       volatile u32    value2;
+       u32     type;
+       u32     value;
+       u32     type2;
+       u32     value2;
 };
 
 struct ffb_par {
        spinlock_t              lock;
-       struct ffb_fbc          *fbc;
-       struct ffb_dac          *dac;
+       struct ffb_fbc __iomem  *fbc;
+       struct ffb_dac __iomem  *dac;
 
        u32                     flags;
 #define FFB_FLAG_AFB           0x00000001
@@ -353,16 +354,13 @@ struct ffb_par {
        unsigned long           physbase;
        unsigned long           fbsize;
 
-       char                    name[64];
-       int                     prom_node;
-       int                     prom_parent_node;
        int                     dac_rev;
        int                     board_type;
 };
 
 static void FFBFifo(struct ffb_par *par, int n)
 {
-       struct ffb_fbc *fbc;
+       struct ffb_fbc __iomem *fbc;
        int cache = par->fifo_cache;
 
        if (cache - n < 0) {
@@ -375,7 +373,7 @@ static void FFBFifo(struct ffb_par *par, int n)
 
 static void FFBWait(struct ffb_par *par)
 {
-       struct ffb_fbc *fbc;
+       struct ffb_fbc __iomem *fbc;
        int limit = 10000;
 
        fbc = par->fbc;
@@ -408,8 +406,8 @@ static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
 
 static void ffb_switch_from_graph(struct ffb_par *par)
 {
-       struct ffb_fbc *fbc = par->fbc;
-       struct ffb_dac *dac = par->dac;
+       struct ffb_fbc __iomem *fbc = par->fbc;
+       struct ffb_dac __iomem *dac = par->dac;
        unsigned long flags;
 
        spin_lock_irqsave(&par->lock, flags);
@@ -462,7 +460,7 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_fbc *fbc = par->fbc;
+       struct ffb_fbc __iomem *fbc = par->fbc;
        unsigned long flags;
        u32 fg;
 
@@ -505,7 +503,7 @@ static void
 ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_fbc *fbc = par->fbc;
+       struct ffb_fbc __iomem *fbc = par->fbc;
        unsigned long flags;
 
        if (area->dx != area->sx ||
@@ -541,7 +539,7 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_fbc *fbc = par->fbc;
+       struct ffb_fbc __iomem *fbc = par->fbc;
        const u8 *data = image->data;
        unsigned long flags;
        u32 fg, bg, xy;
@@ -664,7 +662,7 @@ static int
 ffb_blank(int blank, struct fb_info *info)
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_dac *dac = par->dac;
+       struct ffb_dac __iomem *dac = par->dac;
        unsigned long flags;
        u32 tmp;
 
@@ -883,78 +881,42 @@ ffb_init_fix(struct fb_info *info)
        info->fix.accel = FB_ACCEL_SUN_CREATOR;
 }
 
-static int ffb_apply_upa_parent_ranges(int parent,
-                                      struct linux_prom64_registers *regs)
-{
-       struct linux_prom64_ranges ranges[PROMREG_MAX];
-       char name[128];
-       int len, i;
-
-       prom_getproperty(parent, "name", name, sizeof(name));
-       if (strcmp(name, "upa") != 0)
-               return 0;
-
-       len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
-       if (len <= 0)
-               return 1;
-
-       len /= sizeof(struct linux_prom64_ranges);
-       for (i = 0; i < len; i++) {
-               struct linux_prom64_ranges *rng = &ranges[i];
-               u64 phys_addr = regs->phys_addr;
-
-               if (phys_addr >= rng->ot_child_base &&
-                   phys_addr < (rng->ot_child_base + rng->or_size)) {
-                       regs->phys_addr -= rng->ot_child_base;
-                       regs->phys_addr += rng->ot_parent_base;
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
 struct all_info {
        struct fb_info info;
        struct ffb_par par;
        u32 pseudo_palette[256];
-       struct list_head list;
 };
-static LIST_HEAD(ffb_list);
 
-static void ffb_init_one(int node, int parent)
+static int ffb_init_one(struct of_device *op)
 {
-       struct linux_prom64_registers regs[2*PROMREG_MAX];
-       struct ffb_fbc *fbc;
-       struct ffb_dac *dac;
+       struct device_node *dp = op->node;
+       struct ffb_fbc __iomem *fbc;
+       struct ffb_dac __iomem *dac;
        struct all_info *all;
+       int err;
 
-       if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) {
-               printk("ffb: Cannot get reg device node property.\n");
-               return;
-       }
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
-       if (ffb_apply_upa_parent_ranges(parent, &regs[0])) {
-               printk("ffb: Cannot apply parent ranges to regs.\n");
-               return;
+       spin_lock_init(&all->par.lock);
+       all->par.fbc = of_ioremap(&op->resource[2], 0,
+                                 sizeof(struct ffb_fbc), "ffb fbc");
+       if (!all->par.fbc) {
+               kfree(all);
+               return -ENOMEM;
        }
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "ffb: Cannot allocate memory.\n");
-               return;
+       all->par.dac = of_ioremap(&op->resource[1], 0,
+                                 sizeof(struct ffb_dac), "ffb dac");
+       if (!all->par.dac) {
+               of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
+               kfree(all);
+               return -ENOMEM;
        }
-       memset(all, 0, sizeof(*all));
-
-       INIT_LIST_HEAD(&all->list);     
 
-       spin_lock_init(&all->par.lock);
-       all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
-       all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
        all->par.rop_cache = FFB_ROP_NEW;
-       all->par.physbase = regs[0].phys_addr;
-       all->par.prom_node = node;
-       all->par.prom_parent_node = parent;
+       all->par.physbase = op->resource[0].start;
 
        /* Don't mention copyarea, so SCROLL_REDRAW is always
         * used.  It is the fastest on this chip.
@@ -968,7 +930,7 @@ static void ffb_init_one(int node, int parent)
        all->info.par = &all->par;
        all->info.pseudo_palette = all->pseudo_palette;
 
-       sbusfb_fill_var(&all->info.var, all->par.prom_node, 32);
+       sbusfb_fill_var(&all->info.var, dp->node, 32);
        all->par.fbsize = PAGE_ALIGN(all->info.var.xres *
                                     all->info.var.yres *
                                     4);
@@ -976,14 +938,13 @@ static void ffb_init_one(int node, int parent)
 
        all->info.var.accel_flags = FB_ACCELF_TEXT;
 
-       prom_getstring(node, "name", all->par.name, sizeof(all->par.name));
-       if (!strcmp(all->par.name, "SUNW,afb"))
+       if (!strcmp(dp->name, "SUNW,afb"))
                all->par.flags |= FFB_FLAG_AFB;
 
-       all->par.board_type = prom_getintdefault(node, "board_type", 0);
+       all->par.board_type = of_getintprop_default(dp, "board_type", 0);
 
        fbc = all->par.fbc;
-       if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
+       if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
                upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
 
        ffb_switch_from_graph(&all->par);
@@ -1008,81 +969,88 @@ static void ffb_init_one(int node, int parent)
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
                printk(KERN_ERR "ffb: Could not allocate color map.\n");
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
        ffb_init_fix(&all->info);
 
-       if (register_framebuffer(&all->info) < 0) {
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                printk(KERN_ERR "ffb: Could not register framebuffer.\n");
                fb_dealloc_cmap(&all->info.cmap);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &ffb_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("ffb: %s at %016lx type %d DAC %d\n",
+       printk("%s: %s at %016lx, type %d, DAC revision %d\n",
+              dp->full_name,
               ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
-              regs[0].phys_addr, all->par.board_type, all->par.dac_rev);
+              all->par.physbase, all->par.board_type, all->par.dac_rev);
+
+       return 0;
 }
 
-static void ffb_scan_siblings(int root)
+static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       int node, child;
-
-       child = prom_getchild(root);
-       for (node = prom_searchsiblings(child, "SUNW,ffb"); node;
-            node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb"))
-               ffb_init_one(node, root);
-       for (node = prom_searchsiblings(child, "SUNW,afb"); node;
-            node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb"))
-               ffb_init_one(node, root);
+       struct of_device *op = to_of_device(&dev->dev);
+
+       return ffb_init_one(op);
 }
 
-int __init ffb_init(void)
+static int __devexit ffb_remove(struct of_device *dev)
 {
-       int root;
+       struct all_info *all = dev_get_drvdata(&dev->dev);
 
-       if (fb_get_options("ffb", NULL))
-               return -ENODEV;
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
 
-       ffb_scan_siblings(prom_root_node);
+       of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
+       of_iounmap(all->par.dac, sizeof(struct ffb_dac));
 
-       root = prom_getchild(prom_root_node);
-       for (root = prom_searchsiblings(root, "upa"); root;
-            root = prom_searchsiblings(prom_getsibling(root), "upa"))
-               ffb_scan_siblings(root);
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit ffb_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id ffb_match[] = {
+       {
+               .name = "SUNW,ffb",
+       },
+       {
+               .name = "SUNW,afb",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ffb_match);
+
+static struct of_platform_driver ffb_driver = {
+       .name           = "ffb",
+       .match_table    = ffb_match,
+       .probe          = ffb_probe,
+       .remove         = __devexit_p(ffb_remove),
+};
 
-       list_for_each_safe(pos, tmp, &ffb_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+int __init ffb_init(void)
+{
+       if (fb_get_options("ffb", NULL))
+               return -ENODEV;
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+       return of_register_driver(&ffb_driver, &of_bus_type);
 }
 
-int __init
-ffb_setup(char *arg)
+void __exit ffb_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&ffb_driver);
 }
 
 module_init(ffb_init);
-
-#ifdef MODULE
 module_exit(ffb_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index a23cfdb9d826391ff5d4007fb33f884da0d53f1c..f3a24338d9ac830b0b67051fe5e76f09979ee611 100644 (file)
@@ -1,6 +1,6 @@
 /* leo.c: LEO frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
  *
@@ -18,8 +18,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -80,10 +80,10 @@ static struct fb_ops leo_ops = {
 
 struct leo_cursor {
        u8              xxx0[16];
-       volatile u32    cur_type;
-       volatile u32    cur_misc;
-       volatile u32    cur_cursxy;
-       volatile u32    cur_data;
+       u32     cur_type;
+       u32     cur_misc;
+       u32     cur_cursxy;
+       u32     cur_data;
 };
 
 #define LEO_KRN_TYPE_CLUT0     0x00001000
@@ -99,27 +99,27 @@ struct leo_cursor {
 #define LEO_KRN_CSR_UNK2       0x00000001
 
 struct leo_lx_krn {
-       volatile u32    krn_type;
-       volatile u32    krn_csr;
-       volatile u32    krn_value;
+       u32     krn_type;
+       u32     krn_csr;
+       u32     krn_value;
 };
 
 struct leo_lc_ss0_krn {
-       volatile u32    misc;
+       u32     misc;
        u8              xxx0[0x800-4];
-       volatile u32    rev;
+       u32     rev;
 };
 
 struct leo_lc_ss0_usr {
-       volatile u32    csr;
-       volatile u32    addrspace;
-       volatile u32    fontmsk;
-       volatile u32    fontt;
-       volatile u32    extent;
-       volatile u32    src;
+       u32     csr;
+       u32     addrspace;
+       u32     fontmsk;
+       u32     fontt;
+       u32     extent;
+       u32     src;
        u32             dst;
-       volatile u32    copy;
-       volatile u32    fill;
+       u32     copy;
+       u32     fill;
 };
 
 struct leo_lc_ss1_krn {
@@ -132,47 +132,47 @@ struct leo_lc_ss1_usr {
 
 struct leo_ld {
        u8              xxx0[0xe00];
-       volatile u32    csr;
-       volatile u32    wid;
-       volatile u32    wmask;
-       volatile u32    widclip;
-       volatile u32    vclipmin;
-       volatile u32    vclipmax;
-       volatile u32    pickmin;        /* SS1 only */
-       volatile u32    pickmax;        /* SS1 only */
-       volatile u32    fg;
-       volatile u32    bg;
-       volatile u32    src;            /* Copy/Scroll (SS0 only) */
-       volatile u32    dst;            /* Copy/Scroll/Fill (SS0 only) */
-       volatile u32    extent;         /* Copy/Scroll/Fill size (SS0 only) */
+       u32     csr;
+       u32     wid;
+       u32     wmask;
+       u32     widclip;
+       u32     vclipmin;
+       u32     vclipmax;
+       u32     pickmin;        /* SS1 only */
+       u32     pickmax;        /* SS1 only */
+       u32     fg;
+       u32     bg;
+       u32     src;            /* Copy/Scroll (SS0 only) */
+       u32     dst;            /* Copy/Scroll/Fill (SS0 only) */
+       u32     extent;         /* Copy/Scroll/Fill size (SS0 only) */
        u32             xxx1[3];
-       volatile u32    setsem;         /* SS1 only */
-       volatile u32    clrsem;         /* SS1 only */
-       volatile u32    clrpick;        /* SS1 only */
-       volatile u32    clrdat;         /* SS1 only */
-       volatile u32    alpha;          /* SS1 only */
+       u32     setsem;         /* SS1 only */
+       u32     clrsem;         /* SS1 only */
+       u32     clrpick;        /* SS1 only */
+       u32     clrdat;         /* SS1 only */
+       u32     alpha;          /* SS1 only */
        u8              xxx2[0x2c];
-       volatile u32    winbg;
-       volatile u32    planemask;
-       volatile u32    rop;
-       volatile u32    z;
-       volatile u32    dczf;           /* SS1 only */
-       volatile u32    dczb;           /* SS1 only */
-       volatile u32    dcs;            /* SS1 only */
-       volatile u32    dczs;           /* SS1 only */
-       volatile u32    pickfb;         /* SS1 only */
-       volatile u32    pickbb;         /* SS1 only */
-       volatile u32    dcfc;           /* SS1 only */
-       volatile u32    forcecol;       /* SS1 only */
-       volatile u32    door[8];        /* SS1 only */
-       volatile u32    pick[5];        /* SS1 only */
+       u32     winbg;
+       u32     planemask;
+       u32     rop;
+       u32     z;
+       u32     dczf;           /* SS1 only */
+       u32     dczb;           /* SS1 only */
+       u32     dcs;            /* SS1 only */
+       u32     dczs;           /* SS1 only */
+       u32     pickfb;         /* SS1 only */
+       u32     pickbb;         /* SS1 only */
+       u32     dcfc;           /* SS1 only */
+       u32     forcecol;       /* SS1 only */
+       u32     door[8];        /* SS1 only */
+       u32     pick[5];        /* SS1 only */
 };
 
 #define LEO_SS1_MISC_ENABLE    0x00000001
 #define LEO_SS1_MISC_STEREO    0x00000002
 struct leo_ld_ss1 {
-       u8              xxx0[0xef4];
-       volatile u32    ss1_misc;
+       u8      xxx0[0xef4];
+       u32     ss1_misc;
 };
 
 struct leo_ld_gbl {
@@ -193,9 +193,8 @@ struct leo_par {
 #define LEO_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
@@ -368,8 +367,7 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(leo_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
@@ -385,11 +383,9 @@ static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  */
 
 static void
-leo_init_fix(struct fb_info *info)
+leo_init_fix(struct fb_info *info, struct device_node *dp)
 {
-       struct leo_par *par = (struct leo_par *)info->par;
-
-       strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
+       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_TRUECOLOR;
@@ -532,60 +528,74 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
 struct all_info {
        struct fb_info info;
        struct leo_par par;
-       struct list_head list;
 };
-static LIST_HEAD(leo_list);
 
-static void leo_init_one(struct sbus_dev *sdev)
+static void leo_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       int linebytes;
+       if (all->par.lc_ss0_usr)
+               of_iounmap(all->par.lc_ss0_usr, 0x1000);
+       if (all->par.ld_ss0)
+               of_iounmap(all->par.ld_ss0, 0x1000);
+       if (all->par.ld_ss1)
+               of_iounmap(all->par.ld_ss1, 0x1000);
+       if (all->par.lx_krn)
+               of_iounmap(all->par.lx_krn, 0x1000);
+       if (all->par.cursor)
+               of_iounmap(all->par.cursor, sizeof(struct leo_cursor));
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, 0x800000);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "leo: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit leo_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.physbase = sdev->reg_addrs[0].phys_addr;
+       all->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 32);
+       sbusfb_fill_var(&all->info.var, dp->node, 32);
        leo_fixup_var_rgb(&all->info.var);
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-#ifdef CONFIG_SPARC32
-       all->info.screen_base = (char __iomem *)
-               prom_getintdefault(sdev->prom_node, "address", 0);
-#endif
-       if (!all->info.screen_base)
-               all->info.screen_base = 
-                       sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0,
-                                    0x800000, "leo ram");
-
        all->par.lc_ss0_usr =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR,
-                            0x1000, "leolc ss0usr");
+               of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR,
+                          0x1000, "leolc ss0usr");
        all->par.ld_ss0 =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0,
-                            0x1000, "leold ss0");
+               of_ioremap(&op->resource[0], LEO_OFF_LD_SS0,
+                          0x1000, "leold ss0");
        all->par.ld_ss1 =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1,
-                            0x1000, "leold ss1");
+               of_ioremap(&op->resource[0], LEO_OFF_LD_SS1,
+                          0x1000, "leold ss1");
        all->par.lx_krn =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN,
-                            0x1000, "leolx krn");
+               of_ioremap(&op->resource[0], LEO_OFF_LX_KRN,
+                          0x1000, "leolx krn");
        all->par.cursor =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR,
-                            sizeof(struct leo_cursor), "leolx cursor");
+               of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR,
+                          sizeof(struct leo_cursor), "leolx cursor");
+       all->info.screen_base = 
+               of_ioremap(&op->resource[0], LEO_OFF_SS0,
+                          0x800000, "leo ram");
+       if (!all->par.lc_ss0_usr ||
+           !all->par.ld_ss0 ||
+           !all->par.ld_ss1 ||
+           !all->par.lx_krn ||
+           !all->par.cursor ||
+           !all->info.screen_base) {
+               leo_unmap_regs(all);
+               kfree(all);
+               return -ENOMEM;
+       }
 
        all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
        all->info.fbops = &leo_ops;
@@ -597,69 +607,85 @@ static void leo_init_one(struct sbus_dev *sdev)
        leo_blank(0, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "leo: Could not allocate color map.\n");
+               leo_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;;
        }
 
-       leo_init_fix(&all->info);
+       leo_init_fix(&all->info, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "leo: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               leo_unmap_regs(all);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &leo_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: leo at %lx:%lx\n",
+              dp->full_name,
+              all->par.which_io, all->par.physbase);
 
-       printk("leo: %s at %lx:%lx\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+       return 0;
 }
 
-int __init leo_init(void)
+static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("leofb", NULL))
-               return -ENODEV;
+       return leo_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "leo"))
-                       leo_init_one(sdev);
-       }
+static int __devexit leo_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       leo_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit leo_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id leo_match[] = {
+       {
+               .name = "leo",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, leo_match);
+
+static struct of_platform_driver leo_driver = {
+       .name           = "leo",
+       .match_table    = leo_match,
+       .probe          = leo_probe,
+       .remove         = __devexit_p(leo_remove),
+};
 
-       list_for_each_safe(pos, tmp, &leo_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static int __init leo_init(void)
+{
+       if (fb_get_options("leofb", NULL))
+               return -ENODEV;
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+       return of_register_driver(&leo_driver, &of_bus_type);
 }
 
-int __init
-leo_setup(char *arg)
+static void __exit leo_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&leo_driver);
 }
 
 module_init(leo_init);
-#ifdef MODULE
 module_exit(leo_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for LEO chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 0d19575053598b665a6d425805672860e614bb6b..56ac51d6a7f3f0380b0a76dc7f86ed28948cf8b3 100644 (file)
@@ -1,6 +1,6 @@
 /* p9100.c: P9100 frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
  *
  * Driver layout based loosely on tgafb.c, see that file for credits.
@@ -17,8 +17,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -72,60 +72,60 @@ static struct fb_ops p9100_ops = {
 
 struct p9100_regs {
        /* Registers for the system control */
-       volatile u32 sys_base;
-       volatile u32 sys_config;
-       volatile u32 sys_intr;
-       volatile u32 sys_int_ena;
-       volatile u32 sys_alt_rd;
-       volatile u32 sys_alt_wr;
-       volatile u32 sys_xxx[58];
+       u32 sys_base;
+       u32 sys_config;
+       u32 sys_intr;
+       u32 sys_int_ena;
+       u32 sys_alt_rd;
+       u32 sys_alt_wr;
+       u32 sys_xxx[58];
 
        /* Registers for the video control */
-       volatile u32 vid_base;
-       volatile u32 vid_hcnt;
-       volatile u32 vid_htotal;
-       volatile u32 vid_hsync_rise;
-       volatile u32 vid_hblank_rise;
-       volatile u32 vid_hblank_fall;
-       volatile u32 vid_hcnt_preload;
-       volatile u32 vid_vcnt;
-       volatile u32 vid_vlen;
-       volatile u32 vid_vsync_rise;
-       volatile u32 vid_vblank_rise;
-       volatile u32 vid_vblank_fall;
-       volatile u32 vid_vcnt_preload;
-       volatile u32 vid_screenpaint_addr;
-       volatile u32 vid_screenpaint_timectl1;
-       volatile u32 vid_screenpaint_qsfcnt;
-       volatile u32 vid_screenpaint_timectl2;
-       volatile u32 vid_xxx[15];
+       u32 vid_base;
+       u32 vid_hcnt;
+       u32 vid_htotal;
+       u32 vid_hsync_rise;
+       u32 vid_hblank_rise;
+       u32 vid_hblank_fall;
+       u32 vid_hcnt_preload;
+       u32 vid_vcnt;
+       u32 vid_vlen;
+       u32 vid_vsync_rise;
+       u32 vid_vblank_rise;
+       u32 vid_vblank_fall;
+       u32 vid_vcnt_preload;
+       u32 vid_screenpaint_addr;
+       u32 vid_screenpaint_timectl1;
+       u32 vid_screenpaint_qsfcnt;
+       u32 vid_screenpaint_timectl2;
+       u32 vid_xxx[15];
 
        /* Registers for the video control */
-       volatile u32 vram_base;
-       volatile u32 vram_memcfg;
-       volatile u32 vram_refresh_pd;
-       volatile u32 vram_refresh_cnt;
-       volatile u32 vram_raslo_max;
-       volatile u32 vram_raslo_cur;
-       volatile u32 pwrup_cfg;
-       volatile u32 vram_xxx[25];
+       u32 vram_base;
+       u32 vram_memcfg;
+       u32 vram_refresh_pd;
+       u32 vram_refresh_cnt;
+       u32 vram_raslo_max;
+       u32 vram_raslo_cur;
+       u32 pwrup_cfg;
+       u32 vram_xxx[25];
 
        /* Registers for IBM RGB528 Palette */
-       volatile u32 ramdac_cmap_wridx; 
-       volatile u32 ramdac_palette_data;
-       volatile u32 ramdac_pixel_mask;
-       volatile u32 ramdac_palette_rdaddr;
-       volatile u32 ramdac_idx_lo;
-       volatile u32 ramdac_idx_hi;
-       volatile u32 ramdac_idx_data;
-       volatile u32 ramdac_idx_ctl;
-       volatile u32 ramdac_xxx[1784];
+       u32 ramdac_cmap_wridx; 
+       u32 ramdac_palette_data;
+       u32 ramdac_pixel_mask;
+       u32 ramdac_palette_rdaddr;
+       u32 ramdac_idx_lo;
+       u32 ramdac_idx_hi;
+       u32 ramdac_idx_data;
+       u32 ramdac_idx_ctl;
+       u32 ramdac_xxx[1784];
 };
 
 struct p9100_cmd_parameng {
-       volatile u32 parameng_status;
-       volatile u32 parameng_bltcmd;
-       volatile u32 parameng_quadcmd;
+       u32 parameng_status;
+       u32 parameng_bltcmd;
+       u32 parameng_quadcmd;
 };
 
 struct p9100_par {
@@ -136,9 +136,8 @@ struct p9100_par {
 #define P9100_FLAG_BLANKED     0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 /**
@@ -227,8 +226,7 @@ static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(p9100_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
@@ -245,12 +243,9 @@ static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
  *  Initialisation
  */
 
-static void
-p9100_init_fix(struct fb_info *info, int linebytes)
+static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
 {
-       struct p9100_par *par = (struct p9100_par *)info->par;
-
-       strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
+       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -263,121 +258,137 @@ p9100_init_fix(struct fb_info *info, int linebytes)
 struct all_info {
        struct fb_info info;
        struct p9100_par par;
-       struct list_head list;
 };
-static LIST_HEAD(p9100_list);
 
-static void p9100_init_one(struct sbus_dev *sdev)
+static int __devinit p9100_init_one(struct of_device *op)
 {
+       struct device_node *dp = op->node;
        struct all_info *all;
-       int linebytes;
-
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "p9100: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
        /* This is the framebuffer and the only resource apps can mmap.  */
-       all->par.physbase = sdev->reg_addrs[2].phys_addr;
+       all->par.physbase = op->resource[2].start;
+       all->par.which_io = op->resource[2].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.regs = sbus_ioremap(&sdev->resource[0], 0,
-                            sizeof(struct p9100_regs), "p9100 regs");
+       all->par.regs = of_ioremap(&op->resource[0], 0,
+                                  sizeof(struct p9100_regs), "p9100 regs");
+       if (!all->par.regs) {
+               kfree(all);
+               return -ENOMEM;
+       }
 
        all->info.flags = FBINFO_DEFAULT;
        all->info.fbops = &p9100_ops;
-#ifdef CONFIG_SPARC32
-       all->info.screen_base = (char __iomem *)
-               prom_getintdefault(sdev->prom_node, "address", 0);
-#endif
-       if (!all->info.screen_base)
-               all->info.screen_base = sbus_ioremap(&sdev->resource[2], 0,
-                                    all->par.fbsize, "p9100 ram");
+       all->info.screen_base = of_ioremap(&op->resource[2], 0,
+                                          all->par.fbsize, "p9100 ram");
+       if (!all->info.screen_base) {
+               of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+               kfree(all);
+               return -ENOMEM;
+       }
        all->info.par = &all->par;
 
        p9100_blank(0, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "p9100: Could not allocate color map.\n");
+               of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
-       p9100_init_fix(&all->info, linebytes);
+       p9100_init_fix(&all->info, linebytes, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "p9100: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return err;
        }
        fb_set_cmap(&all->info.cmap, &all->info);
 
-       list_add(&all->list, &p9100_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: p9100 at %lx:%lx\n",
+              dp->full_name,
+              all->par.which_io, all->par.physbase);
 
-       printk("p9100: %s at %lx:%lx\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+       return 0;
 }
 
-int __init p9100_init(void)
+static int __devinit p9100_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("p9100fb", NULL))
-               return -ENODEV;
+       return p9100_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "p9100"))
-                       p9100_init_one(sdev);
-       }
+static int __devexit p9100_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+       of_iounmap(all->info.screen_base, all->par.fbsize);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit p9100_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id p9100_match[] = {
+       {
+               .name = "p9100",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, p9100_match);
 
-       list_for_each_safe(pos, tmp, &p9100_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver p9100_driver = {
+       .name           = "p9100",
+       .match_table    = p9100_match,
+       .probe          = p9100_probe,
+       .remove         = __devexit_p(p9100_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+static int __init p9100_init(void)
+{
+       if (fb_get_options("p9100fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&p9100_driver, &of_bus_type);
 }
 
-int __init
-p9100_setup(char *arg)
+static void __exit p9100_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&p9100_driver);
 }
 
 module_init(p9100_init);
-
-#ifdef MODULE
 module_exit(p9100_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 95b918229d9b13e6f35879d39ccc78924f43ec7c..6990ab11cd06ef184bee2ea364885ae6c7741a61 100644 (file)
@@ -1,6 +1,6 @@
 /* tcx.c: TCX frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -77,32 +77,32 @@ static struct fb_ops tcx_ops = {
 
 /* The contents are unknown */
 struct tcx_tec {
-       volatile u32 tec_matrix;
-       volatile u32 tec_clip;
-       volatile u32 tec_vdc;
+       u32 tec_matrix;
+       u32 tec_clip;
+       u32 tec_vdc;
 };
 
 struct tcx_thc {
-       volatile u32 thc_rev;
+       u32 thc_rev;
         u32 thc_pad0[511];
-       volatile u32 thc_hs;            /* hsync timing */
-       volatile u32 thc_hsdvs;
-       volatile u32 thc_hd;
-       volatile u32 thc_vs;            /* vsync timing */
-       volatile u32 thc_vd;
-       volatile u32 thc_refresh;
-       volatile u32 thc_misc;
+       u32 thc_hs;             /* hsync timing */
+       u32 thc_hsdvs;
+       u32 thc_hd;
+       u32 thc_vs;             /* vsync timing */
+       u32 thc_vd;
+       u32 thc_refresh;
+       u32 thc_misc;
        u32 thc_pad1[56];
-       volatile u32 thc_cursxy;        /* cursor x,y position (16 bits each) */
-       volatile u32 thc_cursmask[32];  /* cursor mask bits */
-       volatile u32 thc_cursbits[32];  /* what to show where mask enabled */
+       u32 thc_cursxy; /* cursor x,y position (16 bits each) */
+       u32 thc_cursmask[32];   /* cursor mask bits */
+       u32 thc_cursbits[32];   /* what to show where mask enabled */
 };
 
 struct bt_regs {
-       volatile u32 addr;
-       volatile u32 color_map;
-       volatile u32 control;
-       volatile u32 cursor;
+       u32 addr;
+       u32 color_map;
+       u32 control;
+       u32 cursor;
 };
 
 #define TCX_MMAP_ENTRIES 14
@@ -112,24 +112,23 @@ struct tcx_par {
        struct bt_regs          __iomem *bt;
        struct tcx_thc          __iomem *thc;
        struct tcx_tec          __iomem *tec;
-       volatile u32            __iomem *cplane;
+       u32                     __iomem *cplane;
 
        u32                     flags;
 #define TCX_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
 
        struct sbus_mmap_map    mmap_map[TCX_MMAP_ENTRIES];
        int                     lowdepth;
-
-       struct sbus_dev         *sdev;
 };
 
 /* Reset control plane so that WID is 8-bit plane. */
 static void __tcx_set_control_plane (struct tcx_par *par)
 {
-       volatile u32 __iomem *p, *pend;
+       u32 __iomem *p, *pend;
         
        if (par->lowdepth)
                return;
@@ -307,8 +306,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(par->mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
@@ -350,48 +348,71 @@ tcx_init_fix(struct fb_info *info, int linebytes)
 struct all_info {
        struct fb_info info;
        struct tcx_par par;
-       struct list_head list;
 };
-static LIST_HEAD(tcx_list);
 
-static void tcx_init_one(struct sbus_dev *sdev)
+static void tcx_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       int linebytes, i;
+       if (all->par.tec)
+               of_iounmap(all->par.tec, sizeof(struct tcx_tec));
+       if (all->par.thc)
+               of_iounmap(all->par.thc, sizeof(struct tcx_thc));
+       if (all->par.bt)
+               of_iounmap(all->par.bt, sizeof(struct bt_regs));
+       if (all->par.cplane)
+               of_iounmap(all->par.cplane, all->par.fbsize * sizeof(u32));
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, all->par.fbsize);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "tcx: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit tcx_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int linebytes, i, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit");
+       all->par.lowdepth =
+               (of_find_property(dp, "tcx-8-bit", NULL) != NULL);
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.tec = sbus_ioremap(&sdev->resource[7], 0,
-                            sizeof(struct tcx_tec), "tcx tec");
-       all->par.thc = sbus_ioremap(&sdev->resource[9], 0,
-                            sizeof(struct tcx_thc), "tcx thc");
-       all->par.bt = sbus_ioremap(&sdev->resource[8], 0,
-                            sizeof(struct bt_regs), "tcx dac");
+       all->par.tec = of_ioremap(&op->resource[7], 0,
+                                 sizeof(struct tcx_tec), "tcx tec");
+       all->par.thc = of_ioremap(&op->resource[9], 0,
+                                 sizeof(struct tcx_thc), "tcx thc");
+       all->par.bt = of_ioremap(&op->resource[8], 0,
+                                sizeof(struct bt_regs), "tcx dac");
+       all->info.screen_base = of_ioremap(&op->resource[0], 0,
+                                          all->par.fbsize, "tcx ram");
+       if (!all->par.tec || !all->par.thc ||
+           !all->par.bt || !all->info.screen_base) {
+               tcx_unmap_regs(all);
+               kfree(all);
+               return -ENOMEM;
+       }
+
        memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map));
        if (!all->par.lowdepth) {
-               all->par.cplane = sbus_ioremap(&sdev->resource[4], 0,
-                                    all->par.fbsize * sizeof(u32), "tcx cplane");
+               all->par.cplane = of_ioremap(&op->resource[4], 0,
+                                            all->par.fbsize * sizeof(u32),
+                                            "tcx cplane");
+               if (!all->par.cplane) {
+                       tcx_unmap_regs(all);
+                       kfree(all);
+                       return -ENOMEM;
+               }
        } else {
                all->par.mmap_map[1].size = SBUS_MMAP_EMPTY;
                all->par.mmap_map[4].size = SBUS_MMAP_EMPTY;
@@ -400,6 +421,8 @@ static void tcx_init_one(struct sbus_dev *sdev)
        }
 
        all->par.physbase = 0;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
+
        for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
                int j;
 
@@ -416,18 +439,11 @@ static void tcx_init_one(struct sbus_dev *sdev)
                        j = i;
                        break;
                };
-               all->par.mmap_map[i].poff = sdev->reg_addrs[j].phys_addr;
+               all->par.mmap_map[i].poff = op->resource[j].start;
        }
 
        all->info.flags = FBINFO_DEFAULT;
        all->info.fbops = &tcx_ops;
-#ifdef CONFIG_SPARC32
-       all->info.screen_base = (char __iomem *)
-               prom_getintdefault(sdev->prom_node, "address", 0);
-#endif
-       if (!all->info.screen_base)
-               all->info.screen_base = sbus_ioremap(&sdev->resource[0], 0,
-                                    all->par.fbsize, "tcx ram");
        all->info.par = &all->par;
 
        /* Initialize brooktree DAC. */
@@ -445,72 +461,88 @@ static void tcx_init_one(struct sbus_dev *sdev)
        tcx_blank(FB_BLANK_UNBLANK, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "tcx: Could not allocate color map.\n");
+               tcx_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
        fb_set_cmap(&all->info.cmap, &all->info);
        tcx_init_fix(&all->info, linebytes);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "tcx: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               tcx_unmap_regs(all);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &tcx_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("tcx: %s at %lx:%lx, %s\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr,
+       printk("%s: TCX at %lx:%lx, %s\n",
+              dp->full_name,
+              all->par.which_io,
+              op->resource[0].start,
               all->par.lowdepth ? "8-bit only" : "24-bit depth");
+
+       return 0;
 }
 
-int __init tcx_init(void)
+static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("tcxfb", NULL))
-               return -ENODEV;
+       return tcx_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "SUNW,tcx"))
-                       tcx_init_one(sdev);
-       }
+static int __devexit tcx_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       tcx_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit tcx_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id tcx_match[] = {
+       {
+               .name = "SUNW,tcx",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, tcx_match);
 
-       list_for_each_safe(pos, tmp, &tcx_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver tcx_driver = {
+       .name           = "tcx",
+       .match_table    = tcx_match,
+       .probe          = tcx_probe,
+       .remove         = __devexit_p(tcx_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+int __init tcx_init(void)
+{
+       if (fb_get_options("tcxfb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&tcx_driver, &of_bus_type);
 }
 
-int __init
-tcx_setup(char *arg)
+void __exit tcx_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&tcx_driver);
 }
 
 module_init(tcx_init);
-
-#ifdef MODULE
 module_exit(tcx_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for TCX chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index d0ea6bfccf29a6071144919b44e3b31f064ed879..89135428a539184580b2b0305ec46f6e7d5bfa86 100644 (file)
@@ -66,7 +66,6 @@ obj-$(CONFIG_MSDOS_FS)                += msdos/
 obj-$(CONFIG_VFAT_FS)          += vfat/
 obj-$(CONFIG_BFS_FS)           += bfs/
 obj-$(CONFIG_ISO9660_FS)       += isofs/
-obj-$(CONFIG_DEVFS_FS)         += devfs/
 obj-$(CONFIG_HFSPLUS_FS)       += hfsplus/ # Before hfs to find wrapped HFS+
 obj-$(CONFIG_HFS_FS)           += hfs/
 obj-$(CONFIG_VXFS_FS)          += freevxfs/
index 7f7600e2381cdafab5c360101b6c2b9573b2765d..909cb0595b4e5279a54176cf52e2a2287a4c0bef 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/major.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 #include <linux/highmem.h>
 #include <linux/blkdev.h>
index f3418f7a6e9d9da9bf894840cd23eba9be77d5b7..97986635b641393dd1b39cfc43eb4acdc1dbfc4e 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/seq_file.h>
 
 #include <linux/kobject.h>
index 7caee8d8ea3b9a24656f40a20c247986f796d39f..803aacf0d49c29576252dcbe2aa2ff8e73d9e5f5 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/file.h>
@@ -365,22 +364,12 @@ static int init_coda_psdev(void)
                err = PTR_ERR(coda_psdev_class);
                goto out_chrdev;
        }               
-       devfs_mk_dir ("coda");
-       for (i = 0; i < MAX_CODADEVS; i++) {
+       for (i = 0; i < MAX_CODADEVS; i++)
                class_device_create(coda_psdev_class, NULL,
                                MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i);
-               err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
-                               S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
-               if (err)
-                       goto out_class;
-       }
        coda_sysctl_init();
        goto out;
 
-out_class:
-       for (i = 0; i < MAX_CODADEVS; i++) 
-               class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
-       class_destroy(coda_psdev_class);
 out_chrdev:
        unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
 out:
@@ -419,12 +408,9 @@ static int __init init_coda(void)
        }
        return 0;
 out:
-       for (i = 0; i < MAX_CODADEVS; i++) {
+       for (i = 0; i < MAX_CODADEVS; i++)
                class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
-               devfs_remove("coda/%d", i);
-       }
        class_destroy(coda_psdev_class);
-       devfs_remove("coda");
        unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
        coda_sysctl_clean();
 out1:
@@ -441,12 +427,9 @@ static void __exit exit_coda(void)
         if ( err != 0 ) {
                 printk("coda: failed to unregister filesystem\n");
         }
-       for (i = 0; i < MAX_CODADEVS; i++) {
+       for (i = 0; i < MAX_CODADEVS; i++)
                class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
-               devfs_remove("coda/%d", i);
-       }
        class_destroy(coda_psdev_class);
-       devfs_remove("coda");
        unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
        coda_sysctl_clean();
        coda_destroy_inodecache();
index d8ecfedef18940ba28c0cd042d71ce6e2fe3515f..d8d50a70c58d65064931f6b0b5a8f2fa1beaf1a0 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/loop.h>
 #include <linux/auto_fs.h>
 #include <linux/auto_fs4.h>
-#include <linux/devfs_fs.h>
 #include <linux/tty.h>
 #include <linux/vt_kern.h>
 #include <linux/fb.h>
diff --git a/fs/devfs/Makefile b/fs/devfs/Makefile
deleted file mode 100644 (file)
index 6dd8d12..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for the linux devfs-filesystem routines.
-#
-
-obj-$(CONFIG_DEVFS_FS) += devfs.o
-
-devfs-objs := base.o util.o
-
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
deleted file mode 100644 (file)
index 51a97f1..0000000
+++ /dev/null
@@ -1,2836 +0,0 @@
-/*  devfs (Device FileSystem) driver.
-
-    Copyright (C) 1998-2002  Richard Gooch
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
-    The postal address is:
-      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-
-    ChangeLog
-
-    19980110   Richard Gooch <rgooch@atnf.csiro.au>
-               Original version.
-  v0.1
-    19980111   Richard Gooch <rgooch@atnf.csiro.au>
-               Created per-fs inode table rather than using inode->u.generic_ip
-  v0.2
-    19980111   Richard Gooch <rgooch@atnf.csiro.au>
-               Created .epoch inode which has a ctime of 0.
-              Fixed loss of named pipes when dentries lost.
-              Fixed loss of inode data when devfs_register() follows mknod().
-  v0.3
-    19980111   Richard Gooch <rgooch@atnf.csiro.au>
-               Fix for when compiling with CONFIG_KERNELD.
-    19980112   Richard Gooch <rgooch@atnf.csiro.au>
-               Fix for readdir() which sometimes didn't show entries.
-              Added <<tolerant>> option to <devfs_register>.
-  v0.4
-    19980113   Richard Gooch <rgooch@atnf.csiro.au>
-               Created <devfs_fill_file> function.
-  v0.5
-    19980115   Richard Gooch <rgooch@atnf.csiro.au>
-               Added subdirectory support. Major restructuring.
-    19980116   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixed <find_by_dev> to not search major=0,minor=0.
-              Added symlink support.
-  v0.6
-    19980120   Richard Gooch <rgooch@atnf.csiro.au>
-               Created <devfs_mk_dir> function and support directory unregister
-    19980120   Richard Gooch <rgooch@atnf.csiro.au>
-               Auto-ownership uses real uid/gid rather than effective uid/gid.
-  v0.7
-    19980121   Richard Gooch <rgooch@atnf.csiro.au>
-               Supported creation of sockets.
-  v0.8
-    19980122   Richard Gooch <rgooch@atnf.csiro.au>
-               Added DEVFS_FL_HIDE_UNREG flag.
-              Interface change to <devfs_mk_symlink>.
-               Created <devfs_symlink> to support symlink(2).
-  v0.9
-    19980123   Richard Gooch <rgooch@atnf.csiro.au>
-               Added check to <devfs_fill_file> to check inode is in devfs.
-              Added optional traversal of symlinks.
-  v0.10
-    19980124   Richard Gooch <rgooch@atnf.csiro.au>
-               Created <devfs_get_flags> and <devfs_set_flags>.
-  v0.11
-    19980125   C. Scott Ananian <cananian@alumni.princeton.edu>
-               Created <devfs_find_handle>.
-    19980125   Richard Gooch <rgooch@atnf.csiro.au>
-               Allow removal of symlinks.
-  v0.12
-    19980125   Richard Gooch <rgooch@atnf.csiro.au>
-               Created <devfs_set_symlink_destination>.
-    19980126   Richard Gooch <rgooch@atnf.csiro.au>
-               Moved DEVFS_SUPER_MAGIC into header file.
-              Added DEVFS_FL_HIDE flag.
-              Created <devfs_get_maj_min>.
-              Created <devfs_get_handle_from_inode>.
-              Fixed minor bug in <find_by_dev>.
-    19980127   Richard Gooch <rgooch@atnf.csiro.au>
-              Changed interface to <find_by_dev>, <find_entry>,
-              <devfs_unregister>, <devfs_fill_file> and <devfs_find_handle>.
-              Fixed inode times when symlink created with symlink(2).
-  v0.13
-    19980129   C. Scott Ananian <cananian@alumni.princeton.edu>
-               Exported <devfs_set_symlink_destination>, <devfs_get_maj_min>
-              and <devfs_get_handle_from_inode>.
-    19980129   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_unlink> to support unlink(2).
-  v0.14
-    19980129   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed kerneld support for entries in devfs subdirectories.
-    19980130   Richard Gooch <rgooch@atnf.csiro.au>
-              Bugfixes in <call_kerneld>.
-  v0.15
-    19980207   Richard Gooch <rgooch@atnf.csiro.au>
-              Call kerneld when looking up unregistered entries.
-  v0.16
-    19980326   Richard Gooch <rgooch@atnf.csiro.au>
-              Modified interface to <devfs_find_handle> for symlink traversal.
-  v0.17
-    19980331   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed persistence bug with device numbers for manually created
-              device files.
-              Fixed problem with recreating symlinks with different content.
-  v0.18
-    19980401   Richard Gooch <rgooch@atnf.csiro.au>
-              Changed to CONFIG_KMOD.
-              Hide entries which are manually unlinked.
-              Always invalidate devfs dentry cache when registering entries.
-              Created <devfs_rmdir> to support rmdir(2).
-              Ensure directories created by <devfs_mk_dir> are visible.
-  v0.19
-    19980402   Richard Gooch <rgooch@atnf.csiro.au>
-              Invalidate devfs dentry cache when making directories.
-              Invalidate devfs dentry cache when removing entries.
-              Fixed persistence bug with fifos.
-  v0.20
-    19980421   Richard Gooch <rgooch@atnf.csiro.au>
-              Print process command when debugging kerneld/kmod.
-              Added debugging for register/unregister/change operations.
-    19980422   Richard Gooch <rgooch@atnf.csiro.au>
-              Added "devfs=" boot options.
-  v0.21
-    19980426   Richard Gooch <rgooch@atnf.csiro.au>
-              No longer lock/unlock superblock in <devfs_put_super>.
-              Drop negative dentries when they are released.
-              Manage dcache more efficiently.
-  v0.22
-    19980427   Richard Gooch <rgooch@atnf.csiro.au>
-              Added DEVFS_FL_AUTO_DEVNUM flag.
-  v0.23
-    19980430   Richard Gooch <rgooch@atnf.csiro.au>
-              No longer set unnecessary methods.
-  v0.24
-    19980504   Richard Gooch <rgooch@atnf.csiro.au>
-              Added PID display to <call_kerneld> debugging message.
-              Added "after" debugging message to <call_kerneld>.
-    19980519   Richard Gooch <rgooch@atnf.csiro.au>
-              Added "diread" and "diwrite" boot options.
-    19980520   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed persistence problem with permissions.
-  v0.25
-    19980602   Richard Gooch <rgooch@atnf.csiro.au>
-              Support legacy device nodes.
-              Fixed bug where recreated inodes were hidden.
-  v0.26
-    19980602   Richard Gooch <rgooch@atnf.csiro.au>
-              Improved debugging in <get_vfs_inode>.
-    19980607   Richard Gooch <rgooch@atnf.csiro.au>
-              No longer free old dentries in <devfs_mk_dir>.
-              Free all dentries for a given entry when deleting inodes.
-  v0.27
-    19980627   Richard Gooch <rgooch@atnf.csiro.au>
-              Limit auto-device numbering to majors 128 to 239.
-  v0.28
-    19980629   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed inode times persistence problem.
-  v0.29
-    19980704   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed spelling in <devfs_readlink> debug.
-              Fixed bug in <devfs_setup> parsing "dilookup".
-  v0.30
-    19980705   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed devfs inode leak when manually recreating inodes.
-              Fixed permission persistence problem when recreating inodes.
-  v0.31
-    19980727   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed harmless "unused variable" compiler warning.
-              Fixed modes for manually recreated device nodes.
-  v0.32
-    19980728   Richard Gooch <rgooch@atnf.csiro.au>
-              Added NULL devfs inode warning in <devfs_read_inode>.
-              Force all inode nlink values to 1.
-  v0.33
-    19980730   Richard Gooch <rgooch@atnf.csiro.au>
-              Added "dimknod" boot option.
-              Set inode nlink to 0 when freeing dentries.
-              Fixed modes for manually recreated symlinks.
-  v0.34
-    19980802   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed bugs in recreated directories and symlinks.
-  v0.35
-    19980806   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed bugs in recreated device nodes.
-    19980807   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed bug in currently unused <devfs_get_handle_from_inode>.
-              Defined new <devfs_handle_t> type.
-              Improved debugging when getting entries.
-              Fixed bug where directories could be emptied.
-  v0.36
-    19980809   Richard Gooch <rgooch@atnf.csiro.au>
-              Replaced dummy .epoch inode with .devfsd character device.
-    19980810   Richard Gooch <rgooch@atnf.csiro.au>
-              Implemented devfsd protocol revision 0.
-  v0.37
-    19980819   Richard Gooch <rgooch@atnf.csiro.au>
-              Added soothing message to warning in <devfs_d_iput>.
-  v0.38
-    19980829   Richard Gooch <rgooch@atnf.csiro.au>
-              Use GCC extensions for structure initialisations.
-              Implemented async open notification.
-              Incremented devfsd protocol revision to 1.
-  v0.39
-    19980908   Richard Gooch <rgooch@atnf.csiro.au>
-              Moved async open notification to end of <devfs_open>.
-  v0.40
-    19980910   Richard Gooch <rgooch@atnf.csiro.au>
-              Prepended "/dev/" to module load request.
-              Renamed <call_kerneld> to <call_kmod>.
-  v0.41
-    19980910   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed typo "AYSNC" -> "ASYNC".
-  v0.42
-    19980910   Richard Gooch <rgooch@atnf.csiro.au>
-              Added open flag for files.
-  v0.43
-    19980927   Richard Gooch <rgooch@atnf.csiro.au>
-              Set i_blocks=0 and i_blksize=1024 in <devfs_read_inode>.
-  v0.44
-    19981005   Richard Gooch <rgooch@atnf.csiro.au>
-              Added test for empty <<name>> in <devfs_find_handle>.
-              Renamed <generate_path> to <devfs_generate_path> and published.
-  v0.45
-    19981006   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_get_fops>.
-  v0.46
-    19981007   Richard Gooch <rgooch@atnf.csiro.au>
-              Limit auto-device numbering to majors 144 to 239.
-  v0.47
-    19981010   Richard Gooch <rgooch@atnf.csiro.au>
-              Updated <devfs_follow_link> for VFS change in 2.1.125.
-  v0.48
-    19981022   Richard Gooch <rgooch@atnf.csiro.au>
-              Created DEVFS_ FL_COMPAT flag.
-  v0.49
-    19981023   Richard Gooch <rgooch@atnf.csiro.au>
-              Created "nocompat" boot option.
-  v0.50
-    19981025   Richard Gooch <rgooch@atnf.csiro.au>
-              Replaced "mount" boot option with "nomount".
-  v0.51
-    19981110   Richard Gooch <rgooch@atnf.csiro.au>
-              Created "only" boot option.
-  v0.52
-    19981112   Richard Gooch <rgooch@atnf.csiro.au>
-              Added DEVFS_FL_REMOVABLE flag.
-  v0.53
-    19981114   Richard Gooch <rgooch@atnf.csiro.au>
-              Only call <scan_dir_for_removable> on first call to
-              <devfs_readdir>.
-  v0.54
-    19981205   Richard Gooch <rgooch@atnf.csiro.au>
-              Updated <devfs_rmdir> for VFS change in 2.1.131.
-  v0.55
-    19981218   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_mk_compat>.
-    19981220   Richard Gooch <rgooch@atnf.csiro.au>
-              Check for partitions on removable media in <devfs_lookup>.
-  v0.56
-    19990118   Richard Gooch <rgooch@atnf.csiro.au>
-              Added support for registering regular files.
-              Created <devfs_set_file_size>.
-              Update devfs inodes from entries if not changed through FS.
-  v0.57
-    19990124   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed <devfs_fill_file> to only initialise temporary inodes.
-              Trap for NULL fops in <devfs_register>.
-              Return -ENODEV in <devfs_fill_file> for non-driver inodes.
-  v0.58
-    19990126   Richard Gooch <rgooch@atnf.csiro.au>
-              Switched from PATH_MAX to DEVFS_PATHLEN.
-  v0.59
-    19990127   Richard Gooch <rgooch@atnf.csiro.au>
-              Created "nottycompat" boot option.
-  v0.60
-    19990318   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed <devfsd_read> to not overrun event buffer.
-  v0.61
-    19990329   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_auto_unregister>.
-  v0.62
-    19990330   Richard Gooch <rgooch@atnf.csiro.au>
-              Don't return unregistred entries in <devfs_find_handle>.
-              Panic in <devfs_unregister> if entry unregistered.
-    19990401   Richard Gooch <rgooch@atnf.csiro.au>
-              Don't panic in <devfs_auto_unregister> for duplicates.
-  v0.63
-    19990402   Richard Gooch <rgooch@atnf.csiro.au>
-              Don't unregister already unregistered entries in <unregister>.
-  v0.64
-    19990510   Richard Gooch <rgooch@atnf.csiro.au>
-              Disable warning messages when unable to read partition table for
-              removable media.
-  v0.65
-    19990512   Richard Gooch <rgooch@atnf.csiro.au>
-              Updated <devfs_lookup> for VFS change in 2.3.1-pre1.
-              Created "oops-on-panic" boot option.
-              Improved debugging in <devfs_register> and <devfs_unregister>.
-  v0.66
-    19990519   Richard Gooch <rgooch@atnf.csiro.au>
-              Added documentation for some functions.
-    19990525   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed "oops-on-panic" boot option: now always Oops.
-  v0.67
-    19990531   Richard Gooch <rgooch@atnf.csiro.au>
-              Improved debugging in <devfs_register>.
-  v0.68
-    19990604   Richard Gooch <rgooch@atnf.csiro.au>
-              Added "diunlink" and "nokmod" boot options.
-              Removed superfluous warning message in <devfs_d_iput>.
-  v0.69
-    19990611   Richard Gooch <rgooch@atnf.csiro.au>
-              Took account of change to <d_alloc_root>.
-  v0.70
-    19990614   Richard Gooch <rgooch@atnf.csiro.au>
-              Created separate event queue for each mounted devfs.
-              Removed <devfs_invalidate_dcache>.
-              Created new ioctl()s.
-              Incremented devfsd protocol revision to 3.
-              Fixed bug when re-creating directories: contents were lost.
-              Block access to inodes until devfsd updates permissions.
-    19990615   Richard Gooch <rgooch@atnf.csiro.au>
-              Support 2.2.x kernels.
-  v0.71
-    19990623   Richard Gooch <rgooch@atnf.csiro.au>
-              Switched to sending process uid/gid to devfsd.
-              Renamed <call_kmod> to <try_modload>.
-              Added DEVFSD_NOTIFY_LOOKUP event.
-    19990624   Richard Gooch <rgooch@atnf.csiro.au>
-              Added DEVFSD_NOTIFY_CHANGE event.
-              Incremented devfsd protocol revision to 4.
-  v0.72
-    19990713   Richard Gooch <rgooch@atnf.csiro.au>
-              Return EISDIR rather than EINVAL for read(2) on directories.
-  v0.73
-    19990809   Richard Gooch <rgooch@atnf.csiro.au>
-              Changed <devfs_setup> to new __init scheme.
-  v0.74
-    19990901   Richard Gooch <rgooch@atnf.csiro.au>
-              Changed remaining function declarations to new __init scheme.
-  v0.75
-    19991013   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_get_info>, <devfs_set_info>,
-              <devfs_get_first_child> and <devfs_get_next_sibling>.
-              Added <<dir>> parameter to <devfs_register>, <devfs_mk_compat>,
-              <devfs_mk_dir> and <devfs_find_handle>.
-              Work sponsored by SGI.
-  v0.76
-    19991017   Richard Gooch <rgooch@atnf.csiro.au>
-              Allow multiple unregistrations.
-              Work sponsored by SGI.
-  v0.77
-    19991026   Richard Gooch <rgooch@atnf.csiro.au>
-              Added major and minor number to devfsd protocol.
-              Incremented devfsd protocol revision to 5.
-              Work sponsored by SGI.
-  v0.78
-    19991030   Richard Gooch <rgooch@atnf.csiro.au>
-              Support info pointer for all devfs entry types.
-              Added <<info>> parameter to <devfs_mk_dir> and
-              <devfs_mk_symlink>.
-              Work sponsored by SGI.
-  v0.79
-    19991031   Richard Gooch <rgooch@atnf.csiro.au>
-              Support "../" when searching devfs namespace.
-              Work sponsored by SGI.
-  v0.80
-    19991101   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_get_unregister_slave>.
-              Work sponsored by SGI.
-  v0.81
-    19991103   Richard Gooch <rgooch@atnf.csiro.au>
-              Exported <devfs_get_parent>.
-              Work sponsored by SGI.
-  v0.82
-    19991104   Richard Gooch <rgooch@atnf.csiro.au>
-               Removed unused <devfs_set_symlink_destination>.
-    19991105   Richard Gooch <rgooch@atnf.csiro.au>
-               Do not hide entries from devfsd or children.
-              Removed DEVFS_ FL_TTY_COMPAT flag.
-              Removed "nottycompat" boot option.
-              Removed <devfs_mk_compat>.
-              Work sponsored by SGI.
-  v0.83
-    19991107   Richard Gooch <rgooch@atnf.csiro.au>
-              Added DEVFS_FL_WAIT flag.
-              Work sponsored by SGI.
-  v0.84
-    19991107   Richard Gooch <rgooch@atnf.csiro.au>
-              Support new "disc" naming scheme in <get_removable_partition>.
-              Allow NULL fops in <devfs_register>.
-              Work sponsored by SGI.
-  v0.85
-    19991110   Richard Gooch <rgooch@atnf.csiro.au>
-              Fall back to major table if NULL fops given to <devfs_register>.
-              Work sponsored by SGI.
-  v0.86
-    19991204   Richard Gooch <rgooch@atnf.csiro.au>
-              Support fifos when unregistering.
-              Work sponsored by SGI.
-  v0.87
-    19991209   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed obsolete DEVFS_ FL_COMPAT and DEVFS_ FL_TOLERANT flags.
-              Work sponsored by SGI.
-  v0.88
-    19991214   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed kmod support.
-              Work sponsored by SGI.
-  v0.89
-    19991216   Richard Gooch <rgooch@atnf.csiro.au>
-              Improved debugging in <get_vfs_inode>.
-              Ensure dentries created by devfsd will be cleaned up.
-              Work sponsored by SGI.
-  v0.90
-    19991223   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_get_name>.
-              Work sponsored by SGI.
-  v0.91
-    20000203   Richard Gooch <rgooch@atnf.csiro.au>
-              Ported to kernel 2.3.42.
-              Removed <devfs_fill_file>.
-              Work sponsored by SGI.
-  v0.92
-    20000306   Richard Gooch <rgooch@atnf.csiro.au>
-              Added DEVFS_ FL_NO_PERSISTENCE flag.
-              Removed unnecessary call to <update_devfs_inode_from_entry> in
-              <devfs_readdir>.
-              Work sponsored by SGI.
-  v0.93
-    20000413   Richard Gooch <rgooch@atnf.csiro.au>
-              Set inode->i_size to correct size for symlinks.
-    20000414   Richard Gooch <rgooch@atnf.csiro.au>
-              Only give lookup() method to directories to comply with new VFS
-              assumptions.
-              Work sponsored by SGI.
-    20000415   Richard Gooch <rgooch@atnf.csiro.au>
-              Remove unnecessary tests in symlink methods.
-              Don't kill existing block ops in <devfs_read_inode>.
-              Work sponsored by SGI.
-  v0.94
-    20000424   Richard Gooch <rgooch@atnf.csiro.au>
-              Don't create missing directories in <devfs_find_handle>.
-              Work sponsored by SGI.
-  v0.95
-    20000430   Richard Gooch <rgooch@atnf.csiro.au>
-              Added CONFIG_DEVFS_MOUNT.
-              Work sponsored by SGI.
-  v0.96
-    20000608   Richard Gooch <rgooch@atnf.csiro.au>
-              Disabled multi-mount capability (use VFS bindings instead).
-              Work sponsored by SGI.
-  v0.97
-    20000610   Richard Gooch <rgooch@atnf.csiro.au>
-              Switched to FS_SINGLE to disable multi-mounts.
-    20000612   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed module support.
-              Removed multi-mount code.
-              Removed compatibility macros: VFS has changed too much.
-              Work sponsored by SGI.
-  v0.98
-    20000614   Richard Gooch <rgooch@atnf.csiro.au>
-              Merged devfs inode into devfs entry.
-              Work sponsored by SGI.
-  v0.99
-    20000619   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed dead code in <devfs_register> which used to call
-              <free_dentries>.
-              Work sponsored by SGI.
-  v0.100
-    20000621   Richard Gooch <rgooch@atnf.csiro.au>
-              Changed interface to <devfs_register>.
-              Work sponsored by SGI.
-  v0.101
-    20000622   Richard Gooch <rgooch@atnf.csiro.au>
-              Simplified interface to <devfs_mk_symlink> and <devfs_mk_dir>.
-              Simplified interface to <devfs_find_handle>.
-              Work sponsored by SGI.
-  v0.102
-    20010519   Richard Gooch <rgooch@atnf.csiro.au>
-              Ensure <devfs_generate_path> terminates string for root entry.
-              Exported <devfs_get_name> to modules.
-    20010520   Richard Gooch <rgooch@atnf.csiro.au>
-              Make <devfs_mk_symlink> send events to devfsd.
-              Cleaned up option processing in <devfs_setup>.
-    20010521   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed bugs in handling symlinks: could leak or cause Oops.
-    20010522   Richard Gooch <rgooch@atnf.csiro.au>
-              Cleaned up directory handling by separating fops.
-  v0.103
-    20010601   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed handling of inverted options in <devfs_setup>.
-  v0.104
-    20010604   Richard Gooch <rgooch@atnf.csiro.au>
-              Adjusted <try_modload> to account for <devfs_generate_path> fix.
-  v0.105
-    20010617   Richard Gooch <rgooch@atnf.csiro.au>
-              Answered question posed by Al Viro and removed his comments.
-              Moved setting of registered flag after other fields are changed.
-              Fixed race between <devfsd_close> and <devfsd_notify_one>.
-              Global VFS changes added bogus BKL to <devfsd_close>: removed.
-              Widened locking in <devfs_readlink> and <devfs_follow_link>.
-              Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc.
-              Simplified locking in <devfsd_ioctl> and fixed memory leak.
-  v0.106
-    20010709   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed broken devnum allocation and use <devfs_alloc_devnum>.
-              Fixed old devnum leak by calling new <devfs_dealloc_devnum>.
-  v0.107
-    20010712   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed bug in <devfs_setup> which could hang boot process.
-  v0.108
-    20010730   Richard Gooch <rgooch@atnf.csiro.au>
-              Added DEVFSD_NOTIFY_DELETE event.
-    20010801   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed #include <asm/segment.h>.
-  v0.109
-    20010807   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed inode table races by removing it and using
-              inode->u.generic_ip instead.
-              Moved <devfs_read_inode> into <get_vfs_inode>.
-              Moved <devfs_write_inode> into <devfs_notify_change>.
-  v0.110
-    20010808   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed race in <devfs_do_symlink> for uni-processor.
-  v0.111
-    20010818   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed remnant of multi-mount support in <devfs_mknod>.
-               Removed unused DEVFS_FL_SHOW_UNREG flag.
-  v0.112
-    20010820   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed nlink field from struct devfs_inode.
-  v0.113
-    20010823   Richard Gooch <rgooch@atnf.csiro.au>
-              Replaced BKL with global rwsem to protect symlink data (quick
-              and dirty hack).
-  v0.114
-    20010827   Richard Gooch <rgooch@atnf.csiro.au>
-              Replaced global rwsem for symlink with per-link refcount.
-  v0.115
-    20010919   Richard Gooch <rgooch@atnf.csiro.au>
-              Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>.
-  v0.116
-    20011008   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed overrun in <devfs_link> by removing function (not needed).
-    20011009   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed buffer underrun in <try_modload>.
-    20011029   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed race in <devfsd_ioctl> when setting event mask.
-    20011114   Richard Gooch <rgooch@atnf.csiro.au>
-              First release of new locking code.
-  v1.0
-    20011117   Richard Gooch <rgooch@atnf.csiro.au>
-              Discard temporary buffer, now use "%s" for dentry names.
-    20011118   Richard Gooch <rgooch@atnf.csiro.au>
-              Don't generate path in <try_modload>: use fake entry instead.
-              Use "existing" directory in <_devfs_make_parent_for_leaf>.
-    20011122   Richard Gooch <rgooch@atnf.csiro.au>
-              Use slab cache rather than fixed buffer for devfsd events.
-  v1.1
-    20011125   Richard Gooch <rgooch@atnf.csiro.au>
-              Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>.
-    20011127   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed locking bug in <devfs_d_revalidate_wait> due to typo.
-              Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from
-              devfsd or children.
-  v1.2
-    20011202   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed bug in <devfsd_read>: was dereferencing freed pointer.
-  v1.3
-    20011203   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed bug in <devfsd_close>: was dereferencing freed pointer.
-              Added process group check for devfsd privileges.
-  v1.4
-    20011204   Richard Gooch <rgooch@atnf.csiro.au>
-              Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>.
-  v1.5
-    20011211   Richard Gooch <rgooch@atnf.csiro.au>
-              Return old entry in <devfs_mk_dir> for 2.4.x kernels.
-    20011212   Richard Gooch <rgooch@atnf.csiro.au>
-              Increment refcount on module in <check_disc_changed>.
-    20011215   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_get_handle> and exported <devfs_put>.
-              Increment refcount on module in <devfs_get_ops>.
-              Created <devfs_put_ops>.
-  v1.6
-    20011216   Richard Gooch <rgooch@atnf.csiro.au>
-              Added poisoning to <devfs_put>.
-              Improved debugging messages.
-  v1.7
-    20011221   Richard Gooch <rgooch@atnf.csiro.au>
-              Corrected (made useful) debugging message in <unregister>.
-              Moved <kmem_cache_create> in <mount_devfs_fs> to <init_devfs_fs>
-    20011224   Richard Gooch <rgooch@atnf.csiro.au>
-              Added magic number to guard against scribbling drivers.
-    20011226   Richard Gooch <rgooch@atnf.csiro.au>
-              Only return old entry in <devfs_mk_dir> if a directory.
-              Defined macros for error and debug messages.
-  v1.8
-    20020113   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed (rare, old) race in <devfs_lookup>.
-  v1.9
-    20020120   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed deadlock bug in <devfs_d_revalidate_wait>.
-              Tag VFS deletable in <devfs_mk_symlink> if handle ignored.
-  v1.10
-    20020129   Richard Gooch <rgooch@atnf.csiro.au>
-              Added KERN_* to remaining messages.
-              Cleaned up declaration of <stat_read>.
-  v1.11
-    20020219   Richard Gooch <rgooch@atnf.csiro.au>
-              Changed <devfs_rmdir> to allow later additions if not yet empty.
-  v1.12
-    20020406   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed silently introduced calls to lock_kernel() and
-              unlock_kernel() due to recent VFS locking changes. BKL isn't
-              required in devfs.
-  v1.13
-    20020428   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed 2.4.x compatibility code.
-  v1.14
-    20020510   Richard Gooch <rgooch@atnf.csiro.au>
-              Added BKL to <devfs_open> because drivers still need it.
-  v1.15
-    20020512   Richard Gooch <rgooch@atnf.csiro.au>
-              Protected <scan_dir_for_removable> and <get_removable_partition>
-              from changing directory contents.
-  v1.16
-    20020514   Richard Gooch <rgooch@atnf.csiro.au>
-              Minor cleanup of <scan_dir_for_removable>.
-  v1.17
-    20020721   Richard Gooch <rgooch@atnf.csiro.au>
-              Switched to ISO C structure field initialisers.
-              Switch to set_current_state() and move before add_wait_queue().
-    20020722   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed devfs entry leak in <devfs_readdir> when *readdir fails.
-  v1.18
-    20020725   Richard Gooch <rgooch@atnf.csiro.au>
-              Created <devfs_find_and_unregister>.
-  v1.19
-    20020728   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed deprecated <devfs_find_handle>.
-  v1.20
-    20020820   Richard Gooch <rgooch@atnf.csiro.au>
-              Fixed module unload race in <devfs_open>.
-  v1.21
-    20021013   Richard Gooch <rgooch@atnf.csiro.au>
-              Removed DEVFS_ FL_AUTO_OWNER.
-              Switched lingering structure field initialiser to ISO C.
-              Added locking when updating FCB flags.
-  v1.22
-*/
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/smp_lock.h>
-#include <linux/smp.h>
-#include <linux/rwsem.h>
-#include <linux/sched.h>
-#include <linux/namei.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/atomic.h>
-
-#define DEVFS_VERSION            "2004-01-31"
-
-#define DEVFS_NAME "devfs"
-
-#define FIRST_INODE 1
-
-#define STRING_LENGTH 256
-#define FAKE_BLOCK_SIZE 1024
-#define POISON_PTR ( *(void **) poison_array )
-#define MAGIC_VALUE 0x327db823
-
-#ifndef TRUE
-#  define TRUE 1
-#  define FALSE 0
-#endif
-
-#define MODE_DIR (S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO)
-
-#define DEBUG_NONE         0x0000000
-#define DEBUG_MODULE_LOAD  0x0000001
-#define DEBUG_REGISTER     0x0000002
-#define DEBUG_UNREGISTER   0x0000004
-#define DEBUG_FREE         0x0000008
-#define DEBUG_SET_FLAGS    0x0000010
-#define DEBUG_S_READ       0x0000100   /*  Break  */
-#define DEBUG_I_LOOKUP     0x0001000   /*  Break  */
-#define DEBUG_I_CREATE     0x0002000
-#define DEBUG_I_GET        0x0004000
-#define DEBUG_I_CHANGE     0x0008000
-#define DEBUG_I_UNLINK     0x0010000
-#define DEBUG_I_RLINK      0x0020000
-#define DEBUG_I_FLINK      0x0040000
-#define DEBUG_I_MKNOD      0x0080000
-#define DEBUG_F_READDIR    0x0100000   /*  Break  */
-#define DEBUG_D_DELETE     0x1000000   /*  Break  */
-#define DEBUG_D_RELEASE    0x2000000
-#define DEBUG_D_IPUT       0x4000000
-#define DEBUG_ALL          0xfffffff
-#define DEBUG_DISABLED     DEBUG_NONE
-
-#define OPTION_NONE             0x00
-#define OPTION_MOUNT            0x01
-
-#define PRINTK(format, args...) \
-   {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);}
-
-#define OOPS(format, args...) \
-   {printk (KERN_CRIT "%s" format, __FUNCTION__ , ## args); \
-    printk ("Forcing Oops\n"); \
-    BUG();}
-
-#ifdef CONFIG_DEVFS_DEBUG
-#  define VERIFY_ENTRY(de) \
-   {if ((de) && (de)->magic_number != MAGIC_VALUE) \
-        OOPS ("(%p): bad magic value: %x\n", (de), (de)->magic_number);}
-#  define WRITE_ENTRY_MAGIC(de,magic) (de)->magic_number = (magic)
-#  define DPRINTK(flag, format, args...) \
-   {if (devfs_debug & flag) \
-       printk (KERN_INFO "%s" format, __FUNCTION__ , ## args);}
-#else
-#  define VERIFY_ENTRY(de)
-#  define WRITE_ENTRY_MAGIC(de,magic)
-#  define DPRINTK(flag, format, args...)
-#endif
-
-typedef struct devfs_entry *devfs_handle_t;
-
-struct directory_type {
-       rwlock_t lock;          /*  Lock for searching(R)/updating(W)   */
-       struct devfs_entry *first;
-       struct devfs_entry *last;
-       unsigned char no_more_additions:1;
-};
-
-struct symlink_type {
-       unsigned int length;    /*  Not including the NULL-termimator       */
-       char *linkname;         /*  This is NULL-terminated                 */
-};
-
-struct devfs_inode {           /*  This structure is for "persistent" inode storage  */
-       struct dentry *dentry;
-       struct timespec atime;
-       struct timespec mtime;
-       struct timespec ctime;
-       unsigned int ino;       /*  Inode number as seen in the VFS         */
-       uid_t uid;
-       gid_t gid;
-};
-
-struct devfs_entry {
-#ifdef CONFIG_DEVFS_DEBUG
-       unsigned int magic_number;
-#endif
-       void *info;
-       atomic_t refcount;      /*  When this drops to zero, it's unused    */
-       union {
-               struct directory_type dir;
-               dev_t dev;
-               struct symlink_type symlink;
-               const char *name;       /*  Only used for (mode == 0)               */
-       } u;
-       struct devfs_entry *prev;       /*  Previous entry in the parent directory  */
-       struct devfs_entry *next;       /*  Next entry in the parent directory      */
-       struct devfs_entry *parent;     /*  The parent directory                    */
-       struct devfs_inode inode;
-       umode_t mode;
-       unsigned short namelen; /*  I think 64k+ filenames are a way off... */
-       unsigned char vfs:1;    /*  Whether the VFS may delete the entry   */
-       char name[1];           /*  This is just a dummy: the allocated array
-                                  is bigger. This is NULL-terminated      */
-};
-
-/*  The root of the device tree  */
-static struct devfs_entry *root_entry;
-
-struct devfsd_buf_entry {
-       struct devfs_entry *de; /*  The name is generated with this         */
-       unsigned short type;    /*  The type of event                       */
-       umode_t mode;
-       uid_t uid;
-       gid_t gid;
-       struct devfsd_buf_entry *next;
-};
-
-struct fs_info {               /*  This structure is for the mounted devfs  */
-       struct super_block *sb;
-       spinlock_t devfsd_buffer_lock;  /*  Lock when inserting/deleting events  */
-       struct devfsd_buf_entry *devfsd_first_event;
-       struct devfsd_buf_entry *devfsd_last_event;
-       volatile int devfsd_sleeping;
-       volatile struct task_struct *devfsd_task;
-       volatile pid_t devfsd_pgrp;
-       volatile struct file *devfsd_file;
-       struct devfsd_notify_struct *devfsd_info;
-       volatile unsigned long devfsd_event_mask;
-       atomic_t devfsd_overrun_count;
-       wait_queue_head_t devfsd_wait_queue;    /*  Wake devfsd on input       */
-       wait_queue_head_t revalidate_wait_queue;        /*  Wake when devfsd sleeps    */
-};
-
-static struct fs_info fs_info = {.devfsd_buffer_lock = SPIN_LOCK_UNLOCKED };
-static kmem_cache_t *devfsd_buf_cache;
-#ifdef CONFIG_DEVFS_DEBUG
-static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
-static unsigned int devfs_debug = DEBUG_NONE;
-static DEFINE_SPINLOCK(stat_lock);
-static unsigned int stat_num_entries;
-static unsigned int stat_num_bytes;
-#endif
-static unsigned char poison_array[8] =
-    { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a };
-
-#ifdef CONFIG_DEVFS_MOUNT
-static unsigned int boot_options = OPTION_MOUNT;
-#else
-static unsigned int boot_options = OPTION_NONE;
-#endif
-
-/*  Forward function declarations  */
-static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
-                                      const char *name, int namelen,
-                                      int traverse_symlink);
-static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
-                          loff_t * ppos);
-static int devfsd_ioctl(struct inode *inode, struct file *file,
-                       unsigned int cmd, unsigned long arg);
-static int devfsd_close(struct inode *inode, struct file *file);
-#ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
-                        loff_t * ppos);
-static const struct file_operations stat_fops = {
-       .open = nonseekable_open,
-       .read = stat_read,
-};
-#endif
-
-/*  Devfs daemon file operations  */
-static const struct file_operations devfsd_fops = {
-       .open = nonseekable_open,
-       .read = devfsd_read,
-       .ioctl = devfsd_ioctl,
-       .release = devfsd_close,
-};
-
-/*  Support functions follow  */
-
-/**
- *     devfs_get - Get a reference to a devfs entry.
- *     @de:  The devfs entry.
- */
-
-static struct devfs_entry *devfs_get(struct devfs_entry *de)
-{
-       VERIFY_ENTRY(de);
-       if (de)
-               atomic_inc(&de->refcount);
-       return de;
-}                              /*  End Function devfs_get  */
-
-/**
- *     devfs_put - Put (release) a reference to a devfs entry.
- *     @de:  The handle to the devfs entry.
- */
-
-static void devfs_put(devfs_handle_t de)
-{
-       if (!de)
-               return;
-       VERIFY_ENTRY(de);
-       if (de->info == POISON_PTR)
-               OOPS("(%p): poisoned pointer\n", de);
-       if (!atomic_dec_and_test(&de->refcount))
-               return;
-       if (de == root_entry)
-               OOPS("(%p): root entry being freed\n", de);
-       DPRINTK(DEBUG_FREE, "(%s): de: %p, parent: %p \"%s\"\n",
-               de->name, de, de->parent,
-               de->parent ? de->parent->name : "no parent");
-       if (S_ISLNK(de->mode))
-               kfree(de->u.symlink.linkname);
-       WRITE_ENTRY_MAGIC(de, 0);
-#ifdef CONFIG_DEVFS_DEBUG
-       spin_lock(&stat_lock);
-       --stat_num_entries;
-       stat_num_bytes -= sizeof *de + de->namelen;
-       if (S_ISLNK(de->mode))
-               stat_num_bytes -= de->u.symlink.length + 1;
-       spin_unlock(&stat_lock);
-#endif
-       de->info = POISON_PTR;
-       kfree(de);
-}                              /*  End Function devfs_put  */
-
-/**
- *     _devfs_search_dir - Search for a devfs entry in a directory.
- *     @dir:  The directory to search.
- *     @name:  The name of the entry to search for.
- *     @namelen:  The number of characters in @name.
- *
- *  Search for a devfs entry in a directory and returns a pointer to the entry
- *   on success, else %NULL. The directory must be locked already.
- *   An implicit devfs_get() is performed on the returned entry.
- */
-
-static struct devfs_entry *_devfs_search_dir(struct devfs_entry *dir,
-                                            const char *name,
-                                            unsigned int namelen)
-{
-       struct devfs_entry *curr;
-
-       if (!S_ISDIR(dir->mode)) {
-               PRINTK("(%s): not a directory\n", dir->name);
-               return NULL;
-       }
-       for (curr = dir->u.dir.first; curr != NULL; curr = curr->next) {
-               if (curr->namelen != namelen)
-                       continue;
-               if (memcmp(curr->name, name, namelen) == 0)
-                       break;
-               /*  Not found: try the next one  */
-       }
-       return devfs_get(curr);
-}                              /*  End Function _devfs_search_dir  */
-
-/**
- *     _devfs_alloc_entry - Allocate a devfs entry.
- *     @name:     the name of the entry
- *     @namelen:  the number of characters in @name
- *      @mode:     the mode for the entry
- *
- *  Allocate a devfs entry and returns a pointer to the entry on success, else
- *   %NULL.
- */
-
-static struct devfs_entry *_devfs_alloc_entry(const char *name,
-                                             unsigned int namelen,
-                                             umode_t mode)
-{
-       struct devfs_entry *new;
-       static unsigned long inode_counter = FIRST_INODE;
-       static DEFINE_SPINLOCK(counter_lock);
-
-       if (name && (namelen < 1))
-               namelen = strlen(name);
-       if ((new = kmalloc(sizeof *new + namelen, GFP_KERNEL)) == NULL)
-               return NULL;
-       memset(new, 0, sizeof *new + namelen);  /*  Will set '\0' on name  */
-       new->mode = mode;
-       if (S_ISDIR(mode))
-               rwlock_init(&new->u.dir.lock);
-       atomic_set(&new->refcount, 1);
-       spin_lock(&counter_lock);
-       new->inode.ino = inode_counter++;
-       spin_unlock(&counter_lock);
-       if (name)
-               memcpy(new->name, name, namelen);
-       new->namelen = namelen;
-       WRITE_ENTRY_MAGIC(new, MAGIC_VALUE);
-#ifdef CONFIG_DEVFS_DEBUG
-       spin_lock(&stat_lock);
-       ++stat_num_entries;
-       stat_num_bytes += sizeof *new + namelen;
-       spin_unlock(&stat_lock);
-#endif
-       return new;
-}                              /*  End Function _devfs_alloc_entry  */
-
-/**
- *     _devfs_append_entry - Append a devfs entry to a directory's child list.
- *     @dir:  The directory to add to.
- *     @de:  The devfs entry to append.
- *     @old_de: If an existing entry exists, it will be written here. This may
- *              be %NULL. An implicit devfs_get() is performed on this entry.
- *
- *  Append a devfs entry to a directory's list of children, checking first to
- *   see if an entry of the same name exists. The directory will be locked.
- *   The value 0 is returned on success, else a negative error code.
- *   On failure, an implicit devfs_put() is performed on %de.
- */
-
-static int _devfs_append_entry(devfs_handle_t dir, devfs_handle_t de,
-                              devfs_handle_t * old_de)
-{
-       int retval;
-
-       if (old_de)
-               *old_de = NULL;
-       if (!S_ISDIR(dir->mode)) {
-               PRINTK("(%s): dir: \"%s\" is not a directory\n", de->name,
-                      dir->name);
-               devfs_put(de);
-               return -ENOTDIR;
-       }
-       write_lock(&dir->u.dir.lock);
-       if (dir->u.dir.no_more_additions)
-               retval = -ENOENT;
-       else {
-               struct devfs_entry *old;
-
-               old = _devfs_search_dir(dir, de->name, de->namelen);
-               if (old_de)
-                       *old_de = old;
-               else
-                       devfs_put(old);
-               if (old == NULL) {
-                       de->parent = dir;
-                       de->prev = dir->u.dir.last;
-                       /*  Append to the directory's list of children  */
-                       if (dir->u.dir.first == NULL)
-                               dir->u.dir.first = de;
-                       else
-                               dir->u.dir.last->next = de;
-                       dir->u.dir.last = de;
-                       retval = 0;
-               } else
-                       retval = -EEXIST;
-       }
-       write_unlock(&dir->u.dir.lock);
-       if (retval)
-               devfs_put(de);
-       return retval;
-}                              /*  End Function _devfs_append_entry  */
-
-/**
- *     _devfs_get_root_entry - Get the root devfs entry.
- *
- *     Returns the root devfs entry on success, else %NULL.
- *
- *     TODO it must be called asynchronously due to the fact
- *     that devfs is initialized relatively late. Proper way
- *     is to remove module_init from init_devfs_fs and manually
- *     call it early enough during system init
- */
-
-static struct devfs_entry *_devfs_get_root_entry(void)
-{
-       struct devfs_entry *new;
-       static DEFINE_SPINLOCK(root_lock);
-
-       if (root_entry)
-               return root_entry;
-
-       new = _devfs_alloc_entry(NULL, 0, MODE_DIR);
-       if (new == NULL)
-               return NULL;
-
-       spin_lock(&root_lock);
-       if (root_entry) {
-               spin_unlock(&root_lock);
-               devfs_put(new);
-               return root_entry;
-       }
-       root_entry = new;
-       spin_unlock(&root_lock);
-
-       return root_entry;
-}                              /*  End Function _devfs_get_root_entry  */
-
-/**
- *     _devfs_descend - Descend down a tree using the next component name.
- *     @dir:  The directory to search.
- *     @name:  The component name to search for.
- *     @namelen:  The length of %name.
- *     @next_pos:  The position of the next '/' or '\0' is written here.
- *
- *  Descend into a directory, searching for a component. This function forms
- *   the core of a tree-walking algorithm. The directory will be locked.
- *   The devfs entry corresponding to the component is returned. If there is
- *   no matching entry, %NULL is returned.
- *   An implicit devfs_get() is performed on the returned entry.
- */
-
-static struct devfs_entry *_devfs_descend(struct devfs_entry *dir,
-                                         const char *name, int namelen,
-                                         int *next_pos)
-{
-       const char *stop, *ptr;
-       struct devfs_entry *entry;
-
-       if ((namelen >= 3) && (strncmp(name, "../", 3) == 0)) { /*  Special-case going to parent directory  */
-               *next_pos = 3;
-               return devfs_get(dir->parent);
-       }
-       stop = name + namelen;
-       /*  Search for a possible '/'  */
-       for (ptr = name; (ptr < stop) && (*ptr != '/'); ++ptr) ;
-       *next_pos = ptr - name;
-       read_lock(&dir->u.dir.lock);
-       entry = _devfs_search_dir(dir, name, *next_pos);
-       read_unlock(&dir->u.dir.lock);
-       return entry;
-}                              /*  End Function _devfs_descend  */
-
-static devfs_handle_t _devfs_make_parent_for_leaf(struct devfs_entry *dir,
-                                                 const char *name,
-                                                 int namelen, int *leaf_pos)
-{
-       int next_pos = 0;
-
-       if (dir == NULL)
-               dir = _devfs_get_root_entry();
-       if (dir == NULL)
-               return NULL;
-       devfs_get(dir);
-       /*  Search for possible trailing component and ignore it  */
-       for (--namelen; (namelen > 0) && (name[namelen] != '/'); --namelen) ;
-       *leaf_pos = (name[namelen] == '/') ? (namelen + 1) : 0;
-       for (; namelen > 0; name += next_pos, namelen -= next_pos) {
-               struct devfs_entry *de, *old = NULL;
-
-               if ((de =
-                    _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
-                       de = _devfs_alloc_entry(name, next_pos, MODE_DIR);
-                       devfs_get(de);
-                       if (!de || _devfs_append_entry(dir, de, &old)) {
-                               devfs_put(de);
-                               if (!old || !S_ISDIR(old->mode)) {
-                                       devfs_put(old);
-                                       devfs_put(dir);
-                                       return NULL;
-                               }
-                               de = old;       /*  Use the existing directory  */
-                       }
-               }
-               if (de == dir->parent) {
-                       devfs_put(dir);
-                       devfs_put(de);
-                       return NULL;
-               }
-               devfs_put(dir);
-               dir = de;
-               if (name[next_pos] == '/')
-                       ++next_pos;
-       }
-       return dir;
-}                              /*  End Function _devfs_make_parent_for_leaf  */
-
-static devfs_handle_t _devfs_prepare_leaf(devfs_handle_t * dir,
-                                         const char *name, umode_t mode)
-{
-       int namelen, leaf_pos;
-       struct devfs_entry *de;
-
-       namelen = strlen(name);
-       if ((*dir = _devfs_make_parent_for_leaf(*dir, name, namelen,
-                                               &leaf_pos)) == NULL) {
-               PRINTK("(%s): could not create parent path\n", name);
-               return NULL;
-       }
-       if ((de = _devfs_alloc_entry(name + leaf_pos, namelen - leaf_pos, mode))
-           == NULL) {
-               PRINTK("(%s): could not allocate entry\n", name);
-               devfs_put(*dir);
-               return NULL;
-       }
-       return de;
-}                              /*  End Function _devfs_prepare_leaf  */
-
-static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
-                                      const char *name, int namelen,
-                                      int traverse_symlink)
-{
-       int next_pos = 0;
-
-       if (dir == NULL)
-               dir = _devfs_get_root_entry();
-       if (dir == NULL)
-               return NULL;
-       devfs_get(dir);
-       for (; namelen > 0; name += next_pos, namelen -= next_pos) {
-               struct devfs_entry *de, *link;
-
-               if (!S_ISDIR(dir->mode)) {
-                       devfs_put(dir);
-                       return NULL;
-               }
-
-               if ((de =
-                    _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
-                       devfs_put(dir);
-                       return NULL;
-               }
-               if (S_ISLNK(de->mode) && traverse_symlink) {    /*  Need to follow the link: this is a stack chomper  */
-                       /* FIXME what if it puts outside of mounted tree? */
-                       link = _devfs_walk_path(dir, de->u.symlink.linkname,
-                                               de->u.symlink.length, TRUE);
-                       devfs_put(de);
-                       if (!link) {
-                               devfs_put(dir);
-                               return NULL;
-                       }
-                       de = link;
-               }
-               devfs_put(dir);
-               dir = de;
-               if (name[next_pos] == '/')
-                       ++next_pos;
-       }
-       return dir;
-}                              /*  End Function _devfs_walk_path  */
-
-/**
- *     _devfs_find_entry - Find a devfs entry.
- *     @dir: The handle to the parent devfs directory entry. If this is %NULL the
- *             name is relative to the root of the devfs.
- *     @name: The name of the entry. This may be %NULL.
- *     @traverse_symlink: If %TRUE then symbolic links are traversed.
- *
- *     Returns the devfs_entry pointer on success, else %NULL. An implicit
- *     devfs_get() is performed.
- */
-
-static struct devfs_entry *_devfs_find_entry(devfs_handle_t dir,
-                                            const char *name,
-                                            int traverse_symlink)
-{
-       unsigned int namelen = strlen(name);
-
-       if (name[0] == '/') {
-               /*  Skip leading pathname component  */
-               if (namelen < 2) {
-                       PRINTK("(%s): too short\n", name);
-                       return NULL;
-               }
-               for (++name, --namelen; (*name != '/') && (namelen > 0);
-                    ++name, --namelen) ;
-               if (namelen < 2) {
-                       PRINTK("(%s): too short\n", name);
-                       return NULL;
-               }
-               ++name;
-               --namelen;
-       }
-       return _devfs_walk_path(dir, name, namelen, traverse_symlink);
-}                              /*  End Function _devfs_find_entry  */
-
-static struct devfs_entry *get_devfs_entry_from_vfs_inode(struct inode *inode)
-{
-       if (inode == NULL)
-               return NULL;
-       VERIFY_ENTRY((struct devfs_entry *)inode->u.generic_ip);
-       return inode->u.generic_ip;
-}                              /*  End Function get_devfs_entry_from_vfs_inode  */
-
-/**
- *     free_dentry - Free the dentry for a device entry and invalidate inode.
- *     @de: The entry.
- *
- *     This must only be called after the entry has been unhooked from its
- *      parent directory.
- */
-
-static void free_dentry(struct devfs_entry *de)
-{
-       struct dentry *dentry = de->inode.dentry;
-
-       if (!dentry)
-               return;
-       spin_lock(&dcache_lock);
-       dget_locked(dentry);
-       spin_unlock(&dcache_lock);
-       /*  Forcefully remove the inode  */
-       if (dentry->d_inode != NULL)
-               dentry->d_inode->i_nlink = 0;
-       d_drop(dentry);
-       dput(dentry);
-}                              /*  End Function free_dentry  */
-
-/**
- *     is_devfsd_or_child - Test if the current process is devfsd or one of its children.
- *     @fs_info: The filesystem information.
- *
- *     Returns %TRUE if devfsd or child, else %FALSE.
- */
-
-static int is_devfsd_or_child(struct fs_info *fs_info)
-{
-       struct task_struct *p = current;
-
-       if (p == fs_info->devfsd_task)
-               return (TRUE);
-       if (process_group(p) == fs_info->devfsd_pgrp)
-               return (TRUE);
-       read_lock(&tasklist_lock);
-       for (; p != &init_task; p = p->real_parent) {
-               if (p == fs_info->devfsd_task) {
-                       read_unlock(&tasklist_lock);
-                       return (TRUE);
-               }
-       }
-       read_unlock(&tasklist_lock);
-       return (FALSE);
-}                              /*  End Function is_devfsd_or_child  */
-
-/**
- *     devfsd_queue_empty - Test if devfsd has work pending in its event queue.
- *     @fs_info: The filesystem information.
- *
- *     Returns %TRUE if the queue is empty, else %FALSE.
- */
-
-static inline int devfsd_queue_empty(struct fs_info *fs_info)
-{
-       return (fs_info->devfsd_last_event) ? FALSE : TRUE;
-}                              /*  End Function devfsd_queue_empty  */
-
-/**
- *     wait_for_devfsd_finished - Wait for devfsd to finish processing its event queue.
- *     @fs_info: The filesystem information.
- *
- *     Returns %TRUE if no more waiting will be required, else %FALSE.
- */
-
-static int wait_for_devfsd_finished(struct fs_info *fs_info)
-{
-       DECLARE_WAITQUEUE(wait, current);
-
-       if (fs_info->devfsd_task == NULL)
-               return (TRUE);
-       if (devfsd_queue_empty(fs_info) && fs_info->devfsd_sleeping)
-               return TRUE;
-       if (is_devfsd_or_child(fs_info))
-               return (FALSE);
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       add_wait_queue(&fs_info->revalidate_wait_queue, &wait);
-       if (!devfsd_queue_empty(fs_info) || !fs_info->devfsd_sleeping)
-               if (fs_info->devfsd_task)
-                       schedule();
-       remove_wait_queue(&fs_info->revalidate_wait_queue, &wait);
-       __set_current_state(TASK_RUNNING);
-       return (TRUE);
-}                              /*  End Function wait_for_devfsd_finished  */
-
-/**
- *     devfsd_notify_de - Notify the devfsd daemon of a change.
- *     @de: The devfs entry that has changed. This and all parent entries will
- *            have their reference counts incremented if the event was queued.
- *     @type: The type of change.
- *     @mode: The mode of the entry.
- *     @uid: The user ID.
- *     @gid: The group ID.
- *     @fs_info: The filesystem info.
- *
- *     Returns %TRUE if an event was queued and devfsd woken up, else %FALSE.
- */
-
-static int devfsd_notify_de(struct devfs_entry *de,
-                           unsigned short type, umode_t mode,
-                           uid_t uid, gid_t gid, struct fs_info *fs_info)
-{
-       struct devfsd_buf_entry *entry;
-       struct devfs_entry *curr;
-
-       if (!(fs_info->devfsd_event_mask & (1 << type)))
-               return (FALSE);
-       if ((entry = kmem_cache_alloc(devfsd_buf_cache, SLAB_KERNEL)) == NULL) {
-               atomic_inc(&fs_info->devfsd_overrun_count);
-               return (FALSE);
-       }
-       for (curr = de; curr != NULL; curr = curr->parent)
-               devfs_get(curr);
-       entry->de = de;
-       entry->type = type;
-       entry->mode = mode;
-       entry->uid = uid;
-       entry->gid = gid;
-       entry->next = NULL;
-       spin_lock(&fs_info->devfsd_buffer_lock);
-       if (!fs_info->devfsd_first_event)
-               fs_info->devfsd_first_event = entry;
-       if (fs_info->devfsd_last_event)
-               fs_info->devfsd_last_event->next = entry;
-       fs_info->devfsd_last_event = entry;
-       spin_unlock(&fs_info->devfsd_buffer_lock);
-       wake_up_interruptible(&fs_info->devfsd_wait_queue);
-       return (TRUE);
-}                              /*  End Function devfsd_notify_de  */
-
-/**
- *     devfsd_notify - Notify the devfsd daemon of a change.
- *     @de: The devfs entry that has changed.
- *     @type: The type of change event.
- *     @wait: If TRUE, the function waits for the daemon to finish processing
- *             the event.
- */
-
-static void devfsd_notify(struct devfs_entry *de, unsigned short type)
-{
-       devfsd_notify_de(de, type, de->mode, current->euid,
-                        current->egid, &fs_info);
-}
-
-static int devfs_mk_dev(dev_t dev, umode_t mode, const char *fmt, va_list args)
-{
-       struct devfs_entry *dir = NULL, *de;
-       char buf[64];
-       int error, n;
-
-       n = vsnprintf(buf, sizeof(buf), fmt, args);
-       if (n >= sizeof(buf) || !buf[0]) {
-               printk(KERN_WARNING "%s: invalid format string %s\n",
-                      __FUNCTION__, fmt);
-               return -EINVAL;
-       }
-
-       de = _devfs_prepare_leaf(&dir, buf, mode);
-       if (!de) {
-               printk(KERN_WARNING "%s: could not prepare leaf for %s\n",
-                      __FUNCTION__, buf);
-               return -ENOMEM; /* could be more accurate... */
-       }
-
-       de->u.dev = dev;
-
-       error = _devfs_append_entry(dir, de, NULL);
-       if (error) {
-               printk(KERN_WARNING "%s: could not append to parent for %s\n",
-                      __FUNCTION__, buf);
-               goto out;
-       }
-
-       devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
-      out:
-       devfs_put(dir);
-       return error;
-}
-
-int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
-{
-       va_list args;
-
-       if (!S_ISBLK(mode)) {
-               printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
-                      __FUNCTION__, mode, fmt);
-               return -EINVAL;
-       }
-
-       va_start(args, fmt);
-       return devfs_mk_dev(dev, mode, fmt, args);
-}
-
-EXPORT_SYMBOL(devfs_mk_bdev);
-
-int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
-{
-       va_list args;
-
-       if (!S_ISCHR(mode)) {
-               printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
-                      __FUNCTION__, mode, fmt);
-               return -EINVAL;
-       }
-
-       va_start(args, fmt);
-       return devfs_mk_dev(dev, mode, fmt, args);
-}
-
-EXPORT_SYMBOL(devfs_mk_cdev);
-
-/**
- *     _devfs_unhook - Unhook a device entry from its parents list
- *     @de: The entry to unhook.
- *
- *     Returns %TRUE if the entry was unhooked, else %FALSE if it was
- *             previously unhooked.
- *     The caller must have a write lock on the parent directory.
- */
-
-static int _devfs_unhook(struct devfs_entry *de)
-{
-       struct devfs_entry *parent;
-
-       if (!de || (de->prev == de))
-               return FALSE;
-       parent = de->parent;
-       if (de->prev == NULL)
-               parent->u.dir.first = de->next;
-       else
-               de->prev->next = de->next;
-       if (de->next == NULL)
-               parent->u.dir.last = de->prev;
-       else
-               de->next->prev = de->prev;
-       de->prev = de;          /*  Indicate we're unhooked                      */
-       de->next = NULL;        /*  Force early termination for <devfs_readdir>  */
-       return TRUE;
-}                              /*  End Function _devfs_unhook  */
-
-/**
- *     _devfs_unregister - Unregister a device entry from its parent.
- *     @dir: The parent directory.
- *     @de: The entry to unregister.
- *
- *     The caller must have a write lock on the parent directory, which is
- *     unlocked by this function.
- */
-
-static void _devfs_unregister(struct devfs_entry *dir, struct devfs_entry *de)
-{
-       int unhooked = _devfs_unhook(de);
-
-       write_unlock(&dir->u.dir.lock);
-       if (!unhooked)
-               return;
-       devfs_get(dir);
-       devfsd_notify(de, DEVFSD_NOTIFY_UNREGISTERED);
-       free_dentry(de);
-       devfs_put(dir);
-       if (!S_ISDIR(de->mode))
-               return;
-       while (TRUE) {          /*  Recursively unregister: this is a stack chomper  */
-               struct devfs_entry *child;
-
-               write_lock(&de->u.dir.lock);
-               de->u.dir.no_more_additions = TRUE;
-               child = de->u.dir.first;
-               VERIFY_ENTRY(child);
-               _devfs_unregister(de, child);
-               if (!child)
-                       break;
-               DPRINTK(DEBUG_UNREGISTER, "(%s): child: %p  refcount: %d\n",
-                       child->name, child, atomic_read(&child->refcount));
-               devfs_put(child);
-       }
-}                              /*  End Function _devfs_unregister  */
-
-static int devfs_do_symlink(devfs_handle_t dir, const char *name,
-                           const char *link, devfs_handle_t * handle)
-{
-       int err;
-       unsigned int linklength;
-       char *newlink;
-       struct devfs_entry *de;
-
-       if (handle != NULL)
-               *handle = NULL;
-       if (name == NULL) {
-               PRINTK("(): NULL name pointer\n");
-               return -EINVAL;
-       }
-       if (link == NULL) {
-               PRINTK("(%s): NULL link pointer\n", name);
-               return -EINVAL;
-       }
-       linklength = strlen(link);
-       if ((newlink = kmalloc(linklength + 1, GFP_KERNEL)) == NULL)
-               return -ENOMEM;
-       memcpy(newlink, link, linklength);
-       newlink[linklength] = '\0';
-       if ((de = _devfs_prepare_leaf(&dir, name, S_IFLNK | S_IRUGO | S_IXUGO))
-           == NULL) {
-               PRINTK("(%s): could not prepare leaf\n", name);
-               kfree(newlink);
-               return -ENOTDIR;
-       }
-       de->info = NULL;
-       de->u.symlink.linkname = newlink;
-       de->u.symlink.length = linklength;
-       if ((err = _devfs_append_entry(dir, de, NULL)) != 0) {
-               PRINTK("(%s): could not append to parent, err: %d\n", name,
-                      err);
-               devfs_put(dir);
-               return err;
-       }
-       devfs_put(dir);
-#ifdef CONFIG_DEVFS_DEBUG
-       spin_lock(&stat_lock);
-       stat_num_bytes += linklength + 1;
-       spin_unlock(&stat_lock);
-#endif
-       if (handle != NULL)
-               *handle = de;
-       return 0;
-}                              /*  End Function devfs_do_symlink  */
-
-/**
- *     devfs_mk_symlink Create a symbolic link in the devfs namespace.
- *     @from: The name of the entry.
- *     @to: Name of the destination
- *
- *     Returns 0 on success, else a negative error code is returned.
- */
-
-int devfs_mk_symlink(const char *from, const char *to)
-{
-       devfs_handle_t de;
-       int err;
-
-       err = devfs_do_symlink(NULL, from, to, &de);
-       if (!err) {
-               de->vfs = TRUE;
-               devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
-       }
-
-       return err;
-}
-
-/**
- *     devfs_mk_dir - Create a directory in the devfs namespace.
- *             new name is relative to the root of the devfs.
- *     @fmt: The name of the entry.
- *
- *     Use of this function is optional. The devfs_register() function
- *     will automatically create intermediate directories as needed. This function
- *     is provided for efficiency reasons, as it provides a handle to a directory.
- *     On failure %NULL is returned.
- */
-
-int devfs_mk_dir(const char *fmt, ...)
-{
-       struct devfs_entry *dir = NULL, *de = NULL, *old;
-       char buf[64];
-       va_list args;
-       int error, n;
-
-       va_start(args, fmt);
-       n = vsnprintf(buf, 64, fmt, args);
-       if (n >= 64 || !buf[0]) {
-               printk(KERN_WARNING "%s: invalid argument.", __FUNCTION__);
-               return -EINVAL;
-       }
-
-       de = _devfs_prepare_leaf(&dir, buf, MODE_DIR);
-       if (!de) {
-               PRINTK("(%s): could not prepare leaf\n", buf);
-               return -EINVAL;
-       }
-
-       error = _devfs_append_entry(dir, de, &old);
-       if (error == -EEXIST && S_ISDIR(old->mode)) {
-               /*
-                * devfs_mk_dir() of an already-existing directory will
-                * return success.
-                */
-               error = 0;
-               goto out_put;
-       } else if (error) {
-               PRINTK("(%s): could not append to dir: %p \"%s\"\n",
-                      buf, dir, dir->name);
-               devfs_put(old);
-               goto out_put;
-       }
-
-       devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
-
-      out_put:
-       devfs_put(dir);
-       return error;
-}
-
-void devfs_remove(const char *fmt, ...)
-{
-       char buf[64];
-       va_list args;
-       int n;
-
-       va_start(args, fmt);
-       n = vsnprintf(buf, sizeof(buf), fmt, args);
-       if (n < sizeof(buf) && buf[0]) {
-               devfs_handle_t de = _devfs_find_entry(NULL, buf, 0);
-
-               if (!de) {
-                       printk(KERN_ERR "%s: %s not found, cannot remove\n",
-                              __FUNCTION__, buf);
-                       dump_stack();
-                       return;
-               }
-
-               write_lock(&de->parent->u.dir.lock);
-               _devfs_unregister(de->parent, de);
-               devfs_put(de);
-               devfs_put(de);
-       }
-}
-
-/**
- *     devfs_generate_path - Generate a pathname for an entry, relative to the devfs root.
- *     @de: The devfs entry.
- *     @path: The buffer to write the pathname to. The pathname and '\0'
- *             terminator will be written at the end of the buffer.
- *     @buflen: The length of the buffer.
- *
- *     Returns the offset in the buffer where the pathname starts on success,
- *     else a negative error code.
- */
-
-static int devfs_generate_path(devfs_handle_t de, char *path, int buflen)
-{
-       int pos;
-#define NAMEOF(de) ( (de)->mode ? (de)->name : (de)->u.name )
-
-       if (de == NULL)
-               return -EINVAL;
-       VERIFY_ENTRY(de);
-       if (de->namelen >= buflen)
-               return -ENAMETOOLONG;   /*  Must be first       */
-       path[buflen - 1] = '\0';
-       if (de->parent == NULL)
-               return buflen - 1;      /*  Don't prepend root  */
-       pos = buflen - de->namelen - 1;
-       memcpy(path + pos, NAMEOF(de), de->namelen);
-       for (de = de->parent; de->parent != NULL; de = de->parent) {
-               if (pos - de->namelen - 1 < 0)
-                       return -ENAMETOOLONG;
-               path[--pos] = '/';
-               pos -= de->namelen;
-               memcpy(path + pos, NAMEOF(de), de->namelen);
-       }
-       return pos;
-}                              /*  End Function devfs_generate_path  */
-
-/**
- *     devfs_setup - Process kernel boot options.
- *     @str: The boot options after the "devfs=".
- */
-
-static int __init devfs_setup(char *str)
-{
-       static struct {
-               char *name;
-               unsigned int mask;
-               unsigned int *opt;
-       } devfs_options_tab[] __initdata = {
-#ifdef CONFIG_DEVFS_DEBUG
-               {
-               "dall", DEBUG_ALL, &devfs_debug_init}, {
-               "dmod", DEBUG_MODULE_LOAD, &devfs_debug_init}, {
-               "dreg", DEBUG_REGISTER, &devfs_debug_init}, {
-               "dunreg", DEBUG_UNREGISTER, &devfs_debug_init}, {
-               "dfree", DEBUG_FREE, &devfs_debug_init}, {
-               "diget", DEBUG_I_GET, &devfs_debug_init}, {
-               "dchange", DEBUG_SET_FLAGS, &devfs_debug_init}, {
-               "dsread", DEBUG_S_READ, &devfs_debug_init}, {
-               "dichange", DEBUG_I_CHANGE, &devfs_debug_init}, {
-               "dimknod", DEBUG_I_MKNOD, &devfs_debug_init}, {
-               "dilookup", DEBUG_I_LOOKUP, &devfs_debug_init}, {
-               "diunlink", DEBUG_I_UNLINK, &devfs_debug_init},
-#endif                         /*  CONFIG_DEVFS_DEBUG  */
-               {
-               "mount", OPTION_MOUNT, &boot_options}, {
-               NULL, 0, NULL}
-       };
-
-       while ((*str != '\0') && !isspace(*str)) {
-               int i, found = 0, invert = 0;
-
-               if (strncmp(str, "no", 2) == 0) {
-                       invert = 1;
-                       str += 2;
-               }
-               for (i = 0; devfs_options_tab[i].name != NULL; i++) {
-                       int len = strlen(devfs_options_tab[i].name);
-
-                       if (strncmp(str, devfs_options_tab[i].name, len) == 0) {
-                               if (invert)
-                                       *devfs_options_tab[i].opt &=
-                                           ~devfs_options_tab[i].mask;
-                               else
-                                       *devfs_options_tab[i].opt |=
-                                           devfs_options_tab[i].mask;
-                               str += len;
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found)
-                       return 0;       /*  No match         */
-               if (*str != ',')
-                       return 0;       /*  No more options  */
-               ++str;
-       }
-       return 1;
-}                              /*  End Function devfs_setup  */
-
-__setup("devfs=", devfs_setup);
-
-EXPORT_SYMBOL(devfs_mk_dir);
-EXPORT_SYMBOL(devfs_remove);
-
-/**
- *     try_modload - Notify devfsd of an inode lookup by a non-devfsd process.
- *     @parent: The parent devfs entry.
- *     @fs_info: The filesystem info.
- *     @name: The device name.
- *     @namelen: The number of characters in @name.
- *     @buf: A working area that will be used. This must not go out of scope
- *            until devfsd is idle again.
- *
- *     Returns 0 on success (event was queued), else a negative error code.
- */
-
-static int try_modload(struct devfs_entry *parent, struct fs_info *fs_info,
-                      const char *name, unsigned namelen,
-                      struct devfs_entry *buf)
-{
-       if (!(fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP)))
-               return -ENOENT;
-       if (is_devfsd_or_child(fs_info))
-               return -ENOENT;
-       memset(buf, 0, sizeof *buf);
-       atomic_set(&buf->refcount, 1);
-       buf->parent = parent;
-       buf->namelen = namelen;
-       buf->u.name = name;
-       WRITE_ENTRY_MAGIC(buf, MAGIC_VALUE);
-       if (!devfsd_notify_de(buf, DEVFSD_NOTIFY_LOOKUP, 0,
-                             current->euid, current->egid, fs_info))
-               return -ENOENT;
-       /*  Possible success: event has been queued  */
-       return 0;
-}                              /*  End Function try_modload  */
-
-/*  Superblock operations follow  */
-
-static struct inode_operations devfs_iops;
-static struct inode_operations devfs_dir_iops;
-static const struct file_operations devfs_fops;
-static const struct file_operations devfs_dir_fops;
-static struct inode_operations devfs_symlink_iops;
-
-static int devfs_notify_change(struct dentry *dentry, struct iattr *iattr)
-{
-       int retval;
-       struct devfs_entry *de;
-       struct inode *inode = dentry->d_inode;
-       struct fs_info *fs_info = inode->i_sb->s_fs_info;
-
-       de = get_devfs_entry_from_vfs_inode(inode);
-       if (de == NULL)
-               return -ENODEV;
-       retval = inode_change_ok(inode, iattr);
-       if (retval != 0)
-               return retval;
-       retval = inode_setattr(inode, iattr);
-       if (retval != 0)
-               return retval;
-       DPRINTK(DEBUG_I_CHANGE, "(%d): VFS inode: %p  devfs_entry: %p\n",
-               (int)inode->i_ino, inode, de);
-       DPRINTK(DEBUG_I_CHANGE, "():   mode: 0%o  uid: %d  gid: %d\n",
-               (int)inode->i_mode, (int)inode->i_uid, (int)inode->i_gid);
-       /*  Inode is not on hash chains, thus must save permissions here rather
-          than in a write_inode() method  */
-       de->mode = inode->i_mode;
-       de->inode.uid = inode->i_uid;
-       de->inode.gid = inode->i_gid;
-       de->inode.atime = inode->i_atime;
-       de->inode.mtime = inode->i_mtime;
-       de->inode.ctime = inode->i_ctime;
-       if ((iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) &&
-           !is_devfsd_or_child(fs_info))
-               devfsd_notify_de(de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
-                                inode->i_uid, inode->i_gid, fs_info);
-       return 0;
-}                              /*  End Function devfs_notify_change  */
-
-static struct super_operations devfs_sops = {
-       .drop_inode = generic_delete_inode,
-       .statfs = simple_statfs,
-};
-
-/**
- *     _devfs_get_vfs_inode - Get a VFS inode.
- *     @sb: The super block.
- *     @de: The devfs inode.
- *     @dentry: The dentry to register with the devfs inode.
- *
- *     Returns the inode on success, else %NULL. An implicit devfs_get() is
- *       performed if the inode is created.
- */
-
-static struct inode *_devfs_get_vfs_inode(struct super_block *sb,
-                                         struct devfs_entry *de,
-                                         struct dentry *dentry)
-{
-       struct inode *inode;
-
-       if (de->prev == de)
-               return NULL;    /*  Quick check to see if unhooked  */
-       if ((inode = new_inode(sb)) == NULL) {
-               PRINTK("(%s): new_inode() failed, de: %p\n", de->name, de);
-               return NULL;
-       }
-       if (de->parent) {
-               read_lock(&de->parent->u.dir.lock);
-               if (de->prev != de)
-                       de->inode.dentry = dentry;      /*      Not unhooked  */
-               read_unlock(&de->parent->u.dir.lock);
-       } else
-               de->inode.dentry = dentry;      /*  Root: no locking needed  */
-       if (de->inode.dentry != dentry) {       /*  Must have been unhooked  */
-               iput(inode);
-               return NULL;
-       }
-       /* FIXME where is devfs_put? */
-       inode->u.generic_ip = devfs_get(de);
-       inode->i_ino = de->inode.ino;
-       DPRINTK(DEBUG_I_GET, "(%d): VFS inode: %p  devfs_entry: %p\n",
-               (int)inode->i_ino, inode, de);
-       inode->i_blocks = 0;
-       inode->i_blksize = FAKE_BLOCK_SIZE;
-       inode->i_op = &devfs_iops;
-       inode->i_mode = de->mode;
-       if (S_ISDIR(de->mode)) {
-               inode->i_op = &devfs_dir_iops;
-               inode->i_fop = &devfs_dir_fops;
-       } else if (S_ISLNK(de->mode)) {
-               inode->i_op = &devfs_symlink_iops;
-               inode->i_size = de->u.symlink.length;
-       } else if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
-               init_special_inode(inode, de->mode, de->u.dev);
-       } else if (S_ISFIFO(de->mode) || S_ISSOCK(de->mode)) {
-               init_special_inode(inode, de->mode, 0);
-       } else {
-               PRINTK("(%s): unknown mode %o de: %p\n",
-                      de->name, de->mode, de);
-               iput(inode);
-               devfs_put(de);
-               return NULL;
-       }
-
-       inode->i_uid = de->inode.uid;
-       inode->i_gid = de->inode.gid;
-       inode->i_atime = de->inode.atime;
-       inode->i_mtime = de->inode.mtime;
-       inode->i_ctime = de->inode.ctime;
-       DPRINTK(DEBUG_I_GET, "():   mode: 0%o  uid: %d  gid: %d\n",
-               (int)inode->i_mode, (int)inode->i_uid, (int)inode->i_gid);
-       return inode;
-}                              /*  End Function _devfs_get_vfs_inode  */
-
-/*  File operations for device entries follow  */
-
-static int devfs_readdir(struct file *file, void *dirent, filldir_t filldir)
-{
-       int err, count;
-       int stored = 0;
-       struct fs_info *fs_info;
-       struct devfs_entry *parent, *de, *next = NULL;
-       struct inode *inode = file->f_dentry->d_inode;
-
-       fs_info = inode->i_sb->s_fs_info;
-       parent = get_devfs_entry_from_vfs_inode(file->f_dentry->d_inode);
-       if ((long)file->f_pos < 0)
-               return -EINVAL;
-       DPRINTK(DEBUG_F_READDIR, "(%s): fs_info: %p  pos: %ld\n",
-               parent->name, fs_info, (long)file->f_pos);
-       switch ((long)file->f_pos) {
-       case 0:
-               err = (*filldir) (dirent, "..", 2, file->f_pos,
-                                 parent_ino(file->f_dentry), DT_DIR);
-               if (err == -EINVAL)
-                       break;
-               if (err < 0)
-                       return err;
-               file->f_pos++;
-               ++stored;
-               /*  Fall through  */
-       case 1:
-               err =
-                   (*filldir) (dirent, ".", 1, file->f_pos, inode->i_ino,
-                               DT_DIR);
-               if (err == -EINVAL)
-                       break;
-               if (err < 0)
-                       return err;
-               file->f_pos++;
-               ++stored;
-               /*  Fall through  */
-       default:
-               /*  Skip entries  */
-               count = file->f_pos - 2;
-               read_lock(&parent->u.dir.lock);
-               for (de = parent->u.dir.first; de && (count > 0); de = de->next)
-                       --count;
-               devfs_get(de);
-               read_unlock(&parent->u.dir.lock);
-               /*  Now add all remaining entries  */
-               while (de) {
-                       err = (*filldir) (dirent, de->name, de->namelen,
-                                         file->f_pos, de->inode.ino,
-                                         de->mode >> 12);
-                       if (err < 0)
-                               devfs_put(de);
-                       else {
-                               file->f_pos++;
-                               ++stored;
-                       }
-                       if (err == -EINVAL)
-                               break;
-                       if (err < 0)
-                               return err;
-                       read_lock(&parent->u.dir.lock);
-                       next = devfs_get(de->next);
-                       read_unlock(&parent->u.dir.lock);
-                       devfs_put(de);
-                       de = next;
-               }
-               break;
-       }
-       return stored;
-}                              /*  End Function devfs_readdir  */
-
-/* Open devfs specific special files */
-static int devfs_open(struct inode *inode, struct file *file)
-{
-       int err;
-       int minor = MINOR(inode->i_rdev);
-       struct file_operations *old_fops, *new_fops;
-
-       switch (minor) {
-       case 0:         /* /dev/.devfsd */
-               new_fops = fops_get(&devfsd_fops);
-               break;
-#ifdef CONFIG_DEVFS_DEBUG
-       case 1:         /* /dev/.stat */
-               new_fops = fops_get(&stat_fops);
-               break;
-#endif
-       default:
-               return -ENODEV;
-       }
-
-       if (new_fops == NULL)
-               return -ENODEV;
-       old_fops = file->f_op;
-       file->f_op = new_fops;
-       err = new_fops->open ? new_fops->open(inode, file) : 0;
-       if (err) {
-               file->f_op = old_fops;
-               fops_put(new_fops);
-       } else
-               fops_put(old_fops);
-       return err;
-}                              /*  End Function devfs_open  */
-
-static const struct file_operations devfs_fops = {
-       .open = devfs_open,
-};
-
-static const struct file_operations devfs_dir_fops = {
-       .read = generic_read_dir,
-       .readdir = devfs_readdir,
-};
-
-/*  Dentry operations for device entries follow  */
-
-/**
- *     devfs_d_release - Callback for when a dentry is freed.
- *     @dentry: The dentry.
- */
-
-static void devfs_d_release(struct dentry *dentry)
-{
-       DPRINTK(DEBUG_D_RELEASE, "(%p): inode: %p\n", dentry, dentry->d_inode);
-}                              /*  End Function devfs_d_release  */
-
-/**
- *     devfs_d_iput - Callback for when a dentry loses its inode.
- *     @dentry: The dentry.
- *     @inode: The inode.
- */
-
-static void devfs_d_iput(struct dentry *dentry, struct inode *inode)
-{
-       struct devfs_entry *de;
-
-       de = get_devfs_entry_from_vfs_inode(inode);
-       DPRINTK(DEBUG_D_IPUT,
-               "(%s): dentry: %p inode: %p de: %p de->dentry: %p\n", de->name,
-               dentry, inode, de, de->inode.dentry);
-       if (de->inode.dentry && (de->inode.dentry != dentry))
-               OOPS("(%s): de: %p dentry: %p de->dentry: %p\n",
-                    de->name, de, dentry, de->inode.dentry);
-       de->inode.dentry = NULL;
-       iput(inode);
-       devfs_put(de);
-}                              /*  End Function devfs_d_iput  */
-
-static int devfs_d_delete(struct dentry *dentry);
-
-static struct dentry_operations devfs_dops = {
-       .d_delete = devfs_d_delete,
-       .d_release = devfs_d_release,
-       .d_iput = devfs_d_iput,
-};
-
-static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *);
-
-static struct dentry_operations devfs_wait_dops = {
-       .d_delete = devfs_d_delete,
-       .d_release = devfs_d_release,
-       .d_iput = devfs_d_iput,
-       .d_revalidate = devfs_d_revalidate_wait,
-};
-
-/**
- *     devfs_d_delete - Callback for when all files for a dentry are closed.
- *     @dentry: The dentry.
- */
-
-static int devfs_d_delete(struct dentry *dentry)
-{
-       struct inode *inode = dentry->d_inode;
-
-       if (dentry->d_op == &devfs_wait_dops)
-               dentry->d_op = &devfs_dops;
-       /*  Unhash dentry if negative (has no inode)  */
-       if (inode == NULL) {
-               DPRINTK(DEBUG_D_DELETE, "(%p): dropping negative dentry\n",
-                       dentry);
-               return 1;
-       }
-       return 0;
-}                              /*  End Function devfs_d_delete  */
-
-struct devfs_lookup_struct {
-       devfs_handle_t de;
-       wait_queue_head_t wait_queue;
-};
-
-/* XXX: this doesn't handle the case where we got a negative dentry
-        but a devfs entry has been registered in the meanwhile */
-static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *nd)
-{
-       struct inode *dir = dentry->d_parent->d_inode;
-       struct fs_info *fs_info = dir->i_sb->s_fs_info;
-       devfs_handle_t parent = get_devfs_entry_from_vfs_inode(dir);
-       struct devfs_lookup_struct *lookup_info = dentry->d_fsdata;
-       DECLARE_WAITQUEUE(wait, current);
-       int need_lock;
-
-       /*
-        * FIXME HACK
-        *
-        * make sure that
-        *   d_instantiate always runs under lock
-        *   we release i_mutex lock before going to sleep
-        *
-        * unfortunately sometimes d_revalidate is called with
-        * and sometimes without i_mutex lock held. The following checks
-        * attempt to deduce when we need to add (and drop resp.) lock
-        * here. This relies on current (2.6.2) calling coventions:
-        *
-        *   lookup_hash is always run under i_mutex and is passing NULL
-        *   as nd
-        *
-        *   open(...,O_CREATE,...) calls _lookup_hash under i_mutex
-        *   and sets flags to LOOKUP_OPEN|LOOKUP_CREATE
-        *
-        *   all other invocations of ->d_revalidate seem to happen
-        *   outside of i_mutex
-        */
-       need_lock = nd &&
-           (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT));
-
-       if (need_lock)
-               mutex_lock(&dir->i_mutex);
-
-       if (is_devfsd_or_child(fs_info)) {
-               devfs_handle_t de = lookup_info->de;
-               struct inode *inode;
-
-               DPRINTK(DEBUG_I_LOOKUP,
-                       "(%s): dentry: %p inode: %p de: %p by: \"%s\"\n",
-                       dentry->d_name.name, dentry, dentry->d_inode, de,
-                       current->comm);
-               if (dentry->d_inode)
-                       goto out;
-               if (de == NULL) {
-                       read_lock(&parent->u.dir.lock);
-                       de = _devfs_search_dir(parent, dentry->d_name.name,
-                                              dentry->d_name.len);
-                       read_unlock(&parent->u.dir.lock);
-                       if (de == NULL)
-                               goto out;
-                       lookup_info->de = de;
-               }
-               /*  Create an inode, now that the driver information is available  */
-               inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
-               if (!inode)
-                       goto out;
-               DPRINTK(DEBUG_I_LOOKUP,
-                       "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n",
-                       de->name, de->inode.ino, inode, de, current->comm);
-               d_instantiate(dentry, inode);
-               goto out;
-       }
-       if (lookup_info == NULL)
-               goto out;       /*  Early termination  */
-       read_lock(&parent->u.dir.lock);
-       if (dentry->d_fsdata) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               add_wait_queue(&lookup_info->wait_queue, &wait);
-               read_unlock(&parent->u.dir.lock);
-               /* at this point it is always (hopefully) locked */
-               mutex_unlock(&dir->i_mutex);
-               schedule();
-               mutex_lock(&dir->i_mutex);
-               /*
-                * This does not need nor should remove wait from wait_queue.
-                * Wait queue head is never reused - nothing is ever added to it
-                * after all waiters have been waked up and head itself disappears
-                * very soon after it. Moreover it is local variable on stack that
-                * is likely to have already disappeared so any reference to it
-                * at this point is buggy.
-                */
-
-       } else
-               read_unlock(&parent->u.dir.lock);
-
-      out:
-       if (need_lock)
-               mutex_unlock(&dir->i_mutex);
-       return 1;
-}                              /*  End Function devfs_d_revalidate_wait  */
-
-/*  Inode operations for device entries follow  */
-
-static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry,
-                                  struct nameidata *nd)
-{
-       struct devfs_entry tmp; /*  Must stay in scope until devfsd idle again  */
-       struct devfs_lookup_struct lookup_info;
-       struct fs_info *fs_info = dir->i_sb->s_fs_info;
-       struct devfs_entry *parent, *de;
-       struct inode *inode;
-       struct dentry *retval = NULL;
-
-       /*  Set up the dentry operations before anything else, to ensure cleaning
-          up on any error  */
-       dentry->d_op = &devfs_dops;
-       /*  First try to get the devfs entry for this directory  */
-       parent = get_devfs_entry_from_vfs_inode(dir);
-       DPRINTK(DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n",
-               dentry->d_name.name, dentry, parent, current->comm);
-       if (parent == NULL)
-               return ERR_PTR(-ENOENT);
-       read_lock(&parent->u.dir.lock);
-       de = _devfs_search_dir(parent, dentry->d_name.name, dentry->d_name.len);
-       read_unlock(&parent->u.dir.lock);
-       lookup_info.de = de;
-       init_waitqueue_head(&lookup_info.wait_queue);
-       dentry->d_fsdata = &lookup_info;
-       if (de == NULL) {       /*  Try with devfsd. For any kind of failure, leave a negative dentry
-                                  so someone else can deal with it (in the case where the sysadmin
-                                  does a mknod()). It's important to do this before hashing the
-                                  dentry, so that the devfsd queue is filled before revalidates
-                                  can start  */
-               if (try_modload(parent, fs_info, dentry->d_name.name, dentry->d_name.len, &tmp) < 0) {  /*  Lookup event was not queued to devfsd  */
-                       d_add(dentry, NULL);
-                       return NULL;
-               }
-       }
-       dentry->d_op = &devfs_wait_dops;
-       d_add(dentry, NULL);    /*  Open the floodgates  */
-       /*  Unlock directory semaphore, which will release any waiters. They
-          will get the hashed dentry, and may be forced to wait for
-          revalidation  */
-       mutex_unlock(&dir->i_mutex);
-       wait_for_devfsd_finished(fs_info);      /*  If I'm not devfsd, must wait  */
-       mutex_lock(&dir->i_mutex);      /*  Grab it again because them's the rules  */
-       de = lookup_info.de;
-       /*  If someone else has been so kind as to make the inode, we go home
-          early  */
-       if (dentry->d_inode)
-               goto out;
-       if (de == NULL) {
-               read_lock(&parent->u.dir.lock);
-               de = _devfs_search_dir(parent, dentry->d_name.name,
-                                      dentry->d_name.len);
-               read_unlock(&parent->u.dir.lock);
-               if (de == NULL)
-                       goto out;
-               /*  OK, there's an entry now, but no VFS inode yet  */
-       }
-       /*  Create an inode, now that the driver information is available  */
-       inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
-       if (!inode) {
-               retval = ERR_PTR(-ENOMEM);
-               goto out;
-       }
-       DPRINTK(DEBUG_I_LOOKUP,
-               "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n", de->name,
-               de->inode.ino, inode, de, current->comm);
-       d_instantiate(dentry, inode);
-      out:
-       write_lock(&parent->u.dir.lock);
-       dentry->d_op = &devfs_dops;
-       dentry->d_fsdata = NULL;
-       wake_up(&lookup_info.wait_queue);
-       write_unlock(&parent->u.dir.lock);
-       devfs_put(de);
-       return retval;
-}                              /*  End Function devfs_lookup  */
-
-static int devfs_unlink(struct inode *dir, struct dentry *dentry)
-{
-       int unhooked;
-       struct devfs_entry *de;
-       struct inode *inode = dentry->d_inode;
-       struct fs_info *fs_info = dir->i_sb->s_fs_info;
-
-       de = get_devfs_entry_from_vfs_inode(inode);
-       DPRINTK(DEBUG_I_UNLINK, "(%s): de: %p\n", dentry->d_name.name, de);
-       if (de == NULL)
-               return -ENOENT;
-       if (!de->vfs)
-               return -EPERM;
-       write_lock(&de->parent->u.dir.lock);
-       unhooked = _devfs_unhook(de);
-       write_unlock(&de->parent->u.dir.lock);
-       if (!unhooked)
-               return -ENOENT;
-       if (!is_devfsd_or_child(fs_info))
-               devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
-                                inode->i_uid, inode->i_gid, fs_info);
-       free_dentry(de);
-       devfs_put(de);
-       return 0;
-}                              /*  End Function devfs_unlink  */
-
-static int devfs_symlink(struct inode *dir, struct dentry *dentry,
-                        const char *symname)
-{
-       int err;
-       struct fs_info *fs_info = dir->i_sb->s_fs_info;
-       struct devfs_entry *parent, *de;
-       struct inode *inode;
-
-       /*  First try to get the devfs entry for this directory  */
-       parent = get_devfs_entry_from_vfs_inode(dir);
-       if (parent == NULL)
-               return -ENOENT;
-       err = devfs_do_symlink(parent, dentry->d_name.name, symname, &de);
-       DPRINTK(DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
-               dentry->d_name.name, err);
-       if (err < 0)
-               return err;
-       de->vfs = TRUE;
-       de->inode.uid = current->euid;
-       de->inode.gid = current->egid;
-       de->inode.atime = CURRENT_TIME;
-       de->inode.mtime = CURRENT_TIME;
-       de->inode.ctime = CURRENT_TIME;
-       if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
-               return -ENOMEM;
-       DPRINTK(DEBUG_DISABLED, "(%s): new VFS inode(%u): %p  dentry: %p\n",
-               dentry->d_name.name, de->inode.ino, inode, dentry);
-       d_instantiate(dentry, inode);
-       if (!is_devfsd_or_child(fs_info))
-               devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
-                                inode->i_uid, inode->i_gid, fs_info);
-       return 0;
-}                              /*  End Function devfs_symlink  */
-
-static int devfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
-       int err;
-       struct fs_info *fs_info = dir->i_sb->s_fs_info;
-       struct devfs_entry *parent, *de;
-       struct inode *inode;
-
-       mode = (mode & ~S_IFMT) | S_IFDIR;      /*  VFS doesn't pass S_IFMT part  */
-       parent = get_devfs_entry_from_vfs_inode(dir);
-       if (parent == NULL)
-               return -ENOENT;
-       de = _devfs_alloc_entry(dentry->d_name.name, dentry->d_name.len, mode);
-       if (!de)
-               return -ENOMEM;
-       de->vfs = TRUE;
-       if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
-               return err;
-       de->inode.uid = current->euid;
-       de->inode.gid = current->egid;
-       de->inode.atime = CURRENT_TIME;
-       de->inode.mtime = CURRENT_TIME;
-       de->inode.ctime = CURRENT_TIME;
-       if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
-               return -ENOMEM;
-       DPRINTK(DEBUG_DISABLED, "(%s): new VFS inode(%u): %p  dentry: %p\n",
-               dentry->d_name.name, de->inode.ino, inode, dentry);
-       d_instantiate(dentry, inode);
-       if (!is_devfsd_or_child(fs_info))
-               devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
-                                inode->i_uid, inode->i_gid, fs_info);
-       return 0;
-}                              /*  End Function devfs_mkdir  */
-
-static int devfs_rmdir(struct inode *dir, struct dentry *dentry)
-{
-       int err = 0;
-       struct devfs_entry *de;
-       struct fs_info *fs_info = dir->i_sb->s_fs_info;
-       struct inode *inode = dentry->d_inode;
-
-       if (dir->i_sb->s_fs_info != inode->i_sb->s_fs_info)
-               return -EINVAL;
-       de = get_devfs_entry_from_vfs_inode(inode);
-       if (de == NULL)
-               return -ENOENT;
-       if (!S_ISDIR(de->mode))
-               return -ENOTDIR;
-       if (!de->vfs)
-               return -EPERM;
-       /*  First ensure the directory is empty and will stay that way  */
-       write_lock(&de->u.dir.lock);
-       if (de->u.dir.first)
-               err = -ENOTEMPTY;
-       else
-               de->u.dir.no_more_additions = TRUE;
-       write_unlock(&de->u.dir.lock);
-       if (err)
-               return err;
-       /*  Now unhook the directory from its parent  */
-       write_lock(&de->parent->u.dir.lock);
-       if (!_devfs_unhook(de))
-               err = -ENOENT;
-       write_unlock(&de->parent->u.dir.lock);
-       if (err)
-               return err;
-       if (!is_devfsd_or_child(fs_info))
-               devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
-                                inode->i_uid, inode->i_gid, fs_info);
-       free_dentry(de);
-       devfs_put(de);
-       return 0;
-}                              /*  End Function devfs_rmdir  */
-
-static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
-                      dev_t rdev)
-{
-       int err;
-       struct fs_info *fs_info = dir->i_sb->s_fs_info;
-       struct devfs_entry *parent, *de;
-       struct inode *inode;
-
-       DPRINTK(DEBUG_I_MKNOD, "(%s): mode: 0%o  dev: %u:%u\n",
-               dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
-       parent = get_devfs_entry_from_vfs_inode(dir);
-       if (parent == NULL)
-               return -ENOENT;
-       de = _devfs_alloc_entry(dentry->d_name.name, dentry->d_name.len, mode);
-       if (!de)
-               return -ENOMEM;
-       de->vfs = TRUE;
-       if (S_ISCHR(mode) || S_ISBLK(mode))
-               de->u.dev = rdev;
-       if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
-               return err;
-       de->inode.uid = current->euid;
-       de->inode.gid = current->egid;
-       de->inode.atime = CURRENT_TIME;
-       de->inode.mtime = CURRENT_TIME;
-       de->inode.ctime = CURRENT_TIME;
-       if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
-               return -ENOMEM;
-       DPRINTK(DEBUG_I_MKNOD, ":   new VFS inode(%u): %p  dentry: %p\n",
-               de->inode.ino, inode, dentry);
-       d_instantiate(dentry, inode);
-       if (!is_devfsd_or_child(fs_info))
-               devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
-                                inode->i_uid, inode->i_gid, fs_info);
-       return 0;
-}                              /*  End Function devfs_mknod  */
-
-static void *devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
-       struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode);
-       nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV));
-       return NULL;
-}                              /*  End Function devfs_follow_link  */
-
-static struct inode_operations devfs_iops = {
-       .setattr = devfs_notify_change,
-};
-
-static struct inode_operations devfs_dir_iops = {
-       .lookup = devfs_lookup,
-       .unlink = devfs_unlink,
-       .symlink = devfs_symlink,
-       .mkdir = devfs_mkdir,
-       .rmdir = devfs_rmdir,
-       .mknod = devfs_mknod,
-       .setattr = devfs_notify_change,
-};
-
-static struct inode_operations devfs_symlink_iops = {
-       .readlink = generic_readlink,
-       .follow_link = devfs_follow_link,
-       .setattr = devfs_notify_change,
-};
-
-static int devfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-       struct inode *root_inode = NULL;
-
-       if (_devfs_get_root_entry() == NULL)
-               goto out_no_root;
-       atomic_set(&fs_info.devfsd_overrun_count, 0);
-       init_waitqueue_head(&fs_info.devfsd_wait_queue);
-       init_waitqueue_head(&fs_info.revalidate_wait_queue);
-       fs_info.sb = sb;
-       sb->s_fs_info = &fs_info;
-       sb->s_blocksize = 1024;
-       sb->s_blocksize_bits = 10;
-       sb->s_magic = DEVFS_SUPER_MAGIC;
-       sb->s_op = &devfs_sops;
-       sb->s_time_gran = 1;
-       if ((root_inode = _devfs_get_vfs_inode(sb, root_entry, NULL)) == NULL)
-               goto out_no_root;
-       sb->s_root = d_alloc_root(root_inode);
-       if (!sb->s_root)
-               goto out_no_root;
-       DPRINTK(DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->s_fs_info);
-       return 0;
-
-      out_no_root:
-       PRINTK("(): get root inode failed\n");
-       if (root_inode)
-               iput(root_inode);
-       return -EINVAL;
-}                              /*  End Function devfs_fill_super  */
-
-static int devfs_get_sb(struct file_system_type *fs_type,
-                       int flags, const char *dev_name,
-                       void *data, struct vfsmount *mnt)
-{
-       return get_sb_single(fs_type, flags, data, devfs_fill_super, mnt);
-}
-
-static struct file_system_type devfs_fs_type = {
-       .name = DEVFS_NAME,
-       .get_sb = devfs_get_sb,
-       .kill_sb = kill_anon_super,
-};
-
-/*  File operations for devfsd follow  */
-
-static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
-                          loff_t * ppos)
-{
-       int done = FALSE;
-       int ival;
-       loff_t pos, devname_offset, tlen, rpos;
-       devfs_handle_t de;
-       struct devfsd_buf_entry *entry;
-       struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->s_fs_info;
-       struct devfsd_notify_struct *info = fs_info->devfsd_info;
-       DECLARE_WAITQUEUE(wait, current);
-
-       /*  Verify the task has grabbed the queue  */
-       if (fs_info->devfsd_task != current)
-               return -EPERM;
-       info->major = 0;
-       info->minor = 0;
-       /*  Block for a new entry  */
-       set_current_state(TASK_INTERRUPTIBLE);
-       add_wait_queue(&fs_info->devfsd_wait_queue, &wait);
-       while (devfsd_queue_empty(fs_info)) {
-               fs_info->devfsd_sleeping = TRUE;
-               wake_up(&fs_info->revalidate_wait_queue);
-               schedule();
-               fs_info->devfsd_sleeping = FALSE;
-               if (signal_pending(current)) {
-                       remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
-                       __set_current_state(TASK_RUNNING);
-                       return -EINTR;
-               }
-               set_current_state(TASK_INTERRUPTIBLE);
-       }
-       remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
-       __set_current_state(TASK_RUNNING);
-       /*  Now play with the data  */
-       ival = atomic_read(&fs_info->devfsd_overrun_count);
-       info->overrun_count = ival;
-       entry = fs_info->devfsd_first_event;
-       info->type = entry->type;
-       info->mode = entry->mode;
-       info->uid = entry->uid;
-       info->gid = entry->gid;
-       de = entry->de;
-       if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
-               info->major = MAJOR(de->u.dev);
-               info->minor = MINOR(de->u.dev);
-       }
-       pos = devfs_generate_path(de, info->devname, DEVFS_PATHLEN);
-       if (pos < 0)
-               return pos;
-       info->namelen = DEVFS_PATHLEN - pos - 1;
-       if (info->mode == 0)
-               info->mode = de->mode;
-       devname_offset = info->devname - (char *)info;
-       rpos = *ppos;
-       if (rpos < devname_offset) {
-               /*  Copy parts of the header  */
-               tlen = devname_offset - rpos;
-               if (tlen > len)
-                       tlen = len;
-               if (copy_to_user(buf, (char *)info + rpos, tlen)) {
-                       return -EFAULT;
-               }
-               rpos += tlen;
-               buf += tlen;
-               len -= tlen;
-       }
-       if ((rpos >= devname_offset) && (len > 0)) {
-               /*  Copy the name  */
-               tlen = info->namelen + 1;
-               if (tlen > len)
-                       tlen = len;
-               else
-                       done = TRUE;
-               if (copy_to_user
-                   (buf, info->devname + pos + rpos - devname_offset, tlen)) {
-                       return -EFAULT;
-               }
-               rpos += tlen;
-       }
-       tlen = rpos - *ppos;
-       if (done) {
-               devfs_handle_t parent;
-
-               spin_lock(&fs_info->devfsd_buffer_lock);
-               fs_info->devfsd_first_event = entry->next;
-               if (entry->next == NULL)
-                       fs_info->devfsd_last_event = NULL;
-               spin_unlock(&fs_info->devfsd_buffer_lock);
-               for (; de != NULL; de = parent) {
-                       parent = de->parent;
-                       devfs_put(de);
-               }
-               kmem_cache_free(devfsd_buf_cache, entry);
-               if (ival > 0)
-                       atomic_sub(ival, &fs_info->devfsd_overrun_count);
-               *ppos = 0;
-       } else
-               *ppos = rpos;
-       return tlen;
-}                              /*  End Function devfsd_read  */
-
-static int devfsd_ioctl(struct inode *inode, struct file *file,
-                       unsigned int cmd, unsigned long arg)
-{
-       int ival;
-       struct fs_info *fs_info = inode->i_sb->s_fs_info;
-
-       switch (cmd) {
-       case DEVFSDIOC_GET_PROTO_REV:
-               ival = DEVFSD_PROTOCOL_REVISION_KERNEL;
-               if (copy_to_user((void __user *)arg, &ival, sizeof ival))
-                       return -EFAULT;
-               break;
-       case DEVFSDIOC_SET_EVENT_MASK:
-               /*  Ensure only one reader has access to the queue. This scheme will
-                  work even if the global kernel lock were to be removed, because it
-                  doesn't matter who gets in first, as long as only one gets it  */
-               if (fs_info->devfsd_task == NULL) {
-                       static DEFINE_SPINLOCK(lock);
-
-                       if (!spin_trylock(&lock))
-                               return -EBUSY;
-                       if (fs_info->devfsd_task != NULL) {     /*  We lost the race...  */
-                               spin_unlock(&lock);
-                               return -EBUSY;
-                       }
-                       fs_info->devfsd_task = current;
-                       spin_unlock(&lock);
-                       fs_info->devfsd_pgrp =
-                           (process_group(current) ==
-                            current->pid) ? process_group(current) : 0;
-                       fs_info->devfsd_file = file;
-                       fs_info->devfsd_info =
-                           kmalloc(sizeof *fs_info->devfsd_info, GFP_KERNEL);
-                       if (!fs_info->devfsd_info) {
-                               devfsd_close(inode, file);
-                               return -ENOMEM;
-                       }
-               } else if (fs_info->devfsd_task != current)
-                       return -EBUSY;
-               fs_info->devfsd_event_mask = arg;       /*  Let the masses come forth  */
-               break;
-       case DEVFSDIOC_RELEASE_EVENT_QUEUE:
-               if (fs_info->devfsd_file != file)
-                       return -EPERM;
-               return devfsd_close(inode, file);
-               /*break; */
-#ifdef CONFIG_DEVFS_DEBUG
-       case DEVFSDIOC_SET_DEBUG_MASK:
-               if (copy_from_user(&ival, (void __user *)arg, sizeof ival))
-                       return -EFAULT;
-               devfs_debug = ival;
-               break;
-#endif
-       default:
-               return -ENOIOCTLCMD;
-       }
-       return 0;
-}                              /*  End Function devfsd_ioctl  */
-
-static int devfsd_close(struct inode *inode, struct file *file)
-{
-       struct devfsd_buf_entry *entry, *next;
-       struct fs_info *fs_info = inode->i_sb->s_fs_info;
-
-       if (fs_info->devfsd_file != file)
-               return 0;
-       fs_info->devfsd_event_mask = 0;
-       fs_info->devfsd_file = NULL;
-       spin_lock(&fs_info->devfsd_buffer_lock);
-       entry = fs_info->devfsd_first_event;
-       fs_info->devfsd_first_event = NULL;
-       fs_info->devfsd_last_event = NULL;
-       kfree(fs_info->devfsd_info);
-       fs_info->devfsd_info = NULL;
-       spin_unlock(&fs_info->devfsd_buffer_lock);
-       fs_info->devfsd_pgrp = 0;
-       fs_info->devfsd_task = NULL;
-       wake_up(&fs_info->revalidate_wait_queue);
-       for (; entry; entry = next) {
-               next = entry->next;
-               kmem_cache_free(devfsd_buf_cache, entry);
-       }
-       return 0;
-}                              /*  End Function devfsd_close  */
-
-#ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
-                        loff_t * ppos)
-{
-       ssize_t num;
-       char txt[80];
-
-       num = sprintf(txt, "Number of entries: %u  number of bytes: %u\n",
-                     stat_num_entries, stat_num_bytes) + 1;
-       if (*ppos >= num)
-               return 0;
-       if (*ppos + len > num)
-               len = num - *ppos;
-       if (copy_to_user(buf, txt + *ppos, len))
-               return -EFAULT;
-       *ppos += len;
-       return len;
-}                              /*  End Function stat_read  */
-#endif
-
-static int __init init_devfs_fs(void)
-{
-       int err;
-       int major;
-       struct devfs_entry *devfsd;
-#ifdef CONFIG_DEVFS_DEBUG
-       struct devfs_entry *stat;
-#endif
-
-       if (_devfs_get_root_entry() == NULL)
-               return -ENOMEM;
-
-       printk(KERN_INFO "%s: %s Richard Gooch (rgooch@atnf.csiro.au)\n",
-              DEVFS_NAME, DEVFS_VERSION);
-       devfsd_buf_cache = kmem_cache_create("devfsd_event",
-                                            sizeof(struct devfsd_buf_entry),
-                                            0, 0, NULL, NULL);
-       if (!devfsd_buf_cache)
-               OOPS("(): unable to allocate event slab\n");
-#ifdef CONFIG_DEVFS_DEBUG
-       devfs_debug = devfs_debug_init;
-       printk(KERN_INFO "%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
-#endif
-       printk(KERN_INFO "%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
-
-       /* register special device for devfsd communication */
-       major = register_chrdev(0, "devfs", &devfs_fops);
-       if (major < 0)
-               return major;
-
-       /*  And create the entry for ".devfsd"  */
-       devfsd = _devfs_alloc_entry(".devfsd", 0, S_IFCHR | S_IRUSR | S_IWUSR);
-       if (devfsd == NULL)
-               return -ENOMEM;
-       devfsd->u.dev = MKDEV(major, 0);
-       _devfs_append_entry(root_entry, devfsd, NULL);
-
-#ifdef CONFIG_DEVFS_DEBUG
-       stat = _devfs_alloc_entry(".stat", 0, S_IFCHR | S_IRUGO);
-       if (stat == NULL)
-               return -ENOMEM;
-       stat->u.dev = MKDEV(major, 1);
-       _devfs_append_entry(root_entry, stat, NULL);
-#endif
-
-       err = register_filesystem(&devfs_fs_type);
-       return err;
-}                              /*  End Function init_devfs_fs  */
-
-void __init mount_devfs_fs(void)
-{
-       int err;
-
-       if (!(boot_options & OPTION_MOUNT))
-               return;
-       err = do_mount("none", "/dev", "devfs", 0, NULL);
-       if (err == 0)
-               printk(KERN_INFO "Mounted devfs on /dev\n");
-       else
-               PRINTK("(): unable to mount devfs, err: %d\n", err);
-}                              /*  End Function mount_devfs_fs  */
-
-module_init(init_devfs_fs)
diff --git a/fs/devfs/util.c b/fs/devfs/util.c
deleted file mode 100644 (file)
index db06d38..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*  devfs (Device FileSystem) utilities.
-
-    Copyright (C) 1999-2002  Richard Gooch
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
-    The postal address is:
-      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-
-    ChangeLog
-
-    19991031   Richard Gooch <rgooch@atnf.csiro.au>
-               Created.
-    19991103   Richard Gooch <rgooch@atnf.csiro.au>
-               Created <_devfs_convert_name> and supported SCSI and IDE CD-ROMs
-    20000203   Richard Gooch <rgooch@atnf.csiro.au>
-               Changed operations pointer type to void *.
-    20000621   Richard Gooch <rgooch@atnf.csiro.au>
-               Changed interface to <devfs_register_series>.
-    20000622   Richard Gooch <rgooch@atnf.csiro.au>
-               Took account of interface change to <devfs_mk_symlink>.
-               Took account of interface change to <devfs_mk_dir>.
-    20010519   Richard Gooch <rgooch@atnf.csiro.au>
-               Documentation cleanup.
-    20010709   Richard Gooch <rgooch@atnf.csiro.au>
-               Created <devfs_*alloc_major> and <devfs_*alloc_devnum>.
-    20010710   Richard Gooch <rgooch@atnf.csiro.au>
-               Created <devfs_*alloc_unique_number>.
-    20010730   Richard Gooch <rgooch@atnf.csiro.au>
-               Documentation typo fix.
-    20010806   Richard Gooch <rgooch@atnf.csiro.au>
-               Made <block_semaphore> and <char_semaphore> private.
-    20010813   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixed bug in <devfs_alloc_unique_number>: limited to 128 numbers
-    20010818   Richard Gooch <rgooch@atnf.csiro.au>
-               Updated major masks up to Linus' "no new majors" proclamation.
-              Block: were 126 now 122 free, char: were 26 now 19 free.
-    20020324   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
-              bitfield.
-    20020326   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixed bitfield data type for <devfs_*alloc_devnum>.
-               Made major bitfield type and initialiser 64 bit safe.
-    20020413   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixed shift warning on 64 bit machines.
-    20020428   Richard Gooch <rgooch@atnf.csiro.au>
-               Copied and used macro for error messages from fs/devfs/base.c 
-    20021013   Richard Gooch <rgooch@atnf.csiro.au>
-               Documentation fix.
-    20030101   Adam J. Richter <adam@yggdrasil.com>
-               Eliminate DEVFS_SPECIAL_{CHR,BLK}.  Use mode_t instead.
-    20030106   Christoph Hellwig <hch@infradead.org>
-               Rewrite devfs_{,de}alloc_devnum to look like C code.
-*/
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/genhd.h>
-#include <linux/bitops.h>
-
-int devfs_register_tape(const char *name)
-{
-       char tname[32], dest[64];
-       static unsigned int tape_counter;
-       unsigned int n = tape_counter++;
-
-       sprintf(dest, "../%s", name);
-       sprintf(tname, "tapes/tape%u", n);
-       devfs_mk_symlink(tname, dest);
-
-       return n;
-}
-
-EXPORT_SYMBOL(devfs_register_tape);
-
-void devfs_unregister_tape(int num)
-{
-       if (num >= 0)
-               devfs_remove("tapes/tape%u", num);
-}
-
-EXPORT_SYMBOL(devfs_unregister_tape);
index 42c7d3878ed08272f5d2341fe93d2182c2257665..d713ce6b3e12935891bda7e21d301ec3d53038f8 100644 (file)
@@ -4,7 +4,6 @@
 
 obj-y := check.o
 
-obj-$(CONFIG_DEVFS_FS) += devfs.o
 obj-$(CONFIG_ACORN_PARTITION) += acorn.o
 obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
 obj-$(CONFIG_ATARI_PARTITION) += atari.o
index 2ef313a96b665a09b3e076a6259d131459fc1900..839634026eb5206e934e34a78ec5a5998248569e 100644 (file)
 #include <linux/fs.h>
 #include <linux/kmod.h>
 #include <linux/ctype.h>
-#include <linux/devfs_fs_kernel.h>
 
 #include "check.h"
-#include "devfs.h"
 
 #include "acorn.h"
 #include "amiga.h"
@@ -161,18 +159,11 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
        if (!state)
                return NULL;
 
-#ifdef CONFIG_DEVFS_FS
-       if (hd->devfs_name[0] != '\0') {
-               printk(KERN_INFO " /dev/%s:", hd->devfs_name);
+       disk_name(hd, 0, state->name);
+       printk(KERN_INFO " %s:", state->name);
+       if (isdigit(state->name[strlen(state->name)-1]))
                sprintf(state->name, "p");
-       }
-#endif
-       else {
-               disk_name(hd, 0, state->name);
-               printk(KERN_INFO " %s:", state->name);
-               if (isdigit(state->name[strlen(state->name)-1]))
-                       sprintf(state->name, "p");
-       }
+
        state->limit = hd->minors;
        i = res = 0;
        while (!res && check_part[i]) {
@@ -328,7 +319,6 @@ void delete_partition(struct gendisk *disk, int part)
        p->nr_sects = 0;
        p->ios[0] = p->ios[1] = 0;
        p->sectors[0] = p->sectors[1] = 0;
-       devfs_remove("%s/part%d", disk->devfs_name, part);
        sysfs_remove_link(&p->kobj, "subsystem");
        if (p->holder_dir)
                kobject_unregister(p->holder_dir);
@@ -350,10 +340,6 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
        p->nr_sects = len;
        p->partno = part;
 
-       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor + part),
-                       S_IFBLK|S_IRUSR|S_IWUSR,
-                       "%s/part%d", disk->devfs_name, part);
-
        if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1]))
                snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part);
        else
@@ -423,14 +409,8 @@ void register_disk(struct gendisk *disk)
        disk_sysfs_add_subdirs(disk);
 
        /* No minors to use for partitions */
-       if (disk->minors == 1) {
-               if (disk->devfs_name[0] != '\0')
-                       devfs_add_disk(disk);
+       if (disk->minors == 1)
                goto exit;
-       }
-
-       /* always add handle for the whole disk */
-       devfs_add_partitioned(disk);
 
        /* No such device (e.g., media were just removed) */
        if (!get_capacity(disk))
@@ -538,8 +518,6 @@ void del_gendisk(struct gendisk *disk)
        disk_stat_set_all(disk, 0);
        disk->stamp = 0;
 
-       devfs_remove_disk(disk);
-
        kobject_uevent(&disk->kobj, KOBJ_REMOVE);
        if (disk->holder_dir)
                kobject_unregister(disk->holder_dir);
diff --git a/fs/partitions/devfs.c b/fs/partitions/devfs.c
deleted file mode 100644 (file)
index 3f0a780..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * This tries to keep block devices away from devfs as much as possible.
- */
-#include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/vmalloc.h>
-#include <linux/genhd.h>
-#include <linux/bitops.h>
-#include <linux/mutex.h>
-
-
-struct unique_numspace {
-       u32               num_free;          /*  Num free in bits       */
-       u32               length;            /*  Array length in bytes  */
-       unsigned long     *bits;
-       struct semaphore  mutex;
-};
-
-static DEFINE_MUTEX(numspace_mutex);
-
-static int expand_numspace(struct unique_numspace *s)
-{
-       u32 length;
-       void *bits;
-
-       if (s->length < 16)
-               length = 16;
-       else
-               length = s->length << 1;
-
-       bits = vmalloc(length);
-       if (!bits)
-               return -ENOMEM;
-       if (s->bits) {
-               memcpy(bits, s->bits, s->length);
-               vfree(s->bits);
-       }
-               
-       s->num_free = (length - s->length) << 3;
-       s->bits = bits;
-       memset(bits + s->length, 0, length - s->length);
-       s->length = length;
-
-       return 0;
-}
-
-static int alloc_unique_number(struct unique_numspace *s)
-{
-       int rval = 0;
-
-       mutex_lock(&numspace_mutex);
-       if (s->num_free < 1)
-               rval = expand_numspace(s);
-       if (!rval) {
-               rval = find_first_zero_bit(s->bits, s->length << 3);
-               --s->num_free;
-               __set_bit(rval, s->bits);
-       }
-       mutex_unlock(&numspace_mutex);
-
-       return rval;
-}
-
-static void dealloc_unique_number(struct unique_numspace *s, int number)
-{
-       int old_val;
-
-       if (number >= 0) {
-               mutex_lock(&numspace_mutex);
-               old_val = __test_and_clear_bit(number, s->bits);
-               if (old_val)
-                       ++s->num_free;
-               mutex_unlock(&numspace_mutex);
-       }
-}
-
-static struct unique_numspace disc_numspace;
-static struct unique_numspace cdrom_numspace;
-
-void devfs_add_partitioned(struct gendisk *disk)
-{
-       char dirname[64], symlink[16];
-
-       devfs_mk_dir(disk->devfs_name);
-       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
-                       S_IFBLK|S_IRUSR|S_IWUSR,
-                       "%s/disc", disk->devfs_name);
-
-       disk->number = alloc_unique_number(&disc_numspace);
-
-       sprintf(symlink, "discs/disc%d", disk->number);
-       sprintf(dirname, "../%s", disk->devfs_name);
-       devfs_mk_symlink(symlink, dirname);
-
-}
-
-void devfs_add_disk(struct gendisk *disk)
-{
-       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
-                       (disk->flags & GENHD_FL_CD) ?
-                               S_IFBLK|S_IRUGO|S_IWUGO :
-                               S_IFBLK|S_IRUSR|S_IWUSR,
-                       "%s", disk->devfs_name);
-
-       if (disk->flags & GENHD_FL_CD) {
-               char dirname[64], symlink[16];
-
-               disk->number = alloc_unique_number(&cdrom_numspace);
-
-               sprintf(symlink, "cdroms/cdrom%d", disk->number);
-               sprintf(dirname, "../%s", disk->devfs_name);
-               devfs_mk_symlink(symlink, dirname);
-       }
-}
-
-void devfs_remove_disk(struct gendisk *disk)
-{
-       if (disk->minors != 1) {
-               devfs_remove("discs/disc%d", disk->number);
-               dealloc_unique_number(&disc_numspace, disk->number);
-               devfs_remove("%s/disc", disk->devfs_name);
-       }
-       if (disk->flags & GENHD_FL_CD) {
-               devfs_remove("cdroms/cdrom%d", disk->number);
-               dealloc_unique_number(&cdrom_numspace, disk->number);
-       }
-       devfs_remove(disk->devfs_name);
-}
-
-
diff --git a/fs/partitions/devfs.h b/fs/partitions/devfs.h
deleted file mode 100644 (file)
index 176118b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#ifdef CONFIG_DEVFS_FS
-void devfs_add_disk(struct gendisk *dev);
-void devfs_add_partitioned(struct gendisk *dev);
-void devfs_remove_disk(struct gendisk *dev);
-#else
-# define devfs_add_disk(disk)                  do { } while (0)
-# define devfs_add_partitioned(disk)           do { } while (0)
-# define devfs_remove_disk(disk)               do { } while (0)
-#endif
index b5193229132a12e5f73bfe510830aef1ab95235b..d22ab97ea72efc27e45ef4573498baef7c3a1059 100644 (file)
@@ -51,6 +51,7 @@
 #define SCM_TIMESTAMP          SO_TIMESTAMP
 
 #define SO_PEERSEC             30
+#define SO_PASSSEC             34
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION             19
index 3c51da6438c95b6734e38243ebdbb21af5a6972a..19f7df702b069ebb8398dc3f2dc9d16d9564ec95 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
index 3c51da6438c95b6734e38243ebdbb21af5a6972a..19f7df702b069ebb8398dc3f2dc9d16d9564ec95 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
index 8b1da3e58c5580468f60961c498592b71c7f56c7..01cfdf1d6d339ab2f0b4a25649989e6cacfa9ea8 100644 (file)
@@ -50,6 +50,7 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
 
index 7177f8b9817cc3586bf6c4bd4b21662ed32d2d72..31db18fc871fa07af87aad3a932eac3a46003362 100644 (file)
@@ -48,6 +48,7 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
 
index d98cf85bafc1d667d9d2ebdac62752a7da267214..ebc830fee0d0888ce1f3e938d06d1d1832205ac4 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
index 802ae76195b72a4a09e3f9c052e96968389be694..5755d57c4e952c121a0a215c94778cbf1c1386e6 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
index a255006fb7b51f0db085e82f547f25938ee7c84c..d638ef3d50c3a5767a7d6a50496d47775c2145dc 100644 (file)
@@ -57,5 +57,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_IA64_SOCKET_H */
index 8b6680f223c0b4a5f18781f36129cc1d541b68f8..acdf748fcdc8a38220ffea31e946947ca671bee1 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_M32R_SOCKET_H */
index f578ca4b776a3bfcb45b1e60781ebeb74eac785c..a5966ec005ae67d1bdb338aa209f1cf76f85bf78 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
index 0bb31e5aaca6a23f93ffcf7aaa02ae41118e6be5..36ebe4e186a7a635970909c46f03cd8b394bc367 100644 (file)
@@ -69,6 +69,7 @@ To add: #define SO_REUSEPORT 0x0200   /* Allow local address and port reuse.  */
 #define SO_PEERSEC             30
 #define SO_SNDBUFFORCE         31
 #define SO_RCVBUFFORCE         33
+#define SO_PASSSEC             34
 
 #ifdef __KERNEL__
 
index 1bf54dc53c101337200deeaafa7adcf27daf97ff..ce2eae1708b5ec84ad7976c83984c35ceb5b2122 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          0x401c
 
 #define SO_PEERSEC             0x401d
+#define SO_PASSSEC             0x401e
 
 #endif /* _ASM_SOCKET_H */
index e4b8177d4acc48313dbb905bbf59400d659f0253..c8b1da50e72db7df8be5c61b36d8f6694461fd55 100644 (file)
@@ -55,5 +55,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_POWERPC_SOCKET_H */
index 3be5d760ffcd9c5eaa1a81ce0b6449cf2f68bfa7..16dbc7d174506e2b2754210ab24e7451f3cca6e7 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/device.h>
 
 #include <asm/mmu.h>
index 15a5298c8744bf1401be8b0cb736b406b410d55d..1778a49a74c5b0fd24facee8d5d49fc3657f3600 100644 (file)
@@ -56,5 +56,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
index 553904ff9336c2e26304810e0f0db20e0f4a4220..ca70362eb563bf7224d743340dde1364dc824242 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* __ASM_SH_SOCKET_H */
index 4816d102f918438948cc5a3e8f41ecd83648fd73..80ea31f6e17f937358025b0cfea00b6d409f99d3 100644 (file)
@@ -4,10 +4,12 @@
 
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <asm/openprom.h>
 #include <asm/prom.h>
 
 extern struct bus_type ebus_bus_type;
 extern struct bus_type sbus_bus_type;
+extern struct bus_type of_bus_type;
 
 /*
  * The of_device is a kind of "base class" that is a superset of
@@ -16,11 +18,25 @@ extern struct bus_type sbus_bus_type;
  */
 struct of_device
 {
-       struct device_node      *node;          /* OF device node */
-       struct device           dev;            /* Generic device interface */
+       struct device_node              *node;
+       struct device                   dev;
+       struct resource                 resource[PROMREG_MAX];
+       unsigned int                    irqs[PROMINTR_MAX];
+       int                             num_irqs;
+
+       void                            *sysdata;
+
+       int                             slot;
+       int                             portid;
+       int                             clock_freq;
 };
 #define        to_of_device(d) container_of(d, struct of_device, dev)
 
+extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
+extern void of_iounmap(void __iomem *base, unsigned long size);
+
+extern struct of_device *of_find_device_by_node(struct device_node *);
+
 extern const struct of_device_id *of_match_device(
        const struct of_device_id *matches, const struct of_device *dev);
 
index f9cf44c0716428d56971062ab29db6a35164a290..86c13dccea3d37f36cc9416d19e7e6c60fc83b8e 100644 (file)
 typedef u32 phandle;
 typedef u32 ihandle;
 
-struct interrupt_info {
-       int     line;
-       int     sense;          /* +ve/-ve logic, edge or level, etc. */
-};
-
 struct property {
        char    *name;
        int     length;
@@ -43,9 +38,6 @@ struct device_node {
        char    *name;
        char    *type;
        phandle node;
-       phandle linux_phandle;
-       int     n_intrs;
-       struct  interrupt_info *intrs;
        char    *path_component_name;
        char    *full_name;
 
@@ -69,6 +61,8 @@ struct device_node {
 #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
 #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
 
+#define OF_BAD_ADDR    ((u64)-1)
+
 static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
 {
        dn->pde = de;
@@ -101,6 +95,8 @@ extern int of_set_property(struct device_node *node, const char *name, void *val
 extern int of_getintprop_default(struct device_node *np,
                                 const char *name,
                                 int def);
+extern int of_n_addr_cells(struct device_node *np);
+extern int of_n_size_cells(struct device_node *np);
 
 extern void prom_build_devicetree(void);
 
index 4e0ce3a35ea9d48b62a5195b49daba535fa1e596..f6c4e5baf3f7bd4ea9c065b25c9d49d723de1ace 100644 (file)
@@ -48,6 +48,7 @@
 #define SCM_TIMESTAMP          SO_TIMESTAMP
 
 #define SO_PEERSEC             0x001e
+#define SO_PASSSEC             0x001f
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION             0x5001
index 024088ef9d27060dd7b99c436231f7d5a3bfc087..a62c7b997d662fa1dc9b552b91cb57b5cd808f19 100644 (file)
@@ -4,11 +4,13 @@
 
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <asm/openprom.h>
 #include <asm/prom.h>
 
 extern struct bus_type isa_bus_type;
 extern struct bus_type ebus_bus_type;
 extern struct bus_type sbus_bus_type;
+extern struct bus_type of_bus_type;
 
 /*
  * The of_device is a kind of "base class" that is a superset of
@@ -17,11 +19,25 @@ extern struct bus_type sbus_bus_type;
  */
 struct of_device
 {
-       struct device_node      *node;          /* OF device node */
-       struct device           dev;            /* Generic device interface */
+       struct device_node              *node;
+       struct device                   dev;
+       struct resource                 resource[PROMREG_MAX];
+       unsigned int                    irqs[PROMINTR_MAX];
+       int                             num_irqs;
+
+       void                            *sysdata;
+
+       int                             slot;
+       int                             portid;
+       int                             clock_freq;
 };
 #define        to_of_device(d) container_of(d, struct of_device, dev)
 
+extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
+extern void of_iounmap(void __iomem *base, unsigned long size);
+
+extern struct of_device *of_find_device_by_node(struct device_node *);
+
 extern const struct of_device_id *of_match_device(
        const struct of_device_id *matches, const struct of_device *dev);
 
index cebe80b1da6c70f9aa626ea13add9fd7a2e00ac1..dcfa7629358c396c9e977447ee24f56b31cd799e 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/page.h>
 #include <asm/oplib.h>
 #include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/iommu.h>
 
 /* The abstraction used here is that there are PCI controllers,
@@ -209,7 +210,6 @@ struct pci_controller_info {
 
        /* Operations which are controller specific. */
        void (*scan_bus)(struct pci_controller_info *);
-       unsigned int (*irq_build)(struct pci_pbm_info *, struct pci_dev *, unsigned int);
        void (*base_address_update)(struct pci_dev *, int);
        void (*resource_adjust)(struct pci_dev *, struct resource *, struct resource *);
 
@@ -217,8 +217,6 @@ struct pci_controller_info {
        struct pci_ops                  *pci_ops;
        unsigned int                    pci_first_busno;
        unsigned int                    pci_last_busno;
-
-       void                            *starfire_cookie;
 };
 
 /* PCI devices which are not bridges have this placed in their pci_dev
@@ -228,6 +226,7 @@ struct pci_controller_info {
 struct pcidev_cookie {
        struct pci_pbm_info             *pbm;
        struct device_node              *prom_node;
+       struct of_device                *op;
        struct linux_prom_pci_registers prom_regs[PROMREG_MAX];
        int num_prom_regs;
        struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
index 265614d497c43990bc0087cee48d7c401986af79..99671ed6625d15a8fa19f2a721ed9eb28f5255ef 100644 (file)
 typedef u32 phandle;
 typedef u32 ihandle;
 
-struct interrupt_info {
-       int     line;
-       int     sense;          /* +ve/-ve logic, edge or level, etc. */
-};
-
 struct property {
        char    *name;
        int     length;
@@ -39,13 +34,11 @@ struct property {
        unsigned int unique_id;
 };
 
+struct of_irq_controller;
 struct device_node {
        char    *name;
        char    *type;
        phandle node;
-       phandle linux_phandle;
-       int     n_intrs;
-       struct  interrupt_info *intrs;
        char    *path_component_name;
        char    *full_name;
 
@@ -61,6 +54,13 @@ struct device_node {
        unsigned long _flags;
        void    *data;
        unsigned int unique_id;
+
+       struct of_irq_controller *irq_trans;
+};
+
+struct of_irq_controller {
+       unsigned int    (*irq_build)(struct device_node *, unsigned int, void *);
+       void            *data;
 };
 
 /* flag descriptions */
@@ -69,6 +69,8 @@ struct device_node {
 #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
 #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
 
+#define OF_BAD_ADDR    ((u64)-1)
+
 static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
 {
        dn->pde = de;
@@ -101,6 +103,8 @@ extern int of_set_property(struct device_node *node, const char *name, void *val
 extern int of_getintprop_default(struct device_node *np,
                                 const char *name,
                                 int def);
+extern int of_n_addr_cells(struct device_node *np);
+extern int of_n_size_cells(struct device_node *np);
 
 extern void prom_build_devicetree(void);
 
index 56ee985e46050f9502336b78c2abe29c71813fa8..7efd49d31bb8a55a71f9ce9d07dcdf3a2a2e920f 100644 (file)
@@ -80,7 +80,6 @@ struct sbus_bus {
        int num_sbus_ranges;
 
        int portid;
-       void *starfire_cookie;
 };
 #define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
 
index 59987dad3359912059a37039512dafc807c5d2df..754d46a50af30af85564808262592cc16f59fe48 100644 (file)
@@ -48,6 +48,7 @@
 #define SCM_TIMESTAMP          SO_TIMESTAMP
 
 #define SO_PEERSEC             0x001e
+#define SO_PASSSEC             0x001f
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION             0x5001
index b606cb2b32a89536e6f55f38cd5e37bd9e709e34..48b50b5e35b0fcb90da700d8d20b271e93d26a79 100644 (file)
@@ -14,7 +14,7 @@ extern int this_is_starfire;
 extern void check_if_starfire(void);
 extern void starfire_cpu_setup(void);
 extern int starfire_hard_smp_processor_id(void);
-extern void *starfire_hookup(int);
+extern void starfire_hookup(int);
 extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
 
 #endif
index 0240d366a0a4db32672c6e20c734efe21e32aa17..0dfe55ac2ef2acf1deeb4e72e8ca112a770d8c8a 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* __V850_SOCKET_H__ */
index f2cdbeae5d5ba17e453f24aa172f6076f9441f9b..b46702607933ddedf9e5dc323da8d4c787799e94 100644 (file)
@@ -48,5 +48,6 @@
 #define SO_ACCEPTCONN          30
 
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _ASM_SOCKET_H */
index 00f83f3a6d72194ad0b0f3059897cecde2d61e0f..971d231be60ebe095f9a5b29e21831662df2e1f8 100644 (file)
@@ -59,5 +59,6 @@
 
 #define SO_ACCEPTCONN          30
 #define SO_PEERSEC             31
+#define SO_PASSSEC             34
 
 #endif /* _XTENSA_SOCKET_H */
index 1eb238affb124fe8d657cda89f55b2a627142eb8..41788a31c4382b86698cf7a16875588d470bf069 100644 (file)
@@ -7,6 +7,7 @@
 #define LINUX_ATMDEV_H
 
 
+#include <linux/device.h>
 #include <linux/atmapi.h>
 #include <linux/atm.h>
 #include <linux/atmioc.h>
@@ -358,6 +359,7 @@ struct atm_dev {
        struct proc_dir_entry *proc_entry; /* proc entry */
        char *proc_name;                /* proc entry name */
 #endif
+       struct class_device class_dev;  /* sysfs class device */
        struct list_head dev_list;      /* linkage */
 };
 
@@ -459,7 +461,7 @@ static inline void atm_dev_put(struct atm_dev *dev)
                BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags));
                if (dev->ops->dev_close)
                        dev->ops->dev_close(dev);
-               kfree(dev);
+               class_device_put(&dev->class_dev);
        }
 }
 
index 917d62e4148073ebb80d82cec1bb7399da468e1d..269d000bb2a3e6f283a66a177b779069acc4962f 100644 (file)
@@ -567,11 +567,6 @@ COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
 COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
 COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
 COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
-/* DEVFS */
-COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
-COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
-COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE)
-COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK)
 /* Raw devices */
 COMPATIBLE_IOCTL(RAW_SETBIND)
 COMPATIBLE_IOCTL(RAW_GETBIND)
diff --git a/include/linux/devfs_fs.h b/include/linux/devfs_fs.h
deleted file mode 100644 (file)
index de236f4..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _LINUX_DEVFS_FS_H
-#define _LINUX_DEVFS_FS_H
-
-#include <linux/ioctl.h>
-
-#define DEVFSD_PROTOCOL_REVISION_KERNEL  5
-
-#define        DEVFSD_IOCTL_BASE       'd'
-
-/*  These are the various ioctls  */
-#define DEVFSDIOC_GET_PROTO_REV         _IOR(DEVFSD_IOCTL_BASE, 0, int)
-#define DEVFSDIOC_SET_EVENT_MASK        _IOW(DEVFSD_IOCTL_BASE, 2, int)
-#define DEVFSDIOC_RELEASE_EVENT_QUEUE   _IOW(DEVFSD_IOCTL_BASE, 3, int)
-#define DEVFSDIOC_SET_DEBUG_MASK        _IOW(DEVFSD_IOCTL_BASE, 4, int)
-
-#define DEVFSD_NOTIFY_REGISTERED    0
-#define DEVFSD_NOTIFY_UNREGISTERED  1
-#define DEVFSD_NOTIFY_ASYNC_OPEN    2
-#define DEVFSD_NOTIFY_CLOSE         3
-#define DEVFSD_NOTIFY_LOOKUP        4
-#define DEVFSD_NOTIFY_CHANGE        5
-#define DEVFSD_NOTIFY_CREATE        6
-#define DEVFSD_NOTIFY_DELETE        7
-
-#define DEVFS_PATHLEN               1024       /*  Never change this otherwise the
-                                                  binary interface will change   */
-
-struct devfsd_notify_struct {  /*  Use native C types to ensure same types in kernel and user space     */
-       unsigned int type;      /*  DEVFSD_NOTIFY_* value                   */
-       unsigned int mode;      /*  Mode of the inode or device entry       */
-       unsigned int major;     /*  Major number of device entry            */
-       unsigned int minor;     /*  Minor number of device entry            */
-       unsigned int uid;       /*  Uid of process, inode or device entry   */
-       unsigned int gid;       /*  Gid of process, inode or device entry   */
-       unsigned int overrun_count;     /*  Number of lost events                   */
-       unsigned int namelen;   /*  Number of characters not including '\0' */
-       /*  The device name MUST come last                                       */
-       char devname[DEVFS_PATHLEN];    /*  This will be '\0' terminated            */
-};
-
-#endif                         /*  _LINUX_DEVFS_FS_H  */
diff --git a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h
deleted file mode 100644 (file)
index 0d74a6f..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _LINUX_DEVFS_FS_KERNEL_H
-#define _LINUX_DEVFS_FS_KERNEL_H
-
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-
-#include <asm/semaphore.h>
-
-#define DEVFS_SUPER_MAGIC                0x1373
-
-#ifdef CONFIG_DEVFS_FS
-extern int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
-    __attribute__ ((format(printf, 3, 4)));
-extern int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
-    __attribute__ ((format(printf, 3, 4)));
-extern int devfs_mk_symlink(const char *name, const char *link);
-extern int devfs_mk_dir(const char *fmt, ...)
-    __attribute__ ((format(printf, 1, 2)));
-extern void devfs_remove(const char *fmt, ...)
-    __attribute__ ((format(printf, 1, 2)));
-extern int devfs_register_tape(const char *name);
-extern void devfs_unregister_tape(int num);
-extern void mount_devfs_fs(void);
-#else                          /*  CONFIG_DEVFS_FS  */
-static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
-{
-       return 0;
-}
-static inline int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
-{
-       return 0;
-}
-static inline int devfs_mk_symlink(const char *name, const char *link)
-{
-       return 0;
-}
-static inline int devfs_mk_dir(const char *fmt, ...)
-{
-       return 0;
-}
-static inline void devfs_remove(const char *fmt, ...)
-{
-}
-static inline int devfs_register_tape(const char *name)
-{
-       return -1;
-}
-static inline void devfs_unregister_tape(int num)
-{
-}
-static inline void mount_devfs_fs(void)
-{
-       return;
-}
-#endif                         /*  CONFIG_DEVFS_FS  */
-#endif                         /*  _LINUX_DEVFS_FS_KERNEL_H  */
index 07a08e92bc736889b9c3077a2b379353fb500f7a..b45928f5c63fe838dee88eb7d03da5a6e4679e8b 100644 (file)
@@ -380,7 +380,6 @@ struct fb_cursor {
 #include <linux/tty.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/notifier.h>
 #include <linux/list.h>
 #include <asm/io.h>
index 3498a0c6818441cb9a81f6e329dac5fa8b03f7e3..e4af57e87c178ab0bff22b97b2e710e72a870428 100644 (file)
@@ -112,8 +112,6 @@ struct gendisk {
        sector_t capacity;
 
        int flags;
-       char devfs_name[64];            /* devfs crap */
-       int number;                     /* more of the same */
        struct device *driverfs_dev;
        struct kobject kobj;
        struct kobject *holder_dir;
index 0c100168c0cf2e20f5dc53ce83290545b2961876..285316c836b5436932f9d90abb384d16ef983b59 100644 (file)
@@ -552,7 +552,6 @@ typedef struct ide_drive_s {
        struct hd_driveid       *id;    /* drive model identification info */
        struct proc_dir_entry *proc;    /* /proc/ide/ directory entry */
        struct ide_settings_s *settings;/* /proc/ide/ drive settings */
-       char            devfs_name[64]; /* devfs crap */
 
        struct hwif_s           *hwif;  /* actually (ide_hwif_t *) */
 
index 5b584dafb5a6d4384f9b3169b2500d8cf0c3b518..b03cfb91e228dd993987e3b2eb497c832397e073 100644 (file)
@@ -40,7 +40,6 @@ struct miscdevice  {
        struct list_head list;
        struct device *dev;
        struct class_device *class;
-       char devfs_name[64];
 };
 
 extern int misc_register(struct miscdevice * misc);
index 385e68f5bd93264c96f1e29c3f720f3b3921a8be..b20c53c744130384ae7ad28a9b8a6d1bdf5ff716 100644 (file)
@@ -61,6 +61,7 @@ typedef enum {
 #define SOCK_ASYNC_WAITDATA    1
 #define SOCK_NOSPACE           2
 #define SOCK_PASSCRED          3
+#define SOCK_PASSSEC           4
 
 #ifndef ARCH_HAS_SOCKET_TYPES
 /**
index 03cd7551a7a100b2ba0079f40b26e957e531b5cf..aa2d3c12c4d80cffdb6a011ee1d01a0ca57f8af9 100644 (file)
@@ -315,6 +315,8 @@ struct net_device
 #define NETIF_F_GSO_SHIFT      16
 #define NETIF_F_TSO            (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
 #define NETIF_F_UFO            (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
+#define NETIF_F_GSO_ROBUST     (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
+#define NETIF_F_TSO_ECN                (SKB_GSO_TCPV4_ECN << NETIF_F_GSO_SHIFT)
 
 #define NETIF_F_GEN_CSUM       (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
 #define NETIF_F_ALL_CSUM       (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
@@ -543,7 +545,8 @@ struct packet_type {
                                         struct net_device *,
                                         struct packet_type *,
                                         struct net_device *);
-       struct sk_buff          *(*gso_segment)(struct sk_buff *skb, int sg);
+       struct sk_buff          *(*gso_segment)(struct sk_buff *skb,
+                                               int features);
        void                    *af_packet_priv;
        struct list_head        list;
 };
@@ -968,7 +971,7 @@ extern int          netdev_max_backlog;
 extern int             weight_p;
 extern int             netdev_set_master(struct net_device *dev, struct net_device *master);
 extern int skb_checksum_help(struct sk_buff *skb, int inward);
-extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int sg);
+extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
 #ifdef CONFIG_BUG
 extern void netdev_rx_csum_fault(struct net_device *dev);
 #else
@@ -988,11 +991,16 @@ extern void dev_seq_stop(struct seq_file *seq, void *v);
 
 extern void linkwatch_run_queue(void);
 
+static inline int skb_gso_ok(struct sk_buff *skb, int features)
+{
+       int feature = skb_shinfo(skb)->gso_size ?
+                     skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
+       return (features & feature) == feature;
+}
+
 static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
 {
-       int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT;
-       return skb_shinfo(skb)->gso_size &&
-              (dev->features & feature) != feature;
+       return !skb_gso_ok(skb, dev->features);
 }
 
 #endif /* __KERNEL__ */
index 51805806f9741bf63da2d7d344f05a9ee7cf3821..c7ea15716dce5cdcc5c293c120471a99248fa669 100644 (file)
@@ -67,7 +67,7 @@ struct xfrm_state;
 struct xfrm_user_sec_ctx;
 
 extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
-extern int cap_netlink_recv(struct sk_buff *skb);
+extern int cap_netlink_recv(struct sk_buff *skb, int cap);
 
 /*
  * Values used in the task_security_ops calls
@@ -656,6 +656,7 @@ struct swap_info_struct;
  *     Check permission before processing the received netlink message in
  *     @skb.
  *     @skb contains the sk_buff structure for the netlink message.
+ *     @cap indicates the capability required
  *     Return 0 if permission is granted.
  *
  * Security hooks for Unix domain networking.
@@ -1266,7 +1267,7 @@ struct security_operations {
                          struct sembuf * sops, unsigned nsops, int alter);
 
        int (*netlink_send) (struct sock * sk, struct sk_buff * skb);
-       int (*netlink_recv) (struct sk_buff * skb);
+       int (*netlink_recv) (struct sk_buff * skb, int cap);
 
        /* allow module stacking */
        int (*register_security) (const char *name,
@@ -2032,9 +2033,9 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff * skb)
        return security_ops->netlink_send(sk, skb);
 }
 
-static inline int security_netlink_recv(struct sk_buff * skb)
+static inline int security_netlink_recv(struct sk_buff * skb, int cap)
 {
-       return security_ops->netlink_recv(skb);
+       return security_ops->netlink_recv(skb, cap);
 }
 
 /* prototypes */
@@ -2670,9 +2671,9 @@ static inline int security_netlink_send (struct sock *sk, struct sk_buff *skb)
        return cap_netlink_send (sk, skb);
 }
 
-static inline int security_netlink_recv (struct sk_buff *skb)
+static inline int security_netlink_recv (struct sk_buff *skb, int cap)
 {
-       return cap_netlink_recv (skb);
+       return cap_netlink_recv (skb, cap);
 }
 
 static inline struct dentry *securityfs_create_dir(const char *name,
index 951c4e858274618ba3295dbce522954088ea9379..fc1104a2cfa9c52841fe84ce7d3b68975df24c8b 100644 (file)
@@ -336,7 +336,6 @@ struct uart_driver {
        struct module           *owner;
        const char              *driver_name;
        const char              *dev_name;
-       const char              *devfs_name;
        int                      major;
        int                      minor;
        int                      nr;
index 16eef03ce0eb2dba578c52cc136e1b80b068fa99..59918be91d0a95c203e43356ae95371861e97132 100644 (file)
@@ -172,6 +172,12 @@ enum {
 enum {
        SKB_GSO_TCPV4 = 1 << 0,
        SKB_GSO_UDPV4 = 1 << 1,
+
+       /* This indicates the skb is from an untrusted source. */
+       SKB_GSO_DODGY = 1 << 2,
+
+       /* This indicates the tcp segment has CWR set. */
+       SKB_GSO_TCPV4_ECN = 1 << 3,
 };
 
 /** 
@@ -1298,8 +1304,7 @@ extern void              skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
 extern void           skb_split(struct sk_buff *skb,
                                 struct sk_buff *skb1, const u32 len);
 
-extern void           skb_release_data(struct sk_buff *skb);
-extern struct sk_buff *skb_segment(struct sk_buff *skb, int sg);
+extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
 
 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
                                       int len, void *buffer)
index b368b296d035d1564f29586efb37365dac316ce3..58c961c9e1707027fe8989bfa821c78121fdb183 100644 (file)
@@ -157,7 +157,6 @@ struct tty_driver {
        struct cdev cdev;
        struct module   *owner;
        const char      *driver_name;
-       const char      *devfs_name;
        const char      *name;
        int     name_base;      /* offset of printed name */
        int     major;          /* major device number */
@@ -242,8 +241,15 @@ void tty_set_operations(struct tty_driver *driver, struct tty_operations *op);
  *     is also a promise, if the above case is true, not to signal
  *     overruns, either.)
  *
- * TTY_DRIVER_NO_DEVFS --- if set, do not create devfs entries. This
- *     is only used by tty_register_driver().
+ * TTY_DRIVER_DYNAMIC_DEV --- if set, the individual tty devices need
+ *     to be registered with a call to tty_register_driver() when the
+ *     device is found in the system and unregistered with a call to
+ *     tty_unregister_device() so the devices will be show up
+ *     properly in sysfs.  If not set, driver->num entries will be
+ *     created by the tty core in sysfs when tty_register_driver() is
+ *     called.  This is to be used by drivers that have tty devices
+ *     that can appear and disappear while the main tty driver is
+ *     registered with the tty core.
  *
  * TTY_DRIVER_DEVPTS_MEM -- don't use the standard arrays, instead
  *     use dynamic memory keyed through the devpts filesystem.  This
@@ -252,7 +258,7 @@ void tty_set_operations(struct tty_driver *driver, struct tty_operations *op);
 #define TTY_DRIVER_INSTALLED           0x0001
 #define TTY_DRIVER_RESET_TERMIOS       0x0002
 #define TTY_DRIVER_REAL_RAW            0x0004
-#define TTY_DRIVER_NO_DEVFS            0x0008
+#define TTY_DRIVER_DYNAMIC_DEV         0x0008
 #define TTY_DRIVER_DEVPTS_MEM          0x0010
 
 /* tty driver types */
index a1b473190e650b6ca2db5be2375facb3bde7c42c..62dae1a8c4412c3f363193ad8efdd898f3fd0c22 100644 (file)
@@ -314,7 +314,6 @@ void *priv;
        /* for videodev.c intenal usage -- please don't touch */
        int users;                     /* video_exclusive_{open|close} ... */
        struct mutex lock;             /* ... helper function uses these   */
-       char devfs_name[64];           /* devfs */
        struct class_device class_dev; /* sysfs */
 };
 
index 795f81f9ec7ff9c4e064e085d6c491d351a39f19..5ba72d95280c3f87a4aa3f434805e375f69dc9e6 100644 (file)
@@ -53,10 +53,16 @@ struct unix_address {
 struct unix_skb_parms {
        struct ucred            creds;          /* Skb credentials      */
        struct scm_fp_list      *fp;            /* Passed files         */
+#ifdef CONFIG_SECURITY_NETWORK
+       char                    *secdata;       /* Security context     */
+       u32                     seclen;         /* Security length      */
+#endif
 };
 
 #define UNIXCB(skb)    (*(struct unix_skb_parms*)&((skb)->cb))
 #define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
+#define UNIXSECDATA(skb)       (&UNIXCB((skb)).secdata)
+#define UNIXSECLEN(skb)                (&UNIXCB((skb)).seclen)
 
 #define unix_state_rlock(s)    spin_lock(&unix_sk(s)->lock)
 #define unix_state_runlock(s)  spin_unlock(&unix_sk(s)->lock)
index 75b5b9333fc75cc3b4289c80870b8a77ed6f0892..1925c65e617b9eddae6e199f660a72232e750235 100644 (file)
@@ -169,17 +169,23 @@ psched_tod_diff(int delta_sec, int bound)
 
 #define PSCHED_TADD2(tv, delta, tv_res) \
 ({ \
-          int __delta = (tv).tv_usec + (delta); \
-          (tv_res).tv_sec = (tv).tv_sec; \
-          if (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
+          int __delta = (delta); \
+          (tv_res) = (tv); \
+          while(__delta >= USEC_PER_SEC){ \
+                (tv_res).tv_sec++; \
+                __delta -= USEC_PER_SEC; \
+          } \
           (tv_res).tv_usec = __delta; \
 })
 
 #define PSCHED_TADD(tv, delta) \
 ({ \
-          (tv).tv_usec += (delta); \
-          if ((tv).tv_usec > USEC_PER_SEC) { (tv).tv_sec++; \
-                (tv).tv_usec -= USEC_PER_SEC; } \
+          int __delta = (delta); \
+          while(__delta >= USEC_PER_SEC){ \
+                (tv).tv_sec++; \
+                __delta -= USEC_PER_SEC; \
+          } \
+          (tv).tv_usec = __delta; \
 })
 
 /* Set/check that time is in the "past perfect";
index 3b6dc15c68a58fcd0c19996a4f058a1f6879588b..40b6b9c9973f5dd2756fd3dc4c6439d7676784e6 100644 (file)
@@ -36,7 +36,8 @@
 struct net_protocol {
        int                     (*handler)(struct sk_buff *skb);
        void                    (*err_handler)(struct sk_buff *skb, u32 info);
-       struct sk_buff         *(*gso_segment)(struct sk_buff *skb, int sg);
+       struct sk_buff         *(*gso_segment)(struct sk_buff *skb,
+                                              int features);
        int                     no_policy;
 };
 
index 540619cb7160f20e590471110ce63811c1d6e267..02daa097cdcd0cefcf81be18e75667a910ccf1a6 100644 (file)
@@ -19,6 +19,10 @@ struct scm_cookie
 {
        struct ucred            creds;          /* Skb credentials      */
        struct scm_fp_list      *fp;            /* Passed files         */
+#ifdef CONFIG_SECURITY_NETWORK
+       char                    *secdata;       /* Security context     */
+       u32                     seclen;         /* Security length      */
+#endif
        unsigned long           seq;            /* Connection seqno     */
 };
 
@@ -48,6 +52,17 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
        return __scm_send(sock, msg, scm);
 }
 
+#ifdef CONFIG_SECURITY_NETWORK
+static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
+{
+       if (test_bit(SOCK_PASSSEC, &sock->flags) && scm->secdata != NULL)
+               put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scm->seclen, scm->secdata);
+}
+#else
+static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
+{ }
+#endif /* CONFIG_SECURITY_NETWORK */
+
 static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
                                struct scm_cookie *scm, int flags)
 {
@@ -62,6 +77,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
        if (test_bit(SOCK_PASSCRED, &sock->flags))
                put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
 
+       scm_passec(sock, msg, scm);
+
        if (!scm->fp)
                return;
        
index 2d8d6adf16161b9dff029cfee3418e66b77d5f1f..7136bae48c2f1d98977542f253d7b0b97a055829 100644 (file)
@@ -383,7 +383,6 @@ enum sock_flags {
        SOCK_USE_WRITE_QUEUE, /* whether to call sk->sk_write_space in sock_wfree */
        SOCK_DBG, /* %SO_DEBUG setting */
        SOCK_RCVTSTAMP, /* %SO_TIMESTAMP setting */
-       SOCK_NO_LARGESEND, /* whether to sent large segments or not */
        SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
        SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
 };
@@ -1033,7 +1032,7 @@ static inline void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
        if (sk->sk_route_caps & NETIF_F_GSO)
                sk->sk_route_caps |= NETIF_F_TSO;
        if (sk->sk_route_caps & NETIF_F_TSO) {
-               if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
+               if (dst->header_len)
                        sk->sk_route_caps &= ~NETIF_F_TSO;
                else 
                        sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
index ca3d38dfc00bb3911c697dea4a936f36b1edd067..624921e763329d952cf5b68805cc75ca20399d5c 100644 (file)
@@ -1086,7 +1086,7 @@ extern struct request_sock_ops tcp_request_sock_ops;
 
 extern int tcp_v4_destroy_sock(struct sock *sk);
 
-extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int sg);
+extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
 
 #ifdef CONFIG_PROC_FS
 extern int  tcp4_proc_init(void);
index c6b84397448dac0b810079c96fe1c642773b16fd..7bb366f70934787e19b7dfa2f0ddd05895cd12a0 100644 (file)
@@ -31,10 +31,9 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct tcp_sock *tp,
                                    struct sk_buff *skb)
 {
        tp->ecn_flags = 0;
-       if (sysctl_tcp_ecn && !(sk->sk_route_caps & NETIF_F_TSO)) {
+       if (sysctl_tcp_ecn) {
                TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE|TCPCB_FLAG_CWR;
                tp->ecn_flags = TCP_ECN_OK;
-               sock_set_flag(sk, SOCK_NO_LARGESEND);
        }
 }
 
@@ -56,6 +55,9 @@ static inline void TCP_ECN_send(struct sock *sk, struct tcp_sock *tp,
                        if (tp->ecn_flags&TCP_ECN_QUEUE_CWR) {
                                tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
                                skb->h.th->cwr = 1;
+                               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+                                       skb_shinfo(skb)->gso_type |=
+                                               SKB_GSO_TCPV4_ECN;
                        }
                } else {
                        /* ACK or retransmitted segment: clear ECT|CE */
index a2300078f2b7d98f97a603678e40a39d034bdea5..633a268d270d3cc8bfa906c1a22476caa9645360 100644 (file)
@@ -6,7 +6,6 @@ obj-y                           := main.o version.o mounts.o initramfs.o
 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
 
 mounts-y                       := do_mounts.o
-mounts-$(CONFIG_DEVFS_FS)      += do_mounts_devfs.o
 mounts-$(CONFIG_BLK_DEV_RAM)   += do_mounts_rd.o
 mounts-$(CONFIG_BLK_DEV_INITRD)        += do_mounts_initrd.o
 mounts-$(CONFIG_BLK_DEV_MD)    += do_mounts_md.o
index 21b3b8f33a728c505cd7396d9e7517775c07706c..94aeec7aa917fbf727e5be22c55f842621b31ef3 100644 (file)
@@ -325,7 +325,7 @@ static int __init mount_nfs_root(void)
 {
        void *data = nfs_root_data();
 
-       create_dev("/dev/root", ROOT_DEV, NULL);
+       create_dev("/dev/root", ROOT_DEV);
        if (data &&
            do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
                return 1;
@@ -386,7 +386,7 @@ void __init mount_root(void)
                        change_floppy("root floppy");
        }
 #endif
-       create_dev("/dev/root", ROOT_DEV, root_device_name);
+       create_dev("/dev/root", ROOT_DEV);
        mount_block_root("/dev/root", root_mountflags);
 }
 
@@ -397,8 +397,6 @@ void __init prepare_namespace(void)
 {
        int is_floppy;
 
-       mount_devfs();
-
        if (root_delay) {
                printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
                       root_delay);
@@ -428,10 +426,8 @@ void __init prepare_namespace(void)
 
        mount_root();
 out:
-       umount_devfs("/dev");
        sys_mount(".", "/", NULL, MS_MOVE, NULL);
        sys_chroot(".");
        security_sb_post_mountroot();
-       mount_devfs_fs ();
 }
 
index e0a7ac9649e1e4c10c080a7691744ce62e6bc497..e7f2e7fa066eb6715c0f54fb27649338b60f475a 100644 (file)
@@ -1,6 +1,5 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/init.h>
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
@@ -15,25 +14,12 @@ void  mount_root(void);
 extern int root_mountflags;
 extern char *root_device_name;
 
-#ifdef CONFIG_DEVFS_FS
-
-void mount_devfs(void);
-void umount_devfs(char *path);
-int  create_dev(char *name, dev_t dev, char *devfs_name);
-
-#else
-
-static inline void mount_devfs(void) {}
-static inline void umount_devfs(const char *path) {}
-
-static inline int create_dev(char *name, dev_t dev, char *devfs_name)
+static inline int create_dev(char *name, dev_t dev)
 {
        sys_unlink(name);
        return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
 }
 
-#endif
-
 #if BITS_PER_LONG == 32
 static inline u32 bstat(char *name)
 {
diff --git a/init/do_mounts_devfs.c b/init/do_mounts_devfs.c
deleted file mode 100644 (file)
index cc52647..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-
-#include <linux/kernel.h>
-#include <linux/dirent.h>
-#include <linux/string.h>
-
-#include "do_mounts.h"
-
-void __init mount_devfs(void)
-{
-       sys_mount("devfs", "/dev", "devfs", 0, NULL);
-}
-
-void __init umount_devfs(char *path)
-{
-       sys_umount(path, 0);
-}
-
-/*
- * If the dir will fit in *buf, return its length.  If it won't fit, return
- * zero.  Return -ve on error.
- */
-static int __init do_read_dir(int fd, void *buf, int len)
-{
-       long bytes, n;
-       char *p = buf;
-       sys_lseek(fd, 0, 0);
-
-       for (bytes = 0; bytes < len; bytes += n) {
-               n = sys_getdents64(fd, (struct linux_dirent64 *)(p + bytes),
-                                       len - bytes);
-               if (n < 0)
-                       return n;
-               if (n == 0)
-                       return bytes;
-       }
-       return 0;
-}
-
-/*
- * Try to read all of a directory.  Returns the contents at *p, which
- * is kmalloced memory.  Returns the number of bytes read at *len.  Returns
- * NULL on error.
- */
-static void * __init read_dir(char *path, int *len)
-{
-       int size;
-       int fd = sys_open(path, 0, 0);
-
-       *len = 0;
-       if (fd < 0)
-               return NULL;
-
-       for (size = 1 << 9; size <= (PAGE_SIZE << MAX_ORDER); size <<= 1) {
-               void *p = kmalloc(size, GFP_KERNEL);
-               int n;
-               if (!p)
-                       break;
-               n = do_read_dir(fd, p, size);
-               if (n > 0) {
-                       sys_close(fd);
-                       *len = n;
-                       return p;
-               }
-               kfree(p);
-               if (n == -EINVAL)
-                       continue;       /* Try a larger buffer */
-               if (n < 0)
-                       break;
-       }
-       sys_close(fd);
-       return NULL;
-}
-
-/*
- * recursively scan <path>, looking for a device node of type <dev>
- */
-static int __init find_in_devfs(char *path, unsigned dev)
-{
-       char *end = path + strlen(path);
-       int rest = path + 64 - end;
-       int size;
-       char *p = read_dir(path, &size);
-       char *s;
-
-       if (!p)
-               return -1;
-       for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
-               struct linux_dirent64 *d = (struct linux_dirent64 *)s;
-               if (strlen(d->d_name) + 2 > rest)
-                       continue;
-               switch (d->d_type) {
-                       case DT_BLK:
-                               sprintf(end, "/%s", d->d_name);
-                               if (bstat(path) != dev)
-                                       break;
-                               kfree(p);
-                               return 0;
-                       case DT_DIR:
-                               if (strcmp(d->d_name, ".") == 0)
-                                       break;
-                               if (strcmp(d->d_name, "..") == 0)
-                                       break;
-                               sprintf(end, "/%s", d->d_name);
-                               if (find_in_devfs(path, dev) < 0)
-                                       break;
-                               kfree(p);
-                               return 0;
-               }
-       }
-       kfree(p);
-       return -1;
-}
-
-/*
- * create a device node called <name> which points to
- * <devfs_name> if possible, otherwise find a device node
- * which matches <dev> and make <name> a symlink pointing to it.
- */
-int __init create_dev(char *name, dev_t dev, char *devfs_name)
-{
-       char path[64];
-
-       sys_unlink(name);
-       if (devfs_name && devfs_name[0]) {
-               if (strncmp(devfs_name, "/dev/", 5) == 0)
-                       devfs_name += 5;
-               sprintf(path, "/dev/%s", devfs_name);
-               if (sys_access(path, 0) == 0)
-                       return sys_symlink(devfs_name, name);
-       }
-       if (!dev)
-               return -1;
-       strcpy(path, "/dev");
-       if (find_in_devfs(path, new_encode_dev(dev)) < 0)
-               return -1;
-       return sys_symlink(path + 5, name);
-}
index 405f9031af873c1d4631e597e65f123d2fe95e65..a06f037fa000a932d9de7b6f8dee909e5ce01720 100644 (file)
@@ -44,7 +44,7 @@ static void __init handle_initrd(void)
        int pid;
 
        real_root_dev = new_encode_dev(ROOT_DEV);
-       create_dev("/dev/root.old", Root_RAM0, NULL);
+       create_dev("/dev/root.old", Root_RAM0);
        /* mount initrd on rootfs' /root */
        mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
        sys_mkdir("/old", 0700);
@@ -54,7 +54,6 @@ static void __init handle_initrd(void)
        sys_chdir("/root");
        sys_mount(".", "/", NULL, MS_MOVE, NULL);
        sys_chroot(".");
-       mount_devfs_fs ();
 
        current->flags |= PF_NOFREEZE;
        pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
@@ -71,7 +70,6 @@ static void __init handle_initrd(void)
        sys_chroot(".");
        sys_close(old_fd);
        sys_close(root_fd);
-       umount_devfs("/old/dev");
 
        if (new_decode_dev(real_root_dev) == Root_RAM0) {
                sys_chdir("/old");
@@ -107,7 +105,7 @@ static void __init handle_initrd(void)
 int __init initrd_load(void)
 {
        if (mount_initrd) {
-               create_dev("/dev/ram", Root_RAM0, NULL);
+               create_dev("/dev/ram", Root_RAM0);
                /*
                 * Load the initrd data into /dev/ram0. Execute it as initrd
                 * unless /dev/ram0 is supposed to be our actual root device,
index f6f36806f84a09bed0f76467a3133a08a84e01ac..2429e1bf8c60a1277edaed473760cfad8e486a1f 100644 (file)
@@ -125,19 +125,18 @@ static void __init md_setup_drive(void)
                int err = 0;
                char *devname;
                mdu_disk_info_t dinfo;
-               char name[16], devfs_name[16];
+               char name[16];
 
                minor = md_setup_args[ent].minor;
                partitioned = md_setup_args[ent].partitioned;
                devname = md_setup_args[ent].device_names;
 
                sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
-               sprintf(devfs_name, "/dev/md/%s%d", partitioned?"d":"", minor);
                if (partitioned)
                        dev = MKDEV(mdp_major, minor << MdpMinorShift);
                else
                        dev = MKDEV(MD_MAJOR, minor);
-               create_dev(name, dev, devfs_name);
+               create_dev(name, dev);
                for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
                        char *p;
                        char comp_name[64];
@@ -272,7 +271,7 @@ __setup("md=", md_setup);
 
 void __init md_run_setup(void)
 {
-       create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
+       create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
        if (raid_noautodetect)
                printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
        else {
index c2683fcd792deb75a5f79d3e0ec02424fecd1a7c..ed652f40f075a68e2b41b68911a97a0f5224ed96 100644 (file)
@@ -262,8 +262,8 @@ int __init rd_load_disk(int n)
 {
        if (rd_prompt)
                change_floppy("root floppy disk to be loaded into RAM disk");
-       create_dev("/dev/root", ROOT_DEV, root_device_name);
-       create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
+       create_dev("/dev/root", ROOT_DEV);
+       create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
        return rd_load_image("/dev/root");
 }
 
index 0d57f6ccb63a1a7c1f1efd47810727feb40e8ae8..bce0eb7f4f8fb50413a516b1a3bafbb8ae81b821 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/kernel.h>
 #include <linux/syscalls.h>
 #include <linux/string.h>
index 82443fb433efcb9d550126be82dabf80c0308c23..d417ca1db79b02fc3cb2d30a3a2122494afd0f14 100644 (file)
@@ -445,7 +445,7 @@ void audit_send_reply(int pid, int seq, int type, int done, int multi,
  * Check for appropriate CAP_AUDIT_ capabilities on incoming audit
  * control messages.
  */
-static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
+static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
 {
        int err = 0;
 
@@ -459,13 +459,13 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
        case AUDIT_DEL:
        case AUDIT_DEL_RULE:
        case AUDIT_SIGNAL_INFO:
-               if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
+               if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
                        err = -EPERM;
                break;
        case AUDIT_USER:
        case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
        case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
-               if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
+               if (security_netlink_recv(skb, CAP_AUDIT_WRITE))
                        err = -EPERM;
                break;
        default:  /* bad msg */
@@ -488,7 +488,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        char                    *ctx;
        u32                     len;
 
-       err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
+       err = audit_netlink_ok(skb, msg_type);
        if (err)
                return err;
 
index ea64c07cbe72b036c4e58bc37bad35cce892213b..b14ff817d16264db042313ccb8ba362edc1be014 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -2252,9 +2251,7 @@ static int __init init_tmpfs(void)
                printk(KERN_ERR "Could not register tmpfs\n");
                goto out2;
        }
-#ifdef CONFIG_TMPFS
-       devfs_mk_dir("shm");
-#endif
+
        shm_mnt = vfs_kern_mount(&tmpfs_fs_type, MS_NOUSER,
                                tmpfs_fs_type.name, NULL);
        if (IS_ERR(shm_mnt)) {
index f9d6a9cc91c4bc806700c6119f45e34283abdeb7..5f2cbf0f153c7a35db2219cab124c0ac8513ce4c 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/fs.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/vfs.h>
 #include <linux/mount.h>
 #include <linux/file.h>
@@ -33,9 +32,6 @@ static int __init init_tmpfs(void)
 {
        BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
 
-#ifdef CONFIG_TMPFS
-       devfs_mk_dir("shm");
-#endif
        shm_mnt = kern_mount(&tmpfs_fs_type);
        BUG_ON(IS_ERR(shm_mnt));
 
index d5818751f6ba43d5f7c3ec414c2f8ffe55b13118..89656d6c0b90d3f9310cbf4b5733f1a24102d25a 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the ATM Protocol Families.
 #
 
-atm-y          := addr.o pvc.o signaling.o svc.o ioctl.o common.o atm_misc.o raw.o resources.o
+atm-y          := addr.o pvc.o signaling.o svc.o ioctl.o common.o atm_misc.o raw.o resources.o atm_sysfs.o
 mpoa-objs      := mpc.o mpoa_caches.o mpoa_proc.o
 
 obj-$(CONFIG_ATM) += atm.o
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
new file mode 100644 (file)
index 0000000..5df4b9a
--- /dev/null
@@ -0,0 +1,176 @@
+/* ATM driver model support. */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/atmdev.h>
+#include "common.h"
+#include "resources.h"
+
+#define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev)
+
+static ssize_t show_type(struct class_device *cdev, char *buf)
+{
+       struct atm_dev *adev = to_atm_dev(cdev);
+       return sprintf(buf, "%s\n", adev->type);
+}
+
+static ssize_t show_address(struct class_device *cdev, char *buf)
+{
+       char *pos = buf;
+       struct atm_dev *adev = to_atm_dev(cdev);
+       int i;
+
+       for (i = 0; i < (ESI_LEN - 1); i++)
+               pos += sprintf(pos, "%02x:", adev->esi[i]);
+       pos += sprintf(pos, "%02x\n", adev->esi[i]);
+
+       return pos - buf;
+}
+
+static ssize_t show_atmaddress(struct class_device *cdev, char *buf)
+{
+        unsigned long flags;
+       char *pos = buf;
+       struct atm_dev *adev = to_atm_dev(cdev);
+        struct atm_dev_addr *aaddr;
+       int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin;
+       int i, j;
+
+        spin_lock_irqsave(&adev->lock, flags);
+        list_for_each_entry(aaddr, &adev->local, entry) {
+               for(i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) {
+                       if (j == *fmt) {
+                               pos += sprintf(pos, ".");
+                               ++fmt;
+                               j = 0;
+                       }
+                       pos += sprintf(pos, "%02x", aaddr->addr.sas_addr.prv[i]);
+               }
+               pos += sprintf(pos, "\n");
+       }
+        spin_unlock_irqrestore(&adev->lock, flags);
+
+       return pos - buf;
+}
+
+static ssize_t show_carrier(struct class_device *cdev, char *buf)
+{
+       char *pos = buf;
+       struct atm_dev *adev = to_atm_dev(cdev);
+
+       pos += sprintf(pos, "%d\n",
+                      adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
+               
+       return pos - buf;
+}
+
+static ssize_t show_link_rate(struct class_device *cdev, char *buf)
+{
+       char *pos = buf;
+       struct atm_dev *adev = to_atm_dev(cdev);
+       int link_rate;
+
+       /* show the link rate, not the data rate */
+       switch (adev->link_rate) {
+               case ATM_OC3_PCR:
+                       link_rate = 155520000;
+                       break;
+               case ATM_OC12_PCR:
+                       link_rate = 622080000;
+                       break;
+               case ATM_25_PCR:
+                       link_rate = 25600000;
+                       break;
+               default:
+                       link_rate = adev->link_rate * 8 * 53;
+       }
+       pos += sprintf(pos, "%d\n", link_rate);
+               
+       return pos - buf;
+}
+
+static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static CLASS_DEVICE_ATTR(atmaddress, S_IRUGO, show_atmaddress, NULL);
+static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
+static CLASS_DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
+static CLASS_DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL);
+
+static struct class_device_attribute *atm_attrs[] = {
+       &class_device_attr_atmaddress,
+       &class_device_attr_address,
+       &class_device_attr_carrier,
+       &class_device_attr_type,
+       &class_device_attr_link_rate,
+       NULL
+};
+
+static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
+{
+       struct atm_dev *adev;
+       int i = 0, len = 0;
+
+       if (!cdev)
+               return -ENODEV;
+
+       adev = to_atm_dev(cdev);
+       if (!adev)
+               return -ENODEV;
+
+       if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
+                          "NAME=%s%d", adev->type, adev->number))
+               return -ENOMEM;
+
+       envp[i] = NULL;
+       return 0;
+}
+
+static void atm_release(struct class_device *cdev)
+{
+       struct atm_dev *adev = to_atm_dev(cdev);
+
+       kfree(adev);
+}
+
+static struct class atm_class = {
+       .name           = "atm",
+       .release        = atm_release,
+       .uevent         = atm_uevent,
+};
+
+int atm_register_sysfs(struct atm_dev *adev)
+{
+       struct class_device *cdev = &adev->class_dev;
+       int i, err;
+
+       cdev->class = &atm_class;
+       class_set_devdata(cdev, adev);
+
+       snprintf(cdev->class_id, BUS_ID_SIZE, "%s%d", adev->type, adev->number);
+       err = class_device_register(cdev);
+       if (err < 0)
+               return err;
+
+       for (i = 0; atm_attrs[i]; i++)
+               class_device_create_file(cdev, atm_attrs[i]);
+
+       return 0;
+}
+
+void atm_unregister_sysfs(struct atm_dev *adev)
+{
+       struct class_device *cdev = &adev->class_dev;
+
+       class_device_del(cdev);
+}
+
+int __init atm_sysfs_init(void)
+{
+       return class_register(&atm_class);
+}
+
+void __exit atm_sysfs_exit(void)
+{
+       class_unregister(&atm_class);
+}
index ae002220fa99096aa00edc4ce0fd8df3e5c8694b..35ab1a61e831471407bb0462782cd08bd65a2eba 100644 (file)
@@ -791,8 +791,14 @@ static int __init atm_init(void)
                printk(KERN_ERR "atm_proc_init() failed with %d\n",error);
                goto out_atmsvc_exit;
        }
+        if ((error = atm_sysfs_init()) < 0) {
+               printk(KERN_ERR "atm_sysfs_init() failed with %d\n",error);
+               goto out_atmproc_exit;
+       }
 out:
        return error;
+out_atmproc_exit:
+       atm_proc_exit();
 out_atmsvc_exit:
        atmsvc_exit();
 out_atmpvc_exit:
@@ -805,6 +811,7 @@ out_unregister_vcc_proto:
 static void __exit atm_exit(void)
 {
        atm_proc_exit();
+       atm_sysfs_exit();
        atmsvc_exit();
        atmpvc_exit();
        proto_unregister(&vcc_proto);
index 4887c317cefe99365576c2812875dc730257aa13..a422da7788fbd44852fadba2261c5c5f1cdd1c0e 100644 (file)
@@ -28,6 +28,8 @@ int atmpvc_init(void);
 void atmpvc_exit(void);
 int atmsvc_init(void);
 void atmsvc_exit(void);
+int atm_sysfs_init(void);
+void atm_sysfs_exit(void);
 
 #ifdef CONFIG_PROC_FS
 int atm_proc_init(void);
index 18ac80698f835906cab6cd9f45971892ef42d46b..534baf7040561448324537c50483d80fd97895b5 100644 (file)
@@ -114,14 +114,27 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
                printk(KERN_ERR "atm_dev_register: "
                       "atm_proc_dev_register failed for dev %s\n",
                       type);
-               mutex_unlock(&atm_dev_mutex);
-               kfree(dev);
-               return NULL;
+               goto out_fail;
+       }
+
+       if (atm_register_sysfs(dev) < 0) {
+               printk(KERN_ERR "atm_dev_register: "
+                      "atm_register_sysfs failed for dev %s\n",
+                      type);
+               atm_proc_dev_deregister(dev);
+               goto out_fail;
        }
+
        list_add_tail(&dev->dev_list, &atm_devs);
-       mutex_unlock(&atm_dev_mutex);
 
+out:
+       mutex_unlock(&atm_dev_mutex);
        return dev;
+
+out_fail:
+       kfree(dev);
+       dev = NULL;
+       goto out;
 }
 
 
@@ -140,6 +153,7 @@ void atm_dev_deregister(struct atm_dev *dev)
        mutex_unlock(&atm_dev_mutex);
 
        atm_dev_release_vccs(dev);
+       atm_unregister_sysfs(dev);
        atm_proc_dev_deregister(dev);
 
        atm_dev_put(dev);
index ac7222fee7a8e38db42aa066ca03a241ab323735..644989980c37f9b173cde5ca1ad3a5988922ff2a 100644 (file)
@@ -43,4 +43,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev)
 
 #endif /* CONFIG_PROC_FS */
 
+int atm_register_sysfs(struct atm_dev *adev);
+void atm_unregister_sysfs(struct atm_dev *adev);
 #endif
index b81fad893328663203c6be595df7de9f2895c4e4..b105a715fa93e76624b0af98bd9ba1c7126bc7b2 100644 (file)
@@ -1021,13 +1021,12 @@ int rfcomm_init_ttys(void)
 
        rfcomm_tty_driver->owner        = THIS_MODULE;
        rfcomm_tty_driver->driver_name  = "rfcomm";
-       rfcomm_tty_driver->devfs_name   = "bluetooth/rfcomm/";
        rfcomm_tty_driver->name         = "rfcomm";
        rfcomm_tty_driver->major        = RFCOMM_TTY_MAJOR;
        rfcomm_tty_driver->minor_start  = RFCOMM_TTY_MINOR;
        rfcomm_tty_driver->type         = TTY_DRIVER_TYPE_SERIAL;
        rfcomm_tty_driver->subtype      = SERIAL_TYPE_NORMAL;
-       rfcomm_tty_driver->flags        = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       rfcomm_tty_driver->flags        = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        rfcomm_tty_driver->init_termios = tty_std_termios;
        rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
index 2afdc7c0736c48b6baa39c5e9fa37987a7cdb779..f8dbcee80ebad7cdffb110fd87a8796db93643ab 100644 (file)
@@ -184,6 +184,6 @@ void br_dev_setup(struct net_device *dev)
        dev->set_mac_address = br_set_mac_address;
        dev->priv_flags = IFF_EBRIDGE;
 
-       dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
-               | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_NO_CSUM;
+       dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
+                       NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
 }
index 07956ecf545e313775967da4e48570bf33243732..f55ef682ef846e979b7e1b24569399a7c2fbd7da 100644 (file)
@@ -392,7 +392,8 @@ void br_features_recompute(struct net_bridge *br)
                features &= feature;
        }
 
-       br->dev->features = features | checksum | NETIF_F_LLTX;
+       br->dev->features = features | checksum | NETIF_F_LLTX |
+                           NETIF_F_GSO_ROBUST;
 }
 
 /* called with RTNL */
index f1c52cbd6ef7bfa8ae13ff04913b585b0c9be286..08976b08df5b6b6c4d6d88d029179b9f06f981b4 100644 (file)
@@ -1190,11 +1190,14 @@ out:
 /**
  *     skb_gso_segment - Perform segmentation on skb.
  *     @skb: buffer to segment
- *     @sg: whether scatter-gather is supported on the target.
+ *     @features: features for the output path (see dev->features)
  *
  *     This function segments the given skb and returns a list of segments.
+ *
+ *     It may return NULL if the skb requires no segmentation.  This is
+ *     only possible when GSO is used for verifying header integrity.
  */
-struct sk_buff *skb_gso_segment(struct sk_buff *skb, int sg)
+struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
 {
        struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
        struct packet_type *ptype;
@@ -1210,12 +1213,14 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int sg)
        rcu_read_lock();
        list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
                if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
-                       segs = ptype->gso_segment(skb, sg);
+                       segs = ptype->gso_segment(skb, features);
                        break;
                }
        }
        rcu_read_unlock();
 
+       __skb_push(skb, skb->data - skb->mac.raw);
+
        return segs;
 }
 
@@ -1234,7 +1239,6 @@ void netdev_rx_csum_fault(struct net_device *dev)
 EXPORT_SYMBOL(netdev_rx_csum_fault);
 #endif
 
-#ifdef CONFIG_HIGHMEM
 /* Actually, we should eliminate this check as soon as we know, that:
  * 1. IOMMU is present and allows to map all the memory.
  * 2. No high memory really exists on this machine.
@@ -1242,6 +1246,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault);
 
 static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 {
+#ifdef CONFIG_HIGHMEM
        int i;
 
        if (dev->features & NETIF_F_HIGHDMA)
@@ -1251,11 +1256,9 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
                if (PageHighMem(skb_shinfo(skb)->frags[i].page))
                        return 1;
 
+#endif
        return 0;
 }
-#else
-#define illegal_highdma(dev, skb)      (0)
-#endif
 
 struct dev_gso_cb {
        void (*destructor)(struct sk_buff *skb);
@@ -1291,9 +1294,15 @@ static int dev_gso_segment(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
        struct sk_buff *segs;
+       int features = dev->features & ~(illegal_highdma(dev, skb) ?
+                                        NETIF_F_SG : 0);
+
+       segs = skb_gso_segment(skb, features);
+
+       /* Verifying header integrity only. */
+       if (!segs)
+               return 0;
 
-       segs = skb_gso_segment(skb, dev->features & NETIF_F_SG &&
-                                   !illegal_highdma(dev, skb));
        if (unlikely(IS_ERR(segs)))
                return PTR_ERR(segs);
 
@@ -1310,13 +1319,17 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (netdev_nit)
                        dev_queue_xmit_nit(skb, dev);
 
-               if (!netif_needs_gso(dev, skb))
-                       return dev->hard_start_xmit(skb, dev);
+               if (netif_needs_gso(dev, skb)) {
+                       if (unlikely(dev_gso_segment(skb)))
+                               goto out_kfree_skb;
+                       if (skb->next)
+                               goto gso;
+               }
 
-               if (unlikely(dev_gso_segment(skb)))
-                       goto out_kfree_skb;
+               return dev->hard_start_xmit(skb, dev);
        }
 
+gso:
        do {
                struct sk_buff *nskb = skb->next;
                int rc;
index 3fcfa9c59e1fb75abfae6c9ad6c27f4cbda0f083..f25aac17497a7e79d8ed4cdcdbc6bdca18c54c8e 100644 (file)
@@ -663,7 +663,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
        sz_idx = type>>2;
        kind = type&3;
 
-       if (kind != 2 && security_netlink_recv(skb)) {
+       if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) {
                *errp = -EPERM;
                return -1;
        }
index 6edbb90cbcec303605be4064b2f1da0d56e18eb3..a1c9ecf4f1e077c205a5e383cabce391b0243134 100644 (file)
@@ -272,7 +272,7 @@ static void skb_clone_fraglist(struct sk_buff *skb)
                skb_get(list);
 }
 
-void skb_release_data(struct sk_buff *skb)
+static void skb_release_data(struct sk_buff *skb)
 {
        if (!skb->cloned ||
            !atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1,
@@ -1848,13 +1848,13 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum);
 /**
  *     skb_segment - Perform protocol segmentation on skb.
  *     @skb: buffer to segment
- *     @sg: whether scatter-gather can be used for generated segments
+ *     @features: features for the output path (see dev->features)
  *
  *     This function performs segmentation on the given skb.  It returns
  *     the segment at the given position.  It returns NULL if there are
  *     no more segments to generate, or when an error is encountered.
  */
-struct sk_buff *skb_segment(struct sk_buff *skb, int sg)
+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 {
        struct sk_buff *segs = NULL;
        struct sk_buff *tail = NULL;
@@ -1863,6 +1863,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int sg)
        unsigned int offset = doffset;
        unsigned int headroom;
        unsigned int len;
+       int sg = features & NETIF_F_SG;
        int nfrags = skb_shinfo(skb)->nr_frags;
        int err = -ENOMEM;
        int i = 0;
index 5d820c3766530a991056050d23be7013107ae20c..204a8dec65cc76503ff6bf209b8ec6c8956ac17e 100644 (file)
@@ -565,6 +565,13 @@ set_rcvbuf:
                        ret = -ENONET;
                        break;
 
+               case SO_PASSSEC:
+                       if (valbool)
+                               set_bit(SOCK_PASSSEC, &sock->flags);
+                       else
+                               clear_bit(SOCK_PASSSEC, &sock->flags);
+                       break;
+
                /* We implement the SO_SNDLOWAT etc to
                   not be settable (1003.1g 5.3) */
                default:
@@ -723,6 +730,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                        v.val = sk->sk_state == TCP_LISTEN;
                        break;
 
+               case SO_PASSSEC:
+                       v.val = test_bit(SOCK_PASSSEC, &sock->flags) ? 1 : 0;
+                       break;
+
                case SO_PEERSEC:
                        return security_socket_getpeersec_stream(sock, optval, optlen, len);
 
index 74133ecd77005e4292485c557d97e39a7f12424b..8b99bd33540d53fc072278aa6ade21906a541f90 100644 (file)
@@ -107,7 +107,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
        if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
                return;
 
-       if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
+       if (security_netlink_recv(skb, CAP_NET_ADMIN))
                RCV_SKB_FAIL(-EPERM);
 
        /* Eventually we might send routing messages too */
index 461216b47948681791162829e8c4ca2b78e54d87..8d157157bf8e68c65ae3523b62c13ba0486437ab 100644 (file)
@@ -1097,7 +1097,7 @@ int inet_sk_rebuild_header(struct sock *sk)
 
 EXPORT_SYMBOL(inet_sk_rebuild_header);
 
-static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int sg)
+static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
 {
        struct sk_buff *segs = ERR_PTR(-EINVAL);
        struct iphdr *iph;
@@ -1126,10 +1126,10 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int sg)
        rcu_read_lock();
        ops = rcu_dereference(inet_protos[proto]);
        if (ops && ops->gso_segment)
-               segs = ops->gso_segment(skb, sg);
+               segs = ops->gso_segment(skb, features);
        rcu_read_unlock();
 
-       if (IS_ERR(segs))
+       if (!segs || unlikely(IS_ERR(segs)))
                goto out;
 
        skb = segs;
index e1d7f5fbc52634550908485439d6ebbac7d8fb2e..ef0b5aac58382f2132f4912b641af4a7639a2cbd 100644 (file)
@@ -332,7 +332,7 @@ config IP_NF_MATCH_HASHLIMIT
        help
          This option adds a new iptables `hashlimit' match.  
 
-         As opposed to `limit', this match dynamically crates a hash table
+         As opposed to `limit', this match dynamically creates a hash table
          of limit buckets, based on your selection of source/destination
          ip addresses and/or ports.
 
index d0d19192026d9eb2327cf68a47a4ba1b23dc7fe5..ad39bf640567caaf81e71fd40a83886739611537 100644 (file)
@@ -1120,7 +1120,8 @@ int arpt_register_table(struct arpt_table *table,
                return ret;
        }
 
-       if (xt_register_table(table, &bootstrap, newinfo) != 0) {
+       ret = xt_register_table(table, &bootstrap, newinfo);
+       if (ret != 0) {
                xt_free_table_info(newinfo);
                return ret;
        }
index b93f0494362f888785d2dd8af8524d86f67ccdc0..198ac36db861225ec879f21b3ce3b833b082ce0b 100644 (file)
@@ -457,11 +457,19 @@ dev_cmp(struct ipq_queue_entry *entry, unsigned long ifindex)
        if (entry->info->indev)
                if (entry->info->indev->ifindex == ifindex)
                        return 1;
-                       
        if (entry->info->outdev)
                if (entry->info->outdev->ifindex == ifindex)
                        return 1;
-
+#ifdef CONFIG_BRIDGE_NETFILTER
+       if (entry->skb->nf_bridge) {
+               if (entry->skb->nf_bridge->physindev &&
+                   entry->skb->nf_bridge->physindev->ifindex == ifindex)
+                       return 1;
+               if (entry->skb->nf_bridge->physoutdev &&
+                   entry->skb->nf_bridge->physoutdev->ifindex == ifindex)
+                       return 1;
+       }
+#endif
        return 0;
 }
 
@@ -507,7 +515,7 @@ ipq_rcv_skb(struct sk_buff *skb)
        if (type <= IPQM_BASE)
                return;
                
-       if (security_netlink_recv(skb))
+       if (security_netlink_recv(skb, CAP_NET_ADMIN))
                RCV_SKB_FAIL(-EPERM);
        
        write_lock_bh(&queue_lock);
index 706c0025ec5e43768c7c9dadfb30e3782c275d67..7aaaf92efb59ef755a6993a07023cd125a05faa5 100644 (file)
@@ -2113,7 +2113,8 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
                return ret;
        }
 
-       if (xt_register_table(table, &bootstrap, newinfo) != 0) {
+       ret = xt_register_table(table, &bootstrap, newinfo);
+       if (ret != 0) {
                xt_free_table_info(newinfo);
                return ret;
        }
index c04176be7ed12826de51bcf036d2e64cd7f0b17e..0336422c88a03becbf006d26c064b25504b62bf9 100644 (file)
@@ -2145,7 +2145,7 @@ int compat_tcp_getsockopt(struct sock *sk, int level, int optname,
 EXPORT_SYMBOL(compat_tcp_getsockopt);
 #endif
 
-struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int sg)
+struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
 {
        struct sk_buff *segs = ERR_PTR(-EINVAL);
        struct tcphdr *th;
@@ -2166,10 +2166,14 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int sg)
        if (!pskb_may_pull(skb, thlen))
                goto out;
 
+       segs = NULL;
+       if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
+               goto out;
+
        oldlen = (u16)~skb->len;
        __skb_pull(skb, thlen);
 
-       segs = skb_segment(skb, sg);
+       segs = skb_segment(skb, features);
        if (IS_ERR(segs))
                goto out;
 
index c148c1081880a03aa1a7f24a692cb439f7ee3d70..b56399c7cc12ac626372331768a7ac9effd2e946 100644 (file)
@@ -26,7 +26,10 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
        const struct tcp_sock *tp = tcp_sk(sk);
        struct tcp_info *info = _info;
 
-       r->idiag_rqueue = tp->rcv_nxt - tp->copied_seq;
+       if (sk->sk_state == TCP_LISTEN)
+               r->idiag_rqueue = sk->sk_ack_backlog;
+       else
+               r->idiag_rqueue = tp->rcv_nxt - tp->copied_seq;
        r->idiag_wqueue = tp->write_seq - tp->snd_una;
        if (info != NULL)
                tcp_get_info(sk, info);
index 94fe5b1f9dcbeb1b819da503b8d5a09d0c35569c..7fa0b4a8a389c6e08c7eaf51ba1ceb922e1eede9 100644 (file)
@@ -4178,8 +4178,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                 */
 
                TCP_ECN_rcv_synack(tp, th);
-               if (tp->ecn_flags&TCP_ECN_OK)
-                       sock_set_flag(sk, SOCK_NO_LARGESEND);
 
                tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
                tcp_ack(sk, skb, FLAG_SLOWPATH);
@@ -4322,8 +4320,6 @@ discard:
                tp->max_window = tp->snd_wnd;
 
                TCP_ECN_rcv_syn(tp, th);
-               if (tp->ecn_flags&TCP_ECN_OK)
-                       sock_set_flag(sk, SOCK_NO_LARGESEND);
 
                tcp_mtup_init(sk);
                tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
index 25ecc6e2478b5eb9a5ad64b4ed61b4e7a937bc0f..4c6ef47eb1c372d72ba2eab9d877672b7ca9646d 100644 (file)
@@ -1726,7 +1726,8 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
        sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
                        "%08X %5d %8d %lu %d %p %u %u %u %u %d",
                i, src, srcp, dest, destp, sp->sk_state,
-               tp->write_seq - tp->snd_una, tp->rcv_nxt - tp->copied_seq,
+               tp->write_seq - tp->snd_una,
+               (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
                timer_active,
                jiffies_to_clock_t(timer_expires - jiffies),
                icsk->icsk_retransmits,
index 2b9b7f6c7f7c101867d1318bcc56d64b995eb0ed..54b2ef7d3efeb26e2fa7866d344604faa47c8bca 100644 (file)
@@ -440,8 +440,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                        newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len;
                newtp->rx_opt.mss_clamp = req->mss;
                TCP_ECN_openreq_child(newtp, req);
-               if (newtp->ecn_flags&TCP_ECN_OK)
-                       sock_set_flag(newsk, SOCK_NO_LARGESEND);
 
                TCP_INC_STATS_BH(TCP_MIB_PASSIVEOPENS);
        }
index bdd71db8bf908e3d20dad25ee43ec777970c139c..5a7cb4a9c867f7a0cd4c1edf738dae2138a9e6c6 100644 (file)
@@ -2044,8 +2044,6 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        memset(th, 0, sizeof(struct tcphdr));
        th->syn = 1;
        th->ack = 1;
-       if (dst->dev->features&NETIF_F_TSO)
-               ireq->ecn_ok = 0;
        TCP_ECN_make_synack(req, th);
        th->source = inet_sk(sk)->sport;
        th->dest = ireq->rmt_port;
index b4b7d441af25411f04af9e7a657cb21488f51370..968a14be0d0578eb17f48e2ea03018845cbd40f8 100644 (file)
@@ -505,7 +505,7 @@ ipq_rcv_skb(struct sk_buff *skb)
        if (type <= IPQM_BASE)
                return;
        
-       if (security_netlink_recv(skb))
+       if (security_netlink_recv(skb, CAP_NET_ADMIN))
                RCV_SKB_FAIL(-EPERM);   
 
        write_lock_bh(&queue_lock);
index 2e72f89a7019929f2da18cb74ef1ba26e9d1d74b..0b5bd5587a3e67926b9baf2322d7797b1c70dd34 100644 (file)
@@ -1281,7 +1281,8 @@ int ip6t_register_table(struct xt_table *table,
                return ret;
        }
 
-       if (xt_register_table(table, &bootstrap, newinfo) != 0) {
+       ret = xt_register_table(table, &bootstrap, newinfo);
+       if (ret != 0) {
                xt_free_table_info(newinfo);
                return ret;
        }
index a50eb306e9e277605e4202cc14cacdf026357b59..b36d5b2e7c30e8a4217b1d3945fe5983dc6bc42d 100644 (file)
@@ -1469,7 +1469,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
                   dest->s6_addr32[0], dest->s6_addr32[1],
                   dest->s6_addr32[2], dest->s6_addr32[3], destp,
                   sp->sk_state, 
-                  tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq,
+                  tp->write_seq-tp->snd_una,
+                  (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
                   timer_active,
                   jiffies_to_clock_t(timer_expires - jiffies),
                   icsk->icsk_retransmits,
index 6f20b4206e08a56bc3b79902b9fededeac826cd9..b592c4bc33312a8d7efa7550936ff96182886386 100644 (file)
@@ -124,7 +124,6 @@ static int __init ircomm_tty_init(void)
        driver->owner           = THIS_MODULE;
        driver->driver_name     = "ircomm";
        driver->name            = "ircomm";
-       driver->devfs_name      = "ircomm";
        driver->major           = IRCOMM_TTY_MAJOR;
        driver->minor_start     = IRCOMM_TTY_MINOR;
        driver->type            = TTY_DRIVER_TYPE_SERIAL;
index f8e6cb0db04bc79712e17f406af1bf8e40bcaadc..95cf1234ea17ff2e88a088c3da5766361bbaa7e4 100644 (file)
@@ -173,13 +173,14 @@ void irlan_client_discovery_indication(discinfo_t *discovery,
        rcu_read_lock();
        self = irlan_get_any();
        if (self) {
-               IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
+               IRDA_ASSERT(self->magic == IRLAN_MAGIC, goto out;);
 
                IRDA_DEBUG(1, "%s(), Found instance (%08x)!\n", __FUNCTION__ ,
                      daddr);
                
                irlan_client_wakeup(self, saddr, daddr);
        }
+IRDA_ASSERT_LABEL(out:)
        rcu_read_unlock();
 }
        
index e4fe1e80029c55cdb89a0b7d5c47763fda282f24..ad6caba02a7be931439ae73f37f56c4b02a992ed 100644 (file)
 #include <linux/skbuff.h>
 #include <linux/tty.h>
 #include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/netdevice.h>
 #include <linux/miscdevice.h>
 #include <linux/poll.h>
index b1622b7de1cfb0a6f3b4c0cf496622321b668cd6..42a178aa30f9fde82b434b48ece146e8b1e27b98 100644 (file)
@@ -411,7 +411,10 @@ config NETFILTER_XT_MATCH_STATISTIC
        tristate '"statistic" match support'
        depends on NETFILTER_XTABLES
        help
-         statistic module
+         This option adds a `statistic' match, which allows you to match
+         on packets periodically or randomly with a given percentage.
+
+         To compile it as a module, choose M here.  If unsure, say N.
 
 config NETFILTER_XT_MATCH_STRING
        tristate  '"string" match support'
index b8c7c567c9df5a0c3a27e6cbf01680854a7b8914..af4845971f70606d568e731093118b74c0fbf104 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/errno.h>
 #include <linux/netlink.h>
 #include <linux/spinlock.h>
+#include <linux/interrupt.h>
 #include <linux/notifier.h>
 
 #include <linux/netfilter.h>
index 0c6da496cfa9fc5311115b81b26b1b8176fcaa9d..0839b701b9309f3fd9a98e58c31c0f1a4e897406 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/sctp.h>
 #include <linux/string.h>
 #include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_protocol.h>
index b88e82a1a987461dfae03f7686bdd348cc3c6d26..ec9f0efea6bb58e18bb7bcf9dbab66b333029fac 100644 (file)
@@ -229,7 +229,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb,
                 NFNL_SUBSYS_ID(nlh->nlmsg_type),
                 NFNL_MSG_TYPE(nlh->nlmsg_type));
 
-       if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
+       if (security_netlink_recv(skb, CAP_NET_ADMIN)) {
                DEBUGP("missing CAP_NET_ADMIN\n");
                *errp = -EPERM;
                return -1;
index 86a4ac33de3495791e5e465a5352afe79690c3cf..49ef41e34c48309eb3d7dc6553056a822e6fb112 100644 (file)
@@ -680,11 +680,19 @@ dev_cmp(struct nfqnl_queue_entry *entry, unsigned long ifindex)
        if (entinf->indev)
                if (entinf->indev->ifindex == ifindex)
                        return 1;
-                       
        if (entinf->outdev)
                if (entinf->outdev->ifindex == ifindex)
                        return 1;
-
+#ifdef CONFIG_BRIDGE_NETFILTER
+       if (entry->skb->nf_bridge) {
+               if (entry->skb->nf_bridge->physindev &&
+                   entry->skb->nf_bridge->physindev->ifindex == ifindex)
+                       return 1;
+               if (entry->skb->nf_bridge->physoutdev &&
+                   entry->skb->nf_bridge->physoutdev->ifindex == ifindex)
+                       return 1;
+       }
+#endif
        return 0;
 }
 
index 9316c753692fef1bbbd81f71a381000d6edbb024..843383e01d4155179c66928fafd08e5e64f2f8ac 100644 (file)
@@ -151,7 +151,7 @@ match(const struct sk_buff *skb,
                && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) 
                        && (ntohs(sh->dest) <= info->dpts[1])), 
                        XT_SCTP_DEST_PORTS, info->flags, info->invflags)
-               && SCCHECK(match_packet(skb, protoff,
+               && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t),
                                        info->chunkmap, info->chunk_match_type,
                                        info->flag_info, info->flag_count, 
                                        hotdrop),
index 1b61dac9c873f2d82ec29812f96f6d134b8bfc67..a9a63aa6893692a774b52c1cae9441262c2c1602 100644 (file)
@@ -260,7 +260,7 @@ static int __init xt_tcpudp_init(void)
        return ret;
 
 out_unreg_udp:
-       xt_unregister_match(&tcp_matchstruct);
+       xt_unregister_match(&udp_matchstruct);
 out_unreg_tcp6:
        xt_unregister_match(&tcp6_matchstruct);
 out_unreg_tcp:
index f329b72578f568440d8e0ef331210eb6408a9bb8..edf084becd5ecafccb25a99ddc0c8cd997336125 100644 (file)
@@ -320,7 +320,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto errout;
        }
 
-       if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb)) {
+       if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb, CAP_NET_ADMIN)) {
                err = -EPERM;
                goto errout;
        }
index 5003acb1591975c995ed92decb6ab412dc988b1a..0539a8362858997cbe6baa2d2445c75c081e3996 100644 (file)
@@ -191,7 +191,8 @@ static int __init tipc_init(void)
        int res;
 
        tipc_log_reinit(CONFIG_TIPC_LOG);
-       info("Activated (compiled " __DATE__ " " __TIME__ ")\n");
+       info("Activated (version " TIPC_MOD_VER 
+            " compiled " __DATE__ " " __TIME__ ")\n");
 
        tipc_own_addr = 0;
        tipc_remote_management = 1;
index d64658053746f093d4429cdcd076666bf4bf99ce..c6831c75cfa4dd9ec9c03fb3da7cb451928f7a0c 100644 (file)
@@ -2,7 +2,7 @@
  * net/tipc/link.c: TIPC link code
  * 
  * Copyright (c) 1996-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 2004-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -988,17 +988,18 @@ static int link_bundle_buf(struct link *l_ptr,
        struct tipc_msg *bundler_msg = buf_msg(bundler);
        struct tipc_msg *msg = buf_msg(buf);
        u32 size = msg_size(msg);
-       u32 to_pos = align(msg_size(bundler_msg));
-       u32 rest = link_max_pkt(l_ptr) - to_pos;
+       u32 bundle_size = msg_size(bundler_msg);
+       u32 to_pos = align(bundle_size);
+       u32 pad = to_pos - bundle_size;
 
        if (msg_user(bundler_msg) != MSG_BUNDLER)
                return 0;
        if (msg_type(bundler_msg) != OPEN_MSG)
                return 0;
-       if (rest < align(size))
+       if (skb_tailroom(bundler) < (pad + size))
                return 0;
 
-       skb_put(bundler, (to_pos - msg_size(bundler_msg)) + size);
+       skb_put(bundler, pad + size);
        memcpy(bundler->data + to_pos, buf->data, size);
        msg_set_size(bundler_msg, to_pos + size);
        msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
index 861322b935daf1be3aee4ac4e5eca284c4a7c89a..fc6d09630ccd5e114afca1e631845778d0d21525 100644 (file)
@@ -2,7 +2,7 @@
  * net/tipc/node.c: TIPC node management routines
  * 
  * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
+ * Copyright (c) 2005-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -592,6 +592,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
        struct sk_buff *buf;
        struct node *n_ptr;
         struct tipc_node_info node_info;
+       u32 payload_size;
 
        if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
                return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -608,8 +609,11 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
        /* For now, get space for all other nodes 
           (will need to modify this when slave nodes are supported */
 
-       buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(node_info)) *
-                                  (tipc_max_nodes - 1));
+       payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1);
+       if (payload_size > 32768u)
+               return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+                                                  " (too many nodes)");
+       buf = tipc_cfg_reply_alloc(payload_size);
        if (!buf)
                return NULL;
 
@@ -633,6 +637,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
        struct sk_buff *buf;
        struct node *n_ptr;
         struct tipc_link_info link_info;
+       u32 payload_size;
 
        if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
                return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -645,12 +650,15 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
 
         if (!tipc_nodes)
                 return tipc_cfg_reply_none();
-
-       /* For now, get space for 2 links to all other nodes + bcast link 
-          (will need to modify this when slave nodes are supported */
-
-       buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(link_info)) *
-                                  (2 * (tipc_max_nodes - 1) + 1));
+       
+       /* Get space for all unicast links + multicast link */
+
+       payload_size = TLV_SPACE(sizeof(link_info)) *
+               (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1);
+       if (payload_size > 32768u)
+               return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+                                                  " (too many links)");
+       buf = tipc_cfg_reply_alloc(payload_size);
        if (!buf)
                return NULL;
 
index 267999c5a240fb570fa9e52e4694b482b2e7f700..5ab3d08602e2528d31dc45f9cea84c656b9dbfb3 100644 (file)
@@ -2,7 +2,7 @@
  * net/tipc/zone.h: Include file for TIPC zone management routines
  * 
  * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
+ * Copyright (c) 2005-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,7 @@
  * struct _zone - TIPC zone structure
  * @addr: network address of zone
  * @clusters: array of pointers to all clusters within zone
- * @links: (used for inter-zone communication)
+ * @links: number of (unicast) links to zone
  */
  
 struct _zone {
index d901465ce0135093276d55adabbb7691591097c3..fd11d4048b5223c1fe7b39e4dc66f82b0f988f67 100644 (file)
@@ -128,6 +128,30 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 #define UNIX_ABSTRACT(sk)      (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
 
+#ifdef CONFIG_SECURITY_NETWORK
+static void unix_get_peersec_dgram(struct sk_buff *skb)
+{
+       int err;
+
+       err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb),
+                                              UNIXSECLEN(skb));
+       if (err)
+               *(UNIXSECDATA(skb)) = NULL;
+}
+
+static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
+{
+       scm->secdata = *UNIXSECDATA(skb);
+       scm->seclen = *UNIXSECLEN(skb);
+}
+#else
+static void unix_get_peersec_dgram(struct sk_buff *skb)
+{ }
+
+static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
+{ }
+#endif /* CONFIG_SECURITY_NETWORK */
+
 /*
  *  SMP locking strategy:
  *    hash table is protected with spinlock unix_table_lock
@@ -1291,6 +1315,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        if (siocb->scm->fp)
                unix_attach_fds(siocb->scm, skb);
 
+       unix_get_peersec_dgram(skb);
+
        skb->h.raw = skb->data;
        err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
        if (err)
@@ -1570,6 +1596,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
                memset(&tmp_scm, 0, sizeof(tmp_scm));
        }
        siocb->scm->creds = *UNIXCREDS(skb);
+       unix_set_secdata(siocb->scm, skb);
 
        if (!(flags & MSG_PEEK))
        {
index 17b29ec3c41779d70562113ed1219e68ff3ae5fc..43f00fc28a3d14e724ba70af6915c73680e28d0b 100644 (file)
@@ -1164,8 +1164,6 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
        return res;
 }
 
-EXPORT_SYMBOL(xfrm_state_mtu);
-
 int xfrm_init_state(struct xfrm_state *x)
 {
        struct xfrm_state_afinfo *afinfo;
index c21dc26141eae947f921e881016cbd64da735c64..3e6a722d072ed8b75c0561b82617abd5a2d3adcd 100644 (file)
@@ -1435,7 +1435,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err
        link = &xfrm_dispatch[type];
 
        /* All operations require privileges, even GET */
-       if (security_netlink_recv(skb)) {
+       if (security_netlink_recv(skb, CAP_NET_ADMIN)) {
                *errp = -EPERM;
                return -1;
        }
index 841eb4e5c62b6e91b0e799802791289366bfb45d..57673ee07ceb59b45a05167ab1766eb551ad4ac8 100644 (file)
@@ -33,9 +33,9 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
 
 EXPORT_SYMBOL(cap_netlink_send);
 
-int cap_netlink_recv(struct sk_buff *skb)
+int cap_netlink_recv(struct sk_buff *skb, int cap)
 {
-       if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
+       if (!cap_raised(NETLINK_CB(skb).eff_cap, cap))
                return -EPERM;
        return 0;
 }
index 310fcdf7b7495ce07e50c393e5d810817a4e7817..9135408085770e604dde12f53e32afdc898b8b72 100644 (file)
@@ -675,9 +675,9 @@ static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-static int dummy_netlink_recv (struct sk_buff *skb)
+static int dummy_netlink_recv (struct sk_buff *skb, int cap)
 {
-       if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN))
+       if (!cap_raised (NETLINK_CB (skb).eff_cap, cap))
                return -EPERM;
        return 0;
 }
index 28832e689800b9c9250b54cc4c0be918adebb51d..b85afcf3852774166aeb5b9b65200388e8ee4a72 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/sysctl.h>
 #include <linux/audit.h>
 #include <linux/string.h>
+#include <linux/selinux.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -3420,7 +3421,13 @@ out:
 static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
 {
        int err = 0;
-       u32 peer_sid = selinux_socket_getpeer_dgram(skb);
+       u32 peer_sid;
+
+       if (skb->sk->sk_family == PF_UNIX)
+               selinux_get_inode_sid(SOCK_INODE(skb->sk->sk_socket),
+                                     &peer_sid);
+       else
+               peer_sid = selinux_socket_getpeer_dgram(skb);
 
        if (peer_sid == SECSID_NULL)
                return -EINVAL;
@@ -3432,8 +3439,6 @@ static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
        return 0;
 }
 
-
-
 static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 {
        return sk_alloc_security(sk, family, priority);
@@ -3641,32 +3646,32 @@ static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
 
 static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
-       struct task_security_struct *tsec;
-       struct av_decision avd;
        int err;
 
        err = secondary_ops->netlink_send(sk, skb);
        if (err)
                return err;
 
-       tsec = current->security;
-
-       avd.allowed = 0;
-       avc_has_perm_noaudit(tsec->sid, tsec->sid,
-                               SECCLASS_CAPABILITY, ~0, &avd);
-       cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed);
-
        if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
                err = selinux_nlmsg_perm(sk, skb);
 
        return err;
 }
 
-static int selinux_netlink_recv(struct sk_buff *skb)
+static int selinux_netlink_recv(struct sk_buff *skb, int capability)
 {
-       if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
-               return -EPERM;
-       return 0;
+       int err;
+       struct avc_audit_data ad;
+
+       err = secondary_ops->netlink_recv(skb, capability);
+       if (err)
+               return err;
+
+       AVC_AUDIT_DATA_INIT(&ad, CAP);
+       ad.u.cap = capability;
+
+       return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
+                           SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad);
 }
 
 static int ipc_alloc_security(struct task_struct *task,
index 10c1772bf3ea3dbe9ff06960f945d06457112a35..340332c6d97337889e73927730747feecd6e37a6 100644 (file)
@@ -29,7 +29,6 @@
 #include <sound/info.h>
 #include <sound/version.h>
 #include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/mutex.h>
 #include <stdarg.h>
 
index cd862728346cb03e74abe870f4a997c0e5fa6de7..264f2efd1af88ffc26b3b333d08e88a0dd6e19e1 100644 (file)
@@ -32,7 +32,6 @@
 #include <sound/control.h>
 #include <sound/initval.h>
 #include <linux/kmod.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/mutex.h>
 
 #define SNDRV_OS_MINORS 256
@@ -42,7 +41,6 @@ int snd_major;
 EXPORT_SYMBOL(snd_major);
 
 static int cards_limit = 1;
-static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO;
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture driver for soundcards.");
@@ -51,10 +49,6 @@ module_param(major, int, 0444);
 MODULE_PARM_DESC(major, "Major # for sound driver.");
 module_param(cards_limit, int, 0444);
 MODULE_PARM_DESC(cards_limit, "Count of auto-loadable soundcards.");
-#ifdef CONFIG_DEVFS_FS
-module_param(device_mode, int, 0444);
-MODULE_PARM_DESC(device_mode, "Device file permission mask for devfs.");
-#endif
 MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
 
 /* this one holds the actual max. card number currently available.
@@ -273,8 +267,6 @@ int snd_register_device(int type, struct snd_card *card, int dev,
                return minor;
        }
        snd_minors[minor] = preg;
-       if (type != SNDRV_DEVICE_TYPE_CONTROL || preg->card >= cards_limit)
-               devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
        if (card)
                device = card->dev;
        class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
@@ -314,9 +306,6 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
                return -EINVAL;
        }
 
-       if (mptr->type != SNDRV_DEVICE_TYPE_CONTROL ||
-           mptr->card >= cards_limit)                  /* created in sound.c */
-               devfs_remove("snd/%s", mptr->name);
        class_device_destroy(sound_class, MKDEV(major, minor));
 
        snd_minors[minor] = NULL;
@@ -411,24 +400,17 @@ int __exit snd_minor_info_done(void)
 
 static int __init alsa_sound_init(void)
 {
-       short controlnum;
-
        snd_major = major;
        snd_ecards_limit = cards_limit;
-       devfs_mk_dir("snd");
        if (register_chrdev(major, "alsa", &snd_fops)) {
                snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
-               devfs_remove("snd");
                return -EIO;
        }
        if (snd_info_init() < 0) {
                unregister_chrdev(major, "alsa");
-               devfs_remove("snd");
                return -ENOMEM;
        }
        snd_info_minor_register();
-       for (controlnum = 0; controlnum < cards_limit; controlnum++)
-               devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
 #ifndef MODULE
        printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
 #endif
@@ -437,16 +419,10 @@ static int __init alsa_sound_init(void)
 
 static void __exit alsa_sound_exit(void)
 {
-       short controlnum;
-
-       for (controlnum = 0; controlnum < cards_limit; controlnum++)
-               devfs_remove("snd/controlC%d", controlnum);
-
        snd_info_minor_unregister();
        snd_info_done();
        if (unregister_chrdev(major, "alsa") != 0)
                snd_printk(KERN_ERR "unable to unregister major device number %d\n", major);
-       devfs_remove("snd");
 }
 
 module_init(alsa_sound_init)
index d33bb464f70e9a536a3448fdd7f69ae181bac0b7..a332899489021a870ad67face6268f6f690197ff 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/major.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
@@ -564,9 +563,6 @@ static int __init oss_init(void)
        sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
 
        for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
-               devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
-                               S_IFCHR | dev_list[i].mode,
-                               "sound/%s", dev_list[i].name);
                class_device_create(sound_class, NULL,
                                    MKDEV(SOUND_MAJOR, dev_list[i].minor),
                                    NULL, "%s", dev_list[i].name);
@@ -574,15 +570,10 @@ static int __init oss_init(void)
                if (!dev_list[i].num)
                        continue;
 
-               for (j = 1; j < *dev_list[i].num; j++) {
-                       devfs_mk_cdev(MKDEV(SOUND_MAJOR,
-                                               dev_list[i].minor + (j*0x10)),
-                                       S_IFCHR | dev_list[i].mode,
-                                       "sound/%s%d", dev_list[i].name, j);
+               for (j = 1; j < *dev_list[i].num; j++)
                        class_device_create(sound_class, NULL,
                                            MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
                                            NULL, "%s%d", dev_list[i].name, j);
-               }
        }
 
        if (sound_nblocks >= 1024)
@@ -596,14 +587,11 @@ static void __exit oss_cleanup(void)
        int i, j;
 
        for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
-               devfs_remove("sound/%s", dev_list[i].name);
                class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor));
                if (!dev_list[i].num)
                        continue;
-               for (j = 1; j < *dev_list[i].num; j++) {
-                       devfs_remove("sound/%s%d", dev_list[i].name, j);
+               for (j = 1; j < *dev_list[i].num; j++)
                        class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
-               }
        }
        
        unregister_sound_special(1);
index 6f849720aef35fa08552dc1bc8e16fc84383e0aa..7535ec821dcf8dfb53a55046853ad86b0cbff54d 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/sound.h>
 #include <linux/major.h>
 #include <linux/kmod.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/device.h>
 
 #define SOUND_STEP 16
@@ -172,8 +171,6 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati
        else
                sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
 
-       devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),
-                       S_IFCHR | mode, s->name);
        class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor),
                            dev, s->name+6);
        return r;
@@ -197,7 +194,6 @@ static void sound_remove_unit(struct sound_unit **list, int unit)
        p = __sound_remove_unit(list, unit);
        spin_unlock(&sound_loader_lock);
        if (p) {
-               devfs_remove(p->name);
                class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor));
                kfree(p);
        }
@@ -570,7 +566,6 @@ static void __exit cleanup_soundcore(void)
        /* We have nothing to really do here - we know the lists must be
           empty */
        unregister_chrdev(SOUND_MAJOR, "sound");
-       devfs_remove("sound");
        class_destroy(sound_class);
 }
 
@@ -580,7 +575,6 @@ static int __init init_soundcore(void)
                printk(KERN_ERR "soundcore: sound device already in use.\n");
                return -EBUSY;
        }
-       devfs_mk_dir ("sound");
        sound_class = class_create(THIS_MODULE, "sound");
        if (IS_ERR(sound_class))
                return PTR_ERR(sound_class);